pokerogue/src/temp_interpreter.ts
2023-03-28 14:54:52 -04:00

46178 lines
1.4 MiB

import * as ts from "typescript";
import BattleScene from "./battle-scene";
import Pokemon from "./pokemon";
var moveAnimsContent;
let funcNames = [];
let animFuncsContents = '';
let animTemplateContents = '';
var scene: BattleScene;
var gBattleAnimAttacker: Pokemon;
var gBattleAnimTarget: Pokemon;
var gBattleAnimArgs = [ 0, 0, 0, 0, 0, 0, 0 ];
var gSprites: Sprite[] = [];
var gTasks: Function[] = [];
var gAnimVisualTaskCount: integer = 0;
class SpriteTemplate {
public imageName: string;
public affineAnim: Function;
public callback: Function;
constructor(imageName: string, affineAnim: Function, callback: Function) {
this.imageName = imageName;
this.affineAnim = affineAnim;
this.callback = callback;
}
}
class Sprite {
public template: SpriteTemplate;
public callback: Function;
public x: integer;
public y: integer;
public x2: integer;
public y2: integer;
public centerToCornerVecX: integer;
public centerToCornerVecY: integer;
public animPaused: boolean = true;
public affineAnimPaused: boolean = true;
public animLoopCounter: integer;
public data: integer[] = [ 0, 0, 0, 0, 0, 0, 0, 0 ];
public hFlip: boolean;
public vFlip: boolean;
public subpriority: integer;
constructor() {
}
};
/*function createSprite(sheetId: string, callback: Function, target: AnimTarget, subpriorityOffset: integer, args: any) {
console.log(sheetId, target, subpriorityOffset, args)
const sprite = new Sprite();
callback(sprite);
}*/
function CreateSprite(template: SpriteTemplate, target: AnimTarget, subpriorityOffset: integer, args: any[])
{
/*s32 i;
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
s16 subpriority;
sBattleAnimScriptPtr++;
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;*/
let value = target == AnimTarget.TARGET
? 0x80 | (subpriorityOffset & 0x7F)
: (subpriorityOffset & 0x7F);
for (let i in args)
{
let arg = args[i];
if (arg instanceof Boolean)
arg = arg ? 1 : 0;
gBattleAnimArgs[i] = arg as number;
}
var subpriority = 0;
/*if (argVar & 128)
{
argVar ^= 128;
if (argVar >= 64)
argVar -= 64;
else
argVar *= -1;
subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (s8)(argVar);
}
else
{
if (argVar >= 64)
argVar -= 64;
else
argVar *= -1;
subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + (s8)(argVar);
}
if (subpriority < 3)
subpriority = 3;*/
CreateSpriteAndAnimate(
template,
GetBattlerSpriteCoord(gBattleAnimTarget, BattlerCoord.X_2),
GetBattlerSpriteCoord(gBattleAnimTarget, BattlerCoord.Y_PIC_OFFSET),
subpriority);
gAnimVisualTaskCount++;
}
function CreateNewSprite(index: integer, template: SpriteTemplate, x: integer, y: integer, subpriority: integer): integer {
const sprite = new Sprite();
sprite.subpriority = subpriority;
sprite.template = template;
sprite.callback = template.callback;
sprite.x = x;
sprite.y = y;
sprite.callback();
/*
struct Sprite *sprite = &gSprites[index];
ResetSprite(sprite);
sprite->inUse = TRUE;
sprite->animBeginning = TRUE;
sprite->affineAnimBeginning = TRUE;
sprite->usingSheet = TRUE;
sprite->subpriority = subpriority;
sprite->oam = *template->oam;
sprite->anims = template->anims;
sprite->affineAnims = template->affineAnims;
sprite->template = template;
sprite->callback = template->callback;
sprite->x = x;
sprite->y = y;
CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
if (template->tileTag == TAG_NONE)
{
s16 tileNum;
sprite->images = template->images;
tileNum = AllocSpriteTiles((u8)(sprite->images->size / TILE_SIZE_4BPP));
if (tileNum == -1)
{
ResetSprite(sprite);
return MAX_SPRITES;
}
sprite->oam.tileNum = tileNum;
sprite->usingSheet = FALSE;
sprite->sheetTileStart = 0;
}
else
{
sprite->sheetTileStart = GetSpriteTileStartByTag(template->tileTag);
SetSpriteSheetFrameTileNum(sprite);
}
if (sprite->oam.affineMode & ST_OAM_AFFINE_ON_MASK)
InitSpriteAffineAnim(sprite);
if (template->paletteTag != TAG_NONE)
sprite->oam.paletteNum = IndexOfSpritePaletteTag(template->paletteTag);
return index;*/
}
function CreateSpriteAndAnimate(template: SpriteTemplate, x: integer, y: integer, subpriority: integer) {
/*u8 i;
for (i = 0; i < MAX_SPRITES; i++)
{
struct Sprite *sprite = &gSprites[i];
if (!gSprites[i].inUse)
{
u8 index = CreateSpriteAt(i, template, x, y, subpriority);
if (index == MAX_SPRITES)
return MAX_SPRITES;
gSprites[i].callback(sprite);
if (gSprites[i].inUse)
AnimateSprite(sprite);
return index;
}
}
return MAX_SPRITES;*/
}
function CreateVisualTask(taskFunc: Function, taskPriority: integer, args: any[]) {
/*TaskFunc taskFunc;
u8 taskPriority;
u8 taskId;
u8 numArgs;
s32 i;
sBattleAnimScriptPtr++;
taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 4;
taskPriority = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
numArgs = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
for (i = 0; i < numArgs; i++)
{
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}*/
const taskId = CreateTask(taskFunc, taskPriority);
taskFunc(taskId);
gAnimVisualTaskCount++;
}
function CreateTask(func: Function, priority: integer): integer
{
const taskId = gTasks.length;
gTasks.push(func);
return taskId;
}
enum AnimTarget {
ATTACKER,
TARGET
};
enum BattlerCoord {
X,
X_2,
Y,
Y_PIC_OFFSET,
Y_PIC_OFFSET_DEFAULT
};
enum BattleSide {
PLAYER,
ENEMY
}
function GetBattlerSpriteCoord(target: Pokemon, coordType: BattlerCoord): integer {
console.log('TEST1');
switch (coordType) {
case BattlerCoord.X:
case BattlerCoord.X_2:
return target.x;
case BattlerCoord.Y:
return target.y;
case BattlerCoord.Y_PIC_OFFSET:
case BattlerCoord.Y_PIC_OFFSET_DEFAULT:
return target.y;
}
}
function GetBattlerSpriteCoord2(target: Pokemon, coordType: BattlerCoord): integer {
console.log('TEST2')
/*var species;
struct BattleSpriteInfo *spriteInfo;
if (coordType == BATTLER_COORD_Y_PIC_OFFSET || coordType == BATTLER_COORD_Y_PIC_OFFSET_DEFAULT)
{
spriteInfo = gBattleSpritesDataPtr.battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = gAnimBattlerSpecies[battlerId];
else
species = spriteInfo[battlerId].transformSpecies;
if (coordType == BATTLER_COORD_Y_PIC_OFFSET)
return GetBattlerSpriteFinal_Y(battlerId, species, true);
else
return GetBattlerSpriteFinal_Y(battlerId, species, false);
}
else
{
return GetBattlerSpriteCoord(battlerId, coordType);
}*/
switch (coordType) {
case BattlerCoord.X:
return target.x;
case BattlerCoord.Y:
return target.y;
case BattlerCoord.Y_PIC_OFFSET:
return target.y;
}
}
function SetAnimSpriteInitialXOffset(sprite: Sprite, xOffset: integer) {
let attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BattlerCoord.X);
let targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BattlerCoord.X);
if (attackerX > targetX) {
sprite.x -= xOffset;
} else if (attackerX < targetX) {
sprite.x += xOffset;
} else {
if (GetBattlerSide(gBattleAnimAttacker) !== BattleSide.PLAYER)
sprite.x -= xOffset;
else
sprite.x += xOffset;
}
}
function StoreSpriteCallbackInData6(sprite: Sprite, callback: Function)
{
//sprite.data[6] = (callback) & 0xffff;
//sprite.data[7] = (callback) >> 16;
}
function SetCallbackToStoredInData6(sprite: Sprite)
{
console.log('need to fix this');
//u32 callback = (u16)sprite->data[6] | (sprite->data[7] << 16);
//sprite->callback = (void (*)(struct Sprite *))callback;
}
function GetBattlerSide(battler: Pokemon): BattleSide
{
return battler.player ? BattleSide.PLAYER : BattleSide.ENEMY;
}
const multiPatterns = [
[ /\nMove_(.*?):/g, '\nfunction doMoveAnim_$1() {' ],
[ /\t+end\n(.*?):/g, '\tend\n\nfunction doAnim_$1() {' ],
[ /\n\t+(?:end|return)/g, '\n}' ]
];
const linePatterns = [
[ /([\t ]+)playsewithpan (.*?), SOUND_PAN_(?:ATTACKER|TARGET)/, res => {
return `${res[1]}scene.sound.play(\'${res[2].slice(3).toLowerCase()}\');\n`;
} ],
[ /([\t ]+)createsprite (.*?), (.*?), (.*?)(?:, (.*?))?$/, res => {
let ret = res[0];
const args = res[5].split(', ');
let search = `const struct SpriteTemplate ${res[2]}`;
let i = animTemplates.indexOf(search);
if (i > -1) {
const template = animTemplates.slice(i, animTemplates.indexOf('}', i) + 1);
search = `.tileTag = ANIM_TAG_`;
i = template.indexOf(search);
const imageName = template.slice(i + search.length, template.indexOf(',', i));
search = '.affineAnims = ';
i = template.indexOf(search);
const affineAnimName = template.slice(i + search.length, template.indexOf(',', i));
search = '.callback = ';
i = template.indexOf(search);
const animFuncName = template.slice(i + search.length, template.indexOf(',', i));
console.log(imageName, animFuncName)
animTemplateContents += `const ${args[0]} = new SpriteTemplate('${imageName}', ${affineAnimName !== 'gDummySpriteAffineAnimTable' && false ? affineAnimName : 'null'}, ${animFuncName});\n`
if (funcNames.indexOf(animFuncName) === -1) {
search = `void ${animFuncName}(struct Sprite *sprite`;
i = animTemplates.indexOf(search);
if (i > -1) {
funcNames.push(animFuncName);
processFunc(animFuncName, animTemplates.slice(i, /\}\n\n(?:\n|static void)/g.exec(animTemplates.slice(i)).index + i + 1));
return `${res[1]}CreateSprite(${res[2]}, AnimTarget.${res[3] === 'ANIM_TARGET' ? 'TARGET' : 'ATTACKER'}, ${res[4]}, [ ${res[5]} ]);`;
} else
console.log(animFuncName, 'not found');
} else
return `${res[1]}CreateSprite(${res[2]}, ${animFuncName}, AnimTarget.${res[3] === 'ANIM_TARGET' ? 'TARGET' : 'ATTACKER'}, ${res[4]}, [ ${res[5]} ]);`;
}
return `${res[1]}// ${ret}`;
} ],
[ /([\t ]+)createvisualtask (.*?), (.*?)(?:, (.*?))?$/, res => {
let ret = res[0];
const args = res[4].split(', ');
/*
let search = `const struct SpriteTemplate ${args[0]}`;
let i = animTemplates.indexOf(search);
if (i > -1) {
const template = animTemplates.slice(i, animTemplates.indexOf('}', i) + 1);
search = `.tileTag = ANIM_TAG_`;
i = template.indexOf(search);
const imageName = template.slice(i + search.length, template.indexOf(',', i));
search = '.affineAnims = ';
i = template.indexOf(search);
const affineAnimName = template.slice(i + search.length, template.indexOf(',', i));
search = '.callback = ';
i = template.indexOf(search);
const animFuncName = template.slice(i + search.length, template.indexOf(',', i));
console.log(imageName, animFuncName)
animTemplateContents += `const ${args[0]} = new SpriteTemplate('${imageName}', ${affineAnimName !== 'gDummySpriteAffineAnimTable' && false ? affineAnimName : 'null'}, ${animFuncName});\n`
if (funcNames.indexOf(animFuncName) === -1) {
search = `void ${animFuncName}(struct Sprite *sprite`;
i = animTemplates.indexOf(search);
if (i > -1) {
funcNames.push(animFuncName);
processFunc(animFuncName, animTemplates.slice(i, /\}\n\n(?:\n|static void)/g.exec(animTemplates.slice(i)).index + i + 1));
return `${res[1]}CreateSprite(${args[0]}, AnimTarget.${res[3] === 'ANIM_TARGET' ? 'TARGET' : 'ATTACKER'}, ${res[4]}, [ ${res[5]} ]);`;
} else
console.log(animFuncName, 'not found');
} else
return `${res[1]}CreateSprite(${args[0]}, ${animFuncName}, AnimTarget.${res[3] === 'ANIM_TARGET' ? 'TARGET' : 'ATTACKER'}, ${res[4]}, [ ${res[5]} ]);`;
}
return `${res[1]}// ${ret}`;*/
return res[0];
} ],
[ /([\t ]+)delay (\d+)/, res => {
return `${res[1]}delay ${Math.round(16.6666666667 * parseInt(res[2]))}`;
} ],
[ /splitbgprio.*?$/, '' ],
[ /ANIM\_TARGET/g, 'AnimTarget.TARGET' ],
[ /ANIM\_ATTACKER/g, 'AnimTarget.ATTACKER' ]
];
const funcLinePatterns = [
[ /^[\t ]+([A-Z][a-zA-Z0-9\_]+)\((.*?)\);$/, res => {
const funcName = res[1];
if (funcNames.indexOf(funcName) === -1) {
const searchRes = new RegExp(`\n\n(?:static )?([^ ]+) ${funcName}\\((.*?)\\)\n\{`).exec(animTemplates);
console.log('found', funcName, searchRes)
if (searchRes) {
const funcIndex = searchRes.index;
const funcContent = animTemplates.slice(funcIndex + 2, /\}\n\n[^ ]/.exec(animTemplates.slice(funcIndex + 2)).index + funcIndex + 3);
funcNames.push(funcName);
processFunc(funcName, funcContent);
}
}
return res[0];
} ],
[ /\->/g, '.' ],
[ /(\(|,)&([A-Za-z])/, '$1$2' ],
[ /^([ \t]+)(int|bool8|u8|u16|u32|s8|s16|s32) ([a-zA-Z0-9\_]+),/, '$1$2 $3; $1$2' ],
[ /^([ \t]+)(?:int|bool8|u8|u16|u32|s8|s16|s32) ([a-zA-Z0-9\_]+)(,| =|;)/, '$1let $2$3' ],
[ /(int|bool8|bool16|u8|u16|u32|s8|s16|s32) (?:\*)?([a-zA-Z0-9\_]+)(,|\))/g, '$2: $1$3' ],
[ /: (?:int|u8|u16|u32|s8|s16|s32)(,|\))/g, ': integer$1' ],
[ /: (?:bool8)(,|\))/g, ': boolean$1' ],
[ /(?:bool8|bool16)(,|\))/g, 'boolean$1' ],
[ /(?:int|u8|u16|u32|s8|s16|s32)(,|\))/g, 'integer$1' ],
[ /void \(\*callback\)\(struct Sprite \*\)/g, 'callback: Function' ],
[ /struct Sprite \*sprite/, 'sprite: Sprite' ],
[ /&sprite/g, 'sprite' ],
[ /^u8 ([A-Z][A-Za-z\_0-9]+)\((.*?)\)/, 'function $1($2): integer' ],
[ /^(?:static )?void /, 'function ' ],
[ /TRUE/g, 'true' ],
[ /FALSE/g, 'false' ],
[ /BATTLER\_COORD\_/g, 'BattlerCoord.' ],
[ /B\_SIDE\_PLAYER/g, 'BattleSide.PLAYER' ],
[ /B\_SIDE\_OPPONENT/g, 'BattleSide.ENEMY' ],
[ /abs\(/g, 'Math.abs(' ],
[ /^([\t ]+)\*([a-zA-Z\_]+) =/, '$1$2 =' ],
[ /([\t ]+)([a-zA-Z\_]+) = (.*?);/, '$1$2 = $3;' ],
[ /^[\t ]+([^ ]+ =|return|if \() ([A-Z][a-zA-Z0-9\_]+)(?:\((.*?)\))?(\))?;$/, res => {
const funcName = res[2];
if (funcNames.indexOf(funcName) === -1) {
const searchRes = new RegExp(`\n\n(?:static )?([^ ]+) ${funcName}\\((.*?)\\)\n\{`).exec(animTemplates);
console.log('found', funcName, searchRes)
if (searchRes) {
const funcIndex = searchRes.index;
const funcContent = animTemplates.slice(funcIndex + 2, /\}\n\n[^ ]/.exec(animTemplates.slice(funcIndex + 2)).index + funcIndex + 3);
funcNames.push(funcName);
processFunc(funcName, funcContent);
}
}
return res[0];
} ]
]
function processFunc(funcName, funcContent) {
try {
if (typeof eval(funcName) === 'function') {
console.log('skip', funcName);
return null;
}
} catch (e) {
}
const funcLines = funcContent.split('\n');
for (let l in funcLines) {
let line = funcLines[l];
var matched = false;
for (let i in funcLinePatterns) {
const pattern = funcLinePatterns[i][0];
const match = pattern.exec(line);
if (match) {
const value = funcLinePatterns[i][1];
console.log(line, line.replace(pattern, value), pattern, value)
if (typeof value === 'string')
line = line.replace(pattern, value);
else if (typeof value === 'function')
line = value(match);
matched = true;
funcLines[l] = line;
}
}
if (!matched) {
if (false && line.length && !/^(?:static|void|\{|\})/.test(line))
funcLines[l] = `//${line}`;
}
}
funcContent = funcLines.join('\n');
animFuncsContents += `${funcContent}\n\n`;
funcNames.push(funcName);
return funcContent;
}
export function interp(sceneIn) {
let output = moveAnimsContent.slice(0);
for (let i in multiPatterns) {
output = output.replace(multiPatterns[i][0], multiPatterns[i][1]);
}
let lines = output.split('\n');
for (let l in lines) {
let line = lines[l];
var matched = false;
for (let i in linePatterns) {
const pattern = linePatterns[i][0];
if (pattern.test(line)) {
const value = linePatterns[i][1];
if (typeof value === 'string')
line = line.replace(pattern, value);
else if (typeof value === 'function')
line = value(pattern.exec(line));
matched = true;
lines[l] = line;
}
}
if (!matched) {
if (line.length && !/^(?:function|static|void|\{|\})/.test(line))
lines[l] = `//${line}`;
}
}
output = lines.join('\n');
const delayPattern = /([\t ]+)delay (\d+)/;
let delayMatch;
while ((delayMatch = delayPattern.exec(output))) {
const contIndex = delayMatch.index + delayMatch[1].length + delayMatch[2].length + 6;
const contMatch = /\n\}/.exec(output.slice(contIndex));
console.log(contIndex)
if (!contMatch)
console.log(output.slice(delayMatch.index))
console.log(delayMatch)
output = output.slice(0, delayMatch.index) + delayMatch[1] + `scene.time.delayedCall(${delayMatch[2]}, () => {` + output.slice(contIndex, contMatch.index + contIndex).replace(/\n/g, '\n\t') + '\n' + delayMatch[1] + '});' + output.slice(contMatch.index + contIndex);
}
output += '\ndoMoveAnim_WATER_GUN();\n\n';
console.log(output, animTemplateContents, animFuncsContents)
scene = sceneIn;
gBattleAnimAttacker = scene.getPlayerPokemon();
gBattleAnimTarget = scene.getEnemyPokemon();
eval(ts.transpile(animTemplateContents) + ts.transpile(animFuncsContents) + '\n' + ts.transpile(output));
}
moveAnimsContent = `#include "constants/battle.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "constants/moves.h"
.include "asm/macros.inc"
.include "asm/macros/battle_anim_script.inc"
.include "constants/constants.inc"
.section script_data, "aw", %progbits
.align 2
gMovesWithQuietBGM::
.2byte MOVE_SING, MOVE_PERISH_SONG, MOVE_GRASS_WHISTLE, 0xFFFF
.align 2
gBattleAnims_Moves::
.4byte Move_NONE
.4byte Move_POUND
.4byte Move_KARATE_CHOP
.4byte Move_DOUBLE_SLAP
.4byte Move_COMET_PUNCH
.4byte Move_MEGA_PUNCH
.4byte Move_PAY_DAY
.4byte Move_FIRE_PUNCH
.4byte Move_ICE_PUNCH
.4byte Move_THUNDER_PUNCH
.4byte Move_SCRATCH
.4byte Move_VICE_GRIP
.4byte Move_GUILLOTINE
.4byte Move_RAZOR_WIND
.4byte Move_SWORDS_DANCE
.4byte Move_CUT
.4byte Move_GUST
.4byte Move_WING_ATTACK
.4byte Move_WHIRLWIND
.4byte Move_FLY
.4byte Move_BIND
.4byte Move_SLAM
.4byte Move_VINE_WHIP
.4byte Move_STOMP
.4byte Move_DOUBLE_KICK
.4byte Move_MEGA_KICK
.4byte Move_JUMP_KICK
.4byte Move_ROLLING_KICK
.4byte Move_SAND_ATTACK
.4byte Move_HEADBUTT
.4byte Move_HORN_ATTACK
.4byte Move_FURY_ATTACK
.4byte Move_HORN_DRILL
.4byte Move_TACKLE
.4byte Move_BODY_SLAM
.4byte Move_WRAP
.4byte Move_TAKE_DOWN
.4byte Move_THRASH
.4byte Move_DOUBLE_EDGE
.4byte Move_TAIL_WHIP
.4byte Move_POISON_STING
.4byte Move_TWINEEDLE
.4byte Move_PIN_MISSILE
.4byte Move_LEER
.4byte Move_BITE
.4byte Move_GROWL
.4byte Move_ROAR
.4byte Move_SING
.4byte Move_SUPERSONIC
.4byte Move_SONIC_BOOM
.4byte Move_DISABLE
.4byte Move_ACID
.4byte Move_EMBER
.4byte Move_FLAMETHROWER
.4byte Move_MIST
.4byte Move_WATER_GUN
.4byte Move_HYDRO_PUMP
.4byte Move_SURF
.4byte Move_ICE_BEAM
.4byte Move_BLIZZARD
.4byte Move_PSYBEAM
.4byte Move_BUBBLE_BEAM
.4byte Move_AURORA_BEAM
.4byte Move_HYPER_BEAM
.4byte Move_PECK
.4byte Move_DRILL_PECK
.4byte Move_SUBMISSION
.4byte Move_LOW_KICK
.4byte Move_COUNTER
.4byte Move_SEISMIC_TOSS
.4byte Move_STRENGTH
.4byte Move_ABSORB
.4byte Move_MEGA_DRAIN
.4byte Move_LEECH_SEED
.4byte Move_GROWTH
.4byte Move_RAZOR_LEAF
.4byte Move_SOLAR_BEAM
.4byte Move_POISON_POWDER
.4byte Move_STUN_SPORE
.4byte Move_SLEEP_POWDER
.4byte Move_PETAL_DANCE
.4byte Move_STRING_SHOT
.4byte Move_DRAGON_RAGE
.4byte Move_FIRE_SPIN
.4byte Move_THUNDER_SHOCK
.4byte Move_THUNDERBOLT
.4byte Move_THUNDER_WAVE
.4byte Move_THUNDER
.4byte Move_ROCK_THROW
.4byte Move_EARTHQUAKE
.4byte Move_FISSURE
.4byte Move_DIG
.4byte Move_TOXIC
.4byte Move_CONFUSION
.4byte Move_PSYCHIC
.4byte Move_HYPNOSIS
.4byte Move_MEDITATE
.4byte Move_AGILITY
.4byte Move_QUICK_ATTACK
.4byte Move_RAGE
.4byte Move_TELEPORT
.4byte Move_NIGHT_SHADE
.4byte Move_MIMIC
.4byte Move_SCREECH
.4byte Move_DOUBLE_TEAM
.4byte Move_RECOVER
.4byte Move_HARDEN
.4byte Move_MINIMIZE
.4byte Move_SMOKESCREEN
.4byte Move_CONFUSE_RAY
.4byte Move_WITHDRAW
.4byte Move_DEFENSE_CURL
.4byte Move_BARRIER
.4byte Move_LIGHT_SCREEN
.4byte Move_HAZE
.4byte Move_REFLECT
.4byte Move_FOCUS_ENERGY
.4byte Move_BIDE
.4byte Move_METRONOME
.4byte Move_MIRROR_MOVE @ doesnt have an actual animation
.4byte Move_SELF_DESTRUCT
.4byte Move_EGG_BOMB
.4byte Move_LICK
.4byte Move_SMOG
.4byte Move_SLUDGE
.4byte Move_BONE_CLUB
.4byte Move_FIRE_BLAST
.4byte Move_WATERFALL
.4byte Move_CLAMP
.4byte Move_SWIFT
.4byte Move_SKULL_BASH
.4byte Move_SPIKE_CANNON
.4byte Move_CONSTRICT
.4byte Move_AMNESIA
.4byte Move_KINESIS
.4byte Move_SOFT_BOILED
.4byte Move_HI_JUMP_KICK
.4byte Move_GLARE
.4byte Move_DREAM_EATER
.4byte Move_POISON_GAS
.4byte Move_BARRAGE
.4byte Move_LEECH_LIFE
.4byte Move_LOVELY_KISS
.4byte Move_SKY_ATTACK
.4byte Move_TRANSFORM
.4byte Move_BUBBLE
.4byte Move_DIZZY_PUNCH
.4byte Move_SPORE
.4byte Move_FLASH
.4byte Move_PSYWAVE
.4byte Move_SPLASH
.4byte Move_ACID_ARMOR
.4byte Move_CRABHAMMER
.4byte Move_EXPLOSION
.4byte Move_FURY_SWIPES
.4byte Move_BONEMERANG
.4byte Move_REST
.4byte Move_ROCK_SLIDE
.4byte Move_HYPER_FANG
.4byte Move_SHARPEN
.4byte Move_CONVERSION
.4byte Move_TRI_ATTACK
.4byte Move_SUPER_FANG
.4byte Move_SLASH
.4byte Move_SUBSTITUTE
.4byte Move_STRUGGLE
.4byte Move_SKETCH
.4byte Move_TRIPLE_KICK
.4byte Move_THIEF
.4byte Move_SPIDER_WEB
.4byte Move_MIND_READER
.4byte Move_NIGHTMARE
.4byte Move_FLAME_WHEEL
.4byte Move_SNORE
.4byte Move_CURSE
.4byte Move_FLAIL
.4byte Move_CONVERSION_2
.4byte Move_AEROBLAST
.4byte Move_COTTON_SPORE
.4byte Move_REVERSAL
.4byte Move_SPITE
.4byte Move_POWDER_SNOW
.4byte Move_PROTECT
.4byte Move_MACH_PUNCH
.4byte Move_SCARY_FACE
.4byte Move_FAINT_ATTACK
.4byte Move_SWEET_KISS
.4byte Move_BELLY_DRUM
.4byte Move_SLUDGE_BOMB
.4byte Move_MUD_SLAP
.4byte Move_OCTAZOOKA
.4byte Move_SPIKES
.4byte Move_ZAP_CANNON
.4byte Move_FORESIGHT
.4byte Move_DESTINY_BOND
.4byte Move_PERISH_SONG
.4byte Move_ICY_WIND
.4byte Move_DETECT
.4byte Move_BONE_RUSH
.4byte Move_LOCK_ON
.4byte Move_OUTRAGE
.4byte Move_SANDSTORM
.4byte Move_GIGA_DRAIN
.4byte Move_ENDURE
.4byte Move_CHARM
.4byte Move_ROLLOUT
.4byte Move_FALSE_SWIPE
.4byte Move_SWAGGER
.4byte Move_MILK_DRINK
.4byte Move_SPARK
.4byte Move_FURY_CUTTER
.4byte Move_STEEL_WING
.4byte Move_MEAN_LOOK
.4byte Move_ATTRACT
.4byte Move_SLEEP_TALK
.4byte Move_HEAL_BELL
.4byte Move_RETURN
.4byte Move_PRESENT
.4byte Move_FRUSTRATION
.4byte Move_SAFEGUARD
.4byte Move_PAIN_SPLIT
.4byte Move_SACRED_FIRE
.4byte Move_MAGNITUDE
.4byte Move_DYNAMIC_PUNCH
.4byte Move_MEGAHORN
.4byte Move_DRAGON_BREATH
.4byte Move_BATON_PASS
.4byte Move_ENCORE
.4byte Move_PURSUIT
.4byte Move_RAPID_SPIN
.4byte Move_SWEET_SCENT
.4byte Move_IRON_TAIL
.4byte Move_METAL_CLAW
.4byte Move_VITAL_THROW
.4byte Move_MORNING_SUN
.4byte Move_SYNTHESIS
.4byte Move_MOONLIGHT
.4byte Move_HIDDEN_POWER
.4byte Move_CROSS_CHOP
.4byte Move_TWISTER
.4byte Move_RAIN_DANCE
.4byte Move_SUNNY_DAY
.4byte Move_CRUNCH
.4byte Move_MIRROR_COAT
.4byte Move_PSYCH_UP
.4byte Move_EXTREME_SPEED
.4byte Move_ANCIENT_POWER
.4byte Move_SHADOW_BALL
.4byte Move_FUTURE_SIGHT
.4byte Move_ROCK_SMASH
.4byte Move_WHIRLPOOL
.4byte Move_BEAT_UP
.4byte Move_FAKE_OUT
.4byte Move_UPROAR
.4byte Move_STOCKPILE
.4byte Move_SPIT_UP
.4byte Move_SWALLOW
.4byte Move_HEAT_WAVE
.4byte Move_HAIL
.4byte Move_TORMENT
.4byte Move_FLATTER
.4byte Move_WILL_O_WISP
.4byte Move_MEMENTO
.4byte Move_FACADE
.4byte Move_FOCUS_PUNCH
.4byte Move_SMELLING_SALT
.4byte Move_FOLLOW_ME
.4byte Move_NATURE_POWER
.4byte Move_CHARGE
.4byte Move_TAUNT
.4byte Move_HELPING_HAND
.4byte Move_TRICK
.4byte Move_ROLE_PLAY
.4byte Move_WISH
.4byte Move_ASSIST
.4byte Move_INGRAIN
.4byte Move_SUPERPOWER
.4byte Move_MAGIC_COAT
.4byte Move_RECYCLE
.4byte Move_REVENGE
.4byte Move_BRICK_BREAK
.4byte Move_YAWN
.4byte Move_KNOCK_OFF
.4byte Move_ENDEAVOR
.4byte Move_ERUPTION
.4byte Move_SKILL_SWAP
.4byte Move_IMPRISON
.4byte Move_REFRESH
.4byte Move_GRUDGE
.4byte Move_SNATCH
.4byte Move_SECRET_POWER
.4byte Move_DIVE
.4byte Move_ARM_THRUST
.4byte Move_CAMOUFLAGE
.4byte Move_TAIL_GLOW
.4byte Move_LUSTER_PURGE
.4byte Move_MIST_BALL
.4byte Move_FEATHER_DANCE
.4byte Move_TEETER_DANCE
.4byte Move_BLAZE_KICK
.4byte Move_MUD_SPORT
.4byte Move_ICE_BALL
.4byte Move_NEEDLE_ARM
.4byte Move_SLACK_OFF
.4byte Move_HYPER_VOICE
.4byte Move_POISON_FANG
.4byte Move_CRUSH_CLAW
.4byte Move_BLAST_BURN
.4byte Move_HYDRO_CANNON
.4byte Move_METEOR_MASH
.4byte Move_ASTONISH
.4byte Move_WEATHER_BALL
.4byte Move_AROMATHERAPY
.4byte Move_FAKE_TEARS
.4byte Move_AIR_CUTTER
.4byte Move_OVERHEAT
.4byte Move_ODOR_SLEUTH
.4byte Move_ROCK_TOMB
.4byte Move_SILVER_WIND
.4byte Move_METAL_SOUND
.4byte Move_GRASS_WHISTLE
.4byte Move_TICKLE
.4byte Move_COSMIC_POWER
.4byte Move_WATER_SPOUT
.4byte Move_SIGNAL_BEAM
.4byte Move_SHADOW_PUNCH
.4byte Move_EXTRASENSORY
.4byte Move_SKY_UPPERCUT
.4byte Move_SAND_TOMB
.4byte Move_SHEER_COLD
.4byte Move_MUDDY_WATER
.4byte Move_BULLET_SEED
.4byte Move_AERIAL_ACE
.4byte Move_ICICLE_SPEAR
.4byte Move_IRON_DEFENSE
.4byte Move_BLOCK
.4byte Move_HOWL
.4byte Move_DRAGON_CLAW
.4byte Move_FRENZY_PLANT
.4byte Move_BULK_UP
.4byte Move_BOUNCE
.4byte Move_MUD_SHOT
.4byte Move_POISON_TAIL
.4byte Move_COVET
.4byte Move_VOLT_TACKLE
.4byte Move_MAGICAL_LEAF
.4byte Move_WATER_SPORT
.4byte Move_CALM_MIND
.4byte Move_LEAF_BLADE
.4byte Move_DRAGON_DANCE
.4byte Move_ROCK_BLAST
.4byte Move_SHOCK_WAVE
.4byte Move_WATER_PULSE
.4byte Move_DOOM_DESIRE
.4byte Move_PSYCHO_BOOST
.4byte Move_COUNT @ cannot be reached, because last move is Psycho Boost
.align 2
gBattleAnims_StatusConditions::
.4byte Status_Poison @ B_ANIM_STATUS_PSN
.4byte Status_Confusion @ B_ANIM_STATUS_CONFUSION
.4byte Status_Burn @ B_ANIM_STATUS_BRN
.4byte Status_Infatuation @ B_ANIM_STATUS_INFATUATION
.4byte Status_Sleep @ B_ANIM_STATUS_SLP
.4byte Status_Paralysis @ B_ANIM_STATUS_PRZ
.4byte Status_Freeze @ B_ANIM_STATUS_FRZ
.4byte Status_Curse @ B_ANIM_STATUS_CURSED
.4byte Status_Nightmare @ B_ANIM_STATUS_NIGHTMARE
.align 2
gBattleAnims_General::
.4byte General_CastformChange @ B_ANIM_CASTFORM_CHANGE
.4byte General_StatsChange @ B_ANIM_STATS_CHANGE
.4byte General_SubstituteFade @ B_ANIM_SUBSTITUTE_FADE
.4byte General_SubstituteAppear @ B_ANIM_SUBSTITUTE_APPEAR
.4byte General_PokeblockThrow @ B_ANIM_POKEBLOCK_THROW
.4byte General_ItemKnockoff @ B_ANIM_ITEM_KNOCKOFF
.4byte General_TurnTrap @ B_ANIM_TURN_TRAP
.4byte General_HeldItemEffect @ B_ANIM_HELD_ITEM_EFFECT
.4byte General_SmokeballEscape @ B_ANIM_SMOKEBALL_ESCAPE
.4byte General_FocusBand @ B_ANIM_FOCUS_BAND
.4byte General_Rain @ B_ANIM_RAIN_CONTINUES
.4byte General_Sun @ B_ANIM_SUN_CONTINUES
.4byte General_Sandstorm @ B_ANIM_SANDSTORM_CONTINUES
.4byte General_Hail @ B_ANIM_HAIL_CONTINUES
.4byte General_LeechSeedDrain @ B_ANIM_LEECH_SEED_DRAIN
.4byte General_MonHit @ B_ANIM_MON_HIT
.4byte General_ItemSteal @ B_ANIM_ITEM_STEAL
.4byte General_SnatchMove @ B_ANIM_SNATCH_MOVE
.4byte General_FutureSightHit @ B_ANIM_FUTURE_SIGHT_HIT
.4byte General_DoomDesireHit @ B_ANIM_DOOM_DESIRE_HIT
.4byte General_FocusPunchSetUp @ B_ANIM_FOCUS_PUNCH_SETUP
.4byte General_IngrainHeal @ B_ANIM_INGRAIN_HEAL
.4byte General_WishHeal @ B_ANIM_WISH_HEAL
.align 2
gBattleAnims_Special::
.4byte Special_LevelUp @ B_ANIM_LVL_UP
.4byte Special_SwitchOutPlayerMon @ B_ANIM_SWITCH_OUT_PLAYER_MON
.4byte Special_SwitchOutOpponentMon @ B_ANIM_SWITCH_OUT_OPPONENT_MON
.4byte Special_BallThrow @ B_ANIM_BALL_THROW
.4byte Special_BallThrowWithTrainer @ B_ANIM_BALL_THROW_WITH_TRAINER
.4byte Special_SubstituteToMon @ B_ANIM_SUBSTITUTE_TO_MON
.4byte Special_MonToSubstitute @ B_ANIM_MON_TO_SUBSTITUTE
Move_POUND:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_DOUBLE_SLAP:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
choosetwoturnanim DoubleSlapLeft, DoubleSlapRight
DoubleSlapContinue:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
DoubleSlapLeft:
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -8, 0, ANIM_TARGET, 2
goto DoubleSlapContinue
DoubleSlapRight:
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 8, 0, ANIM_TARGET, 2
goto DoubleSlapContinue
Move_POISON_POWDER:
loadspritegfx ANIM_TAG_POISON_POWDER
loadspritegfx ANIM_TAG_POISON_BUBBLE
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 10, 6
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -30, -22, 117, 80, 5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 10, -22, 117, 80, -5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -25, -22, 117, 112, 5, 3
delay 15
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 80, -5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 96, 5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 69, -5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
delay 30
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 15, -22, 117, 80, -5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 96, 7, 2
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 90, -8, 0
delay 20
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 80, -5, 1
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 89, 5, 2
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 20, -22, 117, 112, -8, 2
createsprite gPoisonPowderParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 80, 5, 1
waitforvisualfinish
end
Move_STUN_SPORE:
loadspritegfx ANIM_TAG_STUN_SPORE
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 10, 6
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -30, -22, 117, 80, 5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 10, -22, 117, 80, -5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -25, -22, 117, 112, 5, 3
delay 15
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 80, -5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 96, 5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 69, -5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
delay 30
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 15, -22, 117, 80, -5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 96, 7, 2
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 90, -8, 0
delay 20
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 80, -5, 1
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 89, 5, 2
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 20, -22, 117, 112, -8, 2
createsprite gStunSporeParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 80, 5, 1
waitforvisualfinish
end
Move_SLEEP_POWDER:
loadspritegfx ANIM_TAG_SLEEP_POWDER
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 10, 6
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -30, -22, 117, 80, 5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 10, -22, 117, 80, -5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -25, -22, 117, 112, 5, 3
delay 15
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 80, -5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 96, 5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 69, -5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
delay 30
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -15, -22, 117, 112, 5, 2
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 15, -22, 117, 80, -5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 96, 7, 2
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -5, -22, 117, 90, -8, 0
delay 20
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, -10, -22, 117, 80, -5, 1
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 0, -22, 117, 89, 5, 2
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 20, -22, 117, 112, -8, 2
createsprite gSleepPowderParticleSpriteTemplate, ANIM_TARGET, 2, 5, -22, 117, 80, 5, 1
waitforvisualfinish
end
Move_SWIFT:
loadspritegfx ANIM_TAG_YELLOW_STAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gSwiftStarSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 22, 20, 1
delay 5
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gSwiftStarSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 5, 22, -18, 1
delay 5
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gSwiftStarSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, -10, 22, 15, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 18, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 18, 1
delay 5
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gSwiftStarSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 22, -20, 1
delay 5
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gSwiftStarSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 22, 12, 1
delay 5
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_STRENGTH:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeAndSinkMon, 5, ANIM_ATTACKER, 2, 0, 96, 30
waitforvisualfinish
delay 10
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 4
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_TARGET, 18, 6, 2, 4
delay 4
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 16, 12, ANIM_TARGET, 1
delay 4
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -16, -12, ANIM_TARGET, 1
delay 4
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 3, 4, ANIM_TARGET, 1
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_TACKLE:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_BODY_SLAM:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
waitforvisualfinish
delay 11
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 4, -10, 0, ANIM_TARGET, 0
loopsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET, 10, 2
delay 1
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -28, 0, 0, 3
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
waitforvisualfinish
delay 10
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 6
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SUPERSONIC:
loadspritegfx ANIM_TAG_GOLD_RING
monbg ANIM_ATK_PARTNER
splitbgprio_foes ANIM_ATTACKER
setalpha 12, 8
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 2, 0, 8, 1
call SupersonicRing
call SupersonicRing
call SupersonicRing
call SupersonicRing
call SupersonicRing
call SupersonicRing
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
SupersonicRing:
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
createsprite gSupersonicRingSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 30, 0
delay 2
return
Move_SCREECH:
loadspritegfx ANIM_TAG_PURPLE_RING
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 3, 0, 2, 1
call ScreechRing
call ScreechRing
delay 16
createvisualtask AnimTask_SwayMon, 5, 0, 6, 2048, 2, ANIM_TARGET
waitforvisualfinish
end
ScreechRing:
playsewithpan SE_M_SCREECH, SOUND_PAN_ATTACKER
createsprite gScreechRingSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 30, 0
delay 2
return
Move_FLAME_WHEEL:
loadspritegfx ANIM_TAG_SMALL_EMBER
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 0
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 4
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 8
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 12
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 16
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 20
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
delay 2
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 56, 24
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 6
delay 4
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 8, 1
createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET
call FireSpreadEffect
delay 7
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 9
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
FlameWheel1: @ Unused
createsprite gFireSpiralOutwardSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 50
delay 4
return
Move_PIN_MISSILE:
loadspritegfx ANIM_TAG_NEEDLE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gPinMissileSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, -8, -8, 20, -32
delay 15
createsprite gPinMissileSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, 8, 8, 20, -40
delay 4
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -8, -8, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
delay 9
createsprite gPinMissileSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, 0, 0, 20, -32
delay 4
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 8, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
delay 14
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_ICICLE_SPEAR:
loadspritegfx ANIM_TAG_ICICLE_SPEAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_ICY_WIND, SOUND_PAN_ATTACKER
createsprite gIcicleSpearSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, -8, -8, 20, -32
delay 15
createsprite gIcicleSpearSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, 8, 8, 20, -40
delay 4
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -8, -8, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
delay 9
createsprite gIcicleSpearSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, 0, 0, 20, -32
delay 4
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 8, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
delay 14
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 2, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_TAKE_DOWN:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_WindUpLunge, 5, ANIM_ATTACKER, -24, 8, 23, 10, 40, 10
delay 35
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 10, RGB_BLACK, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 4, -10, 0, ANIM_TARGET, 0
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
delay 1
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -16, 0, 0, 4
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
waitforvisualfinish
delay 2
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 7
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_DOUBLE_EDGE:
loadspritegfx ANIM_TAG_IMPACT
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 4, 2, RGB_WHITE, 10, RGB_BLACK, 0
waitforvisualfinish
delay 10
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 2, 4
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 16, 16, RGB_WHITE
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
delay 3
waitforvisualfinish
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, ANIM_TARGET, 0
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -32, 0, 0, 3
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 0
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 4, 0, 12, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 16, 0, RGB_WHITE
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 7
waitforvisualfinish
end
Move_POISON_STING:
loadspritegfx ANIM_TAG_NEEDLE
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_POISON_BUBBLE
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gLinearStingerSpriteTemplate, ANIM_TARGET, 2, 20, 0, -8, 0, 20
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 5, 1
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
waitforvisualfinish
call PoisonBubblesEffect
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_TWINEEDLE:
loadspritegfx ANIM_TAG_NEEDLE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 6, 2
createsprite gLinearStingerSpriteTemplate, ANIM_TARGET, 2, 10, -4, 0, -4, 20
createsprite gLinearStingerSpriteTemplate, ANIM_TARGET, 2, 20, 12, 10, 12, 20
delay 20
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 5, 1
createsprite gHandleInvertHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -4, 1, 3
loopsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 5, 2
delay 1
createsprite gHandleInvertHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 10, 12, 1, 3
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_FIRE_BLAST:
loadspritegfx ANIM_TAG_SMALL_EMBER
createsoundtask SoundTask_FireBlast, SE_M_FLAME_WHEEL, SE_M_FLAME_WHEEL2
call FireBlastRing
call FireBlastRing
call FireBlastRing
delay 24
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 0, 8, RGB_BLACK
waitforvisualfinish
delay 19
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 20, 1
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
delay 3
call FireBlastCross
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 2, 8, 0, RGB_BLACK
waitforvisualfinish
end
FireBlastRing:
createsprite gFireBlastRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0
createsprite gFireBlastRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 51
createsprite gFireBlastRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 102
createsprite gFireBlastRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 153
createsprite gFireBlastRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 204
delay 5
return
FireBlastCross:
createsprite gFireBlastCrossSpriteTemplate, ANIM_TARGET, 2, 0, 0, 10, 0, -2
createsprite gFireBlastCrossSpriteTemplate, ANIM_TARGET, 2, 0, 0, 13, -2, 0
createsprite gFireBlastCrossSpriteTemplate, ANIM_TARGET, 2, 0, 0, 13, 2, 0
createsprite gFireBlastCrossSpriteTemplate, ANIM_TARGET, 2, 0, 0, 15, -2, 2
createsprite gFireBlastCrossSpriteTemplate, ANIM_TARGET, 2, 0, 0, 15, 2, 2
return
Move_LEECH_SEED:
loadspritegfx ANIM_TAG_SEED
playsewithpan SE_M_POISON_POWDER, SOUND_PAN_ATTACKER
createsprite gLeechSeedSpriteTemplate, ANIM_TARGET, 2, 15, 0, 0, 24, 35, -32
delay 8
playsewithpan SE_M_POISON_POWDER, SOUND_PAN_ATTACKER
createsprite gLeechSeedSpriteTemplate, ANIM_TARGET, 2, 15, 0, -16, 24, 35, -40
delay 8
playsewithpan SE_M_POISON_POWDER, SOUND_PAN_ATTACKER
createsprite gLeechSeedSpriteTemplate, ANIM_TARGET, 2, 15, 0, 16, 24, 35, -37
delay 12
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_TARGET, 10, 8
waitforvisualfinish
end
Move_EMBER:
loadspritegfx ANIM_TAG_SMALL_EMBER
loopsewithpan SE_M_EMBER, SOUND_PAN_ATTACKER, 5, 2
createsprite gEmberSpriteTemplate, ANIM_TARGET, 2, 20, 0, -16, 24, 20, 1
delay 4
createsprite gEmberSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 24, 20, 1
delay 4
createsprite gEmberSpriteTemplate, ANIM_TARGET, 2, 20, 0, 16, 24, 20, 1
delay 16
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
call EmberFireHit
call EmberFireHit
call EmberFireHit
end
EmberFireHit:
createsprite gEmberFlareSpriteTemplate, ANIM_TARGET, 2, -24, 24, 24, 24, 20, ANIM_TARGET, 1
delay 4
return
Move_MEGA_PUNCH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_TARGET
delay 2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 0, 16, RGB_BLACK
setalpha 12, 8
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_TARGET
createsprite gMegaPunchKickSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 50
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 7, RGB_WHITE
delay 50
call SetImpactBackground
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 22, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 0, RGB_WHITE
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 2
restorebg
waitbgfadein
end
SetImpactBackground:
delay 2
createvisualtask AnimTask_IsContest, 2
jumprettrue SetImpactContestsBG
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse SetImpactOpponentBG
jumprettrue SetImpactPlayerBG
SetImpactBackgroundRet:
return
SetImpactOpponentBG:
changebg BG_IMPACT_OPPONENT
goto SetImpactBackgroundRet
SetImpactPlayerBG:
changebg BG_IMPACT_PLAYER
goto SetImpactBackgroundRet
SetImpactContestsBG:
changebg BG_IMPACT_CONTESTS
goto SetImpactBackgroundRet
Move_MEGA_KICK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_TARGET
delay 2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 0, 16, RGB_BLACK
setalpha 12, 8
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_TARGET
createsprite gMegaPunchKickSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 50
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 7, RGB_WHITE
delay 50
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
call SetImpactBackground
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 22, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 0, RGB_WHITE
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 2
restorebg
waitbgfadein
end
Move_COMET_PUNCH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_TARGET
setalpha 12, 8
choosetwoturnanim CometPunchLeft, CometPunchRight
CometPunchContinue:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
CometPunchLeft:
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -8, -8, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, -8, 0, 8, 1, 0
goto CometPunchContinue
CometPunchRight:
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 8, -8, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, 8, 0, 8, 1, 0
goto CometPunchContinue
Move_SONIC_BOOM:
loadspritegfx ANIM_TAG_AIR_WAVE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
call SonicBoomProjectile
call SonicBoomProjectile
call SonicBoomProjectile
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 10, 1
call SonicBoomHit
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
SonicBoomProjectile:
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gSonicBoomSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 15
delay 4
return
SonicBoomHit:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 2
delay 4
return
Move_THUNDER_SHOCK:
loadspritegfx ANIM_TAG_SPARK
loadspritegfx ANIM_TAG_SPARK_2
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 0, 6, RGB_BLACK
waitforvisualfinish
delay 10
createvisualtask AnimTask_ElectricBolt, 5, 0, -44, 0
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
delay 9
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 0, 0, 13, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 0, 13, 0, RGB_BLACK
waitforvisualfinish
delay 20
call ElectricityEffect
waitforvisualfinish
delay 20
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 6, 0, RGB_BLACK
waitforvisualfinish
end
Move_THUNDERBOLT:
loadspritegfx ANIM_TAG_SPARK
loadspritegfx ANIM_TAG_SHOCK_3
loadspritegfx ANIM_TAG_SPARK_2
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 0, 6, RGB_BLACK
waitforvisualfinish
delay 10
createvisualtask AnimTask_ElectricBolt, 5, 24, -52, 0
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
delay 7
createvisualtask AnimTask_ElectricBolt, 5, -24, -52, 0
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
delay 7
createvisualtask AnimTask_ElectricBolt, 5, 0, -60, 1
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
delay 9
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 0, 0, 13, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 0, 13, 0, RGB_BLACK
waitforvisualfinish
delay 20
createsprite gThunderboltOrbSpriteTemplate, ANIM_TARGET, 3, 44, 0, 0, 3
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 32, 44, 0, 40, 0, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 32, 44, 64, 40, 1, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 32, 44, 128, 40, 0, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 32, 44, 192, 40, 2, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 16, 44, 32, 40, 0, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 16, 44, 96, 40, 1, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 16, 44, 160, 40, 0, -32765
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0, 0, 16, 44, 224, 40, 2, -32765
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 0
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 2, 2, RGB_BLACK
delay 6
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 6, 6, RGB_BLACK
delay 6
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 2, 2, RGB_BLACK
delay 6
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 6, 6, RGB_BLACK
waitforvisualfinish
delay 20
waitplaysewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET, 19
call ElectricityEffect
waitforvisualfinish
delay 20
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 6, 0, RGB_BLACK
waitforvisualfinish
end
Move_THUNDER_WAVE:
loadspritegfx ANIM_TAG_SPARK
loadspritegfx ANIM_TAG_SPARK_2
loadspritegfx ANIM_TAG_SPARK_H
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 0, 6, RGB_BLACK
waitforvisualfinish
delay 10
createvisualtask AnimTask_ElectricBolt, 5, 0, -48, 0
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
delay 20
loopsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET, 10, 4
createsprite gThunderWaveSpriteTemplate, ANIM_TARGET, 2, -16, -16
delay 4
createsprite gThunderWaveSpriteTemplate, ANIM_TARGET, 2, -16, 0
delay 4
createsprite gThunderWaveSpriteTemplate, ANIM_TARGET, 2, -16, 16
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 6, 0, RGB_BLACK
waitforvisualfinish
end
Move_BEAT_UP:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_TARGET
setalpha 12, 8
choosetwoturnanim BeatUpLeft, BeatUpRight
BeatUpContinue:
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
BeatUpLeft:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -20, -20, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, -20, -12, 8, 1, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 8, 0, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, 8, 8, 8, 1, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
goto BeatUpContinue
BeatUpRight:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 12, -20, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, 12, -12, 8, 1, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -12, 0, ANIM_TARGET, 2
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, -12, 8, 8, 1, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
goto BeatUpContinue
Move_STOMP:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET
createsprite gStompFootSpriteTemplate, ANIM_ATTACKER, 3, 0, -32, 15
delay 19
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, -8, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 4, 9, 1
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_TAIL_WHIP:
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 24, 3
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 4, 2, 3
waitforvisualfinish
end
Move_CUT:
loadspritegfx ANIM_TAG_CUT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0
delay 5
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 10, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
Move_HIDDEN_POWER:
loadspritegfx ANIM_TAG_RED_ORB
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -7, -7, 11, ANIM_ATTACKER, 0
waitforvisualfinish
delay 30
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB(31, 31, 19), 12, 5, 1
delay 4
createvisualtask AnimTask_ScaleMonAndRestore, 5, -7, -7, 11, ANIM_ATTACKER, 0
playsewithpan SE_M_REVERSAL, SOUND_PAN_ATTACKER
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 0
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 42
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 84
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 126
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 168
createsprite gHiddenPowerOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 210
delay 52
setarg 7, 0xFFFF
playsewithpan SE_M_REFLECT, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -7, -7, 11, ANIM_ATTACKER, 0
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 0
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 32
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 64
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 96
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 128
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 160
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 192
createsprite gHiddenPowerOrbScatterSpriteTemplate, ANIM_TARGET, 2, 224
end
Move_REVERSAL:
loadspritegfx ANIM_TAG_BLUE_ORB
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 3, RGB_WHITE, 8, RGB_BLACK, 0
waitforvisualfinish
delay 30
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 2, 0, 10, RGB_WHITE
delay 10
playsewithpan SE_M_REVERSAL, SOUND_PAN_ATTACKER
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 0
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 42
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 84
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 126
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 168
createsprite gReversalOrbSpriteTemplate, ANIM_ATTACKER, 2, 26, 210
waitforvisualfinish
delay 20
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 8
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_WHITE, 8, RGB_BLACK, 0
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 10, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 5, FALSE, 1, 8, 1, 0
end
Move_PURSUIT:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
fadetobg BG_DARK
waitbgfadein
delay 0
setalpha 12, 8
choosetwoturnanim PursuitNormal, PursuitOnSwitchout
PursuitContinue:
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 0
restorebg
waitbgfadein
end
PursuitNormal:
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 5, FALSE, 1, 6, 1, 0
goto PursuitContinue
PursuitOnSwitchout:
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 5, FALSE, 1, 6, 1, 0
goto PursuitContinue
Move_SPIKE_CANNON:
loadspritegfx ANIM_TAG_NEEDLE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_WindUpLunge, 5, ANIM_ATTACKER, -4, 0, 4, 6, 8, 4
waitforvisualfinish
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 5, 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
createsprite gLinearStingerSpriteTemplate, ANIM_ATTACKER, 2, 10, -8, -8, -8, 20
createsprite gLinearStingerSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 0, 0, 20
createsprite gLinearStingerSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 8, 8, 20
waitforvisualfinish
createsprite gHandleInvertHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -8, -8, 1, 2
createsprite gHandleInvertHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 2
createsprite gHandleInvertHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 8, 1, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 7, 1
loopsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 5, 3
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_SWORDS_DANCE:
loadspritegfx ANIM_TAG_SWORD
monbg ANIM_ATTACKER
setalpha 12, 8
playsewithpan SE_M_SWORDS_DANCE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 16, 6, 1, 4
createsprite gSwordsDanceBladeSpriteTemplate, ANIM_ATTACKER, 2, 0, 0
delay 22
createvisualtask AnimTask_FlashAnimTagWithColor, 2, ANIM_TAG_SWORD, 2, 2, RGB(18, 31, 31), 16, 0, 0
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
delay 1
end
Move_PSYCH_UP:
loadspritegfx ANIM_TAG_SPIRAL
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_BlendColorCycleExclude, 2, 1, 2, 6, 1, 11, RGB_BLACK
setalpha 12, 8
loopsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, 5, 10
createsprite gPsychUpSpiralSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0, 0
createvisualtask AnimTask_SwayMon, 5, 0, 5, 2560, 8, ANIM_ATTACKER
delay 127
delay 4
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -5, -5, 10, ANIM_ATTACKER, 1
createvisualtask AnimTask_BlendBattleAnimPal, 9, F_PAL_ATTACKER, 2, 10, 0, RGB_YELLOW
delay 30
clearmonbg ANIM_ATK_PARTNER
blendoff
waitforvisualfinish
end
Move_DIZZY_PUNCH:
loadspritegfx ANIM_TAG_DUCK
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
call DizzyPunchLunge
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 5, 16, 8, 20, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, 16, 0, ANIM_TARGET, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, 160, -32
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, -256, -40
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, 128, -16
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, 416, -38
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, -128, -22
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, 16, 8, -384, -31
delay 10
call DizzyPunchLunge
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 5, -16, -8, 20, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -16, -16, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, 160, -32
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, -256, -40
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, 128, -16
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, 416, -38
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, -128, -22
createsprite gDizzyPunchDuckSpriteTemplate, ANIM_TARGET, 3, -16, -8, -384, -31
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
DizzyPunchLunge:
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 6
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 7, 1
return
Move_FIRE_SPIN:
loadspritegfx ANIM_TAG_SMALL_EMBER
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 47, 1
call FireSpinEffect
call FireSpinEffect
call FireSpinEffect
waitforvisualfinish
end
FireSpinEffect:
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 28, 528, 30, 13, 50, ANIM_TARGET
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 32, 480, 20, 16, -46, ANIM_TARGET
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 33, 576, 20, 8, 42, ANIM_TARGET
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 31, 400, 25, 11, -42, ANIM_TARGET
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 28, 512, 25, 16, 46, ANIM_TARGET
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_TARGET, 2, 0, 33, 464, 30, 15, -50, ANIM_TARGET
delay 2
return
Move_FURY_CUTTER:
loadspritegfx ANIM_TAG_CUT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createvisualtask AnimTask_IsFuryCutterHitRight, 2
jumpretfalse FuryCutterLeft
goto FuryCutterRight
FuryCutterContinue:
createvisualtask AnimTask_GetFuryCutterHitCount, 2
jumpreteq 1, FuryCutterContinue2
jumpreteq 2, FuryCutterMedium
jumpreteq 3, FuryCutterStrong
goto FuryCutterStrongest
FuryCutterContinue2:
delay 5
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 10, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
FuryCutterLeft:
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0
goto FuryCutterContinue
FuryCutterRight:
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 1
goto FuryCutterContinue
FuryCutterMedium:
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB(9, 8, 10), 4, RGB_BLACK, 0
goto FuryCutterContinue2
FuryCutterStrong:
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 3, RGB(9, 8, 10), 4, RGB_BLACK, 0
goto FuryCutterContinue2
FuryCutterStrongest:
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 3, RGB(9, 8, 10), 4, RGB_BLACK, 0
goto FuryCutterContinue2
Move_SELF_DESTRUCT:
loadspritegfx ANIM_TAG_EXPLOSION
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 0, 9, RGB_RED
createvisualtask AnimTask_ShakeMon2, 5, ANIM_PLAYER_LEFT, 6, 0, 38, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_PLAYER_RIGHT, 6, 0, 38, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_OPPONENT_LEFT, 6, 0, 38, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_OPPONENT_RIGHT, 6, 0, 38, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER_FORCE, 6, 0, 38, 1
call SelfDestructExplode
call SelfDestructExplode
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 9, 0, RGB_RED
end
SelfDestructExplode:
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 24, -24, 0, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -16, 16, 0, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -24, -12, 0, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 16, 16, 0, 1
delay 6
return
Move_SLAM:
loadspritegfx ANIM_TAG_SLAM_HIT
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_ATTACKER
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 3, 0, 4
delay 1
createsprite gSlamHitSpriteTemplate, ANIM_ATTACKER, 2, 0, 0
delay 3
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -12, 10, 0, 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 0, 3, 6, 1
waitforvisualfinish
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_VINE_WHIP:
loadspritegfx ANIM_TAG_WHIP_HIT
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6
delay 6
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
createsprite gVineWhipSpriteTemplate, ANIM_TARGET, 2, 0, 0
delay 6
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 6, 1
end
Move_DRILL_PECK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_WHIRLWIND_LINES
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 2
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
delay 2
loopsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 4, 8
createvisualtask AnimTask_DrillPeckHitSplats, 5
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 18, 1
waitforvisualfinish
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 6
waitforvisualfinish
end
Move_WATERFALL:
loadspritegfx ANIM_TAG_WATER_IMPACT
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_ICE_CRYSTALS
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 23, 1
delay 5
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -15, 0, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 20, 10, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 0, -10, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -10, 15, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 25, 20, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -20, 20, 25, ANIM_ATTACKER
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 12, 0, 25, ANIM_ATTACKER
waitforvisualfinish
delay 10
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 5
delay 6
call RisingWaterHitEffect
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
RisingWaterHitEffect:
playsewithpan SE_M_WATERFALL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 17, 1
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 20, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 20
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 20
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 15, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 15
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 15
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 10, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 10
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 10
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 5
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 5
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 0
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, 0
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -5, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -5
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -5
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -10, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -10
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -10
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -15
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -15
delay 2
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -20, ANIM_TARGET, 1
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -20
createsprite gSmallDriftingBubblesSpriteTemplate, ANIM_ATTACKER, 4, 0, -20
return
Move_EXPLOSION:
loadspritegfx ANIM_TAG_EXPLOSION
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 8, 9, RGB(26, 8, 8), 8, RGB_BLACK, 8
createvisualtask AnimTask_ShakeMon2, 5, ANIM_PLAYER_LEFT, 8, 0, 40, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_PLAYER_RIGHT, 8, 0, 40, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_OPPONENT_LEFT, 8, 0, 40, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_OPPONENT_RIGHT, 8, 0, 40, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER_FORCE, 8, 0, 40, 1
call Explosion1
call Explosion1
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 1, 16, 16, RGB_WHITE
delay 50
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 16, 0, RGB_WHITE
end
Explosion1:
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 1
delay 6
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 24, -24, 0, 1
delay 6
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -16, 16, 0, 1
delay 6
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -24, -12, 0, 1
delay 6
playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 16, 16, 0, 1
delay 6
return
Move_DEFENSE_CURL:
loadspritegfx ANIM_TAG_ECLIPSING_ORB
loopsewithpan SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER, 18, 3
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, FALSE
createvisualtask AnimTask_DefenseCurlDeformMon, 5
waitforvisualfinish
createsprite gEclipsingOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 6, 0, 1
waitforvisualfinish
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, TRUE
waitforvisualfinish
end
Move_PROTECT:
loadspritegfx ANIM_TAG_PROTECT
monbg ANIM_ATK_PARTNER
splitbgprio ANIM_ATTACKER
waitplaysewithpan SE_M_REFLECT, SOUND_PAN_ATTACKER, 16
createsprite gProtectSpriteTemplate, ANIM_ATTACKER, 2, 24, 0, 90
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
end
Move_DETECT:
loadspritegfx ANIM_TAG_SPARKLE_4
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 9, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 0, 9, RGB_WHITE
delay 18
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
createsprite gSpinningSparkleSpriteTemplate, ANIM_ATTACKER, 13, 20, -20
waitforvisualfinish
delay 10
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 9, 0, RGB_BLACK
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 9, 0, RGB_WHITE
waitforvisualfinish
end
Move_FRUSTRATION:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ANGER
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_GetFrustrationPowerLevel, 1
jumpreteq 0, Frustration_Strongest
jumpreteq 1, Frustration_Strong
jumpreteq 2, Frustration_Medium
goto Frustration_Weak
Frustration_Continue:
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Frustration_Strongest:
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER, 1, 0, 15, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 0, 9, RGB_RED
waitforvisualfinish
delay 20
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
waitforvisualfinish
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
waitforvisualfinish
delay 10
createvisualtask AnimTask_SwayMon, 5, 0, 16, 6144, 8, ANIM_ATTACKER
delay 5
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 30, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 24, 8, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -24, -16, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 4, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -16, 19, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, -18, ANIM_TARGET, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 9, 0, RGB_RED
goto Frustration_Continue
Frustration_Strong:
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER, 1, 0, 15, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 0, 9, RGB_RED
waitforvisualfinish
delay 20
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
waitforvisualfinish
delay 5
createvisualtask AnimTask_StrongFrustrationGrowAndShrink, 5
delay 7
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 8, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 6, 1
delay 14
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 12, -6, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 6, 1
delay 14
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -12, -6, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 6, 1
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 9, 0, RGB_RED
goto Frustration_Continue
Frustration_Medium:
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
waitforvisualfinish
delay 5
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, 4, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -4, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 6, 1
goto Frustration_Continue
Frustration_Weak:
createsprite gWeakFrustrationAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 20, -28
waitforvisualfinish
delay 10
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 10, 2
delay 12
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1
goto Frustration_Continue
Move_SAFEGUARD:
loadspritegfx ANIM_TAG_GUARD_RING
monbg ANIM_ATK_PARTNER
setalpha 8, 8
playsewithpan SE_M_MILK_DRINK, SOUND_PAN_ATTACKER
createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 2
delay 4
createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 2
delay 4
createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 2
waitforvisualfinish
playsewithpan SE_SHINY, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATK_SIDE, 0, 2, 0, 10, RGB_WHITE
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
Move_PAIN_SPLIT:
loadspritegfx ANIM_TAG_PAIN_SPLIT
createsprite gPainSplitProjectileSpriteTemplate, ANIM_ATTACKER, 2, -8, -42, ANIM_ATTACKER
createsprite gPainSplitProjectileSpriteTemplate, ANIM_TARGET, 2, -8, -42, ANIM_TARGET
delay 10
playsewithpan SE_M_SWAGGER2, 0
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_ATTACKER, 0
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_TARGET, 0
waitforvisualfinish
createsprite gPainSplitProjectileSpriteTemplate, ANIM_ATTACKER, 2, -24, -42, ANIM_ATTACKER
createsprite gPainSplitProjectileSpriteTemplate, ANIM_TARGET, 2, -24, -42, ANIM_TARGET
delay 10
playsewithpan SE_M_SWAGGER2, 0
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_ATTACKER, 1
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_TARGET, 1
waitforvisualfinish
createsprite gPainSplitProjectileSpriteTemplate, ANIM_ATTACKER, 2, 8, -42, ANIM_ATTACKER
createsprite gPainSplitProjectileSpriteTemplate, ANIM_TARGET, 2, 8, -42, ANIM_TARGET
delay 10
playsewithpan SE_M_SWAGGER2, 0
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_ATTACKER, 2
createvisualtask AnimTask_PainSplitMovement, 2, ANIM_TARGET, 2
end
Move_VICE_GRIP:
loadspritegfx ANIM_TAG_CUT
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_VICEGRIP, SOUND_PAN_TARGET
createsprite gViceGripSpriteTemplate, ANIM_ATTACKER, 2, 0
createsprite gViceGripSpriteTemplate, ANIM_ATTACKER, 2, 1
delay 9
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 5, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_GUILLOTINE:
loadspritegfx ANIM_TAG_CUT
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
fadetobgfromset BG_GUILLOTINE_OPPONENT, BG_GUILLOTINE_PLAYER, BG_GUILLOTINE_CONTESTS
waitbgfadein
playsewithpan SE_M_VICEGRIP, SOUND_PAN_TARGET
createsprite gGuillotineSpriteTemplate, ANIM_ATTACKER, 2, 0
createsprite gGuillotineSpriteTemplate, ANIM_ATTACKER, 2, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 16, RGB_BLACK
delay 9
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 23, 1
delay 46
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 8, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 0
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
restorebg
waitbgfadein
end
Move_PAY_DAY:
loadspritegfx ANIM_TAG_COIN
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gCoinThrowSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 1152
waitforvisualfinish
playsewithpan SE_M_PAY_DAY, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, ANIM_TARGET, 2
createsprite gFallingCoinSpriteTemplate, ANIM_ATTACKER, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_OUTRAGE:
loadspritegfx ANIM_TAG_SMALL_EMBER
loopsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER, 8, 3
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER | F_PAL_TARGET, 2, 5, 3, 8, RGB(14, 13, 0)
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 6, 5, 4
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, 0, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, 0, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 0, 1280, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 0, -1280, 3
delay 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 40, 1
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, 768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, 768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, -768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, -768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, 0, 3
call OutrageFlames
call OutrageFlames
waitforvisualfinish
end
OutrageFlames:
delay 3
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, 0, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 0, 1280, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 0, -1280, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, 768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, 768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 1280, -768, 3
delay 0
createsprite gOutrageFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -1280, -768, 3
return
Move_SPARK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_SPARK_2
delay 0
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 5, 5, RGB(31, 31, 22)
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, ANIM_ATTACKER, 1, 0
delay 0
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 80, 24, 22, 12, ANIM_ATTACKER, 1, 0
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 156, 24, 121, 13, ANIM_ATTACKER, 1, 1
delay 0
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 0, 0, RGB(31, 31, 22)
delay 10
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 5, 5, RGB(31, 31, 22)
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 100, 24, 60, 10, ANIM_ATTACKER, 1, 0
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 170, 24, 42, 11, ANIM_ATTACKER, 1, 1
delay 0
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 238, 24, 165, 10, ANIM_ATTACKER, 1, 1
delay 0
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 0, 0, RGB(31, 31, 22)
delay 20
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 7, 7, RGB(31, 31, 22)
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 0, 20, 0, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 64, 20, 1, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 128, 20, 0, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 32, 12, 192, 20, 2, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 32, 20, 0, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 96, 20, 1, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 160, 20, 0, 0
createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 16, 12, 224, 20, 2, 0
delay 4
waitforvisualfinish
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_ATTACKER, -31, 1, 0, 0, RGB(31, 31, 22)
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 4
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, -31, 2, 0, 6, RGB(31, 31, 22)
call ElectricityEffect
waitforvisualfinish
end
Move_ATTRACT:
loadspritegfx ANIM_TAG_RED_HEART
loopsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER, 12, 3
createvisualtask AnimTask_SwayMon, 5, 0, 12, 4096, 4, ANIM_ATTACKER
delay 15
createsprite gRedHeartProjectileSpriteTemplate, ANIM_TARGET, 3, 20, -8
waitforvisualfinish
playsewithpan SE_M_ATTRACT, SOUND_PAN_TARGET
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 160, -32
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -256, -40
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 128, -16
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 416, -38
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -128, -22
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -384, -31
waitforvisualfinish
waitplaysewithpan SE_M_ATTRACT2, 0, 15
createvisualtask AnimTask_HeartsBackground, 5
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 16, 256, 0
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 224, 240, 15
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 126, 272, 30
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 80, 224, 45
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 170, 272, 60
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 40, 256, 75
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 112, 256, 90
createsprite gRedHeartRisingSpriteTemplate, ANIM_ATTACKER, 40, 200, 272, 90
delay 75
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 4, 4, 0, 10, RGB(31, 25, 27)
end
Move_GROWTH:
call GrowthEffect
waitforvisualfinish
call GrowthEffect
waitforvisualfinish
end
GrowthEffect:
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB_WHITE
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -3, -3, 16, ANIM_ATTACKER, 0
return
Move_WHIRLWIND:
loadspritegfx ANIM_TAG_WHIRLWIND_LINES
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, -8, ANIM_TARGET, 60, 0
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 60, 1
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, 8, ANIM_TARGET, 60, 2
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, ANIM_TARGET, 60, 3
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, ANIM_TARGET, 60, 4
createsprite gWhirlwindLineSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, ANIM_TARGET, 60, 0
delay 5
loopsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET, 10, 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 15, 1
delay 29
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_TARGET, 12, 6, 1, 5
delay 7
playsewithpan SE_M_STRING_SHOT, SOUND_PAN_TARGET
createvisualtask AnimTask_SlideOffScreen, 5, ANIM_TARGET, 8
waitforvisualfinish
end
Move_CONFUSE_RAY:
loadspritegfx ANIM_TAG_YELLOW_BALL
monbg ANIM_DEF_PARTNER
fadetobg BG_GHOST
waitbgfadein
createvisualtask SoundTask_AdjustPanningVar, 2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 0
createvisualtask AnimTask_BlendColorCycleByTag, 2, ANIM_TAG_YELLOW_BALL, 0, 6, 0, 14, RGB(31, 10, 0)
createsprite gConfuseRayBallBounceSpriteTemplate, ANIM_TARGET, 2, 28, 0, 288
waitforvisualfinish
setalpha 8, 8
playsewithpan SE_M_STRING_SHOT2, SOUND_PAN_TARGET
createsprite gConfuseRayBallSpiralSpriteTemplate, ANIM_TARGET, 2, 0, -16
waitforvisualfinish
delay 0
blendoff
clearmonbg ANIM_DEF_PARTNER
restorebg
waitbgfadein
end
Move_LOCK_ON:
loadspritegfx ANIM_TAG_LOCK_ON
createsprite gLockOnTargetSpriteTemplate, ANIM_ATTACKER, 40
createsprite gLockOnMoveTargetSpriteTemplate, ANIM_ATTACKER, 40, 1
createsprite gLockOnMoveTargetSpriteTemplate, ANIM_ATTACKER, 40, 2
createsprite gLockOnMoveTargetSpriteTemplate, ANIM_ATTACKER, 40, 3
createsprite gLockOnMoveTargetSpriteTemplate, ANIM_ATTACKER, 40, 4 @ Also transitions to red target
delay 120
setarg 7, 0xFFFF @ Signal target to flash/disappear
waitforvisualfinish
end
Move_MEAN_LOOK:
loadspritegfx ANIM_TAG_EYE
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 16, RGB_BLACK
loopsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_TARGET, 15, 4
waitplaysewithpan SE_M_LEER, SOUND_PAN_TARGET, 85
createsprite gMeanLookEyeSpriteTemplate, ANIM_ATTACKER, 2
delay 120
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 16, 0, RGB_BLACK
delay 30
clearmonbg ANIM_DEF_PARTNER
waitforvisualfinish
end
Move_ROCK_THROW:
loadspritegfx ANIM_TAG_ROCKS
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_TARGET, 2, 6, 1, 15, 1
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 0, 1, 0, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 6
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 19, 1, 10, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 6
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -23, 2, -10, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 20, 1
delay 6
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -15, 1, -10, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 6
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 23, 2, 10, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
waitforvisualfinish
end
Move_ROCK_SLIDE:
loadspritegfx ANIM_TAG_ROCKS
monbg ANIM_DEF_PARTNER
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 7, 1, 11, 1
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -5, 1, -5, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 5, 0, 6, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 19, 1, 10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -23, 2, -10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 50, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_DEF_PARTNER, 0, 5, 50, 1
delay 2
call RockSlideRocks
call RockSlideRocks
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
RockSlideRocks:
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -20, 0, -10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 28, 1, 10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -10, 1, -5, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 10, 0, 6, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 24, 1, 10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -32, 2, -10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, -20, 0, -10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
createsprite gFallingRockSpriteTemplate, ANIM_TARGET, 2, 30, 2, 10, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 2
return
Move_THIEF:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
delay 1
fadetobg BG_DARK
waitbgfadein
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 6
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 8, 1
waitforvisualfinish
delay 20
clearmonbg ANIM_TARGET
blendoff
restorebg
waitbgfadein
end
Move_BUBBLE_BEAM:
loadspritegfx ANIM_TAG_BUBBLE
loadspritegfx ANIM_TAG_SMALL_BUBBLES
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
delay 1
call BulbblebeamCreateBubbles
createvisualtask AnimTask_SwayMon, 5, 0, 3, 3072, 8, ANIM_TARGET
call BulbblebeamCreateBubbles
call BulbblebeamCreateBubbles
waitforvisualfinish
call WaterBubblesEffectShort
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
BulbblebeamCreateBubbles:
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 35, 70, 0, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 20, 40, -10, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 10, -60, 0, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 15, -15, 10, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 30, 10, -10, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 25, -30, 10, 256, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
delay 3
return
Move_ICY_WIND:
loadspritegfx ANIM_TAG_ICE_CRYSTALS
loadspritegfx ANIM_TAG_ICE_SPIKES
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_ATK_SIDE, 4, 0, 4, RGB_BLACK
fadetobg BG_ICE
waitbgfadeout
playsewithpan SE_M_ICY_WIND, 0
waitbgfadein
waitforvisualfinish
panse SE_M_GUST, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
call IcyWindSwirlingSnowballs
delay 5
call IcyWindSwirlingSnowballs
playsewithpan SE_M_GUST2, SOUND_PAN_TARGET
delay 55
call IceSpikesEffectLong
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
restorebg
waitbgfadeout
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_ATK_SIDE, 4, 4, 0, RGB_BLACK
waitbgfadein
end
IcyWindSwirlingSnowballs:
createsprite gSwirlingSnowballSpriteTemplate, ANIM_TARGET, 40, 0, 0, 0, 0, 72, 1
delay 5
createsprite gSwirlingSnowballSpriteTemplate, ANIM_TARGET, 40, 0, 10, 0, 10, 72, 1
delay 5
createsprite gSwirlingSnowballSpriteTemplate, ANIM_TARGET, 40, 0, -10, 0, -10, 72, 1
delay 5
createsprite gSwirlingSnowballSpriteTemplate, ANIM_TARGET, 40, 0, 15, 0, 15, 72, 1
delay 5
createsprite gSwirlingSnowballSpriteTemplate, ANIM_TARGET, 40, 0, -5, 0, -5, 72, 1
return
Move_SMOKESCREEN:
loadspritegfx ANIM_TAG_BLACK_SMOKE
loadspritegfx ANIM_TAG_BLACK_BALL
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
createsprite gBlackBallSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 35, -25
waitforvisualfinish
createvisualtask AnimTask_SmokescreenImpact, 2
delay 2
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_TARGET
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, -12, 104, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, -12, 72, 1, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, -6, 56, 1, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, -6, 88, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 0, 56, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 0, 88, 1, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 6, 72, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 6, 104, 1, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 12, 72, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 12, 56, 1, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 18, 80, 0, 75
createsprite gBlackSmokeSpriteTemplate, ANIM_TARGET, 4, 0, 18, 72, 1, 75
waitforvisualfinish
end
Move_CONVERSION:
loadspritegfx ANIM_TAG_CONVERSION
monbg ANIM_ATK_PARTNER
splitbgprio ANIM_ATTACKER
setalpha 16, 0
delay 0
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -24, -24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -8, -24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 8, -24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 24, -24
delay 3
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -24, -8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -8, -8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 8, -8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 24, -8
delay 3
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -24, 8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -8, 8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 8, 8
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 24, 8
delay 3
playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -24, 24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, -8, 24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 8, 24
delay 3
createsprite gConversionSpriteTemplate, ANIM_ATTACKER, 2, 24, 24
delay 20
playsewithpan SE_M_BARRIER, SOUND_PAN_ATTACKER
createvisualtask AnimTask_FlashAnimTagWithColor, 2, ANIM_TAG_CONVERSION, 1, 1, RGB(31, 31, 13), 12, 0, 0
delay 6
createvisualtask AnimTask_ConversionAlphaBlend, 5
waitforvisualfinish
delay 1
clearmonbg ANIM_ATK_PARTNER
blendoff
end
Move_CONVERSION_2:
loadspritegfx ANIM_TAG_CONVERSION
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
setalpha 0, 16
delay 0
playsewithpan SE_M_BARRIER, SOUND_PAN_TARGET
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -24, -24, 60
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -8, -24, 65
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 8, -24, 70
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 24, -24, 75
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -24, -8, 80
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -8, -8, 85
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 8, -8, 90
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 24, -8, 95
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -24, 8, 100
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -8, 8, 105
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 8, 8, 110
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 24, 8, 115
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -24, 24, 120
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, -8, 24, 125
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 8, 24, 130
createsprite gConversion2SpriteTemplate, ANIM_ATTACKER, 2, 24, 24, 135
createvisualtask AnimTask_Conversion2AlphaBlend, 5
delay 60
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
delay 10
playsewithpan SE_M_SWIFT, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_ROLLING_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 1, 4
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 6
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
createsprite gSlidingKickSpriteTemplate, ANIM_ATTACKER, 2, -24, 0, 48, 10, 160, 0
delay 5
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -8, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 8
clearmonbg ANIM_TARGET
blendoff
end
Move_HEADBUTT:
loadspritegfx ANIM_TAG_IMPACT
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 2
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 4, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
end
Move_HORN_ATTACK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HORN_HIT
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 2
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, 0, 0, 10
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 4, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
waitforvisualfinish
end
Move_FURY_ATTACK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HORN_HIT
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 4, 256, ANIM_ATTACKER, 2
choosetwoturnanim FuryAttackRight, FuryAttackLeft
FuryAttackContinue:
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
waitforvisualfinish
end
FuryAttackRight:
createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, 8, 8, 10
waitforvisualfinish
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
goto FuryAttackContinue
FuryAttackLeft:
createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, -8, -8, 10
waitforvisualfinish
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
goto FuryAttackContinue
Move_HORN_DRILL:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HORN_HIT
jumpifcontest HornDrillInContest
fadetobg BG_DRILL
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 768, 1, -1
HornDrillContinue:
waitbgfadein
setalpha 12, 8
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 2
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1
createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, 0, 0, 12
waitforvisualfinish
playse SE_BANG
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 40, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 40, 1
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 2, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -4, 3, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -8, -5, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 4, -12, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 16, 0, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 5, 18, ANIM_TARGET, 3
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -17, 12, ANIM_TARGET, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -21, -15, ANIM_TARGET, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, -27, ANIM_TARGET, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 0, ANIM_TARGET, 2
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
delay 4
createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2
waitforvisualfinish
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
end
HornDrillInContest:
fadetobg BG_DRILL_CONTESTS
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, 2304, 768, 0, -1
goto HornDrillContinue
Move_THRASH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
createvisualtask AnimTask_ThrashMoveMonHorizontal, 2
createvisualtask AnimTask_ThrashMoveMonVertical, 2
createsprite gFistFootRandomPosSpriteTemplate, ANIM_TARGET, 3, 1, 10, 0
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 7, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 28
createsprite gFistFootRandomPosSpriteTemplate, ANIM_TARGET, 3, 1, 10, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 7, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 28
createsprite gFistFootRandomPosSpriteTemplate, ANIM_TARGET, 3, 1, 10, 3
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 8, 0, 16, 1
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
end
Move_SING:
loadspritegfx ANIM_TAG_MUSIC_NOTES
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_MusicNotesRainbowBlend, 2
waitforvisualfinish
panse SE_M_SING, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 7, 0, 12
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 6, 1, 12
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 1, 2, 12
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 3, 12
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 3, 0, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 5, 2, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 6, 3, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 0, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 1, 2, 12
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 5, 3, 12
delay 4
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
createvisualtask AnimTask_MusicNotesClearRainbowBlend, 2
waitforvisualfinish
end
Move_LOW_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
createsprite gSlidingKickSpriteTemplate, ANIM_TARGET, 2, -24, 28, 40, 8, 160, 0
delay 4
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -8, 8, ANIM_TARGET, 2
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 6, 384, ANIM_TARGET, 2
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 4
end
Move_EARTHQUAKE:
createvisualtask AnimTask_HorizontalShake, 5, (MAX_BATTLERS_COUNT + 1), 10, 50
createvisualtask AnimTask_HorizontalShake, 5, MAX_BATTLERS_COUNT, 10, 50
playsewithpan SE_M_EARTHQUAKE, 0
delay 10
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
delay 16
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
end
Move_FISSURE:
loadspritegfx ANIM_TAG_MUD_SAND
createvisualtask AnimTask_HorizontalShake, 3, (MAX_BATTLERS_COUNT + 1), 10, 50
createvisualtask AnimTask_HorizontalShake, 3, ANIM_TARGET, 10, 50
playsewithpan SE_M_EARTHQUAKE, SOUND_PAN_TARGET
delay 8
call FissureDirtPlumeFar
delay 15
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
delay 15
call FissureDirtPlumeClose
delay 15
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
delay 15
call FissureDirtPlumeFar
delay 50
fadetobg BG_FISSURE
waitbgfadeout
createvisualtask AnimTask_PositionFissureBgOnBattler, 5, ANIM_TARGET, 5, -1
waitbgfadein
delay 40
restorebg
waitbgfadeout
setarg 7, -1
waitbgfadein
end
FissureDirtPlumeFar:
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 12, -48, -16, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 16, -16, -10, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 14, -52, -18, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 12, -32, -16, 24
playsewithpan SE_M_DIG, SOUND_PAN_TARGET
return
FissureDirtPlumeClose:
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 12, -24, -16, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 16, -38, -10, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 14, -20, -18, 24
createsprite gDirtPlumeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 12, -36, -16, 24
playsewithpan SE_M_DIG, SOUND_PAN_TARGET
return
Move_DIG:
choosetwoturnanim DigSetUp, DigUnleash
DigEnd:
end
DigSetUp:
loadspritegfx ANIM_TAG_MUD_SAND
loadspritegfx ANIM_TAG_DIRT_MOUND
createsprite gDirtMoundSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, 180
createsprite gDirtMoundSpriteTemplate, ANIM_ATTACKER, 1, 0, 1, 180
monbg_static ANIM_ATTACKER
delay 1
createvisualtask AnimTask_DigDownMovement, 2, FALSE
delay 6
call DigThrowDirt
call DigThrowDirt
call DigThrowDirt
call DigThrowDirt
call DigThrowDirt
waitforvisualfinish
clearmonbg_static ANIM_ATTACKER
delay 1
createvisualtask AnimTask_DigDownMovement, 2, TRUE
goto DigEnd
DigUnleash:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_DIRT_MOUND
createvisualtask AnimTask_DigUpMovement, 2, FALSE
waitforvisualfinish
monbg ANIM_ATTACKER
createsprite gDirtMoundSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, 48
createsprite gDirtMoundSpriteTemplate, ANIM_ATTACKER, 1, 0, 1, 48
delay 1
createvisualtask AnimTask_DigUpMovement, 2, TRUE
delay 16
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -8, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_ATTACKER
clearmonbg ANIM_ATTACKER
goto DigEnd
DigThrowDirt:
createsprite gDirtPlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 12, 4, -16, 18
createsprite gDirtPlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 16, 4, -10, 18
createsprite gDirtPlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 14, 4, -18, 18
createsprite gDirtPlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 12, 4, -16, 18
playsewithpan SE_M_DIG, SOUND_PAN_ATTACKER
delay 32
return
Move_MEDITATE:
call SetPsychicBackground
createvisualtask AnimTask_MeditateStretchAttacker, 2
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
delay 16
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
waitforvisualfinish
call UnsetPsychicBackground
end
Move_AGILITY:
monbg ANIM_ATK_PARTNER
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 4, 4
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 10
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 12
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 12
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
delay 1
end
Move_QUICK_ATTACK:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_ATK_PARTNER
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 1, 5
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
delay 4
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
waitforvisualfinish
end
Move_RAGE:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ANGER
monbg ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_ATTACKER, RGB_RED, 10, 0, 2
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
delay 20
createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6
delay 4
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, TRUE, 1, 10, 1, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
end
Move_TELEPORT:
call SetPsychicBackground
createvisualtask AnimTask_Teleport, 2
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
delay 15
call UnsetPsychicBackground
waitforvisualfinish
end
Move_DOUBLE_TEAM:
createvisualtask AnimTask_DoubleTeam, 2
setalpha 12, 8
monbg ANIM_ATK_PARTNER
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 32
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 24
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 16
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
delay 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
delay 1
end
Move_MINIMIZE:
setalpha 10, 8
createvisualtask AnimTask_Minimize, 2
loopsewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 34, 3
waitforvisualfinish
blendoff
end
Move_METRONOME:
loadspritegfx ANIM_TAG_FINGER
loadspritegfx ANIM_TAG_THOUGHT_BUBBLE
createsprite gThoughtBubbleSpriteTemplate, ANIM_ATTACKER, 11, 0, 100
playsewithpan SE_M_METRONOME, SOUND_PAN_ATTACKER
delay 6
createsprite gMetronomeFingerSpriteTemplate, ANIM_ATTACKER, 12, 0
delay 24
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 22, 3
waitforvisualfinish
end
Move_SKULL_BASH:
choosetwoturnanim SkullBashSetUp, SkullBashAttack
SkullBashEnd:
end
SkullBashSetUp:
call SkullBashSetUpHeadDown
call SkullBashSetUpHeadDown
waitforvisualfinish
goto SkullBashEnd
SkullBashSetUpHeadDown:
createsprite gSlideMonToOffsetAndBackSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, -24, 0, 0, 10, 0
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 2, 16, 96, ANIM_ATTACKER, 2
waitforvisualfinish
createsprite gSlideMonToOffsetAndBackSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, 24, 0, 0, 10, 1
waitforvisualfinish
return
SkullBashAttack:
loadspritegfx ANIM_TAG_IMPACT
createvisualtask AnimTask_SkullBashPosition, 2, 0
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
waitforvisualfinish
playse SE_BANG
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 40, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 40, 1
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 4, 0, 0, ANIM_TARGET, 0
loopsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET, 8, 3
waitforvisualfinish
createvisualtask AnimTask_SkullBashPosition, 2, 1
goto SkullBashEnd
Move_AMNESIA:
loadspritegfx ANIM_TAG_AMNESIA
call SetPsychicBackground
delay 8
createsprite gQuestionMarkSpriteTemplate, ANIM_ATTACKER, 20
playsewithpan SE_M_METRONOME, SOUND_PAN_ATTACKER
delay 54
loopsewithpan SE_M_METRONOME, SOUND_PAN_ATTACKER, 16, 3
waitforvisualfinish
call UnsetPsychicBackground
end
Move_KINESIS:
loadspritegfx ANIM_TAG_ALERT
loadspritegfx ANIM_TAG_BENT_SPOON
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
createsprite gBentSpoonSpriteTemplate, ANIM_ATTACKER, 20
createsprite gKinesisZapEnergySpriteTemplate, ANIM_ATTACKER, 19, 32, -8, 0
createsprite gKinesisZapEnergySpriteTemplate, ANIM_ATTACKER, 19, 32, 16, 1
loopsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_ATTACKER, 21, 2
delay 60
playsewithpan SE_M_DIZZY_PUNCH, SOUND_PAN_ATTACKER
delay 30
loopsewithpan SE_M_DIZZY_PUNCH, SOUND_PAN_ATTACKER, 20, 2
delay 70
playsewithpan SE_M_SWAGGER2, SOUND_PAN_ATTACKER
waitforvisualfinish
call UnsetPsychicBackground
end
Move_GLARE:
loadspritegfx ANIM_TAG_SMALL_RED_EYE
loadspritegfx ANIM_TAG_EYE_SPARKLE
createvisualtask AnimTask_GlareEyeDots, 5, 0
playsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 0, 16, RGB_BLACK
waitforvisualfinish
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, -16, -8
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, 16, -8
createvisualtask AnimTask_ScaryFace, 5
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
delay 2
createvisualtask AnimTask_ShakeTargetInPattern, 3, 20, 1, FALSE
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 16, 0, RGB_BLACK
end
Move_BARRAGE:
loadspritegfx ANIM_TAG_RED_BALL
createvisualtask AnimTask_BarrageBall, 3
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
delay 24
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 8, 1, 40, 1
createvisualtask AnimTask_ShakeMon, 3, ANIM_TARGET, 0, 4, 20, 1
createvisualtask AnimTask_ShakeMon, 3, ANIM_DEF_PARTNER, 0, 4, 20, 1
loopsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET, 8, 2
end
Move_SKY_ATTACK:
choosetwoturnanim SkyAttackSetUp, SkyAttackUnleash
SkyAttackEnd:
end
SkyAttackSetUp:
monbg ANIM_DEF_PARTNER
setalpha 12, 11
createvisualtask AnimTask_GetTargetIsAttackerPartner, 5, ARG_RET_ID
jumpretfalse SkyAttackSetUpAgainstOpponent
goto SkyAttackSetUpAgainstPartner
SkyAttackSetUpAgainstOpponent:
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_ATK_SIDE | F_PAL_DEF_PARTNER, 1, 0, 12, RGB_BLACK
waitforvisualfinish
delay 12
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 8, 0, RGB_BLACK
createvisualtask AnimTask_HorizontalShake, 5, ANIM_ATTACKER, 2, 16
loopsewithpan SE_M_STAT_INCREASE, SOUND_PAN_ATTACKER, 4, 8
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 0, 15, RGB_WHITE
delay 20
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 15, 0, RGB_WHITE
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_ATK_PARTNER | F_PAL_DEF_PARTNER, 1, 8, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
goto SkyAttackEnd
SkyAttackSetUpAgainstPartner:
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, ANIM_TARGET, 1, 0, 12, RGB_BLACK
waitforvisualfinish
delay 12
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 8, 0, RGB_BLACK
createvisualtask AnimTask_HorizontalShake, 5, ANIM_ATTACKER, 2, 16
playsewithpan SE_M_STAT_INCREASE, SOUND_PAN_ATTACKER
delay 8
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 0, 15, RGB_WHITE
delay 20
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 1, 15, 0, RGB_WHITE
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, 4, 1, 8, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
goto SkyAttackEnd
SkyAttackUnleash:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_BIRD
call SetSkyBg
monbg ANIM_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 0, 0, 16, RGB_WHITE
delay 4
createvisualtask AnimTask_AttackerFadeToInvisible, 5, 0
waitforvisualfinish
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_SKY_UPPERCUT, SOUND_PAN_ATTACKER
createsprite gSkyAttackBirdSpriteTemplate, ANIM_TARGET, 2
delay 14
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 10, 0, 18, 1
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
delay 20
createvisualtask AnimTask_AttackerFadeFromInvisible, 5, 1
delay 2
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 0, 15, 0, RGB_WHITE
waitforvisualfinish
clearmonbg ANIM_ATTACKER
call UnsetSkyBg
goto SkyAttackEnd
Move_FLASH:
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
createvisualtask AnimTask_Flash, 2
waitforvisualfinish
end
Move_SPLASH:
createvisualtask AnimTask_Splash, 2, 0, 3
delay 8
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 38, 3
waitforvisualfinish
end
Move_ACID_ARMOR:
monbg ANIM_ATTACKER
setalpha 15, 0
createvisualtask AnimTask_AcidArmor, 2, ANIM_ATTACKER
playsewithpan SE_M_ACID_ARMOR, SOUND_PAN_ATTACKER
waitforvisualfinish
blendoff
clearmonbg ANIM_ATTACKER
delay 1
end
Move_SHARPEN:
loadspritegfx ANIM_TAG_SPHERE_TO_CUBE
createsprite gSharpenSphereSpriteTemplate, ANIM_ATTACKER, 2
waitforvisualfinish
end
Move_SUPER_FANG:
loadspritegfx ANIM_TAG_FANG_ATTACK
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 1, 0, 20, 1
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 48, 1
createvisualtask AnimTask_BlendMonInAndOut, 2, ANIM_ATTACKER, RGB(31, 6, 1), 12, 4, 1
waitforvisualfinish
delay 20
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 4
createsprite gSuperFangSpriteTemplate, ANIM_TARGET, 2
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
delay 8
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB(31, 2, 2), 14, RGB_WHITE, 14
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 7, 12, 1
waitforvisualfinish
blendoff
end
Move_SLASH:
loadspritegfx ANIM_TAG_SLASH
createsprite gSlashSliceSpriteTemplate, ANIM_TARGET, 2, 1, -8, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
delay 4
createsprite gSlashSliceSpriteTemplate, ANIM_TARGET, 2, 1, 8, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 18, 1
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
end
Move_STRUGGLE:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_MOVEMENT_WAVES
monbg ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 12, 4
createsprite gMovementWavesSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 2
createsprite gMovementWavesSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 2
loopsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER, 12, 4
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_SKETCH:
loadspritegfx ANIM_TAG_PENCIL
monbg ANIM_TARGET
createvisualtask AnimTask_SketchDrawMon, 2
createsprite gPencilSpriteTemplate, ANIM_TARGET, 2
waitforvisualfinish
clearmonbg ANIM_TARGET
createvisualtask AnimTask_Splash, 2, 0, 2
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 38, 2
end
Move_NIGHTMARE:
fadetobg BG_GHOST
waitbgfadein
jumpifcontest NightmareInContest
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_NightmareClone, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 40, 1
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
restorebg
waitbgfadein
end
NightmareInContest:
createvisualtask AnimTask_BlendMonInAndOut, 2, ANIM_ATTACKER, RGB_WHITE, 10, 2, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 3, 0, 32, 1
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
waitforvisualfinish
restorebg
waitbgfadein
end
Move_FLAIL:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_FlailMovement, 2, ANIM_ATTACKER
loopsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER, 8, 2
waitforvisualfinish
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 3
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 30, 1, 0
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_SPITE:
fadetobg BG_GHOST
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
waitbgfadein
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 6, 0, 8, RGB_WHITE
createvisualtask AnimTask_SpiteTargetShadow, 2
loopsewithpan SE_M_PSYBEAM, SOUND_PAN_TARGET, 20, 3
waitforvisualfinish
restorebg
waitbgfadein
clearmonbg ANIM_TARGET
end
Move_MACH_PUNCH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_GetAttackerSide, 2
jumprettrue MachPunchAgainstPlayer
fadetobg BG_HIGHSPEED_OPPONENT
MachPunchContinue:
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 0, 1, -1
waitbgfadein
delay 0
setalpha 9, 8
createvisualtask AnimTask_AttackerPunchWithTrace, 2, RGB(8, 9, 28), 10
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 8, 1, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
end
MachPunchAgainstPlayer:
fadetobg BG_HIGHSPEED_PLAYER
goto MachPunchContinue
Move_FORESIGHT:
loadspritegfx ANIM_TAG_MAGNIFYING_GLASS
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 16, 0
createsprite gForesightMagnifyingGlassSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET
delay 17
loopsewithpan SE_M_SKETCH, SOUND_PAN_TARGET, 16, 4
delay 48
delay 24
playsewithpan SE_M_SKETCH, SOUND_PAN_TARGET
delay 10
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_TARGET, RGB_WHITE, 12, 2, 1
playsewithpan SE_M_DETECT, SOUND_PAN_TARGET
waitforvisualfinish
blendoff
clearmonbg ANIM_DEF_PARTNER
end
Move_DESTINY_BOND:
loadspritegfx ANIM_TAG_WHITE_SHADOW
fadetobg BG_GHOST
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
waitbgfadein
createvisualtask AnimTask_DestinyBondWhiteShadow, 5, 0, 48
playsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_ATTACKER
delay 48
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 24, 1
createvisualtask AnimTask_BlendBattleAnimPalExclude, 2, 6, 1, 0, 12, RGB(29, 29, 29)
delay 24
createvisualtask AnimTask_BlendBattleAnimPalExclude, 2, 6, 1, 12, 0, RGB(29, 29, 29)
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
waitforvisualfinish
restorebg
waitbgfadein
blendoff
clearmonbg 5
end
Move_ENDURE:
loadspritegfx ANIM_TAG_FOCUS_ENERGY
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
call EndureEffect
delay 8
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 11, RGB_RED
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 32, 1
call EndureEffect
delay 8
call EndureEffect
waitforvisualfinish
end
EndureEffect:
createsprite gEndureEnergySpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 26, 2
delay 4
createsprite gEndureEnergySpriteTemplate, ANIM_ATTACKER, 2, 0, 14, 28, 1
delay 4
createsprite gEndureEnergySpriteTemplate, ANIM_ATTACKER, 2, 0, -5, 10, 2
delay 4
createsprite gEndureEnergySpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 26, 3
delay 4
createsprite gEndureEnergySpriteTemplate, ANIM_ATTACKER, 2, 0, -12, 0, 1
return
Move_CHARM:
loadspritegfx ANIM_TAG_MAGENTA_HEART
createvisualtask AnimTask_RockMonBackAndForth, 5, ANIM_ATTACKER, 2, 0
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 0, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
delay 15
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, -20, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
delay 15
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 20, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
waitforvisualfinish
end
Move_ROLLOUT:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_MUD_SAND
loadspritegfx ANIM_TAG_ROCKS
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_Rollout, 2
waitforvisualfinish
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 30, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, ANIM_TARGET, 2
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_FALSE_SWIPE:
loadspritegfx ANIM_TAG_SLASH_2
loadspritegfx ANIM_TAG_IMPACT
createsprite gFalseSwipeSliceSpriteTemplate, ANIM_TARGET, 2
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
delay 16
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 0
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET
delay 2
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 16
delay 2
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 32
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET
delay 2
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 48
delay 2
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 64
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET
delay 2
createsprite gFalseSwipePositionedSliceSpriteTemplate, ANIM_TARGET, 2, 80
delay 2
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, 0, 0, ANIM_TARGET, 3
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
end
Move_SWAGGER:
loadspritegfx ANIM_TAG_BREATH
loadspritegfx ANIM_TAG_ANGER
createvisualtask AnimTask_GrowAndShrink, 2
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2
loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2
waitforvisualfinish
delay 24
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, -20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
delay 12
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, 20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
waitforvisualfinish
end
Move_MILK_DRINK:
loadspritegfx ANIM_TAG_MILK_BOTTLE
loadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_TARGET
createsprite gMilkBottleSpriteTemplate, ANIM_ATTACKER, 2
delay 40
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
delay 12
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
delay 20
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 0
playsewithpan SE_M_MILK_DRINK, SOUND_PAN_ATTACKER
waitforvisualfinish
clearmonbg ANIM_TARGET
call HealingEffect2
waitforvisualfinish
end
Move_MAGNITUDE:
createvisualtask AnimTask_IsPowerOver99, 2
waitforvisualfinish
jumpargeq 15, FALSE, MagnitudeRegular
jumpargeq 15, TRUE, MagnitudeIntense
MagnitudeEnd:
end
MagnitudeRegular:
createvisualtask AnimTask_HorizontalShake, 5, (MAX_BATTLERS_COUNT + 1), 0, 50
createvisualtask AnimTask_HorizontalShake, 5, MAX_BATTLERS_COUNT, 0, 50
loopsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET, 8, 10
goto MagnitudeEnd
MagnitudeIntense:
createvisualtask AnimTask_HorizontalShake, 5, (MAX_BATTLERS_COUNT + 1), 0, 50
createvisualtask AnimTask_HorizontalShake, 5, MAX_BATTLERS_COUNT, 0, 50
loopsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET, 8, 10
delay 10
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
delay 16
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_BLACK, 14, RGB_WHITE, 14
goto MagnitudeEnd
Move_RAPID_SPIN:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_RAPID_SPIN
monbg ANIM_ATTACKER
createsprite gRapidSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 32, -32, 40, -2
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 0
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
waitforvisualfinish
delay 8
createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 1
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
Move_MOONLIGHT:
loadspritegfx ANIM_TAG_MOON
loadspritegfx ANIM_TAG_GREEN_SPARKLE
loadspritegfx ANIM_TAG_BLUE_STAR
setalpha 0, 16
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 16, RGB_BLACK
waitforvisualfinish
createsprite gMoonSpriteTemplate, ANIM_ATTACKER, 2, 120, 56
createvisualtask AnimTask_AlphaFadeIn, 3, 0, 16, 16, 0, 1
playsewithpan SE_M_MOONLIGHT, 0
delay 30
createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, -12, 0
delay 30
createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, -24, 0
delay 30
createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, 21, 0
delay 30
createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, 0, 0
delay 30
createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, 10, 0
delay 20
createvisualtask AnimTask_MoonlightEndFade, 2
waitforvisualfinish
call HealingEffect
waitforvisualfinish
end
Move_EXTREME_SPEED:
loadspritegfx ANIM_TAG_SPEED_DUST
loadspritegfx ANIM_TAG_IMPACT
createvisualtask AnimTask_GetAttackerSide, 2
jumprettrue ExtremeSpeedAgainstPlayer
fadetobg BG_HIGHSPEED_OPPONENT
ExtremeSpeedContinue:
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 0, 1, -1
waitbgfadein
createvisualtask AnimTask_AttackerStretchAndDisappear, 2
loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 3
waitforvisualfinish
delay 1
createvisualtask AnimTask_SetAttackerInvisibleWaitForSignal, 2
monbg ANIM_TARGET
setalpha 12, 8
delay 18
createvisualtask AnimTask_ExtremeSpeedImpact, 2
delay 2
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gMonEdgeHitSplatSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 0, -12, 3
delay 10
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gMonEdgeHitSplatSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 0, 12, 3
delay 10
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gMonEdgeHitSplatSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 0, 0, 3
waitforvisualfinish
createvisualtask AnimTask_SpeedDust, 2
delay 10
createvisualtask AnimTask_ExtremeSpeedMonReappear, 2
loopsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER, 8, 4
waitforvisualfinish
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
clearmonbg ANIM_TARGET
blendoff
delay 1
setarg 7, 0x1000
delay 1
end
ExtremeSpeedAgainstPlayer:
fadetobg BG_HIGHSPEED_PLAYER
goto ExtremeSpeedContinue
Move_UPROAR:
loadspritegfx ANIM_TAG_JAGGED_MUSIC_NOTE
loadspritegfx ANIM_TAG_THIN_RING
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_UproarDistortion, 2, 0
createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 31, 8
playsewithpan SE_M_UPROAR, SOUND_PAN_ATTACKER
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, 29, -12, 0
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, -12, -29, 1
delay 16
createvisualtask AnimTask_UproarDistortion, 2, 0
createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 31, 8
playsewithpan SE_M_UPROAR, SOUND_PAN_ATTACKER
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, 12, -29, 1
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, -29, -12, 0
delay 16
createvisualtask AnimTask_UproarDistortion, 2, 0
createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 31, 8
playsewithpan SE_M_UPROAR, SOUND_PAN_ATTACKER
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, -24, 1
createsprite gJaggedMusicNoteSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, -24, 0
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_HEAT_WAVE:
loadspritegfx ANIM_TAG_FLYING_DIRT
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_FLYING_DIRT, 0, 6, 6, RGB_RED
createvisualtask AnimTask_LoadSandstormBackground, 5, TRUE
createvisualtask AnimTask_BlendBackground, 6, 6, RGB_RED
panse SE_M_HEAT_WAVE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
delay 4
createvisualtask AnimTask_MoveHeatWaveTargets, 5
delay 12
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 1
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 1
end
@ Also used by Hail weather
Move_HAIL:
loadspritegfx ANIM_TAG_HAIL
loadspritegfx ANIM_TAG_ICE_CRYSTALS
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 0, 6, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_Hail, 5
loopsewithpan SE_M_HAIL, 0, 8, 10
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 3, 6, 0, RGB_BLACK
end
Move_TORMENT:
loadspritegfx ANIM_TAG_ANGER
loadspritegfx ANIM_TAG_THOUGHT_BUBBLE
createvisualtask AnimTask_TormentAttacker, 2
waitforvisualfinish
createvisualtask AnimTask_BlendMonInAndOut, 2, ANIM_TARGET, RGB_RED, 10, 1, 1
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, -20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
delay 20
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, 20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
end
Move_MEMENTO:
setalpha 0, 16
delay 1
createvisualtask AnimTask_InitMementoShadow, 2
delay 1
createvisualtask AnimTask_MoveAttackerMementoShadow, 5
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
delay 48
playsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_MementoHandleBg, 2
delay 12
setalpha 0, 16
delay 1
monbg_static ANIM_TARGET
createvisualtask AnimTask_MoveTargetMementoShadow, 5
playsewithpan SE_M_PSYBEAM, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg_static ANIM_TARGET
delay 1
blendoff
delay 1
end
Move_FACADE:
loadspritegfx ANIM_TAG_SWEAT_DROP
createvisualtask AnimTask_SquishAndSweatDroplets, 2, ANIM_ATTACKER, 3
createvisualtask AnimTask_FacadeColorBlend, 2, ANIM_ATTACKER, 72
loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 24, 3
end
Move_SMELLING_SALT:
loadspritegfx ANIM_TAG_TAG_HAND
loadspritegfx ANIM_TAG_SMELLINGSALT_EFFECT
createsprite gSmellingSaltsHandSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 0, 2
createsprite gSmellingSaltsHandSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 1, 2
delay 32
createvisualtask AnimTask_SmellingSaltsSquish, 3, ANIM_TARGET, 2
loopsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET, 12, 2
waitforvisualfinish
delay 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 6, 2
createsprite gSmellingSaltExclamationSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 8, 3
loopsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET, 16, 3
end
Move_FOLLOW_ME:
loadspritegfx ANIM_TAG_FINGER
createsprite gFollowMeFingerSpriteTemplate, ANIM_ATTACKER, 2, 0
playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 18
playsewithpan SE_M_ATTRACT, SOUND_PAN_ATTACKER
delay 71
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 22, 3
end
Move_CHARGE:
loadspritegfx ANIM_TAG_ELECTRIC_ORBS
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
loadspritegfx ANIM_TAG_ELECTRICITY
monbg ANIM_ATTACKER
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 4, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_ElectricChargingParticles, 2, ANIM_ATTACKER, 60, 2, 12
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 30
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 30
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
createsprite gGrowingChargeOrbSpriteTemplate, ANIM_ATTACKER, 2, 0
delay 25
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 20
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 15
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 10
delay 6
loopsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER, 6, 5
waitforvisualfinish
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, 16
delay 2
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 0, -16, -16
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 4, 0, RGB_BLACK
clearmonbg ANIM_ATTACKER
blendoff
end
Move_TAUNT:
loadspritegfx ANIM_TAG_FINGER_2
loadspritegfx ANIM_TAG_THOUGHT_BUBBLE
loadspritegfx ANIM_TAG_ANGER
createsprite gThoughtBubbleSpriteTemplate, ANIM_ATTACKER, 11, 0, 45
playsewithpan SE_M_METRONOME, SOUND_PAN_ATTACKER
delay 6
createsprite gTauntFingerSpriteTemplate, ANIM_ATTACKER, 12, 0
delay 4
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 16, 2
waitforvisualfinish
delay 8
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, -20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
waitforvisualfinish
delay 12
createsprite gAngerMarkSpriteTemplate, ANIM_TARGET, 2, 1, 20, -28
playsewithpan SE_M_SWAGGER2, SOUND_PAN_TARGET
end
Move_HELPING_HAND:
loadspritegfx ANIM_TAG_TAG_HAND
createvisualtask AnimTask_HelpingHandAttackerMovement, 5
createsprite gHelpingHandClapSpriteTemplate, ANIM_ATTACKER, 40, 0
createsprite gHelpingHandClapSpriteTemplate, ANIM_ATTACKER, 40, 1
delay 19
playsewithpan SE_M_ENCORE, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATK_PARTNER, 2, 0, 5, 1
delay 14
playsewithpan SE_M_ENCORE, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATK_PARTNER, 2, 0, 5, 1
delay 20
playsewithpan SE_M_ENCORE, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATK_PARTNER, 3, 0, 10, 1
createvisualtask AnimTask_BlendMonInAndOut, 2, ANIM_ATK_PARTNER, RGB_YELLOW, 12, 1, 1
end
Move_ASSIST:
loadspritegfx ANIM_TAG_PAW_PRINT
createsprite gAssistPawprintSpriteTemplate, ANIM_ATTACKER, 50, 112, -16, 140, 128, 36
delay 2
createsprite gAssistPawprintSpriteTemplate, ANIM_ATTACKER, 50, 208, 128, -16, 48, 36
playsewithpan SE_M_SCRATCH, 0
delay 2
createsprite gAssistPawprintSpriteTemplate, ANIM_ATTACKER, 50, -16, 112, 256, -16, 36
playsewithpan SE_M_SCRATCH, 0
delay 2
createsprite gAssistPawprintSpriteTemplate, ANIM_ATTACKER, 50, 108, 128, 84, -16, 36
playsewithpan SE_M_SCRATCH, 0
delay 2
createsprite gAssistPawprintSpriteTemplate, ANIM_ATTACKER, 50, -16, 56, 256, 56, 36
playsewithpan SE_M_SCRATCH, 0
end
Move_SUPERPOWER:
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
loadspritegfx ANIM_TAG_METEOR
loadspritegfx ANIM_TAG_FLAT_ROCK
monbg ANIM_ATK_PARTNER
splitbgprio ANIM_ATTACKER
setalpha 12, 8
createsprite gSuperpowerOrbSpriteTemplate, ANIM_TARGET, 2, ANIM_ATTACKER
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
delay 20
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 4, 1, 180, 1
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_EARTHQUAKE, 0
delay 40
createsprite gSuperpowerRockSpriteTemplate, ANIM_ATTACKER, 41, 200, 96, 1, 120
delay 8
createsprite gSuperpowerRockSpriteTemplate, ANIM_ATTACKER, 41, 20, 248, 4, 112
delay 8
createsprite gSuperpowerRockSpriteTemplate, ANIM_ATTACKER, 41, 130, 160, 2, 104
delay 8
createsprite gSuperpowerRockSpriteTemplate, ANIM_ATTACKER, 41, 160, 192, 0, 96
delay 8
createsprite gSuperpowerRockSpriteTemplate, ANIM_ATTACKER, 41, 60, 288, 3, 88
delay 74
createsprite gSuperpowerFireballSpriteTemplate, ANIM_TARGET, 3, ANIM_ATTACKER
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
delay 16
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 8, 0, 16, 1
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
delay 1
end
Move_RECYCLE:
loadspritegfx ANIM_TAG_RECYCLE
monbg ANIM_ATTACKER
setalpha 0, 16
delay 1
createsprite gRecycleSpriteTemplate, ANIM_ATTACKER, 2
loopsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER, 24, 3
waitforvisualfinish
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB_WHITE, 12, 2, 1
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
waitforvisualfinish
blendoff
clearmonbg ANIM_ATTACKER
delay 1
end
Move_BRICK_BREAK:
loadspritegfx ANIM_TAG_BLUE_LIGHT_WALL
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_TORN_METAL
choosetwoturnanim BrickBreakNormal, BrickBreakShatteredWall
BrickBreakNormal:
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 8
delay 4
delay 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -18, -18, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
delay 20
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 8
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, 18, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
delay 20
createvisualtask AnimTask_WindUpLunge, 2, ANIM_ATTACKER, -24, 0, 24, 10, 24, 3
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 6, RGB_BLACK
delay 37
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 10, 1, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 6, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_TARGET
end
BrickBreakShatteredWall:
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 8
delay 4
createsprite gBrickBreakWallSpriteTemplate, ANIM_ATTACKER, 3, ANIM_TARGET, 0, 0, 90, 10
delay 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -18, -18, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
delay 20
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 8
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, 18, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
delay 20
createvisualtask AnimTask_WindUpLunge, 2, ANIM_ATTACKER, -24, 0, 24, 10, 24, 3
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 6, RGB_BLACK
delay 37
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 10, 1, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, -8, -12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 1, 8, -12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 2, -8, 12
createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 3, 8, 12
playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 6, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_TARGET
end
Move_YAWN:
loadspritegfx ANIM_TAG_PINK_CLOUD
createvisualtask AnimTask_DeepInhale, 2, ANIM_ATTACKER
playsewithpan SE_M_YAWN, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gYawnCloudSpriteTemplate, ANIM_TARGET, 5, 2
playsewithpan SE_M_SPIT_UP, SOUND_PAN_ATTACKER
delay 4
createsprite gYawnCloudSpriteTemplate, ANIM_TARGET, 5, 1
delay 4
createsprite gYawnCloudSpriteTemplate, ANIM_TARGET, 5, 0
waitforvisualfinish
createvisualtask AnimTask_DeepInhale, 2, ANIM_TARGET
playsewithpan SE_M_YAWN, SOUND_PAN_TARGET
end
Move_ENDEAVOR:
loadspritegfx ANIM_TAG_SWEAT_DROP
loadspritegfx ANIM_TAG_IMPACT
createvisualtask AnimTask_SquishAndSweatDroplets, 2, ANIM_ATTACKER, 2
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 24, 2
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB(31, 21, 0), 12, 1, 2
delay 6
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 5, FALSE, 1, 8, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 12, -12, ANIM_TARGET, 2
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
delay 24
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 5, FALSE, 1, 8, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -12, 12, ANIM_TARGET, 2
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
end
Move_ERUPTION:
loadspritegfx ANIM_TAG_WARM_ROCK
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 2, 0, 4, RGB_RED
waitforvisualfinish
createvisualtask AnimTask_EruptionLaunchRocks, 2
waitplaysewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER, 60
waitforvisualfinish
createvisualtask AnimTask_EruptionLaunchRocks, 2
waitplaysewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER, 60
waitforvisualfinish
delay 30
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 200, -32, 0, 100, 0
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 30, -32, 16, 90, 1
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 150, -32, 32, 60, 2
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 90, -32, 48, 80, 3
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 110, -32, 64, 50, 0
createsprite gEruptionFallingRockSpriteTemplate, ANIM_ATTACKER, 40, 60, -32, 80, 70, 1
delay 22
createvisualtask AnimTask_HorizontalShake, 5, (MAX_BATTLERS_COUNT + 1), 8, 60
createvisualtask AnimTask_HorizontalShake, 5, MAX_BATTLERS_COUNT, 8, 60
loopsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET, 16, 12
delay 80
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 40, F_PAL_BG | F_PAL_BATTLERS, 4, 4, 0, RGB_RED
end
Move_SKILL_SWAP:
loadspritegfx ANIM_TAG_BLUEGREEN_ORB
call SetPsychicBackground
createvisualtask AnimTask_SkillSwap, 3, ANIM_TARGET
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_TARGET, RGB_WHITE, 12, 3, 1
loopsewithpan SE_M_REVERSAL, SOUND_PAN_ATTACKER, 24, 3
delay 16
createvisualtask AnimTask_SkillSwap, 3, ANIM_ATTACKER
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB_WHITE, 12, 3, 1
waitforvisualfinish
call UnsetPsychicBackground
end
Move_IMPRISON:
loadspritegfx ANIM_TAG_HOLLOW_ORB
loadspritegfx ANIM_TAG_X_SIGN
call SetPsychicBackground
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_ImprisonOrbs, 5
delay 8
loopsewithpan SE_M_HORN_ATTACK, SOUND_PAN_ATTACKER, 8, 5
waitforvisualfinish
delay 4
createsprite gRedXSpriteTemplate, ANIM_ATTACKER, 5, ANIM_ATTACKER, 40
createvisualtask AnimTask_HorizontalShake, 5, MAX_BATTLERS_COUNT, 1, 10
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_ATTACKER
clearmonbg ANIM_DEF_PARTNER
call UnsetPsychicBackground
end
Move_GRUDGE:
loadspritegfx ANIM_TAG_PURPLE_FLAME
monbg ANIM_ATTACKER
splitbgprio_all
fadetobg BG_GHOST
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
waitbgfadein
createvisualtask AnimTask_GrudgeFlames, 3
loopsewithpan SE_M_EMBER, SOUND_PAN_ATTACKER, 16, 4
delay 10
delay 80
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
waitforvisualfinish
restorebg
waitbgfadein
clearmonbg ANIM_ATTACKER
end
Move_CAMOUFLAGE:
monbg ANIM_ATK_PARTNER
splitbgprio ANIM_ATTACKER
setalpha 16, 0
createvisualtask AnimTask_SetCamouflageBlend, 5, F_PAL_ATTACKER, 3, 0, 14
delay 16
createvisualtask AnimTask_AttackerFadeToInvisible, 2, 4
playsewithpan SE_M_FAINT_ATTACK, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 8
createvisualtask AnimTask_SetCamouflageBlend, 5, F_PAL_ATTACKER, 0, 0, 0
waitforvisualfinish
createvisualtask AnimTask_AttackerFadeFromInvisible, 2, 1
waitforvisualfinish
blendoff
clearmonbg ANIM_ATK_PARTNER
end
Move_TAIL_GLOW:
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
monbg ANIM_ATTACKER
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 4, RGB_BLACK
waitforvisualfinish
createsprite gTailGlowOrbSpriteTemplate, ANIM_ATTACKER, 66, ANIM_ATTACKER
delay 18
loopsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER, 16, 6
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 4, 0, RGB_BLACK
clearmonbg ANIM_ATTACKER
blendoff
delay 1
end
Move_LUSTER_PURGE:
loadspritegfx ANIM_TAG_WHITE_CIRCLE_OF_LIGHT
loadspritegfx ANIM_TAG_IMPACT
fadetobg BG_PSYCHIC
waitbgfadeout
createvisualtask AnimTask_FadeScreenToWhite, 5
waitbgfadein
monbg ANIM_ATTACKER
setalpha 12, 8
playsewithpan SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER
createsprite gLusterPurgeCircleSpriteTemplate, ANIM_ATTACKER, 41, 0, 0, 0, 0
delay 20
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_WHITE_CIRCLE_OF_LIGHT, 2, 0, 16, RGB_WHITEALPHA
waitforvisualfinish
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT, 0, 12, 12, RGB(0, 0, 23)
waitforvisualfinish
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 3
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 3
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 3
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 3
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
delay 3
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_HYPER_BEAM, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, ANIM_TARGET, 5, 14
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
call UnsetPsychicBackground
end
Move_MIST_BALL:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_WHITE_FEATHER
delay 0
playsewithpan SE_M_STRING_SHOT, SOUND_PAN_ATTACKER
createsprite gMistBallSpriteTemplate, ANIM_TARGET, 0, 0, 0, 0, 0, 30, 0
waitforvisualfinish
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 10, 0
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 1, 1, RGB(23, 16, 31), 16, RGB_WHITE, 16
delay 0
playsewithpan SE_M_HAZE, 0
createvisualtask AnimTask_MistBallFog, 5
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 3, 0, 16, RGB_WHITE
delay 8
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 4, 0, 70, 0
delay 70
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 16, 0, RGB_WHITE
end
Move_FEATHER_DANCE:
loadspritegfx ANIM_TAG_WHITE_FEATHER
monbg ANIM_DEF_PARTNER
splitbgprio_all
playsewithpan SE_M_PETAL_DANCE, SOUND_PAN_TARGET
delay 0
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 64, 2, 104, 11304, 32, 1
delay 6
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 32, 2, 104, 11304, 32, 1
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 0, 2, 104, 11304, 32, 1
delay 6
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 224, 2, 104, 11304, 32, 1
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 128, 2, 104, 11304, 32, 1
delay 6
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 192, 2, 104, 11304, 32, 1
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 160, 2, 104, 11304, 32, 1
delay 6
createsprite gFallingFeatherSpriteTemplate, ANIM_TARGET, 0, 0, -16, 96, 2, 104, 11304, 32, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_TEETER_DANCE:
loadspritegfx ANIM_TAG_MUSIC_NOTES
loadspritegfx ANIM_TAG_DUCK
createvisualtask AnimTask_TeeterDanceMovement, 5
createsprite gFastFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, -2
playsewithpan SE_M_TEETER_DANCE, SOUND_PAN_ATTACKER
delay 24
createsprite gFastFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -2
playsewithpan SE_M_TEETER_DANCE, SOUND_PAN_ATTACKER
delay 24
createsprite gFastFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, -16, -2
playsewithpan SE_M_TEETER_DANCE, SOUND_PAN_ATTACKER
delay 24
createsprite gFastFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 1, -8, -2
playsewithpan SE_M_TEETER_DANCE, SOUND_PAN_ATTACKER
delay 24
createsprite gFastFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 2, 8, -2
playsewithpan SE_M_TEETER_DANCE, SOUND_PAN_ATTACKER
end
Move_MUD_SPORT:
loadspritegfx ANIM_TAG_MUD_SAND
createvisualtask AnimTask_Splash, 2, 0, 6
delay 24
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, -4, -16
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, 4, -12
playsewithpan SE_M_DIG, SOUND_PAN_ATTACKER
delay 32
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, -3, -12
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, 5, -14
playsewithpan SE_M_DIG, SOUND_PAN_ATTACKER
delay 32
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, -5, -18
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 0, 3, -14
playsewithpan SE_M_DIG, SOUND_PAN_ATTACKER
delay 16
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 220, 60
waitplaysewithpan SE_M_BUBBLE2, 0, 15
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 60, 100
waitplaysewithpan SE_M_BUBBLE2, 0, 25
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 140, 55
waitplaysewithpan SE_M_BUBBLE2, 0, 14
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 180, 50
waitplaysewithpan SE_M_BUBBLE2, 0, 10
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 20, 90
waitplaysewithpan SE_M_BUBBLE2, 0, 22
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 90, 90
waitplaysewithpan SE_M_BUBBLE2, 0, 22
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 160, 60
waitplaysewithpan SE_M_BUBBLE2, 0, 15
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 30, 90
waitplaysewithpan SE_M_BUBBLE2, 0, 22
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 120, 60
waitplaysewithpan SE_M_BUBBLE2, 0, 15
delay 2
createsprite gMudsportMudSpriteTemplate, ANIM_TARGET, 2, 1, 200, 40
waitplaysewithpan SE_M_BUBBLE2, 0, 10
end
Move_NEEDLE_ARM:
loadspritegfx ANIM_TAG_GREEN_SPIKE
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loopsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 2, 16
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 0, -32, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 22, -22, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 30, 0, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 20, 20, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 0, 28, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, -19, 19, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, -27, 0, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, -18, -18, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 0, -25, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 17, -17, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 23, 0, 16
delay 2
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 16, 16, 16
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 18, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 8, 1, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 0, -24, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 17, -17, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 24, 0, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 17, 17, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, 0, 24, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, -17, 17, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, -24, 0, 10
createsprite gNeedleArmSpikeSpriteTemplate, ANIM_TARGET, 2, 1, 1, -17, -17, 10
end
Move_SLACK_OFF:
loadspritegfx ANIM_TAG_BLUE_STAR
createvisualtask AnimTask_SlackOffSquish, 2, ANIM_ATTACKER
playsewithpan SE_M_YAWN, SOUND_PAN_ATTACKER
waitforvisualfinish
call HealingEffect
waitforvisualfinish
end
Move_CRUSH_CLAW:
loadspritegfx ANIM_TAG_BLUE_LIGHT_WALL
loadspritegfx ANIM_TAG_CLAW_SLASH
loadspritegfx ANIM_TAG_TORN_METAL
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 18, 1
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, -10, 0
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, 10, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
delay 12
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, -10, 1
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, 10, 1
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
blendoff
clearmonbg ANIM_TARGET
end
Move_AROMATHERAPY:
playsewithpan SE_M_PETAL_DANCE, 0
loadspritegfx ANIM_TAG_FLOWER
loadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_SPARKLE_2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 0, 0, 7, RGB(13, 31, 12)
delay 1
monbg ANIM_ATTACKER
delay 1
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 0, 24, 16, 0, 2, 2, 0, 0
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 66, 64, 24, 0, 3, 1, 1, 0
createsprite gAromatherapyBigFlowerSpriteTemplate, ANIM_ATTACKER, 0, 16, 24, 0, 2, 1, 0, 0
delay 20
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 66, 48, 12, 0, 4, 3, 1, 0
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 0, 100, 16, 0, 3, 2, 0, 0
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 0, 74, 24, 180, 3, 2, 0, 0
delay 10
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 66, 80, 30, 0, 4, 1, 1, 0
createsprite gAromatherapySmallFlowerSpriteTemplate, ANIM_ATTACKER, 0, 128, 12, 0, 3, 3, 0, 0
createsprite gAromatherapyBigFlowerSpriteTemplate, ANIM_ATTACKER, 0, 90, 16, 0, 2, 1, 0, 0
waitforvisualfinish
clearmonbg ANIM_ATTACKER
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 0, 7, 0, RGB(13, 31, 12)
delay 1
playsewithpan SE_M_STAT_INCREASE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_StatusClearedEffect, 2, 1
waitforvisualfinish
playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER
createsprite gSparklingStarsSpriteTemplate, ANIM_ATTACKER, 16, -15, 0, 0, 0, 32, 60, 1
delay 8
createsprite gSparklingStarsSpriteTemplate, ANIM_ATTACKER, 16, 12, -5, 0, 0, 32, 60, 1
waitforvisualfinish
playsewithpan SE_SHINY, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG | F_PAL_ATK_SIDE | F_PAL_ANIM_1, 3, 10, 0, RGB(13, 31, 12)
createsprite gBlendThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 16, 0, 0, 0, 1
waitforvisualfinish
end
Move_FAKE_TEARS:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_THOUGHT_BUBBLE
loadspritegfx ANIM_TAG_MUSIC_NOTES
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_SMALL_BUBBLES, 0, 4, 4, RGB(12, 11, 31)
waitforvisualfinish
createvisualtask AnimTask_RockMonBackAndForth, 5, ANIM_ATTACKER, 2, 1
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 12, 4
delay 8
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 0
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 1
delay 8
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 2
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 3
delay 8
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 0
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 1
delay 8
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 2
createsprite gTearDropSpriteTemplate, ANIM_ATTACKER, 2, 0, 3
waitforvisualfinish
end
Move_AIR_CUTTER:
loadspritegfx ANIM_TAG_AIR_WAVE
loadspritegfx ANIM_TAG_CUT
loadspritegfx ANIM_TAG_IMPACT
delay 0
monbg ANIM_DEF_PARTNER
setalpha 12, 8
delay 0
createvisualtask AnimTask_AirCutterProjectile, 2, 32, -24, 6 * 256, 2, 128 @ 6 * 256 == Q_8_8(6)
waitforvisualfinish
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
createsprite gAirCutterSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0, 2
delay 5
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 8, 1
waitforvisualfinish
blendoff
clearmonbg ANIM_DEF_PARTNER
delay 0
end
Move_ODOR_SLEUTH:
monbg ANIM_TARGET
createvisualtask AnimTask_OdorSleuthMovement, 5
delay 24
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
delay 6
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 3, 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
waitforvisualfinish
clearmonbg ANIM_TARGET
delay 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 1, RGB_WHITEALPHA, 16, RGB_WHITEALPHA, 0
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
end
Move_GRASS_WHISTLE:
loadspritegfx ANIM_TAG_MUSIC_NOTES
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 4, RGB(18, 31, 12)
waitforvisualfinish
createvisualtask AnimTask_MusicNotesRainbowBlend, 2
waitforvisualfinish
panse SE_M_GRASSWHISTLE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 7, 1, 0
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 6, 1, 0
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 1, 1, 0
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 0
delay 5
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 3, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 5, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 6, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 2, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 1, 1, 0
delay 4
createsprite gWavyMusicNotesSpriteTemplate, ANIM_TARGET, 2, 5, 1, 0
delay 4
waitforvisualfinish
createvisualtask AnimTask_MusicNotesClearRainbowBlend, 2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 4, 0, RGB(18, 31, 12)
waitforvisualfinish
end
Move_TICKLE:
loadspritegfx ANIM_TAG_EYE_SPARKLE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 0, 0, 16, RGB_BLACK
waitforvisualfinish
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, -16, -8
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, 16, -8
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 0, 16, 0, RGB_BLACK
waitforvisualfinish
delay 20
createvisualtask AnimTask_SwayMon, 3, 0, 6, 1280, 3, ANIM_ATTACKER
delay 12
createvisualtask AnimTask_RockMonBackAndForth, 3, ANIM_TARGET, 6, 2
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_TARGET, 8, 8
waitforvisualfinish
end
Move_WATER_SPOUT:
loadspritegfx ANIM_TAG_GLOWY_BLUE_ORB
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_WaterSpoutLaunch, 5
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
delay 44
playsewithpan SE_M_DIVE, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 16
createvisualtask AnimTask_WaterSpoutRain, 5
playsewithpan SE_M_SURF, SOUND_PAN_TARGET
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SHADOW_PUNCH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
fadetobg BG_GHOST
waitbgfadein
monbg ANIM_ATK_PARTNER
setalpha 9, 8
createvisualtask AnimTask_AttackerPunchWithTrace, 2, RGB_BLACK, 13
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 8, 1, 0
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
restorebg
waitbgfadein
end
Move_EXTRASENSORY:
call SetPsychicBackground
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB(27, 27, 0), 12, 1, 1
createvisualtask AnimTask_ExtrasensoryDistortion, 5, 0
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_BlendMonInAndOut, 5, ANIM_ATTACKER, RGB(27, 27, 0), 12, 1, 1
createvisualtask AnimTask_ExtrasensoryDistortion, 5, 1
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_TransparentCloneGrowAndShrink, 5, ANIM_ATTACKER
createvisualtask AnimTask_ExtrasensoryDistortion, 5, 2
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
waitforvisualfinish
blendoff
clearmonbg ANIM_DEF_PARTNER
call UnsetPsychicBackground
end
Move_AERIAL_ACE:
loadspritegfx ANIM_TAG_CUT
monbg ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 1, 5
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 3
createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
delay 5
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 10, 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 10, RGB_BLACK, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_IRON_DEFENSE:
loopsewithpan SE_SHINY, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 8, 2, RGB_WHITEALPHA, 14, RGB_WHITEALPHA, 0
waitforvisualfinish
end
Move_BLOCK:
loadspritegfx ANIM_TAG_X_SIGN
createsprite gBlockXSpriteTemplate, ANIM_TARGET, 66
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
end
Move_HOWL:
loadspritegfx ANIM_TAG_NOISE_LINE
createvisualtask AnimTask_DeepInhale, 2, ANIM_ATTACKER
delay 12
call RoarEffect
createvisualtask SoundTask_PlayCryHighPitch, 2, ANIM_ATTACKER, 3
waitforvisualfinish
delay 30
end
Move_BULK_UP:
loadspritegfx ANIM_TAG_BREATH
createvisualtask AnimTask_GrowAndShrink, 2
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2
loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2
waitforvisualfinish
end
Move_COVET:
loadspritegfx ANIM_TAG_MAGENTA_HEART
loadspritegfx ANIM_TAG_ITEM_BAG
createvisualtask AnimTask_RockMonBackAndForth, 5, ANIM_ATTACKER, 2, 0
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 0, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
delay 15
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, -20, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
delay 15
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 20, 20
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
loopsewithpan SE_M_DIZZY_PUNCH, SOUND_PAN_TARGET, 4, 3
end
Move_VOLT_TACKLE:
loadspritegfx ANIM_TAG_SPARK
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
loadspritegfx ANIM_TAG_ELECTRICITY
monbg ANIM_ATTACKER
setalpha 12, 8
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 0, 8, RGB_BLACK
waitforvisualfinish
createsprite gVoltTackleOrbSlideSpriteTemplate, ANIM_ATTACKER, 1
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
delay 8
createvisualtask AnimTask_VoltTackleBolt, 5, 0
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_VoltTackleBolt, 5, 1
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_VoltTackleBolt, 5, 2
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_VoltTackleBolt, 5, 3
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_VoltTackleBolt, 5, 4
playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_ATTACKER
delay 8
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 10, 0, 18, 1
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 1, 16, 16
delay 2
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 1, -16, -16
delay 8
createvisualtask AnimTask_VoltTackleAttackerReappear, 5
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 3, 0, 9, 1
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, 16
delay 2
createsprite gElectricPuffSpriteTemplate, ANIM_ATTACKER, 2, 0, -16, -16
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 8, 0, RGB_BLACK
waitforvisualfinish
end
Move_WATER_SPORT:
loadspritegfx ANIM_TAG_GLOWY_BLUE_ORB
createvisualtask AnimTask_WaterSport, 5
delay 8
playsewithpan SE_M_SURF, SOUND_PAN_ATTACKER
delay 44
playsewithpan SE_M_SURF, SOUND_PAN_ATTACKER
delay 44
playsewithpan SE_M_SURF, SOUND_PAN_ATTACKER
delay 44
panse SE_M_SURF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
end
Move_CALM_MIND:
loadspritegfx ANIM_TAG_THIN_RING
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, ANIM_ATTACKER, 0, 0, 16, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_SetAllNonAttackersInvisiblity, 5, TRUE
waitforvisualfinish
createsprite gThinRingShrinkingSpriteTemplate, ANIM_ATTACKER, 40, 0, 0, 0, 0
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
delay 14
createsprite gThinRingShrinkingSpriteTemplate, ANIM_ATTACKER, 40, 0, 0, 0, 0
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
delay 14
createsprite gThinRingShrinkingSpriteTemplate, ANIM_ATTACKER, 40, 0, 0, 0, 0
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_SetAllNonAttackersInvisiblity, 5, FALSE
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, ANIM_ATTACKER, 0, 16, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
end
Move_LEAF_BLADE:
loadspritegfx ANIM_TAG_LEAF
loadspritegfx ANIM_TAG_CROSS_IMPACT
createvisualtask AnimTask_LeafBlade, 5
delay 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
delay 50
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
delay 50
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
playsewithpan SE_M_CUT, SOUND_PAN_TARGET
waitforvisualfinish
monbg ANIM_TARGET
setalpha 12, 8
delay 12
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 8, 0, 18, 1
createsprite gCrossImpactSpriteTemplate, ANIM_TARGET, 2, 0, 0, 1, 36
playsewithpan SE_M_LEER, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_DRAGON_DANCE:
loadspritegfx ANIM_TAG_HOLLOW_ORB
monbg ANIM_ATTACKER
splitbgprio ANIM_ATTACKER
delay 1
createvisualtask AnimTask_DragonDanceWaver, 5
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
delay 8
createvisualtask AnimTask_BlendPalInAndOutByTag, 5, ANIM_TAG_HOLLOW_ORB, RGB(0, 0, 19), 14, 0, 3
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 0
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 43
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 85
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 128
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 170
createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 213
delay 30
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
delay 30
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
waitforvisualfinish
clearmonbg ANIM_ATTACKER
delay 1
end
Move_SHOCK_WAVE:
loadspritegfx ANIM_TAG_ELECTRIC_ORBS
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
loadspritegfx ANIM_TAG_SPARK
loadspritegfx ANIM_TAG_LIGHTNING
monbg ANIM_ATTACKER
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 4, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_ElectricChargingParticles, 2, ANIM_ATTACKER, 20, 0, 2
playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
delay 12
createsprite gGrowingShockWaveOrbSpriteTemplate, ANIM_ATTACKER, 2
delay 30
createvisualtask AnimTask_ShockWaveProgressingBolt, 5
delay 12
waitforvisualfinish
createvisualtask AnimTask_ShockWaveLightning, 5
playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 6, 18, 1
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 3, 16, 0, RGB_WHITE
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 16, 16, RGB_BLACK
delay 4
createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 0, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
end
Move_HARDEN:
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK
waitforvisualfinish
end
Move_BELLY_DRUM:
loadspritegfx ANIM_TAG_MUSIC_NOTES
loadspritegfx ANIM_TAG_PURPLE_HAND_OUTLINE
createvisualtask AnimTask_MusicNotesRainbowBlend, 2
waitforvisualfinish
call BellyDrumRight
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0, 0
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
delay 15
call BellyDrumLeft
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 1, 0
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
delay 15
call BellyDrumRight
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, 3, 3, 128
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
delay 7
call BellyDrumLeft
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 1, 2, 0, 128
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
delay 7
call BellyDrumRight
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 1, 0
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
delay 7
call BellyDrumLeft
createsprite gSlowFlyingMusicNotesSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 3, 0
playsewithpan SE_M_BELLY_DRUM, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_MusicNotesClearRainbowBlend, 2
waitforvisualfinish
end
BellyDrumLeft:
createsprite gBellyDrumHandSpriteTemplate, ANIM_ATTACKER, 3, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 8, 2, 1
return
BellyDrumRight:
createsprite gBellyDrumHandSpriteTemplate, ANIM_ATTACKER, 3, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 8, 2, 1
return
Move_MIND_READER:
loadspritegfx ANIM_TAG_TEAL_ALERT
loadspritegfx ANIM_TAG_OPENING_EYE
loadspritegfx ANIM_TAG_ROUND_WHITE_HALO
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_TARGET
createsprite gOpeningEyeSpriteTemplate, ANIM_ATTACKER, 5, 0, 0, 1, 0
createsprite gWhiteHaloSpriteTemplate, ANIM_ATTACKER, 5
delay 40
playsewithpan SE_M_LEER, SOUND_PAN_TARGET
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG, 1, 2, 0, 10, RGB_BLACK
call MindReaderEyeSpikeEffect
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
MindReaderEyeSpikeEffect:
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 70, 0, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 40, 40, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 10, -60, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -50, -40, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -40, 40, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 50, -50, 6
delay 2
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 50, -30, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 60, 10, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 0, 60, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 0, -40, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -60, 20, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -60, -30, 6
delay 2
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -50, 50, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -60, 20, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, -40, -40, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 20, -60, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 50, -50, 6
createsprite gTealAlertSpriteTemplate, ANIM_ATTACKER, 4, 35, 40, 6
delay 2
return
Move_ICE_PUNCH:
monbg ANIM_DEF_PARTNER
setalpha 12, 8
loadspritegfx ANIM_TAG_ICE_CRYSTALS
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 7, RGB_BLACK
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 9, RGB(12, 26, 31)
delay 20
playsewithpan SE_M_STRING_SHOT, SOUND_PAN_TARGET
createsprite gIceCrystalSpiralInwardSmall, ANIM_ATTACKER, 2, 0
createsprite gIceCrystalSpiralInwardSmall, ANIM_ATTACKER, 2, 64
createsprite gIceCrystalSpiralInwardSmall, ANIM_ATTACKER, 2, 128
createsprite gIceCrystalSpiralInwardSmall, ANIM_ATTACKER, 2, 192
delay 5
createsprite gIceCrystalSpiralInwardLarge, ANIM_ATTACKER, 2, 32
createsprite gIceCrystalSpiralInwardLarge, ANIM_ATTACKER, 2, 96
createsprite gIceCrystalSpiralInwardLarge, ANIM_ATTACKER, 2, 160
createsprite gIceCrystalSpiralInwardLarge, ANIM_ATTACKER, 2, 224
delay 17
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 4, 0, -10, 8, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -10, ANIM_TARGET, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 3, 1
waitforvisualfinish
delay 15
call IceCrystalEffectShort
delay 5
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 9, 0, RGB(12, 26, 31)
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 7, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_REST:
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
loadspritegfx ANIM_TAG_LETTER_Z
createsprite gSleepLetterZSpriteTemplate, ANIM_ATTACKER, 2, 4, -10, 16, 0, 0
delay 20
createsprite gSleepLetterZSpriteTemplate, ANIM_ATTACKER, 2, 4, -10, 16, 0, 0
delay 20
createsprite gSleepLetterZSpriteTemplate, ANIM_ATTACKER, 2, 4, -10, 16, 0, 0
waitforvisualfinish
end
Move_CONFUSION:
monbg ANIM_DEF_PARTNER
call SetPsychicBackground
setalpha 8, 8
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 10, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB_WHITE
waitforvisualfinish
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 15, 1
createvisualtask AnimTask_ScaleMonAndRestore, 5, -4, -4, 15, ANIM_TARGET, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
delay 1
call UnsetPsychicBackground
end
Move_PSYCHIC:
monbg ANIM_DEF_PARTNER
call SetPsychicBackground
setalpha 8, 8
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 10, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB(31, 23, 0)
waitforvisualfinish
loopsewithpan SE_M_SUPERSONIC, SOUND_PAN_TARGET, 10, 3
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 15, 1
createvisualtask AnimTask_ScaleMonAndRestore, 5, -6, -6, 15, ANIM_TARGET, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
delay 1
call UnsetPsychicBackground
end
Move_FUTURE_SIGHT:
goto FutureSight
FutureSightContinue:
waitforvisualfinish
delay 1
call UnsetPsychicBackground
end
FutureSight:
monbg ANIM_ATK_PARTNER
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
setalpha 8, 8
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 8, RGB_WHITE
createvisualtask AnimTask_ScaleMonAndRestore, 5, -4, -4, 15, ANIM_ATTACKER, 1
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
goto FutureSightContinue
Move_THUNDER:
loadspritegfx ANIM_TAG_LIGHTNING
fadetobg BG_THUNDER
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -256, 0, 1, -1
waitbgfadein
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 16, RGB_BLACK
delay 16
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 16, -36
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 16, -20
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 16, 12
delay 20
createsprite gLightningSpriteTemplate, ANIM_TARGET, 6, -16, -32
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 6, -16, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 6, -16, 16
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET
delay 5
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 24, -32
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 24, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 24, 16
delay 30
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 5
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -32
playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 16
delay 10
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createvisualtask AnimTask_ShakeTargetInPattern, 2, 30, 3, TRUE, 0
delay 2
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_TARGET, 2, F_PAL_BG, 2, 16, 0, RGB_BLACK
waitforvisualfinish
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
end
Move_THUNDER_PUNCH:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_LIGHTNING
monbg ANIM_TARGET
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 16, RGB_BLACK
waitforvisualfinish
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 8, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
delay 1
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -48
delay 1
createsprite gLightningSpriteTemplate, ANIM_ATTACKER, 2, 0, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_ATTACKER, 2, 0, 16
delay 1
playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 15, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 16, 0, RGB_BLACK
delay 20
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_SACRED_FIRE:
loadspritegfx ANIM_TAG_FIRE
loadspritegfx ANIM_TAG_FIRE_PLUME
loopsewithpan SE_M_SACRED_FIRE, SOUND_PAN_ATTACKER, 7, 5
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -32, 0, 50, 5, -2, 0
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, -20, -10, 50, 5, -1, -1
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 0, -16, 50, 5, 0, -1
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 20, -10, 50, 5, 1, -1
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 50, 5, 2, 0
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 20, 10, 50, 5, 1, 1
delay 1
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, 50, 5, 0, 1
delay 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -20, 10, 50, 5, -1, 1
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
waitforvisualfinish
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
createsprite gLargeFlameSpriteTemplate, ANIM_TARGET, 2, -16, 0, 70, 16, 0, 1
delay 10
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
createsprite gLargeFlameSpriteTemplate, ANIM_TARGET, 2, 0, 0, 70, 16, 0, 1
delay 10
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
createsprite gLargeFlameSpriteTemplate, ANIM_TARGET, 2, 16, 0, 80, 16, 0, 1
delay 1
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
waitforvisualfinish
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 1
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, 0
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 0, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, -1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 2, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 1, -1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 1, -2
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 3, 1
waitforvisualfinish
end
Move_SCRATCH:
loadspritegfx ANIM_TAG_SCRATCH
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
createsprite gScratchSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
Move_DRAGON_BREATH:
loadspritegfx ANIM_TAG_SMALL_EMBER
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
loopsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_ATTACKER, 7, 7
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 1, 0, 9, RGB_RED
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 21, 1
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
delay 2
createsprite gDragonBreathFireSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0, 0, 20
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 1, 9, 0, RGB_RED
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_ROAR:
loadspritegfx ANIM_TAG_NOISE_LINE
monbg ANIM_ATTACKER
splitbgprio ANIM_ATTACKER
setalpha 8, 8
createvisualtask SoundTask_PlayDoubleCry, 2, ANIM_ATTACKER, DOUBLE_CRY_ROAR
createvisualtask AnimTask_ScaleMonAndRestore, 5, -5, -5, 10, ANIM_ATTACKER, 1
call RoarEffect
delay 20
createvisualtask AnimTask_SlideOffScreen, 5, ANIM_TARGET, 2
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
waitforvisualfinish
createvisualtask SoundTask_WaitForCry, 5
waitforvisualfinish
end
RoarEffect:
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, -8, 0
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, 0, 2
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, 8, 1
delay 15
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, -8, 0
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, 0, 2
createsprite gRoarNoiseLineSpriteTemplate, ANIM_ATTACKER, 2, 24, 8, 1
return
Move_GROWL:
loadspritegfx ANIM_TAG_NOISE_LINE
createvisualtask SoundTask_PlayDoubleCry, 2, ANIM_ATTACKER, DOUBLE_CRY_GROWL
call RoarEffect
delay 10
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 9, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 9, 1
waitforvisualfinish
createvisualtask SoundTask_WaitForCry, 5
waitforvisualfinish
end
Move_SNORE:
loadspritegfx ANIM_TAG_SNORE_Z
monbg ANIM_ATK_PARTNER
setalpha 8, 8
call SnoreEffect
delay 30
call SnoreEffect
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
SnoreEffect:
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -7, -7, 7, ANIM_ATTACKER, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 7, 1
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, 14, 0, 0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -42, -38, 24, 0, 0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0, -42, 24, 0, 0
createsprite gSnoreZSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 42, -38, 24, 0, 0
return
Move_LIGHT_SCREEN:
loadspritegfx ANIM_TAG_SPARKLE_3
loadspritegfx ANIM_TAG_GREEN_LIGHT_WALL
setalpha 0, 16
waitplaysewithpan SE_M_REFLECT, SOUND_PAN_ATTACKER, 15
createsprite gLightScreenWallSpriteTemplate, ANIM_ATTACKER, 1, 40, 0, ANIM_TAG_GREEN_LIGHT_WALL
delay 10
call SpecialScreenSparkle
waitforvisualfinish
delay 1
blendoff
end
SpecialScreenSparkle:
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 23, 0, ANIM_ATTACKER, TRUE
delay 6
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 31, -8, ANIM_ATTACKER, TRUE
delay 5
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 30, 20, ANIM_ATTACKER, TRUE
delay 7
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 10, -15, ANIM_ATTACKER, TRUE
delay 6
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 20, 10, ANIM_ATTACKER, TRUE
delay 6
createsprite gSpecialScreenSparkleSpriteTemplate, ANIM_ATTACKER, 2, 10, 18, ANIM_ATTACKER, TRUE
return
Move_MIRROR_COAT:
loadspritegfx ANIM_TAG_SPARKLE_3
loadspritegfx ANIM_TAG_RED_LIGHT_WALL
setalpha 0, 16
createsprite gMirrorCoatWallSpriteTemplate, ANIM_ATTACKER, 1, 40, 0, ANIM_TAG_RED_LIGHT_WALL
delay 10
playsewithpan SE_M_REFLECT, SOUND_PAN_ATTACKER
call SpecialScreenSparkle
waitforvisualfinish
delay 1
blendoff
end
Move_REFLECT:
loadspritegfx ANIM_TAG_SPARKLE_4
loadspritegfx ANIM_TAG_BLUE_LIGHT_WALL
setalpha 0, 16
waitplaysewithpan SE_M_REFLECT, SOUND_PAN_ATTACKER, 15
createsprite gReflectWallSpriteTemplate, ANIM_ATTACKER, 1, 40, 0, ANIM_TAG_BLUE_LIGHT_WALL
delay 20
createsprite gReflectSparkleSpriteTemplate, ANIM_ATTACKER, 2, 30, 0, ANIM_ATTACKER, TRUE
delay 7
createsprite gReflectSparkleSpriteTemplate, ANIM_ATTACKER, 2, 19, -12, ANIM_ATTACKER, TRUE
delay 7
createsprite gReflectSparkleSpriteTemplate, ANIM_ATTACKER, 2, 10, 20, ANIM_ATTACKER, TRUE
waitforvisualfinish
delay 1
blendoff
end
Move_BARRIER:
loadspritegfx ANIM_TAG_GRAY_LIGHT_WALL
setalpha 0, 16
waitplaysewithpan SE_M_BARRIER, SOUND_PAN_ATTACKER, 15
createsprite gBarrierWallSpriteTemplate, ANIM_ATTACKER, 3, 40, 0, ANIM_TAG_GRAY_LIGHT_WALL
waitforvisualfinish
delay 1
blendoff
end
Move_BUBBLE:
loadspritegfx ANIM_TAG_BUBBLE
loadspritegfx ANIM_TAG_SMALL_BUBBLES
monbg ANIM_TARGET
setalpha 12, 8
delay 1
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 15, -15, 10, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
delay 6
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 35, 37, 40, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
delay 6
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 10, -37, 30, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
delay 6
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 30, 10, 15, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
delay 6
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 20, 33, 20, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
delay 6
createsprite gWaterBubbleProjectileSpriteTemplate, ANIM_ATTACKER, 2, 18, 0, 25, -30, 10, 128, 100
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET, 100
waitforvisualfinish
call WaterBubblesEffectLong
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_SMOG:
loadspritegfx ANIM_TAG_PURPLE_GAS_CLOUD
monbg ANIM_DEF_PARTNER
splitbgprio_all
setalpha 12, 8
loopsewithpan SE_M_MIST, SOUND_PAN_TARGET, 17, 10
call SmogCloud
call SmogCloud
call SmogCloud
call SmogCloud
call SmogCloud
call SmogCloud
call SmogCloud
delay 120
loopsewithpan SE_M_TOXIC, SOUND_PAN_TARGET, 18, 2
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(26, 0, 26)
delay 10
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 15, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
SmogCloud:
createsprite gSmogCloudSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 48, 240, 1, 0
delay 7
return
Move_FAINT_ATTACK:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_ATTACKER
fadetobg BG_DARK
waitbgfadein
delay 0
playsewithpan SE_M_FAINT_ATTACK, SOUND_PAN_ATTACKER
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 1, 3
createvisualtask AnimTask_AttackerFadeToInvisible, 2, 1
waitforvisualfinish
clearmonbg ANIM_ATTACKER
invisible ANIM_ATTACKER
delay 1
createvisualtask AnimTask_SetAttackerInvisibleWaitForSignal, 2
setalpha 12, 8
monbg ANIM_TARGET
delay 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 9, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 1
setarg 7, 0x1000
delay 32
createvisualtask AnimTask_InitAttackerFadeFromInvisible, 2
monbg ANIM_ATTACKER
createvisualtask AnimTask_AttackerFadeFromInvisible, 2, 1
waitforvisualfinish
clearmonbg ANIM_ATTACKER
delay 1
restorebg
waitbgfadein
end
Move_SAND_ATTACK:
loadspritegfx ANIM_TAG_MUD_SAND
monbg ANIM_ATK_PARTNER
splitbgprio ANIM_ATTACKER
setalpha 12, 8
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_ATTACKER
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, -10, 0, 0, 3
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 2
call SandAttackDirt
call SandAttackDirt
call SandAttackDirt
call SandAttackDirt
call SandAttackDirt
call SandAttackDirt
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
SandAttackDirt:
createsprite gSandAttackDirtSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 0, 0
createsprite gSandAttackDirtSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 10, 10
createsprite gSandAttackDirtSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, -10, -10
createsprite gSandAttackDirtSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 20, 5
createsprite gSandAttackDirtSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, -20, -5
delay 2
return
Move_MUD_SLAP:
loadspritegfx ANIM_TAG_MUD_SAND
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_ATTACKER
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, -10, 0, 0, 3
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 2
call MudSlapMud
call MudSlapMud
call MudSlapMud
call MudSlapMud
call MudSlapMud
call MudSlapMud
waitforvisualfinish
end
MudSlapMud:
createsprite gMudSlapMudSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 0, 0
createsprite gMudSlapMudSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 10, 5
createsprite gMudSlapMudSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, -10, -5
createsprite gMudSlapMudSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, 20, 10
createsprite gMudSlapMudSpriteTemplate, ANIM_TARGET, 2, 15, 15, 20, -20, -10
delay 2
return
Move_DRAGON_RAGE:
loadspritegfx ANIM_TAG_SMALL_EMBER
loadspritegfx ANIM_TAG_FIRE_PLUME
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 40, 1
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, 0, 15, 0, 0, 4
waitforvisualfinish
createsprite gDragonRageFireSpitSpriteTemplate, ANIM_TARGET, 2, 30, 15, 0, 10, 10
waitforvisualfinish
loopsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET, 11, 3
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 3, 25, 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 5, 0
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, -10, -15
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 25
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 15, 5
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, -25, 0
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, 30, 30
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, -27, 25
delay 1
createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 0, 8
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_TARGET, 66, 0, 0, 4
waitforvisualfinish
end
Move_RAIN_DANCE:
loadspritegfx ANIM_TAG_RAIN_DROPS
playsewithpan SE_M_RAIN_DANCE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 2, 0, 4, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 120
createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 120
delay 120
delay 30
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 2, 4, 0, RGB_BLACK
waitforvisualfinish
end
Move_BITE:
loadspritegfx ANIM_TAG_SHARP_TEETH
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, 0, -32, 0, 0, 819, 10
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, 4, 0, -819, 10
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 4, 7, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 1
end
Move_CRUNCH:
loadspritegfx ANIM_TAG_SHARP_TEETH
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
fadetobg BG_DARK
waitbgfadein
setalpha 12, 8
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, -32, -32, 1, 819, 819, 10
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, 32, 32, 5, -819, -819, 10
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -8, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 7, 5, 2
waitforvisualfinish
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, 32, -32, 7, -819, 819, 10
createsprite gSharpTeethSpriteTemplate, ANIM_ATTACKER, 2, -32, 32, 3, 819, -819, 10
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 8, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 8, 4, 2
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
delay 1
restorebg
waitbgfadein
end
Move_CLAMP:
loadspritegfx ANIM_TAG_CLAMP
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_VICEGRIP, SOUND_PAN_TARGET
createsprite gClampJawSpriteTemplate, ANIM_ATTACKER, 2, -32, 0, 2, 819, 0, 10
createsprite gClampJawSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 6, -819, 0, 10
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 5, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
Move_ICE_BEAM:
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
loadspritegfx ANIM_TAG_ICE_CRYSTALS
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 7, RGB_BLACK
waitforvisualfinish
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_BUBBLE_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 4, 4, 0, 10
createsprite gIceBeamOuterCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, 12, 0, 12, 20
createsprite gIceBeamOuterCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, -12, 0, -12, 20
delay 1
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_TARGET, -31, 0, 7, RGB(0, 20, 31)
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 25, 1
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
call IceBeamCreateCrystals
createsprite gIceBeamInnerCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 11
delay 1
createsprite gIceBeamInnerCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 11
waitforvisualfinish
delay 20
call IceCrystalEffectShort
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_TARGET, 5, 7, 0, RGB(0, 20, 31)
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 7, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
IceBeamCreateCrystals:
createsprite gIceBeamOuterCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, 12, 0, 12, 20
createsprite gIceBeamOuterCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, -12, 0, -12, 20
createsprite gIceBeamInnerCrystalSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 11
delay 1
return
Move_WITHDRAW:
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
createvisualtask AnimTask_Withdraw, 5
waitforvisualfinish
end
Move_AURORA_BEAM:
loadspritegfx ANIM_TAG_RAINBOW_RINGS
fadetobg BG_AURORA
waitbgfadein
playsewithpan SE_M_BUBBLE_BEAM, SOUND_PAN_ATTACKER
setarg 7, 0
createvisualtask AnimTask_RotateAuroraRingColors, 10, 130
call AuroraBeamCreateRings
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 1, 0, 17, 1
call AuroraBeamCreateRings
call AuroraBeamCreateRings
call AuroraBeamCreateRings
setarg 7, 0xFFFF
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_BUBBLE_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 6, 0, 10
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 40, 1
call AuroraBeamCreateRings
call AuroraBeamCreateRings
call AuroraBeamCreateRings
call AuroraBeamCreateRings
call AuroraBeamCreateRings
call AuroraBeamCreateRings
waitforvisualfinish
restorebg
waitbgfadein
end
AuroraBeamCreateRings:
createsprite gAuroraBeamRingSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 17
delay 1
createsprite gAuroraBeamRingSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 17
delay 1
createsprite gAuroraBeamRingSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 17
delay 1
createsprite gAuroraBeamRingSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 17
delay 1
return
Move_SOLAR_BEAM:
loadspritegfx ANIM_TAG_ORBS
choosetwoturnanim SolarBeamSetUp, SolarBeamUnleash
SolarBeamEnd:
waitforvisualfinish
end
SolarBeamSetUp:
monbg ANIM_ATK_PARTNER
setalpha 12, 8
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 1, 4, 0, 11, RGB(31, 31, 11)
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
call SolarBeamAbsorbEffect
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
goto SolarBeamEnd
SolarBeamAbsorbEffect:
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 40, 40, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -40, -40, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 40, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, -40, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 40, -20, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 40, 20, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -40, -20, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -40, 20, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -20, 30, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 20, -30, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -20, -30, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 20, 30, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -40, 0, 16
delay 2
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 40, 0, 16
delay 2
return
SolarBeamUnleash:
call SetSolarBeamBg
panse SE_M_SOLAR_BEAM, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createvisualtask AnimTask_CreateSmallSolarBeamOrbs, 5
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 0
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 1
delay 4
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 1, 0, 10, RGB(25, 31, 0)
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 2
delay 4
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 65, 1
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 3
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 4
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 5
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 6
delay 4
call SolarBeamUnleash1
call SolarBeamUnleash1
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 1, 10, 0, RGB(25, 31, 0)
call UnsetSolarBeamBg
goto SolarBeamEnd
SolarBeamUnleash1:
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 0
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 1
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 2
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 3
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 4
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 5
delay 4
createsprite gSolarBeamBigOrbSpriteTemplate, ANIM_TARGET, 3, 15, 0, 20, 6
delay 4
return
Move_BLIZZARD:
loadspritegfx ANIM_TAG_ICE_CRYSTALS
monbg ANIM_DEF_PARTNER
createvisualtask AnimTask_GetAttackerSide, 2
jumprettrue BlizzardAgainstPlayer
fadetobg BG_HIGHSPEED_OPPONENT
BlizzardContinue:
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 0, 1, -1
waitbgfadein
waitforvisualfinish
panse SE_M_BLIZZARD, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
call BlizzardIceCrystals
call BlizzardIceCrystals
playsewithpan SE_M_BLIZZARD2, SOUND_PAN_TARGET
waitforvisualfinish
call IceCrystalEffectLong
waitforvisualfinish
delay 20
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
clearmonbg ANIM_DEF_PARTNER
end
BlizzardIceCrystals:
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -10, 0, -10, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, 0, 0, 0, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -15, 0, -15, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, -10, 0, -10, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -5, 0, -5, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, 10, 0, 10, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -10, 0, -10, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, -20, 0, -20, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -20, 0, -20, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, 15, 0, 15, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -15, 0, -15, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, -20, 0, -20, 80, 0, 0, 1
delay 3
createsprite gSwirlingSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -25, 0, -25, 72, 1
createsprite gBlizzardIceCrystalSpriteTemplate, ANIM_ATTACKER, 40, 0, 20, 0, 20, 80, 0, 0, 1
delay 3
return
BlizzardAgainstPlayer:
fadetobg BG_HIGHSPEED_PLAYER
goto BlizzardContinue
Move_POWDER_SNOW:
loadspritegfx ANIM_TAG_ICE_CRYSTALS
monbg ANIM_DEF_PARTNER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 1, 0, 3, RGB_BLACK
waitforvisualfinish
panse SE_M_GUST, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
call PowderSnowSnowballs
call PowderSnowSnowballs
playsewithpan SE_M_GUST2, SOUND_PAN_TARGET
waitforvisualfinish
waitsound
call IceCrystalEffectLong
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
delay 20
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 1, 3, 0, RGB_BLACK
end
PowderSnowSnowballs:
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, 0, 0, 0, 56, 4, 4, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -10, 0, -10, 56, 4, 4, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, 10, 0, 10, 56, -4, 3, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -20, 0, -20, 56, -4, 5, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, 15, 0, 15, 56, 4, 4, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, -20, 0, -20, 56, 4, 4, 1
delay 3
createsprite gPowderSnowSnowballSpriteTemplate, ANIM_ATTACKER, 40, 0, 20, 0, 20, 56, 4, 4, 1
delay 3
return
Move_HYDRO_PUMP:
loadspritegfx ANIM_TAG_WATER_ORB
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 40, 1
delay 6
panse SE_M_HYDRO_PUMP, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
call HydroPumpBeams
call HydroPumpBeams
call HydroPumpBeams
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 37, 1
call HydroPumpHitSplats
call HydroPumpBeams
call HydroPumpBeams
call HydroPumpHitSplats
call HydroPumpBeams
call HydroPumpBeams
call HydroPumpHitSplats
call HydroPumpBeams
call HydroPumpBeams
call HydroPumpHitSplats
call HydroPumpBeams
call HydroPumpBeams
call HydroPumpHitSplats
delay 1
delay 1
call HydroPumpHitSplats
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
HydroPumpBeams:
createsprite gHydroPumpOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
createsprite gHydroPumpOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, -16
delay 1
createsprite gHydroPumpOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
createsprite gHydroPumpOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, -16
delay 1
return
HydroPumpHitSplats:
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 15, ANIM_TARGET, 1
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, -15, ANIM_TARGET, 1
return
Move_SIGNAL_BEAM:
loadspritegfx ANIM_TAG_GLOWY_RED_ORB
loadspritegfx ANIM_TAG_GLOWY_GREEN_ORB
loadspritegfx ANIM_TAG_DUCK
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 25, 1
delay 6
panse SE_M_BUBBLE_BEAM, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 25, 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_TARGET, 8, 5, RGB_RED, 8, RGB(1, 30, 0), 8
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
call SignalBeamOrbs
waitforvisualfinish
end
SignalBeamOrbs:
createsprite gSignalBeamRedOrbSpriteTemplate, ANIM_TARGET, 3, 10, 10, 0, 16
createsprite gSignalBeamGreenOrbSpriteTemplate, ANIM_TARGET, 3, 10, 10, 0, -16
delay 1
return
Move_ABSORB:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 4, RGB(13, 31, 12)
waitforvisualfinish
playsewithpan SE_M_ABSORB, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
delay 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 5, 1
waitforvisualfinish
delay 3
call AbsorbEffect
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 4, 0, RGB(13, 31, 12)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
AbsorbEffect:
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -20, 35
delay 4
return
Move_MEGA_DRAIN:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 8, RGB(13, 31, 12)
waitforvisualfinish
playsewithpan SE_M_ABSORB, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 1
delay 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 5, 1
waitforvisualfinish
delay 3
call MegaDrainAbsorbEffect
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 8, 0, RGB(13, 31, 12)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
MegaDrainAbsorbEffect:
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -20, 35
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -20, 35
delay 4
return
Move_GIGA_DRAIN:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 12, RGB(13, 31, 12)
waitforvisualfinish
playsewithpan SE_M_ABSORB, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
delay 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 5, 1
waitforvisualfinish
delay 3
call GigaDrainAbsorbEffect
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 12, 0, RGB(13, 31, 12)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
GigaDrainAbsorbEffect:
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -40, 35
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 28, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 40, 39
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -32, 26
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -40, 26
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 36, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -20, 35
delay 4
return
Move_LEECH_LIFE:
loadspritegfx ANIM_TAG_NEEDLE
loadspritegfx ANIM_TAG_ORBS
delay 1
loadspritegfx ANIM_TAG_BLUE_STAR
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
setalpha 12, 8
delay 1
createsprite gLeechLifeNeedleSpriteTemplate, ANIM_ATTACKER, 2, -20, 15, 12
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
playsewithpan SE_M_ABSORB, SOUND_PAN_TARGET
delay 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 5, 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 7, RGB_BLACK
waitforvisualfinish
call AbsorbEffect
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 7, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SYNTHESIS:
loadspritegfx ANIM_TAG_SPARKLE_2
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 16, RGB(27, 31, 18)
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
call GrantingStarsEffect
waitforvisualfinish
unloadspritegfx ANIM_TAG_SPARKLE_2
delay 1
loadspritegfx ANIM_TAG_BLUE_STAR
call HealingEffect
waitforvisualfinish
end
Move_TOXIC:
loadspritegfx ANIM_TAG_TOXIC_BUBBLE
loadspritegfx ANIM_TAG_POISON_BUBBLE
call ToxicBubbles
call ToxicBubbles
waitforvisualfinish
delay 15
call PoisonBubblesEffect
waitforvisualfinish
end
ToxicBubbles:
createsprite gToxicBubbleSpriteTemplate, ANIM_TARGET, 2, -24, 16, 1, 1
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 15
createsprite gToxicBubbleSpriteTemplate, ANIM_TARGET, 2, 8, 16, 1, 1
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 15
createsprite gToxicBubbleSpriteTemplate, ANIM_TARGET, 2, -8, 16, 1, 1
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 15
createsprite gToxicBubbleSpriteTemplate, ANIM_TARGET, 2, 24, 16, 1, 1
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 15
return
Move_SLUDGE:
loadspritegfx ANIM_TAG_POISON_BUBBLE
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
createsprite gSludgeProjectileSpriteTemplate, ANIM_TARGET, 2, 20, 0, 40, 0
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 5, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 1, 2, 0, 12, RGB(30, 0, 31)
call PoisonBubblesEffect
waitforvisualfinish
end
Move_SLUDGE_BOMB:
loadspritegfx ANIM_TAG_POISON_BUBBLE
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
call SludgeBombProjectile
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 3, 0, 15, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 1, 2, 0, 12, RGB(30, 0, 31)
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 42, 27, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -27, 44, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 39, -28, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -42, -42, 20
playsewithpan SE_M_DIG, SOUND_PAN_TARGET
delay 5
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 0, 40, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -8, -44, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -46, -28, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 46, 9, 20
playsewithpan SE_M_DIG, SOUND_PAN_TARGET
delay 5
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 42, 0, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -43, -12, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, 16, -46, 20
createsprite gSludgeBombHitParticleSpriteTemplate, ANIM_TARGET, 2, -16, 44, 20
playsewithpan SE_M_DIG, SOUND_PAN_TARGET
delay 0
waitsound
waitforvisualfinish
call PoisonBubblesEffect
waitforvisualfinish
end
SludgeBombProjectile:
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
createsprite gSludgeProjectileSpriteTemplate, ANIM_TARGET, 2, 20, 0, 40, 0
delay 3
return
Move_ACID:
loadspritegfx ANIM_TAG_POISON_BUBBLE
monbg ANIM_DEF_PARTNER
createsprite gAcidPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 20, 0, 40, 1, 0, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 5
createsprite gAcidPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 20, 0, 40, 1, 24, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 5
createsprite gAcidPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 20, 0, 40, 1, -24, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 15
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 2, 0, 10, 1
createvisualtask AnimTask_ShakeMon2, 5, ANIM_DEF_PARTNER, 2, 0, 10, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_DEF_SIDE, 2, 2, 0, 12, RGB(30, 0, 31)
createsprite gAcidPoisonDropletSpriteTemplate, ANIM_TARGET, 2, 0, -22, 0, 15, 55
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
delay 10
createsprite gAcidPoisonDropletSpriteTemplate, ANIM_TARGET, 2, -26, -24, 0, 15, 55
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
delay 10
createsprite gAcidPoisonDropletSpriteTemplate, ANIM_TARGET, 2, 15, -27, 0, 15, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
delay 10
createsprite gAcidPoisonDropletSpriteTemplate, ANIM_TARGET, 2, -15, -17, 0, 10, 45
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
delay 10
createsprite gAcidPoisonDropletSpriteTemplate, ANIM_TARGET, 2, 27, -22, 0, 15, 50
playsewithpan SE_M_BUBBLE, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_BONEMERANG:
loadspritegfx ANIM_TAG_BONE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_BONEMERANG, SOUND_PAN_ATTACKER
createsprite gBonemerangSpriteTemplate, ANIM_ATTACKER, 2
delay 20
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 5, 0, 5, 1
delay 17
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_ATTACKER
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, -4
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_BONE_CLUB:
loadspritegfx ANIM_TAG_BONE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_BONEMERANG, SOUND_PAN_TARGET
createsprite gSpinningBoneSpriteTemplate, ANIM_ATTACKER, 2, -42, -25, 0, 0, 15
delay 12
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 5, 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_ATTACKER | F_PAL_TARGET, 5, 1, RGB_BLACK, 10, RGB_BLACK, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_BONE_RUSH:
loadspritegfx ANIM_TAG_BONE
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_BONEMERANG, SOUND_PAN_TARGET
createsprite gSpinningBoneSpriteTemplate, ANIM_ATTACKER, 2, -42, -25, 0, 0, 15
delay 12
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 3, 5, 1
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SPIKES:
loadspritegfx ANIM_TAG_SPIKES
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 28
createsprite gSpikesSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 24, 30
delay 10
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 28
createsprite gSpikesSpriteTemplate, ANIM_TARGET, 2, 20, 0, -24, 24, 30
delay 10
waitplaysewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET, 28
createsprite gSpikesSpriteTemplate, ANIM_TARGET, 2, 20, 0, 24, 24, 30
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_MEGAHORN:
loadspritegfx ANIM_TAG_HORN_HIT_2
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
jumpifcontest MegahornInContest
fadetobg BG_DRILL
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 768, 1, -1
MegahornContinue:
waitbgfadein
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 2, 0, 15, 1
waitforvisualfinish
delay 10
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 6
delay 3
createsprite gMegahornHornSpriteTemplate, ANIM_ATTACKER, 3, -42, 25, 0, 0, 6
delay 4
playsewithpan SE_M_VICEGRIP, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -16, 4, 1, 4
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, -4, 1, 12, 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_ATTACKER | F_PAL_TARGET, 5, 1, RGB_WHITE, 10, RGB_BLACK, 0
delay 10
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 11
delay 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 7
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
end
MegahornInContest:
fadetobg BG_DRILL_CONTESTS
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, 2304, 768, 0, -1
goto MegahornContinue
Move_GUST:
loadspritegfx ANIM_TAG_GUST
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_GUST, SOUND_PAN_TARGET
createsprite gEllipticalGustSpriteTemplate, ANIM_ATTACKER, 2, 0, -16
createvisualtask AnimTask_AnimateGustTornadoPalette, 5, 1, 70
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 1, 0, 7, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
playsewithpan SE_M_GUST2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_WING_ATTACK:
loadspritegfx ANIM_TAG_GUST
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
loopsewithpan SE_M_WING_ATTACK, SOUND_PAN_ATTACKER, 20, 2
createvisualtask AnimTask_TranslateMonElliptical, 2, 0, 12, 4, 1, 4
createvisualtask AnimTask_AnimateGustTornadoPalette, 5, 1, 70
createsprite gGustToTargetSpriteTemplate, ANIM_ATTACKER, 2, -25, 0, 0, 0, 20
createsprite gGustToTargetSpriteTemplate, ANIM_ATTACKER, 2, 25, 0, 0, 0, 20
delay 24
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 9
delay 17
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 16, 0, ANIM_TARGET, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -16, 0, ANIM_TARGET, 1
loopsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET, 5, 2
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 11
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_PECK:
loadspritegfx ANIM_TAG_IMPACT
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET
createvisualtask AnimTask_RotateMonToSideAndRestore, 2, 3, -768, ANIM_TARGET, 2
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -12, 0, ANIM_TARGET, 3
waitforvisualfinish
end
Move_AEROBLAST:
loadspritegfx ANIM_TAG_AIR_WAVE_2
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
call SetSkyBg
splitbgprio ANIM_TARGET
setalpha 12, 8
call AeroblastBeam
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 5, 0, 50, 1
call AeroblastBeam
call AeroblastBeam
call AeroblastBeam
call AeroblastBeam
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
delay 0
call UnsetSkyBg
end
AeroblastBeam:
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 0, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 0, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 1, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 1, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 2, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 2, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 3, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 3, 0
delay 3
return
Move_WATER_GUN:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createsprite gWaterGunProjectileSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 40, -25
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 1, 0, 8, 1
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, ANIM_TARGET, 2
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, 0, -15, 0, 15, 55
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 10
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, 15, -20, 0, 15, 50
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 10
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, -15, -10, 0, 10, 45
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_CRABHAMMER:
loadspritegfx ANIM_TAG_ICE_CRYSTALS
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB(13, 21, 31), 10, RGB_BLACK, 0
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -24, 0, 0, 4
waitforvisualfinish
delay 8
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 4
waitforvisualfinish
loopsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET, 20, 3
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 4, 8, 1
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 20, -20, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -15, 15, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -10, -20, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 16, -8, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 5, 8, 20, ANIM_TARGET
delay 4
createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, -16, 0, 20, ANIM_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SURF:
createvisualtask AnimTask_CreateSurfWave, 2, FALSE
delay 24
panse SE_M_SURF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
waitforvisualfinish
end
Move_FLAMETHROWER:
loadspritegfx ANIM_TAG_SMALL_EMBER
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 46, 1
delay 6
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
panse SE_M_FLAMETHROWER, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 43, 1
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
call FlamethrowerCreateFlames
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
FlamethrowerCreateFlames:
createsprite gFlamethrowerFlameSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
delay 2
createsprite gFlamethrowerFlameSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
delay 2
return
@ Also used by Sandstorm weather
Move_SANDSTORM:
loadspritegfx ANIM_TAG_FLYING_DIRT
playsewithpan SE_M_SANDSTORM, 0
createvisualtask AnimTask_LoadSandstormBackground, 5, FALSE
delay 16
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 10, 2304, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 90, 2048, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 50, 2560, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 20, 2304, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 70, 1984, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 0, 2816, 96, 0
delay 10
createsprite gFlyingSandCrescentSpriteTemplate, ANIM_ATTACKER, 40, 60, 2560, 96, 0
end
Move_WHIRLPOOL:
loadspritegfx ANIM_TAG_WATER_ORB
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
delay 0
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 0, 7, RGB(0, 13, 23)
playsewithpan SE_M_WHIRLPOOL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 50, 1
call WhirlpoolEffect
call WhirlpoolEffect
call WhirlpoolEffect
delay 12
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 7, 0, RGB(0, 13, 23)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
WhirlpoolEffect:
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 28, 384, 50, 8, 50, ANIM_TARGET
delay 2
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 32, 240, 40, 11, -46, ANIM_TARGET
delay 2
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 33, 416, 40, 4, 42, ANIM_TARGET
delay 2
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 31, 288, 45, 6, -42, ANIM_TARGET
delay 2
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 28, 448, 45, 11, 46, ANIM_TARGET
delay 2
createsprite gWhirlpoolSpriteTemplate, ANIM_TARGET, 2, 0, 33, 464, 50, 10, -50, ANIM_TARGET
delay 2
return
Move_FLY:
loadspritegfx ANIM_TAG_ROUND_SHADOW
loadspritegfx ANIM_TAG_IMPACT
choosetwoturnanim FlySetUp, FlyUnleash
FlyEnd:
waitforvisualfinish
end
FlySetUp:
playsewithpan SE_M_FLY, SOUND_PAN_ATTACKER
createsprite gFlyBallUpSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336
goto FlyEnd
FlyUnleash:
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20
delay 20
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
goto FlyEnd
Move_BOUNCE:
loadspritegfx ANIM_TAG_ROUND_SHADOW
loadspritegfx ANIM_TAG_IMPACT
choosetwoturnanim BounceSetUp, BounceUnleash
BounceEnd:
end
BounceSetUp:
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
createsprite gBounceBallShrinkSpriteTemplate, ANIM_ATTACKER, 2, 0, 0
goto BounceEnd
BounceUnleash:
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gBounceBallLandSpriteTemplate, ANIM_TARGET, 3
delay 7
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 5, 11, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
goto BounceEnd
Move_KARATE_CHOP:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET
createsprite gKarateChopSpriteTemplate, ANIM_ATTACKER, 2, -16, 0, 0, 0, 10, 1, 3, 0
waitforvisualfinish
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_CROSS_CHOP:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_CROSS_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_TARGET
createsprite gCrossChopHandSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0
createsprite gCrossChopHandSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1
delay 40
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_WHITE, 10, RGB_BLACK, 10
createsprite gCrossImpactSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 20
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 7, 0, 9, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_JUMP_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 3
createsprite gJumpKickSpriteTemplate, ANIM_ATTACKER, 2, -16, 8, 0, 0, 10, ANIM_TARGET, 1, 1
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 5, 0, 7, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_HI_JUMP_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 0, 0, 8
waitforvisualfinish
delay 10
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 3
delay 2
createsprite gJumpKickSpriteTemplate, ANIM_ATTACKER, 2, -16, 8, 0, 0, 10, ANIM_TARGET, 1, 1
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -28, 0, 0, 3
delay 3
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 11, 1
waitforvisualfinish
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_DOUBLE_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gFistFootRandomPosSpriteTemplate, ANIM_ATTACKER, 3, 1, 20, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_TRIPLE_KICK:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
jumpifmoveturn 0, TripleKickLeft
jumpifmoveturn 1, TripleKickRight
goto TripleKickCenter
TripleKickContinue:
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
TripleKickLeft:
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, -16, -8, 20, 1, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -16, -16, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1
goto TripleKickContinue
TripleKickRight:
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 8, 8, 20, 1, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1
goto TripleKickContinue
TripleKickCenter:
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 4, 0, 0, 20, 1, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, -8, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
goto TripleKickContinue
Move_DYNAMIC_PUNCH:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_EXPLOSION
loadspritegfx ANIM_TAG_EXPLOSION_6
delay 1
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, 0, 0, 20, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 5, 0, 7, 1
delay 1
waitsound
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 5, 0, 28, 1
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 24, -24, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -16, 16, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -24, -12, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 16, 16, 1, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_COUNTER:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 1, 4
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
delay 4
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -15, 18, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 25, 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, -15, 18, 8, 1, 0
delay 3
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, -4, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, 0, -4, 8, 1, 0
delay 3
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 15, 9, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 3, 15, 9, 8, 1, 0
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_VITAL_THROW:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_ATTACKER
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 4, 1, 2
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4
delay 2
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -24, 0, 0, 4
waitforvisualfinish
delay 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 7
delay 11
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 10
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_ROCK_SMASH:
loadspritegfx ANIM_TAG_ROCKS
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
monbg ANIM_DEF_PARTNER
setalpha 12, 8
delay 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createsprite gFistFootSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 8, 1, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 5, 1
waitforvisualfinish
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 20, 24, 14, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 5, 0, -20, 24, 14, 1
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 5, 20, -24, 14, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, -5, 0, -20, -24, 14, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, -5, 30, 18, 8, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 30, -18, 8, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -30, 18, 8, 2
createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -30, -18, 8, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 7, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_SUBMISSION:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET, 10
waitplaysewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER, 20
waitplaysewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET, 30
waitplaysewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER, 40
waitplaysewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET, 50
waitplaysewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER, 60
waitplaysewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET, 70
waitplaysewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER, 80
waitplaysewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET, 90
createvisualtask AnimTask_TranslateMonElliptical, 2, 0, -18, 6, 6, 4
createvisualtask AnimTask_TranslateMonElliptical, 2, 1, 18, 6, 6, 4
call SubmissionHit
call SubmissionHit
call SubmissionHit
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
SubmissionHit:
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, -12, ANIM_TARGET, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -12, 8, ANIM_TARGET, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 12, 0, ANIM_TARGET, 1
delay 8
return
@ Also used by Sunny weather
Move_SUNNY_DAY:
loadspritegfx ANIM_TAG_SUNLIGHT
monbg ANIM_ATK_PARTNER
setalpha 13, 3
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 1, 0, 6, RGB_WHITE
waitforvisualfinish
panse_adjustnone SE_M_PETAL_DANCE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
call SunnyDayLightRay
call SunnyDayLightRay
call SunnyDayLightRay
call SunnyDayLightRay
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 1, 6, 0, RGB_WHITE
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
SunnyDayLightRay:
createsprite gSunlightRaySpriteTemplate, ANIM_ATTACKER, 40
delay 6
return
Move_COTTON_SPORE:
loadspritegfx ANIM_TAG_SPORE
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 18, 10
call CreateCottonSpores
call CreateCottonSpores
call CreateCottonSpores
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
CreateCottonSpores:
createsprite gSporeParticleSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, 85, 80, 0
delay 12
createsprite gSporeParticleSpriteTemplate, ANIM_ATTACKER, 2, 0, -10, 170, 80, 0
delay 12
createsprite gSporeParticleSpriteTemplate, ANIM_ATTACKER, 2, 0, -15, 0, 80, 0
delay 12
return
Move_SPORE:
loadspritegfx ANIM_TAG_SPORE
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_SporeDoubleBattle, 2
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 16, 11
call CreateSpore
call CreateSpore
call CreateSpore
waitforvisualfinish
delay 1
clearmonbg ANIM_DEF_PARTNER
blendoff
end
CreateSpore:
createsprite gSporeParticleSpriteTemplate, ANIM_TARGET, 2, 0, -20, 85, 80, 1
delay 12
createsprite gSporeParticleSpriteTemplate, ANIM_TARGET, 2, 0, -10, 170, 80, 1
delay 12
createsprite gSporeParticleSpriteTemplate, ANIM_TARGET, 2, 0, -15, 0, 80, 1
delay 12
return
Move_PETAL_DANCE:
loadspritegfx ANIM_TAG_FLOWER
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_PETAL_DANCE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 6, 6, 3
createsprite gPetalDanceBigFlowerSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 8, 140
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, 16, -24, 8, 100
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, -16, -24, 8, 100
delay 15
createsprite gPetalDanceBigFlowerSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 8, 140
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, 32, -24, 8, 100
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, -32, -24, 8, 100
delay 15
createsprite gPetalDanceBigFlowerSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 8, 140
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, 24, -24, 8, 100
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, -24, -24, 8, 100
delay 30
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, 16, -24, 0, 100
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, -16, -24, 0, 100
delay 30
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, 20, -16, 14, 80
createsprite gPetalDanceSmallFlowerSpriteTemplate, ANIM_ATTACKER, 2, -20, -14, 16, 80
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 5
delay 3
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 6, 0, 8, 1
waitforvisualfinish
delay 8
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 7
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_RAZOR_LEAF:
loadspritegfx ANIM_TAG_LEAF
loadspritegfx ANIM_TAG_RAZOR_LEAF
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
delay 1
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_ATTACKER, 10, 5
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -2, 10
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -1, -1, 15
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -4, -4, 7
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 3, -3, 11
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -1, -6, 8
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 2, -1, 12
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -4, 13
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 4, -5, 7
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 2, -6, 11
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -5, 8
delay 60
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gRazorLeafCutterSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 22, 20, 1
createsprite gRazorLeafCutterSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 22, -20, 1
delay 20
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 8, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_NATURE_POWER:
@ No actual animation, uses the animation of a move from sNaturePowerMoves instead
Move_ANCIENT_POWER:
loadspritegfx ANIM_TAG_ROCKS
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 4, 1, 10, 1
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 20, 32, -48, 50, 2
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, -38, 25, 5
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 32, 32, -28, 40, 3
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, -20, 32, -48, 50, 2
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 20, 32, -28, 60, 1
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, -28, 30, 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 30, 1
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
delay 10
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 15, 32, -48, 25, 5
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, -10, 32, -42, 30, 4
delay 10
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, -42, 25, 5
createsprite gAncientPowerRockSpriteTemplate, ANIM_ATTACKER, 2, -25, 32, -48, 30, 4
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, 0, 0, 4
delay 3
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 7
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_OCTAZOOKA:
loadspritegfx ANIM_TAG_GRAY_SMOKE
loadspritegfx ANIM_TAG_BLACK_BALL
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_ATTACKER
createsprite gOctazookaBallSpriteTemplate, ANIM_TARGET, 2, 20, 0, 0, 0, 20, 0
waitforvisualfinish
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, 8, 1, 0
delay 2
createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, -8, 1, 0
delay 2
createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, -8, 1, 0
delay 2
createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 0
waitforvisualfinish
end
Move_MIST:
loadspritegfx ANIM_TAG_MIST_CLOUD
monbg ANIM_ATK_PARTNER
setalpha 12, 8
loopsewithpan SE_M_MIST, SOUND_PAN_ATTACKER, 20, 15
call MistCloud
call MistCloud
call MistCloud
call MistCloud
call MistCloud
call MistCloud
call MistCloud
delay 32
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATK_SIDE, 8, 2, 0, 14, RGB_WHITE
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
MistCloud:
createsprite gMistCloudSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 48, 240, 0, 1
delay 7
return
Move_HAZE:
waitforvisualfinish
playsewithpan SE_M_HAZE, 0
createvisualtask AnimTask_HazeScrollingFog, 5
delay 30
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS_2, 2, 0, 16, RGB_BLACK
delay 90
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS_2, 1, 16, 0, RGB_BLACK
end
Move_FIRE_PUNCH:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_SMALL_EMBER
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 9, RGB_RED
createsprite gFireSpiralInwardSpriteTemplate, ANIM_TARGET, 1, 0
createsprite gFireSpiralInwardSpriteTemplate, ANIM_TARGET, 1, 64
createsprite gFireSpiralInwardSpriteTemplate, ANIM_TARGET, 1, 128
createsprite gFireSpiralInwardSpriteTemplate, ANIM_TARGET, 1, 196
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gFistFootSpriteTemplate, ANIM_TARGET, 3, 0, 0, 8, 1, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 15, 1
call FireSpreadEffect
delay 4
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 0, 9, 0, RGB_RED
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
FireSpreadEffect:
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 192, 176, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -192, 240, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 192, -160, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -192, -112, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 160, 48, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -224, -32, 40
createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 112, -128, 40
return
Move_LEER:
loadspritegfx ANIM_TAG_LEER
monbg ANIM_ATTACKER
splitbgprio ANIM_ATTACKER
setalpha 8, 8
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
createsprite gLeerSpriteTemplate, ANIM_ATTACKER, 2, 24, -12
createvisualtask AnimTask_ScaleMonAndRestore, 5, -5, -5, 10, ANIM_ATTACKER, 1
waitforvisualfinish
delay 10
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 9, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 9, 1
waitforvisualfinish
clearmonbg ANIM_ATTACKER
blendoff
delay 1
waitforvisualfinish
end
Move_DREAM_EATER:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
setalpha 8, 8
playsewithpan SE_M_MINIMIZE, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 15, 1
createvisualtask AnimTask_ScaleMonAndRestore, 5, -6, -6, 15, ANIM_TARGET, 1
waitforvisualfinish
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 2, 25, 1
call DreamEaterAbsorb
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
delay 1
call UnsetPsychicBackground
end
DreamEaterAbsorb:
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -40, 35
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 28, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 40, 39
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -32, 26
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, -15, -16, 36
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 16, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -40, 26
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -5, 15, 36, 33
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, -5, -8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, -10, 20, 20, 39
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 5, 8, 26
createsprite gAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 3, 5, -18, -20, 35
delay 4
return
Move_POISON_GAS:
loadspritegfx ANIM_TAG_PURPLE_GAS_CLOUD
loadspritegfx ANIM_TAG_POISON_BUBBLE
delay 0
monbg ANIM_DEF_PARTNER
splitbgprio_all
setalpha 12, 8
delay 0
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 4
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 4
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 4
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 4
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 4
playsewithpan SE_M_MIST, SOUND_PAN_ATTACKER
createsprite gPoisonGasCloudSpriteTemplate, ANIM_TARGET, 0, 64, 0, 0, -32, -6, 4192, 1072, 0
delay 40
loopsewithpan SE_M_MIST, SOUND_PAN_TARGET, 28, 6
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 6, 2, 0, 12, RGB(26, 0, 26)
waitforvisualfinish
blendoff
clearmonbg ANIM_DEF_PARTNER
delay 0
end
Move_BIND:
createvisualtask AnimTask_SwayMon, 5, 0, 6, 3328, 4, ANIM_ATTACKER
goto BindWrap
BindWrap:
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
call BindWrapSqueezeTarget
call BindWrapSqueezeTarget
waitforvisualfinish
end
BindWrapSqueezeTarget:
createvisualtask AnimTask_ScaleMonAndRestore, 5, 10, -5, 5, ANIM_TARGET, 0
delay 16
return
Move_WRAP:
createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 6, 4, 2, 4
goto BindWrap
Move_PSYBEAM:
loadspritegfx ANIM_TAG_GOLD_RING
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15
call PsybeamRings
call PsybeamRings
createvisualtask AnimTask_SwayMon, 5, 0, 6, 2048, 4, ANIM_TARGET
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(31, 18, 31)
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
call PsybeamRings
waitforvisualfinish
delay 1
call UnsetPsychicBackground
end
PsybeamRings:
createsprite gGoldRingSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 13, 0
delay 4
return
Move_HYPNOSIS:
loadspritegfx ANIM_TAG_GOLD_RING
call SetPsychicBackground
call HypnosisRings
call HypnosisRings
call HypnosisRings
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(31, 18, 31)
waitforvisualfinish
delay 1
call UnsetPsychicBackground
end
HypnosisRings:
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_ATTACKER
createsprite gGoldRingSpriteTemplate, ANIM_TARGET, 2, 0, 8, 0, 8, 27, 0
createsprite gGoldRingSpriteTemplate, ANIM_TARGET, 2, 16, -8, 0, -8, 27, 0
delay 6
return
Move_PSYWAVE:
loadspritegfx ANIM_TAG_BLUE_RING
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_TELEPORT, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 9, 0, 10
call PsywaveRings
call PsywaveRings
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 1, 4, 0, 12, RGB(31, 18, 31)
call PsywaveRings
call PsywaveRings
call PsywaveRings
call PsywaveRings
waitforvisualfinish
delay 1
call UnsetPsychicBackground
end
PsywaveRings:
createsprite gPsywaveRingSpriteTemplate, ANIM_TARGET, 3, 10, 10, 0, 16
delay 4
createsprite gPsywaveRingSpriteTemplate, ANIM_TARGET, 3, 10, 10, 0, 16
delay 4
return
Move_ZAP_CANNON:
loadspritegfx ANIM_TAG_BLACK_BALL_2
loadspritegfx ANIM_TAG_SPARK_2
playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_ATTACKER
createsprite gZapCannonBallSpriteTemplate, ANIM_TARGET, 3, 10, 0, 0, 0, 30, 0
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 0, 40, 0
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 64, 40, 1
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 128, 40, 0
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 16, 30, 192, 40, 2
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 32, 40, 0
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 96, 40, 1
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 160, 40, 0
createsprite gZapCannonSparkSpriteTemplate, ANIM_TARGET, 4, 10, 0, 8, 30, 224, 40, 2
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 5, 1
delay 15
waitplaysewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET, 19
call ElectricityEffect
waitforvisualfinish
end
Move_STEEL_WING:
loadspritegfx ANIM_TAG_GUST
loadspritegfx ANIM_TAG_IMPACT
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK
waitforvisualfinish
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
loopsewithpan SE_M_WING_ATTACK, SOUND_PAN_ATTACKER, 20, 2
createvisualtask AnimTask_TranslateMonElliptical, 2, 0, 12, 4, 1, 4
createvisualtask AnimTask_AnimateGustTornadoPalette, 5, 1, 70
createsprite gGustToTargetSpriteTemplate, ANIM_ATTACKER, 2, -25, 0, 0, 0, 20
createsprite gGustToTargetSpriteTemplate, ANIM_ATTACKER, 2, 25, 0, 0, 0, 20
delay 24
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 9
delay 17
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 16, 0, ANIM_TARGET, 1
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -16, 0, ANIM_TARGET, 1
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 11
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_IRON_TAIL:
loadspritegfx ANIM_TAG_IMPACT
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 1, 0, RGB_BLACK
waitforvisualfinish
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, TRUE
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
Move_POISON_TAIL:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_POISON_BUBBLE
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 1, 1, RGB(24, 6, 23)
waitforvisualfinish
monbg ANIM_TARGET
setalpha 12, 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_ATTACKER, TRUE
clearmonbg ANIM_TARGET
blendoff
call PoisonBubblesEffect
waitforvisualfinish
end
Move_METAL_CLAW:
loadspritegfx ANIM_TAG_CLAW_SLASH
loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2
createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK
waitforvisualfinish
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 2
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, -10, 0
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, 10, 0
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, -4, 1, 10, 3, 1
delay 8
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 2
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, -10, 1
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, 10, 1
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, -4, 1, 10, 3, 1
waitforvisualfinish
end
Move_NIGHT_SHADE:
monbg ANIM_ATTACKER
splitbgprio ANIM_ATTACKER
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
fadetobg BG_GHOST
waitbgfadein
delay 10
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
createvisualtask AnimTask_NightShadeClone, 5, 85
delay 70
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 12, 1
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 0, 2, 0, 13, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATTACKER
delay 1
restorebg
waitbgfadein
end
Move_EGG_BOMB:
loadspritegfx ANIM_TAG_EXPLOSION
loadspritegfx ANIM_TAG_LARGE_FRESH_EGG
playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
createsprite gEggThrowSpriteTemplate, ANIM_TARGET, 2, 10, 0, 0, 0, 25, -32
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 16, 1
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
delay 3
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 4, -16, -15, 1, 0
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
delay 3
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 4, 16, -5, 1, 0
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
delay 3
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 4, -12, 18, 1, 0
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
delay 3
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 4, 0, 5, 1, 0
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
delay 3
waitforvisualfinish
end
Move_SHADOW_BALL:
loadspritegfx ANIM_TAG_SHADOW_BALL
fadetobg BG_GHOST
waitbgfadein
delay 15
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_MIST, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 5, 5, 0, 5
createsprite gShadowBallSpriteTemplate, ANIM_TARGET, 2, 16, 16, 8
waitforvisualfinish
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 8, 1
waitforvisualfinish
restorebg
waitbgfadein
end
Move_LICK:
loadspritegfx ANIM_TAG_LICK
delay 15
playsewithpan SE_M_LICK, SOUND_PAN_TARGET
createsprite gLickSpriteTemplate, ANIM_TARGET, 2, 0, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 16, 1
waitforvisualfinish
end
Move_FOCUS_ENERGY:
loadspritegfx ANIM_TAG_FOCUS_ENERGY
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
call EndureEffect
delay 8
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 11, RGB_WHITE
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 32, 1
call EndureEffect
delay 8
call EndureEffect
waitforvisualfinish
end
Move_BIDE:
choosetwoturnanim BideSetUp, BideUnleash
end
BideSetUp:
loopsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER, 9, 2
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 11, RGB_RED
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 32, 1
waitforvisualfinish
end
BideUnleash:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
loopsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER, 9, 2
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 0, 11, RGB_RED
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 32, 1
waitforvisualfinish
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 24, 0, 0, 4
waitforvisualfinish
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 12, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 16, 1
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 18, -8, ANIM_TARGET, 1
delay 5
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, -18, 8, ANIM_TARGET, 1
delay 5
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, -8, -5, ANIM_TARGET, 1
waitforvisualfinish
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 7
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 11, 0, RGB_RED
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_STRING_SHOT:
loadspritegfx ANIM_TAG_STRING
loadspritegfx ANIM_TAG_WEB_THREAD
monbg ANIM_DEF_PARTNER
delay 0
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 5, F_PAL_BG, 2, 0, 9, RGB_BLACK
waitforvisualfinish
loopsewithpan SE_M_STRING_SHOT, SOUND_PAN_ATTACKER, 9, 6
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
call StringShotThread
waitforvisualfinish
playsewithpan SE_M_STRING_SHOT2, SOUND_PAN_TARGET
createsprite gStringWrapSpriteTemplate, ANIM_TARGET, 2, 0, 10
delay 4
createsprite gStringWrapSpriteTemplate, ANIM_TARGET, 2, 0, -2
delay 4
createsprite gStringWrapSpriteTemplate, ANIM_TARGET, 2, 0, 22
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
delay 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 5, F_PAL_BG, 2, 9, 0, RGB_BLACK
end
StringShotThread:
createsprite gWebThreadSpriteTemplate, ANIM_TARGET, 2, 20, 0, 512, 20, 1
delay 1
return
Move_SPIDER_WEB:
loadspritegfx ANIM_TAG_SPIDER_WEB
loadspritegfx ANIM_TAG_WEB_THREAD
monbg ANIM_DEF_PARTNER
delay 0
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 5, F_PAL_BG, 2, 0, 9, RGB_BLACK
waitforvisualfinish
splitbgprio ANIM_TARGET
loopsewithpan SE_M_STRING_SHOT, SOUND_PAN_ATTACKER, 9, 6
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
call SpiderWebThread
waitforvisualfinish
playsewithpan SE_M_STRING_SHOT2, SOUND_PAN_TARGET
createsprite gSpiderWebSpriteTemplate, ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 5, F_PAL_BG, 2, 9, 0, RGB_BLACK
end
SpiderWebThread:
createsprite gWebThreadSpriteTemplate, ANIM_TARGET, 2, 20, 0, 512, 20, 0
delay 1
return
Move_RAZOR_WIND:
choosetwoturnanim RazorWindSetUp, RazorWindUnleash
RazorWindEnd:
waitforvisualfinish
end
RazorWindSetUp:
loadspritegfx ANIM_TAG_GUST
playsewithpan SE_M_GUST, SOUND_PAN_ATTACKER
createsprite gRazorWindTornadoSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 16, 16, 0, 7, 40
createsprite gRazorWindTornadoSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 16, 16, 85, 7, 40
createsprite gRazorWindTornadoSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 16, 16, 170, 7, 40
waitforvisualfinish
playsewithpan SE_M_GUST2, SOUND_PAN_ATTACKER
goto RazorWindEnd
RazorWindUnleash:
loadspritegfx ANIM_TAG_AIR_WAVE_2
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, 8, 0, 0, 22, 2, 1
delay 2
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -8, 16, 14, 22, 1, 1
delay 2
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, 12, -16, -14, 22, 0, 1
delay 17
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 10, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 10, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
goto RazorWindEnd
Move_DISABLE:
loadspritegfx ANIM_TAG_SPARKLE_4
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 8, 8
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
createsprite gSpinningSparkleSpriteTemplate, ANIM_ATTACKER, 13, 24, -16
waitforvisualfinish
createvisualtask AnimTask_GrowAndGrayscale, 5
loopsewithpan SE_M_BIND, SOUND_PAN_TARGET, 15, 4
waitforvisualfinish
delay 1
clearmonbg ANIM_TARGET
blendoff
end
Move_RECOVER:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_ATK_PARTNER
setalpha 12, 8
loopsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER, 13, 3
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 6, 0, 11, RGB(31, 31, 11)
call RecoverAbsorbEffect
call RecoverAbsorbEffect
call RecoverAbsorbEffect
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
delay 1
call HealingEffect
waitforvisualfinish
end
RecoverAbsorbEffect:
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 40, -10, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -35, -10, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 15, -40, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -10, -32, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 25, -20, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -40, -20, 13
delay 3
createsprite gPowerAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 5, -40, 13
delay 3
return
Move_MIMIC:
loadspritegfx ANIM_TAG_ORBS
setalpha 11, 5
monbg_static ANIM_DEF_PARTNER
splitbgprio_all
panse SE_M_MINIMIZE, SOUND_PAN_TARGET, SOUND_PAN_ATTACKER, -3, 0
createvisualtask AnimTask_ShrinkTargetCopy, 5, 128, 24
delay 15
createsprite gMimicOrbSpriteTemplate, ANIM_TARGET, 2, -12, 24
delay 10
setarg 7, 0xFFFF
waitforvisualfinish
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 2, 0, 11, RGB_WHITE
waitforvisualfinish
clearmonbg_static ANIM_DEF_PARTNER
blendoff
end
Move_CONSTRICT:
loadspritegfx ANIM_TAG_TENDRILS
loopsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET, 6, 4
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 4, 0, 16, 0, 2
delay 7
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 3, 0, 0, 0, 2
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 2, 0, 8, 1, 2
delay 7
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 3, 0, -8, 1, 2
delay 8
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 6, 1
delay 20
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
setarg 7, 0xFFFF
waitforvisualfinish
end
Move_CURSE:
choosetwoturnanim CurseGhost, CurseStats
CurseGhost:
loadspritegfx ANIM_TAG_NAIL
loadspritegfx ANIM_TAG_GHOSTLY_SPIRIT
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_CurseStretchingBlackBg, 5
waitforvisualfinish
delay 20
createsprite gCurseNailSpriteTemplate, ANIM_ATTACKER, 2
delay 60
call CurseGhostShakeFromNail
delay 41
call CurseGhostShakeFromNail
delay 41
call CurseGhostShakeFromNail
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
delay 1
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 14, 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 16, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
CurseGhostShakeFromNail:
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 4, 0, 10, 0
playsewithpan SE_M_BIND, SOUND_PAN_ATTACKER
return
CurseStats:
createvisualtask AnimTask_SwayMon, 5, 0, 10, 1536, 3, ANIM_ATTACKER
waitforvisualfinish
delay 10
call CurseStats1
waitforvisualfinish
end
CurseStats1:
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_DrawFallingWhiteLinesOnAttacker, 5
createvisualtask AnimTask_BlendColorCycle, 5, F_PAL_ATTACKER, 4, 2, 0, 10, RGB_RED
return
Move_SOFT_BOILED:
loadspritegfx ANIM_TAG_BREAKING_EGG
loadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_ATK_PARTNER
playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 2, 6, 1
createsprite gSoftBoiledEggSpriteTemplate, ANIM_ATTACKER, 4, 0, 16, 0
createsprite gSoftBoiledEggSpriteTemplate, ANIM_ATTACKER, 4, 0, 16, 1
delay 120
delay 7
playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 10, 0, RGB(12, 24, 30)
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 3, 31, 16, 0, 1
delay 8
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 3, 31, 16, 0, 1
delay 60
setarg 7, 0xFFFF
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
call HealingEffect2
end
Move_HEAL_BELL:
loadspritegfx ANIM_TAG_BELL
loadspritegfx ANIM_TAG_MUSIC_NOTES_2
loadspritegfx ANIM_TAG_THIN_RING
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATK_SIDE, 0, 0, 10, RGB_WHITE
waitforvisualfinish
createvisualtask AnimTask_LoadMusicNotesPals, 5
createsprite gBellSpriteTemplate, ANIM_ATTACKER, 2, 0, -24, 0, 1
delay 12
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 48, -18, 35, 0, 0
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -48, 20, 30, 1, 1
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -38, -29, 30, 2, 2
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 36, 18, 30, 3, 3
call HealBellRing
delay 33
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 19, 26, 35, 4, 4
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -34, -12, 30, 5, 5
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 41, -20, 34, 6, 2
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -15, 26, 32, 7, 0
call HealBellRing
delay 33
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -48, 18, 31, 0, 2
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 48, -20, 30, 2, 5
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 38, 29, 33, 4, 3
createsprite gHealBellMusicNoteSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, -36, -18, 30, 6, 1
call HealBellRing
waitforvisualfinish
createvisualtask AnimTask_FreeMusicNotesPals, 5
waitforvisualfinish
unloadspritegfx ANIM_TAG_BELL
unloadspritegfx ANIM_TAG_MUSIC_NOTES_2
unloadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_SPARKLE_2
playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER
createsprite gSparklingStarsSpriteTemplate, ANIM_ATTACKER, 16, -15, 0, 0, 0, 32, 60, 1
delay 8
createsprite gSparklingStarsSpriteTemplate, ANIM_ATTACKER, 16, 12, -5, 0, 0, 32, 60, 1
waitforvisualfinish
unloadspritegfx ANIM_TAG_SPARKLE_2
loadspritegfx ANIM_TAG_THIN_RING
playsewithpan SE_SHINY, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, 4, 3, 10, 0, RGB(12, 24, 30)
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATK_SIDE, 3, 10, 0, RGB_WHITE
createsprite gBlendThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 16, 0, 0, 0, 1
end
HealBellRing:
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, 4, 3, 8, 0, RGB(12, 24, 30)
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATK_SIDE, 3, 2, 10, RGB_WHITE
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 40, 0, -24, 0, 1
playsewithpan SE_M_HEAL_BELL, SOUND_PAN_ATTACKER
return
Move_FAKE_OUT:
playsewithpan SE_M_FLATTER, 0
createvisualtask AnimTask_FakeOut, 5
waitforvisualfinish
playsewithpan SE_M_SKETCH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 5, 1
createvisualtask AnimTask_StretchTargetUp, 3
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 16, 0, RGB_WHITE
end
Move_SCARY_FACE:
loadspritegfx ANIM_TAG_EYE_SPARKLE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_ATK_SIDE | F_PAL_DEF_PARTNER, 3, 0, 16, RGB_BLACK
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 10
playsewithpan SE_M_LEER, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaryFace, 5
delay 13
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, -16, -8
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, 16, -8
waitforvisualfinish
createvisualtask AnimTask_ShakeTargetInPattern, 3, 20, 1, FALSE
playsewithpan SE_M_STRING_SHOT2, SOUND_PAN_TARGET
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_ATK_SIDE | F_PAL_DEF_PARTNER, 3, 16, 0, RGB_BLACK
waitforvisualfinish
end
Move_SWEET_KISS:
loadspritegfx ANIM_TAG_RED_HEART
loadspritegfx ANIM_TAG_ANGEL
createsprite gAngelSpriteTemplate, ANIM_TARGET, 2, 16, -48
playsewithpan SE_M_HEAL_BELL, SOUND_PAN_TARGET
delay 23
playsewithpan SE_M_HEAL_BELL, SOUND_PAN_TARGET
delay 23
playsewithpan SE_M_HEAL_BELL, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 160, -30
playsewithpan SE_M_ATTRACT, SOUND_PAN_TARGET
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -256, -42
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 128, -14
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, 416, -38
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -128, -22
createsprite gRedHeartBurstSpriteTemplate, ANIM_TARGET, 3, -384, -31
end
Move_LOVELY_KISS:
loadspritegfx ANIM_TAG_PINK_HEART
loadspritegfx ANIM_TAG_DEVIL
createsprite gDevilSpriteTemplate, ANIM_TARGET, 2, 0, -24
playsewithpan SE_M_PSYBEAM2, SOUND_PAN_TARGET
waitforvisualfinish
playsewithpan SE_M_ATTRACT, SOUND_PAN_TARGET
createsprite gPinkHeartSpriteTemplate, ANIM_TARGET, 3, -256, -42
createsprite gPinkHeartSpriteTemplate, ANIM_TARGET, 3, 128, -14
createsprite gPinkHeartSpriteTemplate, ANIM_TARGET, 3, 416, -38
createsprite gPinkHeartSpriteTemplate, ANIM_TARGET, 3, -128, -22
end
Move_FURY_SWIPES:
loadspritegfx ANIM_TAG_SWIPE
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 5, 5
delay 4
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
createsprite gFurySwipesSpriteTemplate, ANIM_TARGET, 2, 16, 0, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 5, 1
delay 10
createsprite gHorizontalLungeSpriteTemplate, ANIM_TARGET, 2, 5, 5
delay 4
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
createsprite gFurySwipesSpriteTemplate, ANIM_TARGET, 2, -16, 0, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 7, 1
end
Move_INGRAIN:
loadspritegfx ANIM_TAG_ROOTS
loadspritegfx ANIM_TAG_ORBS
createsprite gIngrainRootSpriteTemplate, ANIM_ATTACKER, 2, 16, 26, -1, 2, 150
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
delay 10
createsprite gIngrainRootSpriteTemplate, ANIM_ATTACKER, 2, -32, 20, 1, 1, 140
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
delay 10
createsprite gIngrainRootSpriteTemplate, ANIM_ATTACKER, 2, 32, 22, 1, 0, 130
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
delay 10
createsprite gIngrainRootSpriteTemplate, ANIM_ATTACKER, 2, -16, 25, -1, 3, 120
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
delay 40
createsprite gIngrainOrbSpriteTemplate, ANIM_ATTACKER, 3, 32, 26, -1, 3, 30
delay 5
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 5
createsprite gIngrainOrbSpriteTemplate, ANIM_ATTACKER, 3, -48, 20, 1, 2, 30
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 5
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 5
createsprite gIngrainOrbSpriteTemplate, ANIM_ATTACKER, 3, 48, 26, -2, 3, 18
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
delay 10
waitforvisualfinish
end
Move_PRESENT:
loadspritegfx ANIM_TAG_ITEM_BAG
createvisualtask AnimTask_IsHealingMove, 2
createsprite gPresentSpriteTemplate, ANIM_TARGET, 2, 0, -5, 10, 2, -1
playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 14
playsewithpan SE_M_BUBBLE2, SOUND_PAN_ATTACKER
delay 14
playsewithpan SE_M_BUBBLE2, 0
delay 20
playsewithpan SE_M_BUBBLE2, SOUND_PAN_TARGET
waitforvisualfinish
jumpretfalse PresentDamage
jumprettrue PresentHeal
end
PresentDamage:
loadspritegfx ANIM_TAG_EXPLOSION
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, 24, -24, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, -16, 16, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, -24, -12, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, 16, 16, 1, 1
end
PresentHeal:
loadspritegfx ANIM_TAG_GREEN_SPARKLE
loadspritegfx ANIM_TAG_BLUE_STAR
playsewithpan SE_M_MORNING_SUN, SOUND_PAN_TARGET
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, -16, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, 16, 32, -3, -1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, 32, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, -32, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, 0, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, -8, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, -8, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, 24, 32, -3, 1
delay 3
createsprite gPresentHealParticleSpriteTemplate, ANIM_TARGET, 4, -24, 32, -3, 1
waitforvisualfinish
waitsound
call HealingEffect2
end
Move_BATON_PASS:
loadspritegfx ANIM_TAG_POKEBALL
playsewithpan SE_M_BATON_PASS, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG | F_PAL_BATTLERS, 1, 2, 0, 11, RGB(31, 22, 30)
createsprite gBatonPassPokeballSpriteTemplate, ANIM_ATTACKER, 2
end
Move_PERISH_SONG:
loadspritegfx ANIM_TAG_MUSIC_NOTES_2
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 0
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 1, 1, 16
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 2, 1, 32
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 3, 2, 48
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 4, 2, 64
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 5, 0, 80
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 6, 0, 96
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 7, 1, 112
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 8, 2, 128
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 9, 0, 144
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 10, 2, 160
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 11, 0, 176
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 12, 1, 192
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 13, 3, 208
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 14, 3, 224
createsprite gPerishSongMusicNoteSpriteTemplate, ANIM_ATTACKER, 4, 15, 0, 240
createsprite gPerishSongMusicNote2SpriteTemplate, ANIM_ATTACKER, 4, 15, 0, 0
delay 20
panse SE_M_PERISH_SONG, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
delay 80
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 0, 16, RGB_BLACK
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_PLAYER_LEFT, FALSE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_PLAYER_RIGHT, FALSE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_OPPONENT_LEFT, FALSE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_OPPONENT_RIGHT, FALSE
delay 100
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 16, 0, RGB_BLACK
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_PLAYER_LEFT, TRUE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_PLAYER_RIGHT, TRUE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_OPPONENT_LEFT, TRUE
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_OPPONENT_RIGHT, TRUE
waitforvisualfinish
end
Move_SLEEP_TALK:
loadspritegfx ANIM_TAG_LETTER_Z
createvisualtask AnimTask_SwayMon, 5, 0, 4, 4096, 2, ANIM_ATTACKER
delay 20
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -1
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -1
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -1
delay 20
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -5
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -5
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -5
delay 20
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -3
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -3
delay 6
createsprite gLetterZSpriteTemplate, ANIM_TARGET, 2, 0, 20, 5, -3
waitforvisualfinish
end
Move_HYPER_FANG:
loadspritegfx ANIM_TAG_FANG_ATTACK
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
delay 1
delay 2
createvisualtask AnimTask_IsContest, 2
jumprettrue HyperFangInContest
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse HyperFangOnOpponent
goto HyperFangOnPlayer
HyperFangContinue:
waitbgfadeout
createsprite gFangSpriteTemplate, ANIM_TARGET, 2
waitbgfadein
createvisualtask AnimTask_ShakeMon, 3, ANIM_TARGET, 0, 10, 10, 1
playsewithpan SE_M_LEER, SOUND_PAN_TARGET
delay 20
restorebg
waitbgfadein
waitforvisualfinish
end
HyperFangOnOpponent:
fadetobg BG_IMPACT_OPPONENT
goto HyperFangContinue
HyperFangOnPlayer:
fadetobg BG_IMPACT_PLAYER
goto HyperFangContinue
HyperFangInContest:
fadetobg BG_IMPACT_CONTESTS
goto HyperFangContinue
Move_TRI_ATTACK:
loadspritegfx ANIM_TAG_TRI_ATTACK_TRIANGLE
createsprite gTriAttackTriangleSpriteTemplate, ANIM_TARGET, 2, 16, 0
playsewithpan SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER
delay 20
playsewithpan SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER
delay 20
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 5, 6, 0, 7
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 16, RGB_BLACK
delay 16
loadspritegfx ANIM_TAG_FIRE
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, 0
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 0, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, -1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 2, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 1, -1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, -1, 1
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 1, -2
delay 1
createsprite gLargeFlameScatterSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, 30, 3, 1
delay 2
createvisualtask AnimTask_ShakeTargetInPattern, 2, 20, 3, TRUE, 1
waitforvisualfinish
loadspritegfx ANIM_TAG_LIGHTNING
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -48
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -16
delay 1
createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 16
delay 20
createvisualtask AnimTask_ShakeTargetInPattern, 2, 20, 3, TRUE, 0
delay 2
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
waitforvisualfinish
loadspritegfx ANIM_TAG_ICE_CRYSTALS
call IceCrystalEffectShort
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 16, 0, RGB_BLACK
waitforvisualfinish
end
Move_WILL_O_WISP:
loadspritegfx ANIM_TAG_WISP_FIRE
loadspritegfx ANIM_TAG_WISP_ORB
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
playsewithpan SE_M_EMBER, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_EMBER, SOUND_PAN_ATTACKER, 10
createvisualtask SoundTask_AdjustPanningVar, 2, SOUND_PAN_ATTACKER, SOUND_PAN_ATTACKER, 1, 0
createsprite gWillOWispOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0
delay 3
createsprite gWillOWispOrbSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1
delay 3
createsprite gWillOWispOrbSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 2
delay 3
createsprite gWillOWispOrbSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, 3
delay 40
createvisualtask SoundTask_AdjustPanningVar, 2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 0
waitforvisualfinish
splitbgprio_all
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 13, 1
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 0
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 42
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 84
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 126
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 168
createsprite gWillOWispFireSpriteTemplate, ANIM_ATTACKER, 2, 210
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_ENCORE:
loadspritegfx ANIM_TAG_SPOTLIGHT
loadspritegfx ANIM_TAG_TAG_HAND
createvisualtask AnimTask_CreateSpotlight, 2
createvisualtask AnimTask_HardwarePaletteFade, 2, BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN, 3, 0, 10, FALSE
waitforvisualfinish
createsprite gSpotlightSpriteTemplate, ANIM_TARGET, 2, 0, -8
createsprite gClappingHandSpriteTemplate, ANIM_ATTACKER, 2, -2, 0, 0, 0, 9
createsprite gClappingHandSpriteTemplate, ANIM_ATTACKER, 2, 2, 0, 1, 0, 9
createsprite gClappingHand2SpriteTemplate, ANIM_ATTACKER, 3, -2, 0, 0, 0, 9
createsprite gClappingHand2SpriteTemplate, ANIM_ATTACKER, 3, 2, 0, 1, 0, 9
delay 16
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_ENCORE2, SOUND_PAN_TARGET
createvisualtask AnimTask_SwayMon, 5, 1, 8, 1536, 5, ANIM_TARGET
waitforvisualfinish
createvisualtask AnimTask_HardwarePaletteFade, 2, BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN, 3, 10, 0, TRUE
waitforvisualfinish
createvisualtask AnimTask_RemoveSpotlight, 2
end
Move_TRICK:
loadspritegfx ANIM_TAG_ITEM_BAG
loadspritegfx ANIM_TAG_SPEED_DUST
createsprite gTrickBagSpriteTemplate, ANIM_ATTACKER, 2, -40, 80
createsprite gTrickBagSpriteTemplate, ANIM_ATTACKER, 2, -40, 208
delay 16
playsewithpan SE_M_SKETCH, 0
createvisualtask AnimTask_StretchTargetUp, 3
createvisualtask AnimTask_StretchAttackerUp, 3
delay 30
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 24
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 16
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 16
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 16
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 16
playsewithpan SE_M_DOUBLE_TEAM, 0
delay 16
playsewithpan SE_M_ATTRACT, 0
createvisualtask AnimTask_ShakeMon, 3, ANIM_ATTACKER, 5, 0, 7, 2
createvisualtask AnimTask_ShakeMon, 3, ANIM_TARGET, 5, 0, 7, 2
waitforvisualfinish
end
Move_WISH:
loadspritegfx ANIM_TAG_GOLD_STARS
loadspritegfx ANIM_TAG_SPARKLE_2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 0, 10, RGB_BLACK
waitforvisualfinish
panse_adjustall SE_M_REFLECT, SOUND_PAN_TARGET, SOUND_PAN_ATTACKER, -3, 0
createsprite gWishStarSpriteTemplate, ANIM_ATTACKER, 40
waitforvisualfinish
delay 60
loopsewithpan SE_M_HEAL_BELL, SOUND_PAN_ATTACKER, 16, 3
call GrantingStarsEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 10, 0, RGB_BLACK
waitforvisualfinish
end
Move_STOCKPILE:
loadspritegfx ANIM_TAG_GRAY_ORB
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 8, 1, 0, 12, RGB_WHITE
createvisualtask AnimTask_StockpileDeformMon, 5
call StockpileAbsorb
call StockpileAbsorb
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 0, 12, 0, RGB_WHITE
end
StockpileAbsorb:
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 55, 55, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -55, -55, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 55, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, -55, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 55, -34, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, 55, 34, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -55, -34, 13
delay 1
createsprite gStockpileAbsorptionOrbSpriteTemplate, ANIM_ATTACKER, 2, -55, 34, 13
delay 1
return
Move_SPIT_UP:
loadspritegfx ANIM_TAG_RED_ORB_2
loadspritegfx ANIM_TAG_IMPACT
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_SpitUpDeformMon, 5
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 8, 2
delay 45
playsewithpan SE_M_SPIT_UP, SOUND_PAN_ATTACKER
delay 3
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 32, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 64, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 96, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 128, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 160, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 192, 12
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 224, 12
delay 5
jumpifmoveturn 2, SpitUpStrong
jumpifmoveturn 3, SpitUpStrongest
SpitUpContinue:
delay 5
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 8, 1, 0
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -12, 10, ANIM_TARGET, 1
delay 5
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 12, -10, ANIM_TARGET, 1
waitforvisualfinish
end
SpitUpStrong:
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 16
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 80
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 144
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 208
goto SpitUpContinue
SpitUpStrongest:
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 16
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 48
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 80
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 112
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 144
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 176
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 208
createsprite gSpitUpOrbSpriteTemplate, ANIM_ATTACKER, 2, 240
goto SpitUpContinue
Move_SWALLOW:
loadspritegfx ANIM_TAG_BLUE_ORB
loadspritegfx ANIM_TAG_BLUE_STAR
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_SwallowDeformMon, 5
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 8, 2
delay 38
playsewithpan SE_M_SPIT_UP, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 2, 0, 12, 1
call SwallowEffect
jumpifmoveturn 2, SwallowGood
jumpifmoveturn 3, SwallowBest
SwallowContinue:
waitforvisualfinish
call HealingEffect
end
SwallowEffect:
createsprite gSwallowBlueOrbSpriteTemplate, ANIM_ATTACKER, 2, 0, -8
delay 1
createsprite gSwallowBlueOrbSpriteTemplate, ANIM_ATTACKER, 2, -24, -8
delay 1
createsprite gSwallowBlueOrbSpriteTemplate, ANIM_ATTACKER, 2, 16, -8
delay 1
createsprite gSwallowBlueOrbSpriteTemplate, ANIM_ATTACKER, 2, -16, -8
delay 1
createsprite gSwallowBlueOrbSpriteTemplate, ANIM_ATTACKER, 2, 24, -8
delay 1
return
SwallowGood:
call SwallowEffect
goto SwallowContinue
SwallowBest:
call SwallowEffect
call SwallowEffect
goto SwallowContinue
Move_TRANSFORM:
monbg ANIM_ATTACKER
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
createvisualtask AnimTask_TransformMon, 2, 0
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
Move_MORNING_SUN:
loadspritegfx ANIM_TAG_GREEN_STAR
loadspritegfx ANIM_TAG_BLUE_STAR
createvisualtask AnimTask_MorningSunLightBeam, 5
delay 8
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 8, 0, 12, RGB_WHITE
delay 14
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
call MorningSunStar
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 3, 12, 0, RGB_WHITE
waitforvisualfinish
waitsound
call HealingEffect
end
MorningSunStar:
createsprite gGreenStarSpriteTemplate, ANIM_ATTACKER, 2, 30, 640
delay 5
return
Move_SWEET_SCENT:
loadspritegfx ANIM_TAG_PINK_PETAL
playsewithpan SE_M_SWEET_SCENT, SOUND_PAN_ATTACKER
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 100, 0, 100
delay 25
setpan 0
call SweetScentEffect
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 55, 0
setpan SOUND_PAN_TARGET
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_DEF_SIDE, 1, 5, 5, 13, RGB(31, 21, 21)
call SweetScentEffect
waitforvisualfinish
end
SweetScentEffect:
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 70, 1, 64
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 60, 0, 64
delay 5
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 80, 1, 64
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 58, 0, 120
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 100, 0, 120
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 90, 0, 64
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 48, 0, 64
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 95, 1, 80
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 100, 0, 120
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 75, 1, 64
delay 2
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 85, 0, 120
delay 2
return
Move_HYPER_BEAM:
loadspritegfx ANIM_TAG_ORBS
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 0, 16, RGB_BLACK
waitforvisualfinish
delay 10
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 4, 1
waitforvisualfinish
delay 30
createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 15, 0, 5
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1
createvisualtask AnimTask_FlashAnimTagWithColor, 2, ANIM_TAG_ORBS, 1, 12, RGB_RED, 16, 0, 0
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 11, RGB(25, 25, 25)
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
call HyperBeamOrbs
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 11, 0, RGB(25, 25, 25)
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 4, 16, 0, RGB_BLACK
end
HyperBeamOrbs:
createsprite gHyperBeamOrbSpriteTemplate, ANIM_TARGET, 2
createsprite gHyperBeamOrbSpriteTemplate, ANIM_TARGET, 2
delay 1
return
Move_FLATTER:
loadspritegfx ANIM_TAG_SPOTLIGHT
loadspritegfx ANIM_TAG_CONFETTI
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_ENCORE2, SOUND_PAN_TARGET
createvisualtask AnimTask_CreateSpotlight, 2
createvisualtask AnimTask_HardwarePaletteFade, 2, BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN, 3, 0, 10, FALSE
waitforvisualfinish
createsprite gFlatterSpotlightSpriteTemplate, ANIM_TARGET, 2, 0, -8, 80
delay 0
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 5, 2, ANIM_TARGET
delay 10
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 5, 2, ANIM_TARGET
delay 0
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_FLATTER, SOUND_PAN_ATTACKER
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
call CreateFlatterConfetti
delay 5
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_FLATTER, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_HardwarePaletteFade, 2, BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN, 3, 10, 0, TRUE
waitforvisualfinish
createvisualtask AnimTask_RemoveSpotlight, 2
end
CreateFlatterConfetti:
createsprite gFlatterConfettiSpriteTemplate, ANIM_ATTACKER, 40, ANIM_ATTACKER
createsprite gFlatterConfettiSpriteTemplate, ANIM_ATTACKER, 40, ANIM_TARGET
return
Move_ROLE_PLAY:
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 16, RGB_WHITE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 0, 10, RGB_BLACK
waitforvisualfinish
playsewithpan SE_M_TRI_ATTACK, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_DETECT, SOUND_PAN_ATTACKER, 30
createvisualtask AnimTask_RolePlaySilhouette, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 16, 0, RGB_WHITE
delay 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 2, 10, 0, RGB_BLACK
end
Move_REFRESH:
loadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_SPARKLE_2
playsewithpan SE_M_STAT_INCREASE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_StatusClearedEffect, 2, 0
waitforvisualfinish
playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER
call GrantingStarsEffect
waitforvisualfinish
playsewithpan SE_SHINY, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 10, 0, RGB(12, 24, 30)
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0
end
Move_BLAZE_KICK:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_SMALL_EMBER
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
createsprite gSpinningHandOrFootSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 30
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 7, RGB_WHITE
delay 30
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 14, 1
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_TARGET, 2, 0, 0, RGB_WHITE
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0
call FireSpreadEffect
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_HYPER_VOICE:
loadspritegfx ANIM_TAG_THIN_RING
createvisualtask SoundTask_PlayCryWithEcho, 5, FALSE
call HyperVoiceEffect
waitforvisualfinish
delay 8
createvisualtask SoundTask_PlayCryWithEcho, 5, TRUE
call HyperVoiceEffect
waitforvisualfinish
end
HyperVoiceEffect:
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 8, 0, RGB_YELLOW
createvisualtask AnimTask_ScaleMonAndRestore, 5, -5, -5, 5, ANIM_ATTACKER, 0
createsprite gHyperVoiceRingSpriteTemplate, ANIM_ATTACKER, 0, 45, 0, 0, 0, 0, 0, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 6, 1
createvisualtask AnimTask_ShakeBattleTerrain, 2, 1, 0, 6, 1
createvisualtask SoundTask_WaitForCry, 5
return
Move_SAND_TOMB:
loadspritegfx ANIM_TAG_MUD_SAND
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 0, 7, RGB(19, 17, 0)
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 43, 1
playsewithpan SE_M_SAND_TOMB, SOUND_PAN_TARGET
call SandTombSwirlingDirt
call SandTombSwirlingDirt
call SandTombSwirlingDirt
delay 22
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 7, 0, RGB(19, 17, 0)
waitforvisualfinish
end
SandTombSwirlingDirt:
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 32, 528, 30, 10, 50, ANIM_TARGET
delay 2
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 36, 480, 20, 13, -46, ANIM_TARGET
delay 2
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 37, 576, 20, 5, 42, ANIM_TARGET
delay 2
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 35, 400, 25, 8, -42, ANIM_TARGET
delay 2
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 32, 512, 25, 13, 46, ANIM_TARGET
delay 2
createsprite gSwirlingDirtSpriteTemplate, ANIM_TARGET, 2, 0, 37, 464, 30, 12, -50, ANIM_TARGET
delay 2
return
Move_SHEER_COLD:
fadetobg BG_ICE
waitbgfadeout
playsewithpan SE_M_ICY_WIND, 0
waitbgfadein
loadspritegfx ANIM_TAG_ICE_CUBE
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_FrozenIceCube, 2
waitplaysewithpan SE_M_HAIL, SOUND_PAN_TARGET, 17
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
restorebg
waitbgfadein
end
Move_ARM_THRUST:
loadspritegfx ANIM_TAG_HANDS_AND_FEET
loadspritegfx ANIM_TAG_IMPACT
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, ANIM_ATTACKER, 0
delay 6
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 3
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gArmThrustHandSpriteTemplate, ANIM_TARGET, 2, 10, -8, 14, 3
waitforvisualfinish
createvisualtask AnimTask_RotateMonSpriteToSide, 5, 8, 5, ANIM_ATTACKER, 1
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
choosetwoturnanim ArmThrustRight, ArmThrustLeft
ArmThrustContinue:
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1
waitforvisualfinish
blendoff
end
ArmThrustRight:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 8, 0, ANIM_TARGET, 2
goto ArmThrustContinue
ArmThrustLeft:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -8, 0, ANIM_TARGET, 2
goto ArmThrustContinue
Move_MUDDY_WATER:
panse SE_M_WHIRLPOOL, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createvisualtask AnimTask_CreateSurfWave, 2, TRUE
waitforvisualfinish
end
Move_BULLET_SEED:
loadspritegfx ANIM_TAG_SEED
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 30, 1
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
delay 5
createsprite gBulletSeedSpriteTemplate, ANIM_TARGET, 2, 20, 0
waitforvisualfinish
end
Move_DRAGON_CLAW:
loadspritegfx ANIM_TAG_SMALL_EMBER
loadspritegfx ANIM_TAG_CLAW_SLASH
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 4, 0, 8, RGB(31, 19, 0)
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 15, 1
call DragonClawFireSpiral
call DragonClawFireSpiral
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 528, 30, 13, 50, ANIM_ATTACKER
delay 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, -10, 0
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, -10, 10, 0
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, -4, 1, 10, 3, 1
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, 480, 20, 16, -46, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 576, 20, 8, 42, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 31, 400, 25, 11, -42, ANIM_ATTACKER
delay 2
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 512, 25, 16, 46, ANIM_ATTACKER
delay 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, -10, 1
createsprite gClawSlashSpriteTemplate, ANIM_TARGET, 2, 10, 10, 1
createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, -4, 1, 10, 3, 1
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 464, 30, 15, -50, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 528, 30, 13, 50, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, 480, 20, 16, -46, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 576, 20, 8, 42, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 31, 400, 25, 11, -42, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 512, 25, 16, 46, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 464, 30, 15, -50, ANIM_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 4, 8, 0, RGB(31, 19, 0)
waitforvisualfinish
end
DragonClawFireSpiral:
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 528, 30, 13, 50, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, 480, 20, 16, -46, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 576, 20, 8, 42, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 31, 400, 25, 11, -42, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 512, 25, 16, 46, ANIM_ATTACKER
delay 2
createsprite gFireSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 33, 464, 30, 15, -50, ANIM_ATTACKER
delay 2
return
end
Move_MUD_SHOT:
loadspritegfx ANIM_TAG_BROWN_ORB
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 46, 1
delay 6
createvisualtask AnimTask_StartSinAnimTimer, 5, 100
panse SE_M_WHIRLPOOL, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 43, 1
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
call MudShotOrbs
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
MudShotOrbs:
createsprite gMudShotOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
delay 2
createsprite gMudShotOrbSpriteTemplate, ANIM_ATTACKER, 3, 10, 10, 0, 16
delay 2
return
Move_METEOR_MASH:
loadspritegfx ANIM_TAG_GOLD_STARS
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
panse SE_M_BARRIER, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +3, 0
fadetobg BG_COSMIC
waitbgfadein
waitforvisualfinish
createsprite gMeteorMashStarSpriteTemplate, ANIM_TARGET, 3, -48, -64, 72, 32, 30
delay 10
createsprite gMeteorMashStarSpriteTemplate, ANIM_TARGET, 3, -112, -64, 8, 32, 30
delay 40
createsprite gSpinningHandOrFootSpriteTemplate, ANIM_TARGET, 3, 0, 0, 0, 30
createsprite gMeteorMashStarSpriteTemplate, ANIM_TARGET, 3, -80, -64, 40, 32, 30
delay 20
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 5, 0, 20, 1
waitforvisualfinish
delay 10
restorebg
waitbgfadein
waitforvisualfinish
end
Move_REVENGE:
loadspritegfx ANIM_TAG_PURPLE_SCRATCH
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createsprite gRevengeSmallScratchSpriteTemplate, ANIM_ATTACKER, 2, 10, -10
waitforvisualfinish
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 4, 2, 8, RGB_RED
waitforvisualfinish
unloadspritegfx ANIM_TAG_PURPLE_SCRATCH
loadspritegfx ANIM_TAG_PURPLE_SWIPE
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 6, 4
delay 4
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gRevengeBigScratchSpriteTemplate, ANIM_TARGET, 2, 10, -10
waitforvisualfinish
unloadspritegfx ANIM_TAG_PURPLE_SWIPE
loadspritegfx ANIM_TAG_IMPACT
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 3, 0, 10, 1
createsprite gPersistHitSplatSpriteTemplate, ANIM_TARGET, 3, -10, -8, ANIM_TARGET, 1, 8
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 8
createsprite gPersistHitSplatSpriteTemplate, ANIM_TARGET, 3, 10, 8, ANIM_TARGET, 1, 8
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_POISON_FANG:
loadspritegfx ANIM_TAG_FANG_ATTACK
loadspritegfx ANIM_TAG_POISON_BUBBLE
playsewithpan SE_M_BITE, SOUND_PAN_TARGET
createsprite gFangSpriteTemplate, ANIM_TARGET, 2
delay 10
createvisualtask AnimTask_ShakeMon, 3, ANIM_TARGET, 3, 0, 10, 1
waitforvisualfinish
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 0, 4, 0, 12, RGB(26, 0, 26)
call PoisonBubblesEffect
waitforvisualfinish
end
Move_SUBSTITUTE:
playsewithpan SE_M_ATTRACT, SOUND_PAN_ATTACKER
createvisualtask AnimTask_MonToSubstitute, 2
end
Move_FRENZY_PLANT:
loadspritegfx ANIM_TAG_ROOTS
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 2, 0, 5, RGB_BLACK
waitforvisualfinish
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 10, 8, 2, 0, 0, 100
playsewithpan SE_M_SCRATCH, SOUND_PAN_ATTACKER
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 20, -8, -2, 0, 1, 95
playsewithpan SE_M_SCRATCH, -43
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 30, 8, -4, 0, 0, 90
playsewithpan SE_M_SCRATCH, -22
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 40, -8, 4, 0, 1, 85
playsewithpan SE_M_SCRATCH, 0
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 50, 8, 0, 0, 0, 85
playsewithpan SE_M_SCRATCH, +21
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 60, -8, -2, 0, 1, 85
playsewithpan SE_M_SCRATCH, +42
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 75, 8, 0, 0, 0, 85
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 85, 16, 6, 0, 3, 80
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
delay 5
createsprite gFrenzyPlantRootSpriteTemplate, ANIM_ATTACKER, 2, 85, -16, -6, 0, 2, 75
playsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -10, ANIM_TARGET, 3
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 3, ANIM_TARGET, 8, 0, 20, 1
delay 3
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, 8, ANIM_TARGET, 3
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
delay 3
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, -3, ANIM_TARGET, 2
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
delay 3
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -3, 1, ANIM_TARGET, 2
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
delay 2
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, 1, ANIM_TARGET, 1
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
delay 2
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 10, ANIM_TARGET, 1
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_BG, 2, 5, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
Move_METAL_SOUND:
loadspritegfx ANIM_TAG_METAL_SOUND_WAVES
monbg ANIM_DEF_PARTNER
splitbgprio_foes ANIM_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 2, 0, 8, 1
call MetalSoundRings
call MetalSoundRings
call MetalSoundRings
call MetalSoundRings
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
delay 0
waitforvisualfinish
end
MetalSoundRings:
panse SE_M_SCREECH, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
createsprite gMetalSoundSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 30, 0
delay 2
return
Move_FOCUS_PUNCH:
goto FocusPunch
FocusPunchEnd:
waitforvisualfinish
end
FocusPunch:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_HANDS_AND_FEET
delay 1
createvisualtask AnimTask_IsContest, 2
jumprettrue FocusPunchInContest
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse FocusPunchOnOpponent
jumprettrue FocusPunchOnPlayer
FocusPunchContinue:
waitbgfadein
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_SWAGGER, SOUND_PAN_TARGET
createsprite gFocusPunchFistSpriteTemplate, ANIM_TARGET, 2
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 8, 0, 24, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, 2, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, -6, ANIM_TARGET, 0
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 8, ANIM_TARGET, 0
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
restorebg
waitbgfadein
clearmonbg ANIM_DEF_PARTNER
blendoff
goto FocusPunchEnd
FocusPunchOnOpponent:
fadetobg BG_IMPACT_OPPONENT
goto FocusPunchContinue
FocusPunchOnPlayer:
fadetobg BG_IMPACT_PLAYER
goto FocusPunchContinue
FocusPunchInContest:
fadetobg BG_IMPACT_CONTESTS
goto FocusPunchContinue
Move_RETURN:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createvisualtask AnimTask_GetReturnPowerLevel, 2
delay 2
jumpreteq 0, ReturnWeak
jumpreteq 1, ReturnMedium
jumpreteq 2, ReturnStrong
jumpreteq 3, ReturnStrongest
ReturnContinue:
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
ReturnWeak:
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 16, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 16, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_COMET_PUNCH, SOUND_PAN_TARGET
goto ReturnContinue
ReturnMedium:
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
delay 11
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 5, 4
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
goto ReturnContinue
ReturnStrong:
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 3, -5, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -5, 3, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
goto ReturnContinue
ReturnStrongest:
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 0, 6, RGB_BLACK
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 16, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 3, -5, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 12, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
waitforvisualfinish
delay 4
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 8, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
waitforvisualfinish
delay 2
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 5, 1
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 4, 1, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 5, 1
waitforvisualfinish
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 4, 2, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
delay 5
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 5, 1
waitforvisualfinish
call ReturnStrongestHit
call ReturnStrongestHit
call ReturnStrongestHit
call ReturnStrongestHit
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -10, -8, ANIM_TARGET, 0
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 8, 0, 24, 1
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, ANIM_TARGET, 0
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 3, -5, ANIM_TARGET, 0
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, -5, 3, ANIM_TARGET, 0
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MEGA_KICK2, SOUND_PAN_TARGET
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 6, 0, RGB_BLACK
goto ReturnContinue
ReturnStrongestHit:
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 4, 3, ANIM_ATTACKER
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 5, 1
waitforvisualfinish
return
Move_COSMIC_POWER:
loadspritegfx ANIM_TAG_SPARKLE_2
createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_COSMIC_POWER, 0
playsewithpan SE_M_COSMIC_POWER, 0
createvisualtask AnimTask_BlendNonAttackerPalettes, 2, 0, 0, 15, RGB_BLACK
waitforvisualfinish
fadetobg BG_COSMIC
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 2, 0, 128, 0, -1
waitbgfadein
delay 70
createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_MORNING_SUN, SOUND_PAN_ATTACKER
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, -15, 0, 0, 0, 32, 60
delay 8
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, 12, -5, 0, 0, 32, 60
delay 40
createvisualtask AnimTask_BlendNonAttackerPalettes, 2, 0, 15, 0, RGB_BLACK
waitforvisualfinish
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
waitforvisualfinish
end
Move_BLAST_BURN:
loadspritegfx ANIM_TAG_FIRE_PLUME
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_SACRED_FIRE, SOUND_PAN_ATTACKER
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -32, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -20, -10, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 0, -16, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 20, -10, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 32, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 20, 10, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 16, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -20, 10, 24, 0, 0, 0
delay 25
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_ATTACKER
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -64, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 6, -40, -20, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 70, 0, -32, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 70, 40, -20, 24, 0, 0, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 64, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 40, 20, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 32, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -40, 20, 24, 0, 0, 0
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 25
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_ATTACKER
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -96, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 6, -60, -30, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 70, 0, -48, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 70, 60, -30, 24, 0, 0, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -4, 3, ANIM_TARGET, 0
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 12, 0, 20, 1
createvisualtask AnimTask_ShakeBattleTerrain, 2, 2, 0, 10, 1
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 96, 0, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 66, 60, 30, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, 0, 48, 24, 0, 0, 0
createsprite gFirePlumeSpriteTemplate, ANIM_ATTACKER, 2, -60, 30, 24, 0, 0, 0
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_ROCK_TOMB:
loadspritegfx ANIM_TAG_X_SIGN
loadspritegfx ANIM_TAG_ROCKS
createvisualtask AnimTask_ShakeBattleTerrain, 2, 2, 0, 10, 1
waitforvisualfinish
createsprite gRockTombRockSpriteTemplate, ANIM_TARGET, 2, 20, 12, 64, 114, 0
delay 8
createvisualtask AnimTask_ShakeBattleTerrain, 2, 0, 2, 3, 1
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
delay 8
createsprite gRockTombRockSpriteTemplate, ANIM_TARGET, 2, -20, 12, 64, 98, 0
delay 8
createvisualtask AnimTask_ShakeBattleTerrain, 2, 0, 2, 3, 1
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
delay 8
createsprite gRockTombRockSpriteTemplate, ANIM_TARGET, 66, 3, 6, 64, 82, 0
delay 8
createvisualtask AnimTask_ShakeBattleTerrain, 2, 0, 2, 3, 1
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
delay 8
createsprite gRockTombRockSpriteTemplate, ANIM_TARGET, 2, -3, 13, 64, 66, 0
delay 8
createvisualtask AnimTask_ShakeBattleTerrain, 2, 0, 2, 3, 1
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
delay 24
playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_TARGET
createsprite gRedXSpriteTemplate, ANIM_TARGET, 5, ANIM_TARGET, 50
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 20, 1
createvisualtask AnimTask_ShakeBattleTerrain, 2, 2, 0, 10, 1
waitforvisualfinish
end
Move_SILVER_WIND:
loadspritegfx ANIM_TAG_SPARKLE_6
panse SE_M_GUST, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
playsewithpan SE_M_MORNING_SUN, 0
delay 0
monbg ANIM_DEF_PARTNER
splitbgprio_all
delay 0
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, ANIM_TARGET, 0, 0, 4, RGB_BLACK
createvisualtask AnimTask_GetTargetSide, 2
jumprettrue SilverWindOnPlayer
fadetobg BG_BUG_OPPONENT
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, 1536, 0, 0, -1
SilverWindContinue:
delay 0
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG, 0, 4, 4, RGB_BLACK
waitbgfadein
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_TARGET, 66, -32, 16, 0, 6, 2, 3, 1
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_TARGET, 66, -8, 18, 64, 3, 2, 2, 1
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_ATTACKER, 120, -24, 18, 90, 5, 1, 2, 1
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_ATTACKER, 120, -40, 14, 128, 4, 1, 2, 1
delay 0
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_TARGET, 66, -32, 16, 0, 6, 2, 3, 1
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_TARGET, 66, -8, 18, 64, 3, 2, 2, 1
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_ATTACKER, 120, -24, 18, 90, 5, 1, 2, 1
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_ATTACKER, 120, -40, 14, 128, 4, 1, 2, 1
delay 0
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_TARGET, 66, -32, 16, 0, 6, 2, 3, 1
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_TARGET, 66, -8, 18, 64, 3, 2, 2, 1
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_ATTACKER, 120, -24, 18, 90, 5, 1, 2, 1
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_ATTACKER, 120, -40, 14, 128, 4, 1, 2, 1
delay 6
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_TARGET, 66, -4, 16, 0, 6, 1, 2, 1
createsprite gSilverWindBigSparkSpriteTemplate, ANIM_TARGET, 66, -16, 12, 192, 5, 2, 3, 1
delay 0
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_TARGET, 66, -4, 16, 0, 6, 1, 2, 1
createsprite gSilverWindMediumSparkSpriteTemplate, ANIM_TARGET, 66, -16, 12, 192, 5, 2, 3, 1
delay 0
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_TARGET, 66, -4, 16, 0, 6, 1, 2, 1
createsprite gSilverWindSmallSparkSpriteTemplate, ANIM_TARGET, 66, -16, 12, 192, 5, 2, 3, 1
waitforvisualfinish
playsewithpan SE_M_GUST2, SOUND_PAN_TARGET
clearmonbg ANIM_DEF_PARTNER
delay 0
restorebg
waitbgfadeout
createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, ANIM_TARGET, 0, 4, 0, RGB_BLACK
setarg 7, 0xFFFF
waitbgfadein
end
SilverWindOnPlayer:
fadetobg BG_BUG_PLAYER
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -1536, 0, 0, -1
goto SilverWindContinue
Move_SNATCH:
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_WindUpLunge, 5, ANIM_ATTACKER, -12, 4, 10, 10, 12, 6
end
Move_DIVE:
loadspritegfx ANIM_TAG_SPLASH
loadspritegfx ANIM_TAG_SWEAT_BEAD
choosetwoturnanim DiveSetUp, DiveAttack
DiveSetUp:
loadspritegfx ANIM_TAG_ROUND_SHADOW
playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER
createsprite gDiveBallSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336
waitforvisualfinish
playsewithpan SE_M_DIVE, SOUND_PAN_ATTACKER
createsprite gDiveWaterSplashSpriteTemplate, ANIM_ATTACKER, 3, 0
call DiveSetUpWaterDroplets
call DiveSetUpWaterDroplets
call DiveSetUpWaterDroplets
call DiveSetUpWaterDroplets
call DiveSetUpWaterDroplets
end
DiveSetUpWaterDroplets:
createsprite gSprayWaterDropletSpriteTemplate, ANIM_ATTACKER, 5, 0, 0
createsprite gSprayWaterDropletSpriteTemplate, ANIM_ATTACKER, 5, 1, 0
return
DiveAttack:
loadspritegfx ANIM_TAG_WATER_IMPACT
loadspritegfx ANIM_TAG_SMALL_BUBBLES
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET
createsprite gDiveWaterSplashSpriteTemplate, ANIM_TARGET, 3, 1
call DiveAttackWaterDroplets
call DiveAttackWaterDroplets
call DiveAttackWaterDroplets
call DiveAttackWaterDroplets
call DiveAttackWaterDroplets
delay 12
call RisingWaterHitEffect
waitforvisualfinish
visible ANIM_ATTACKER
clearmonbg ANIM_DEF_PARTNER
blendoff
end
DiveAttackWaterDroplets:
createsprite gSprayWaterDropletSpriteTemplate, ANIM_TARGET, 5, 0, 1
createsprite gSprayWaterDropletSpriteTemplate, ANIM_TARGET, 5, 1, 1
return
Move_ROCK_BLAST:
loadspritegfx ANIM_TAG_ROCKS
loadspritegfx ANIM_TAG_IMPACT
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6
delay 3
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
createsprite gRockBlastRockSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 25, 257
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, 20, 24, 14, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 5, 1
createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 5, 0, -20, 24, 14, 1
createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 5, 20, -24, 14, 2
createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, -5, 0, -20, -24, 14, 2
waitforvisualfinish
end
Move_OVERHEAT:
loadspritegfx ANIM_TAG_SMALL_EMBER
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 18
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 5, RGB(28, 0, 0)
waitforvisualfinish
createvisualtask AnimTask_AllocBackupPalBuffer, 5
waitforvisualfinish
createvisualtask AnimTask_CopyPalUnfadedToBackup, 5, 0, 1
delay 1
createvisualtask AnimTask_CopyPalFadedToUnfaded, 5, 0
delay 1
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_CopyPalUnfadedToBackup, 5, 1, 0
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 1, 0, 13, RGB(28, 0, 0)
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 2, 0, 15, 1
waitforvisualfinish
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_ATTACKER
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 32, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 64, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 96, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 128, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 160, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 192, 30, 25, -20
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 224, 30, 25, -20
delay 5
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 32, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 64, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 96, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 128, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 160, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 192, 30, 25, 0
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 224, 30, 25, 0
delay 5
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 32, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 64, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 96, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 2, 1, 128, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 160, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 192, 30, 25, 10
createsprite gOverheatFlameSpriteTemplate, ANIM_ATTACKER, 66, 1, 224, 30, 25, 10
delay 5
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -5, 3, ANIM_TARGET, 0
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 10, 0, 25, 1
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, -5, ANIM_TARGET, 0
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 10, 10, ANIM_TARGET, 0
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_FIRE_PUNCH, SOUND_PAN_TARGET
createvisualtask AnimTask_CopyPalFadedToUnfaded, 5, 1
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, -1, 0, 13, RGB(18, 18, 18)
createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 3, 0, 15, 1
waitforvisualfinish
createvisualtask AnimTask_CopyPalUnfadedFromBackup, 5, 0, 1
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 5, 0, RGB(28, 0, 0)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
waitforvisualfinish
delay 15
createvisualtask AnimTask_CopyPalUnfadedFromBackup, 5, 1, 0
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 0, 13, 0, RGB(18, 18, 18)
waitforvisualfinish
createvisualtask AnimTask_FreeBackupPalBuffer, 5
waitforvisualfinish
end
Move_HYDRO_CANNON:
loadspritegfx ANIM_TAG_WATER_ORB
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
playsewithpan SE_M_SURF, SOUND_PAN_ATTACKER
createsprite gHydroCannonChargeSpriteTemplate, ANIM_TARGET, 2
delay 10
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
delay 30
panse SE_M_HYDRO_PUMP, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +2, 0
call HydroCannonBeam
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 10, 0, 40, 1
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
call HydroCannonBeam
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
call HydroCannonBeam
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
call HydroCannonBeam
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
call HydroCannonBeam
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
call HydroCannonBeam
createsprite gWaterHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 0
waitforvisualfinish
createvisualtask AnimTask_InvertScreenColor, 2, 257, 257, 257
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
HydroCannonBeam:
createsprite gHydroCannonBeamSpriteTemplate, ANIM_TARGET, 2, 10, -10, 0, 0, 15, 257
delay 1
createsprite gHydroCannonBeamSpriteTemplate, ANIM_TARGET, 2, 10, -10, 0, 0, 15, 257
delay 1
createsprite gHydroCannonBeamSpriteTemplate, ANIM_TARGET, 2, 10, -10, 0, 0, 15, 257
delay 1
createsprite gHydroCannonBeamSpriteTemplate, ANIM_TARGET, 2, 10, -10, 0, 0, 15, 257
delay 1
createsprite gHydroCannonBeamSpriteTemplate, ANIM_TARGET, 2, 10, -10, 0, 0, 15, 257
return
Move_ASTONISH:
loadspritegfx ANIM_TAG_SWEAT_BEAD
playsewithpan SE_M_ENCORE, SOUND_PAN_ATTACKER
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6
delay 25
createsprite gSprayWaterDropletSpriteTemplate, ANIM_TARGET, 5, 0, 1
playsewithpan SE_M_SKETCH, SOUND_PAN_TARGET
createsprite gSprayWaterDropletSpriteTemplate, ANIM_TARGET, 5, 1, 1
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 5, 1
createvisualtask AnimTask_StretchTargetUp, 3
waitforvisualfinish
end
Move_SEISMIC_TOSS:
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ROCKS
setarg 7, 0
monbg ANIM_DEF_PARTNER
setalpha 12, 8
waitforvisualfinish
createvisualtask AnimTask_GetSeismicTossDamageLevel, 3
delay 1
fadetobg BG_IN_AIR
waitbgfadeout
createvisualtask AnimTask_MoveSeismicTossBg, 3
playsewithpan SE_M_SKY_UPPERCUT, 0
waitbgfadein
waitforvisualfinish
createvisualtask AnimTask_SeismicTossBgAccelerateDownAtEnd, 3
jumpreteq 0, SeismicTossWeak
jumpreteq 1, SeismicTossMedium
jumpreteq 2, SeismicTossStrong
SeismicTossContinue:
restorebg
waitbgfadeout
setarg 7, 0xFFF
waitbgfadein
clearmonbg ANIM_DEF_PARTNER
blendoff
end
SeismicTossWeak:
call SeismicTossRockScatter1
delay 16
call SeismicTossRockScatter2
goto SeismicTossContinue
SeismicTossMedium:
call SeismicTossRockScatter1
delay 14
call SeismicTossRockScatter2
delay 14
call SeismicTossRockScatter1
goto SeismicTossContinue
SeismicTossStrong:
call SeismicTossRockScatter2
delay 10
call SeismicTossRockScatter1
delay 10
call SeismicTossRockScatter2
delay 10
call SeismicTossRockScatter1
goto SeismicTossContinue
SeismicTossRockScatter1:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -10, -8, ANIM_TARGET, 1
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 5, 1
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -12, 27, 2, 3
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 8, 28, 3, 4
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -4, 30, 2, 3
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 12, 25, 4, 4
return
SeismicTossRockScatter2:
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 10, -8, ANIM_TARGET, 1
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 5, 1
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -12, 32, 3, 4
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 8, 31, 2, 2
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -4, 28, 2, 3
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 12, 30, 4, 3
return
Move_MAGIC_COAT:
loadspritegfx ANIM_TAG_ORANGE_LIGHT_WALL
setalpha 0, 16
waitplaysewithpan SE_M_BARRIER, SOUND_PAN_ATTACKER, 15
createsprite gMagicCoatWallSpriteTemplate, ANIM_ATTACKER, 3, 40, 0, ANIM_TAG_ORANGE_LIGHT_WALL
waitforvisualfinish
delay 1
blendoff
end
Move_WATER_PULSE:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_BLUE_RING_2
monbg ANIM_TARGET
splitbgprio ANIM_TARGET
playsewithpan SE_M_BUBBLE3, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 0, 0, 7, RGB(0, 25, 28)
delay 10
createsprite gWaterPulseBubbleSpriteTemplate, ANIM_ATTACKER, 66, 100, 100, 8, 1, 20, 40, 0
createsprite gWaterPulseBubbleSpriteTemplate, ANIM_ATTACKER, 66, 20, 100, 16, 2, 10, 35, 1
createsprite gWaterPulseBubbleSpriteTemplate, ANIM_ATTACKER, 66, 200, 80, 8, 1, 40, 20, 0
createsprite gWaterPulseBubbleSpriteTemplate, ANIM_ATTACKER, 66, 80, 60, 10, 3, 20, 50, 0
createsprite gWaterPulseBubbleSpriteTemplate, ANIM_ATTACKER, 66, 140, 100, 16, 1, 20, 30, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
waitforvisualfinish
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_ATTACKER
createsprite gWaterPulseRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 40, 15
delay 5
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_ATTACKER
createsprite gWaterPulseRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 40, 15
delay 5
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_ATTACKER
createsprite gWaterPulseRingSpriteTemplate, ANIM_TARGET, 2, 0, 0, 40, 15
delay 13
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 8, 18, 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 7, 0, RGB(0, 25, 28)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Move_PSYCHO_BOOST:
loadspritegfx ANIM_TAG_CIRCLE_OF_LIGHT
monbg ANIM_ATK_PARTNER
fadetobg BG_PSYCHIC
waitbgfadeout
createvisualtask AnimTask_FadeScreenToWhite, 5
waitbgfadein
delay 6
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_BG, 2, 8, 0, 10, RGB_BLACK
delay 0
splitbgprio ANIM_ATTACKER
setalpha 8, 8
delay 10
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 3, 0, 240, 0
loopsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, 14, 10
createsprite gPsychoBoostOrbSpriteTemplate, ANIM_ATTACKER, 2
delay 110
loopsewithpan SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, 7, 10
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, -8, 1, 24, 1
playsewithpan SE_M_LEER, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
call UnsetPsychicBackground
end
Move_KNOCK_OFF:
loadspritegfx ANIM_TAG_SLAM_HIT_2
loadspritegfx ANIM_TAG_IMPACT
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6
delay 4
playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET
createsprite gKnockOffStrikeSpriteTemplate, ANIM_TARGET, 2, -16, -16
delay 8
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 5, 1, RGB_WHITE, 10, RGB_BLACK, 0
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 2
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -12, 10, 0, 3
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5
delay 3
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 0, 3, 6, 1
delay 5
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
delay 10
waitforvisualfinish
end
Move_DOOM_DESIRE:
createvisualtask GetIsDoomDesireHitTurn, 2
delay 1
monbg ANIM_ATK_PARTNER
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_TARGET, FALSE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 4, RGB_BLACK
waitforvisualfinish
setalpha 8, 8
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ScaleMonAndRestore, 5, -4, -4, 15, ANIM_ATTACKER, 1
waitforvisualfinish
delay 20
createvisualtask AnimTask_SetGrayscaleOrOriginalPal, 5, ANIM_TARGET, TRUE
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 4, 0, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
blendoff
end
Move_SKY_UPPERCUT:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
fadetobg BG_IN_AIR
waitbgfadeout
playsewithpan SE_M_SKY_UPPERCUT, SOUND_PAN_ATTACKER
createvisualtask AnimTask_MoveSkyUppercutBg, 5, 55
waitbgfadein
setalpha 12, 8
delay 38
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 28, 0, 0, 5
delay 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 6, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -28, 28, ANIM_TARGET, 1
delay 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -15, 8, ANIM_TARGET, 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
delay 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -5, -12, ANIM_TARGET, 1
delay 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, -32, ANIM_TARGET, 1
delay 1
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 5, -52, ANIM_TARGET, 1
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -26, 16, 1, 4
delay 4
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 0, 3, 6, 1
delay 30
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 6
delay 4
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6
clearmonbg ANIM_DEF_PARTNER
blendoff
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
end
Move_SECRET_POWER:
createvisualtask AnimTask_GetBattleTerrain, 5
jumpargeq 0, BATTLE_TERRAIN_GRASS, Move_NEEDLE_ARM
jumpargeq 0, BATTLE_TERRAIN_LONG_GRASS, Move_MAGICAL_LEAF
jumpargeq 0, BATTLE_TERRAIN_SAND, Move_MUD_SHOT
jumpargeq 0, BATTLE_TERRAIN_UNDERWATER, Move_WATERFALL
jumpargeq 0, BATTLE_TERRAIN_WATER, Move_SURF
jumpargeq 0, BATTLE_TERRAIN_POND, Move_BUBBLE_BEAM
jumpargeq 0, BATTLE_TERRAIN_MOUNTAIN, Move_ROCK_THROW
jumpargeq 0, BATTLE_TERRAIN_CAVE, Move_BITE
jumpargeq 0, BATTLE_TERRAIN_BUILDING, Move_STRENGTH
goto Move_SLAM
Move_TWISTER:
loadspritegfx ANIM_TAG_LEAF
loadspritegfx ANIM_TAG_IMPACT
loadspritegfx ANIM_TAG_ROCKS
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
playsewithpan SE_M_TWISTER, SOUND_PAN_TARGET
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 120, 70, 5, 70, 30
delay 1
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 115, 55, 6, 60, 25
delay 1
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 115, 60, 7, 60, 30
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 115, 55, 10, 60, 30
delay 3
createsprite gTwisterRockSpriteTemplate, ANIM_TARGET, 2, 100, 50, 4, 50, 26
delay 1
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 105, 25, 8, 60, 20
delay 1
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 115, 40, 10, 48, 30
delay 3
createsprite gTwisterRockSpriteTemplate, ANIM_TARGET, 2, 120, 30, 6, 45, 25
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 115, 35, 10, 60, 30
delay 3
createsprite gTwisterRockSpriteTemplate, ANIM_TARGET, 2, 105, 20, 8, 40, 0
delay 3
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 20, 255, 15, 32, 0
createsprite gTwisterLeafSpriteTemplate, ANIM_TARGET, 2, 110, 10, 8, 32, 20
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -32, -16, ANIM_TARGET, 3
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 12, 1
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_DEF_PARTNER, 3, 0, 12, 1
delay 4
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 3
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 4
createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, ANIM_TARGET, 3
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
delay 4
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 20, ANIM_TARGET, 3
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_MAGICAL_LEAF:
loadspritegfx ANIM_TAG_LEAF
loadspritegfx ANIM_TAG_RAZOR_LEAF
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
setalpha 12, 8
delay 1
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_ATTACKER, 10, 5
createvisualtask AnimTask_CycleMagicalLeafPal, 5
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -2, 10
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -1, -1, 15
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -4, -4, 7
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 3, -3, 11
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -1, -6, 8
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 2, -1, 12
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -4, 13
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 4, -5, 7
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, 2, -6, 11
delay 2
createsprite gRazorLeafParticleSpriteTemplate, ANIM_ATTACKER, 2, -3, -5, 8
delay 60
playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER
createsprite gRazorLeafCutterSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 32, 20, 0
createsprite gRazorLeafCutterSpriteTemplate, ANIM_TARGET, 3, 20, -10, 20, 0, 32, -20, 0
delay 30
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, -4, ANIM_TARGET, 2
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, 10, 4, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
delay 20
setarg 7, 0xFFFF
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
Move_ICE_BALL:
loadspritegfx ANIM_TAG_ICE_CHUNK
loadspritegfx ANIM_TAG_ICE_CRYSTALS
createvisualtask AnimTask_GetIceBallCounter, 5, 0
jumpargeq 0, 4, IceBallSetIceBg
IceBallContinue:
playsewithpan SE_M_ICY_WIND, SOUND_PAN_ATTACKER
createsprite gIceBallChunkSpriteTemplate, ANIM_TARGET, 2, 15, 0, -12, -16, 30, -40
delay 28
playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_TARGET
createvisualtask AnimTask_GetIceBallCounter, 5, 0
jumpargeq 0, 0, IceBallWeakest
jumpargeq 0, 1, IceBallWeak
jumpargeq 0, 2, IceBallMediun
jumpargeq 0, 3, IceBallStrong
jumpargeq 0, 4, IceBallStrongest
IceBallContinue2:
createvisualtask AnimTask_GetIceBallCounter, 5, 0
jumpargeq 0, 4, IceBallUnsetIceBg
IceBallEnd:
end
IceBallSetIceBg:
fadetobg BG_ICE
goto IceBallContinue
IceBallUnsetIceBg:
waitbgfadein
delay 45
restorebg
waitbgfadein
goto IceBallEnd
IceBallWeakest:
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 8, 1, 0
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
goto IceBallContinue2
IceBallWeak:
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
goto IceBallContinue2
IceBallMediun:
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 14, 1, 0
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
goto IceBallContinue2
IceBallStrong:
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 18, 1, 0
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
goto IceBallContinue2
IceBallStrongest:
createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 30, 1, 0
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
call IceBallImpactShard
goto IceBallContinue2
IceBallImpactShard:
createsprite gIceBallImpactShardSpriteTemplate, ANIM_TARGET, 4, -12, -16
return
Move_WEATHER_BALL:
loadspritegfx ANIM_TAG_WEATHER_BALL
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 8, 1, ANIM_ATTACKER
delay 8
playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER
createsprite gWeatherBallUpSpriteTemplate, ANIM_ATTACKER, 2
waitforvisualfinish
delay 15
playsewithpan SE_M_DETECT, 0
createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 5, 1, RGB_WHITE, 10, RGB_BLACK, 0
waitforvisualfinish
createvisualtask AnimTask_GetWeather, 2
delay 1
jumpreteq ANIM_WEATHER_NONE, WeatherBallNormal
jumpreteq ANIM_WEATHER_SUN, WeatherBallFire
jumpreteq ANIM_WEATHER_RAIN, WeatherBallWater
jumpreteq ANIM_WEATHER_SANDSTORM, WeatherBallSandstorm
jumpreteq ANIM_WEATHER_HAIL, WeatherBallIce
WeatherBallNormal:
loadspritegfx ANIM_TAG_IMPACT
createsprite gWeatherBallNormalDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0
waitforvisualfinish
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 8, 1
waitforvisualfinish
end
WeatherBallFire:
loadspritegfx ANIM_TAG_SMALL_EMBER
createsprite gWeatherBallFireDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 40, 10
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
delay 10
createsprite gWeatherBallFireDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, -40, 20
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
delay 10
createsprite gWeatherBallFireDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
waitforvisualfinish
playsewithpan SE_M_FLAME_WHEEL2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 8, 1
waitforvisualfinish
end
WeatherBallWater:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
createsprite gWeatherBallWaterDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 50, 10
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 8
createsprite gWeatherBallWaterDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, -20, 20
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 13
createsprite gWeatherBallWaterDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 8, 1
playsewithpan SE_M_GIGA_DRAIN, SOUND_PAN_TARGET
waitforvisualfinish
end
WeatherBallSandstorm:
loadspritegfx ANIM_TAG_ROCKS
createsprite gWeatherBallRockDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 30, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 5
createsprite gWeatherBallRockDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, -40, 20
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
delay 14
createsprite gWeatherBallRockDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 1, 0, 0
playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET
waitforvisualfinish
playsewithpan SE_M_STRENGTH, SOUND_PAN_TARGET
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -12, 27, 2, 3
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 8, 28, 3, 4
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, -4, 30, 2, 3
createsprite gRockScatterSpriteTemplate, ANIM_TARGET, 2, 12, 25, 4, 4
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
waitforvisualfinish
end
WeatherBallIce:
loadspritegfx ANIM_TAG_HAIL
loadspritegfx ANIM_TAG_ICE_CRYSTALS
createsprite gWeatherBallIceDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 25, -40, 20
playsewithpan SE_M_HAIL, SOUND_PAN_TARGET
delay 10
createsprite gWeatherBallIceDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 25, 40, 0
playsewithpan SE_M_HAIL, SOUND_PAN_TARGET
delay 10
createsprite gWeatherBallIceDownSpriteTemplate, ANIM_TARGET, 2, -30, -100, 25, 25, 0, 0
playsewithpan SE_M_HAIL, SOUND_PAN_TARGET
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
call IceCrystalEffectShort
waitforvisualfinish
end
Move_COUNT:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
IceCrystalEffectShort:
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -10, -10, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 10, 20, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -5, 10, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 17, -12, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, -15, 15, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, 20, 2, 0
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
return
IceCrystalEffectLong:
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -10, -10, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 10, 20, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -29, 0, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 29, -20, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -5, 10, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 17, -12, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, -20, 0, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, -15, 15, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 26, -5, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitSmallSpriteTemplate, ANIM_TARGET, 2, 0, 0, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
delay 4
createsprite gIceCrystalHitLargeSpriteTemplate, ANIM_TARGET, 2, 20, 2, 1
playsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET
return
IceSpikesEffectShort: @ Unused
loopsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET, 6, 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 0, 24, 0
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 8, 24, 0
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -8, 24, 0
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 16, 24, 0
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -16, 24, 0
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 24, 24, 0
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -24, 24, 0
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 32, 24, 0
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -32, 24, 0
return
IceSpikesEffectLong:
loopsewithpan SE_M_ICY_WIND, SOUND_PAN_TARGET, 6, 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 0, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 8, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -8, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 16, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -16, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 24, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -24, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 32, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -32, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 40, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -40, 24, 1
delay 4
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, 48, 24, 1
createsprite gIceGroundSpikeSpriteTemplate, ANIM_TARGET, 2, -48, 24, 1
return
GrantingStarsEffect:
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, -15, 0, 0, 0, 32, 60
delay 8
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 2, 12, -5, 0, 0, 32, 60
delay 8
return
HealingEffect:
playsewithpan SE_M_ABSORB_2, SOUND_PAN_ATTACKER
createsprite gHealingBlueStarSpriteTemplate, ANIM_ATTACKER, 2, 0, -5, 0, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_ATTACKER, 2, -15, 10, 0, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_ATTACKER, 2, -15, -15, 0, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_ATTACKER, 2, 10, -5, 0, 0
delay 7
return
HealingEffect2:
playsewithpan SE_M_ABSORB_2, SOUND_PAN_TARGET
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 0, -5, 1, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, -15, 10, 1, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, -15, -15, 1, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 10, -5, 1, 0
delay 7
return
PoisonBubblesEffect:
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 10, 10, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 6
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 20, -20, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 6
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, -20, 15, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 6
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 0, 0, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 6
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, -20, -20, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
delay 6
createsprite gPoisonBubbleSpriteTemplate, ANIM_TARGET, 2, 16, -8, 0
playsewithpan SE_M_TOXIC, SOUND_PAN_TARGET
return
WaterBubblesEffectShort:
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 20, -20, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, -20, 15, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, -20, -20, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 16, -8, 0
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
return
WaterBubblesEffectLong:
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 10, 10, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, -28, -10, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 20, -20, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, -20, 15, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 27, 8, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, -20, -20, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 6
createsprite gWaterBubbleSpriteTemplate, ANIM_ATTACKER, 2, 16, -8, 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
return
ElectricityEffect:
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 5, 0, 5, 0
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -5, 10, 5, 1
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 15, 20, 5, 2
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -15, -10, 5, 0
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 25, 0, 5, 1
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -8, 8, 5, 2
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 2, -8, 5, 0
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -20, 15, 5, 1
return
ConfusionEffect:
loopsewithpan SE_M_DIZZY_PUNCH, SOUND_PAN_TARGET, 13, 6
createsprite gConfusionDuckSpriteTemplate, ANIM_TARGET, 2, 0, -15, 0, 3, 90
createsprite gConfusionDuckSpriteTemplate, ANIM_TARGET, 2, 0, -15, 51, 3, 90
createsprite gConfusionDuckSpriteTemplate, ANIM_TARGET, 2, 0, -15, 102, 3, 90
createsprite gConfusionDuckSpriteTemplate, ANIM_TARGET, 2, 0, -15, 153, 3, 90
createsprite gConfusionDuckSpriteTemplate, ANIM_TARGET, 2, 0, -15, 204, 3, 90
return
SetPsychicBackground:
fadetobg BG_PSYCHIC
waitbgfadeout
createvisualtask AnimTask_SetPsychicBackground, 5
waitbgfadein
return
UnsetPsychicBackground:
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
return
SetSkyBg:
jumpifcontest SetSkyBgContest
fadetobg BG_SKY
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, -2304, 768, 1, -1
SetSkyBgContinue:
waitbgfadein
return
SetSkyBgContest:
fadetobg BG_SKY_CONTESTS
waitbgfadeout
createvisualtask AnimTask_StartSlidingBg, 5, 2304, 768, 0, -1
goto SetSkyBgContinue
UnsetSkyBg:
restorebg
waitbgfadeout
setarg 7, 0xFFFF
waitbgfadein
return
SetSolarBeamBg:
createvisualtask AnimTask_IsContest, 2
jumprettrue SetSolarBeamBgContest
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse SetSolarBeamBgOpponent
goto SetSolarBeamBgPlayer
SetSolarBeamBgContinue:
waitbgfadein
return
SetSolarBeamBgContest:
fadetobg BG_SOLAR_BEAM_CONTESTS
goto SetSolarBeamBgContinue
SetSolarBeamBgPlayer:
fadetobg BG_SOLAR_BEAM_PLAYER
goto SetSolarBeamBgContinue
SetSolarBeamBgOpponent:
fadetobg BG_SOLAR_BEAM_OPPONENT
goto SetSolarBeamBgContinue
UnsetSolarBeamBg:
restorebg
waitbgfadein
return
Status_Poison:
loopsewithpan SE_M_TOXIC, SOUND_PAN_TARGET, 13, 6
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 18, 2
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 12, RGB(30, 0, 31)
end
Status_Confusion:
loadspritegfx ANIM_TAG_DUCK
call ConfusionEffect
end
Status_Burn:
loadspritegfx ANIM_TAG_SMALL_EMBER
playsewithpan SE_M_FLAME_WHEEL, SOUND_PAN_TARGET
call BurnFlame
call BurnFlame
call BurnFlame
waitforvisualfinish
end
BurnFlame:
createsprite gBurnFlameSpriteTemplate, ANIM_TARGET, 2, -24, 24, 24, 24, 20, 1, 1
delay 4
return
Status_Infatuation:
loadspritegfx ANIM_TAG_MAGENTA_HEART
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 0, 20
delay 15
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, -20, 20
delay 15
playsewithpan SE_M_CHARM, SOUND_PAN_ATTACKER
createsprite gMagentaHeartSpriteTemplate, ANIM_ATTACKER, 3, 20, 20
end
Status_Sleep:
loadspritegfx ANIM_TAG_LETTER_Z
playsewithpan SE_M_SNORE, SOUND_PAN_ATTACKER
createsprite gSleepLetterZSpriteTemplate, ANIM_ATTACKER, 2, 4, -10, 16, 0, 0
delay 30
createsprite gSleepLetterZSpriteTemplate, ANIM_ATTACKER, 2, 4, -10, 16, 0, 0
end
Status_Paralysis:
loadspritegfx ANIM_TAG_SPARK_2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 10, 1
call ElectricityEffect
end
Status_Freeze:
playsewithpan SE_M_ICY_WIND, 0
loadspritegfx ANIM_TAG_ICE_CUBE
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
waitplaysewithpan SE_M_HAIL, SOUND_PAN_TARGET, 17
createvisualtask AnimTask_FrozenIceCube, 2
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Status_Curse:
loadspritegfx ANIM_TAG_GHOSTLY_SPIRIT
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
createsprite gCurseGhostSpriteTemplate, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 14, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
Status_Nightmare:
loadspritegfx ANIM_TAG_DEVIL
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
createsprite gNightmareDevilSpriteTemplate, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 14, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
end
General_CastformChange:
createvisualtask AnimTask_IsMonInvisible, 2
jumpreteq TRUE, CastformChangeSkipAnim
goto CastformChangeContinue
CastformChangeContinue:
monbg ANIM_ATTACKER
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
createvisualtask AnimTask_TransformMon, 2, 1
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
CastformChangeSkipAnim:
createvisualtask AnimTask_CastformGfxDataChange, 2, 1
end
General_StatsChange:
createvisualtask AnimTask_StatsChange, 5
waitforvisualfinish
end
General_SubstituteFade:
monbg ANIM_ATTACKER
createvisualtask AnimTask_SubstituteFadeToInvisible, 5
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 0, 0, 16, RGB_WHITE
waitforvisualfinish
delay 1
clearmonbg ANIM_ATTACKER
delay 2
blendoff
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 0, 0, 0, RGB_WHITE
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, TRUE
end
General_SubstituteAppear:
createvisualtask AnimTask_MonToSubstitute, 2
end
General_PokeblockThrow:
createvisualtask AnimTask_SetAttackerTargetLeftPos, 2, 0
createvisualtask AnimTask_LoadPokeblockGfx, 2
delay 0
waitplaysewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER, 22
createsprite gPokeblockSpriteTemplate, ANIM_TARGET, 3, -18, 12, 0, 32
delay 50
loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_TARGET, 19, 2
createvisualtask AnimTask_SwayMon, 5, 1, 8, 1536, 2, ANIM_TARGET
waitforvisualfinish
createvisualtask AnimTask_FreePokeblockGfx, 2
end
General_ItemKnockoff:
loadspritegfx ANIM_TAG_ITEM_BAG
createsprite gKnockOffItemSpriteTemplate, ANIM_TARGET, 2
end
General_TurnTrap:
createvisualtask AnimTask_GetTrappedMoveAnimId, 5
jumpargeq 0, TRAP_ANIM_FIRE_SPIN, Status_FireSpin
jumpargeq 0, TRAP_ANIM_WHIRLPOOL, Status_Whirlpool
jumpargeq 0, TRAP_ANIM_CLAMP, Status_Clamp
jumpargeq 0, TRAP_ANIM_SAND_TOMB, Status_SandTomb
goto Status_BindWrap
Status_BindWrap:
loadspritegfx ANIM_TAG_TENDRILS
loopsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET, 6, 2
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 4, 0, 16, 0, 1
delay 7
createsprite gConstrictBindingSpriteTemplate, ANIM_TARGET, 2, 0, 8, 1, 1
delay 3
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1
delay 20
setarg 7, 0xFFFF
playsewithpan SE_M_BIND, SOUND_PAN_TARGET
waitforvisualfinish
end
Status_FireSpin:
loadspritegfx ANIM_TAG_SMALL_EMBER
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 30, 1
call FireSpinEffect
call FireSpinEffect
waitforvisualfinish
stopsound
end
Status_Whirlpool:
loadspritegfx ANIM_TAG_WATER_ORB
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
delay 0
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 0, 7, RGB(0, 13, 23)
playsewithpan SE_M_WHIRLPOOL, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 30, 1
call WhirlpoolEffect
call WhirlpoolEffect
delay 12
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 7, 0, RGB(0, 13, 23)
waitforvisualfinish
stopsound
clearmonbg ANIM_DEF_PARTNER
end
Status_Clamp:
loadspritegfx ANIM_TAG_CLAMP
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_VICEGRIP, SOUND_PAN_TARGET
createsprite gClampJawSpriteTemplate, ANIM_ATTACKER, 2, -32, 0, 2, 819, 0, 10
createsprite gClampJawSpriteTemplate, ANIM_ATTACKER, 2, 32, 0, 6, -819, 0, 10
delay 10
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 3, 0, 5, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
waitforvisualfinish
end
Status_SandTomb:
loadspritegfx ANIM_TAG_MUD_SAND
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 0, 7, RGB(19, 17, 0)
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 2, 30, 1
playsewithpan SE_M_SAND_TOMB, SOUND_PAN_TARGET
call SandTombSwirlingDirt
call SandTombSwirlingDirt
delay 22
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_TARGET, 2, 7, 0, RGB(19, 17, 0)
waitforvisualfinish
stopsound
end
General_HeldItemEffect:
loadspritegfx ANIM_TAG_THIN_RING
loadspritegfx ANIM_TAG_SPARKLE_2
delay 0
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_RotateMonToSideAndRestore, 2, 16, 128, ANIM_ATTACKER, 2
waitforvisualfinish
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_RotateMonToSideAndRestore, 2, 16, 128, ANIM_ATTACKER, 2
waitforvisualfinish
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_RotateMonToSideAndRestore, 2, 16, 128, ANIM_ATTACKER, 2
waitforvisualfinish
playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER
call GrantingStarsEffect
waitforvisualfinish
playsewithpan SE_SHINY, SOUND_PAN_ATTACKER
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 3, 7, 0, RGB(17, 31, 25)
createsprite gThinRingExpandingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0
waitforvisualfinish
end
General_SmokeballEscape:
loadspritegfx ANIM_TAG_PINK_CLOUD
monbg ANIM_ATTACKER
setalpha 12, 4
delay 0
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_TARGET, 0, 0, 32, 28, 30
delay 4
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 127, 2, 12, 20, 30
delay 12
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 126, 2, -28, 4, 30
delay 12
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 124, 2, 14, -20, 30
delay 4
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createvisualtask AnimTask_AttackerFadeToInvisible, 2, 2
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 123, 3, 4, 4, 30
delay 14
playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 122, 3, -14, 18, 46
delay 0
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 121, 3, 14, -14, 46
delay 0
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 120, 3, -12, -10, 46
delay 0
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 119, 3, 14, 14, 46
delay 0
createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 118, 3, 0, 0, 46
waitforvisualfinish
clearmonbg ANIM_ATTACKER
invisible ANIM_ATTACKER
delay 0
blendoff
end
General_FocusBand:
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_ATTACKER, 7, 0, 9, RGB_RED
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_SlideMonForFocusBand, 5, 30, 128, 0, 1, 2, 0, 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, F_PAL_ATTACKER, 4, 9, 0, RGB_RED
waitforvisualfinish
delay 6
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 0, 0, 0, 15
end
General_Rain:
loadspritegfx ANIM_TAG_RAIN_DROPS
playsewithpan SE_M_RAIN_DANCE, SOUND_PAN_ATTACKER
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 2, 0, 4, RGB_BLACK
waitforvisualfinish
createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 60
createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 60
delay 50
waitforvisualfinish
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BG | F_PAL_BATTLERS_2, 2, 4, 0, RGB_BLACK
waitforvisualfinish
end
General_Sun:
goto Move_SUNNY_DAY
General_Sandstorm:
goto Move_SANDSTORM
General_Hail:
goto Move_HAIL
General_LeechSeedDrain:
createvisualtask AnimTask_GetBattlersFromArg, 5
delay 0
goto Move_ABSORB
General_MonHit:
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
setalpha 12, 8
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
waitforvisualfinish
clearmonbg ANIM_TARGET
blendoff
end
General_ItemSteal:
loadspritegfx ANIM_TAG_ITEM_BAG
createvisualtask AnimTask_SetAnimAttackerAndTargetForEffectAtk, 2
createvisualtask AnimTask_SetTargetToEffectBattler, 2 @ Redundant with above
delay 1
createsprite gItemStealSpriteTemplate, ANIM_ATTACKER, 2, 0, -5, 10, 2, -1
end
General_SnatchMove:
loadspritegfx ANIM_TAG_ITEM_BAG
createvisualtask AnimTask_SetAnimAttackerAndTargetForEffectTgt, 2
call SnatchMoveTrySwapFromSubstitute
delay 1
createvisualtask AnimTask_SwayMon, 2, 0, 5, 5120, 4, ANIM_TARGET
waitforvisualfinish
createvisualtask AnimTask_IsTargetSameSide, 2
jumpretfalse SnatchOpposingMonMove
goto SnatchPartnerMonMove
SnatchMoveContinue:
waitforvisualfinish
call SnatchMoveTrySwapToSubstitute
end
SnatchOpposingMonMove:
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_SnatchOpposingMonMove, 2
goto SnatchMoveContinue
SnatchPartnerMonMove:
playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
createvisualtask AnimTask_SnatchPartnerMove, 2
goto SnatchMoveContinue
General_FutureSightHit:
createvisualtask AnimTask_SetAnimTargetToBattlerTarget, 2
monbg ANIM_DEF_PARTNER
playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER
call SetPsychicBackground
setalpha 8, 8
playsewithpan SE_M_SUPERSONIC, SOUND_PAN_TARGET
waitplaysewithpan SE_M_SUPERSONIC, SOUND_PAN_TARGET, 8
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 4, 0, 15, 1
createvisualtask AnimTask_ScaleMonAndRestore, 5, -5, -5, 15, ANIM_TARGET, 1
waitforvisualfinish
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 4, 0, 24, 1
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
waitforvisualfinish
delay 1
call UnsetPsychicBackground
end
General_DoomDesireHit:
createvisualtask AnimTask_SetAnimTargetToBattlerTarget, 2
loadspritegfx ANIM_TAG_EXPLOSION
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 0, 16, RGB_WHITE
waitforvisualfinish
delay 10
createvisualtask AnimTask_DoomDesireLightBeam, 5
delay 9
playsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_ATTACKER
delay 9
playsewithpan SE_M_CONFUSE_RAY, 0
delay 9
playsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_TARGET
delay 25
createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 20, 1
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 24, -24, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -16, 16, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, -24, -12, 1, 1
delay 6
playsewithpan SE_M_SELF_DESTRUCT, SOUND_PAN_TARGET
createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 16, 16, 1, 1
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 16, 0, RGB_WHITE
waitforvisualfinish
end
General_FocusPunchSetUp:
loadspritegfx ANIM_TAG_FOCUS_ENERGY
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
call EndureEffect
delay 8
createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 2, 2, 0, 11, RGB_RED
createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 32, 1
call EndureEffect
delay 8
call EndureEffect
waitforvisualfinish
end
General_IngrainHeal:
loadspritegfx ANIM_TAG_ORBS
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_DEF_PARTNER
setalpha 12, 8
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 0, 4, RGB(13, 31, 12)
waitforvisualfinish
delay 3
call AbsorbEffect
waitforvisualfinish
delay 15
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 1, 4, 0, RGB(13, 31, 12)
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
General_WishHeal:
loadspritegfx ANIM_TAG_SPARKLE_2
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 0, 10, RGB_BLACK
waitforvisualfinish
playsewithpan SE_M_MEGA_KICK, SOUND_PAN_ATTACKER
call GrantingStarsEffect
waitforvisualfinish
unloadspritegfx ANIM_TAG_SPARKLE_2
loadspritegfx ANIM_TAG_BLUE_STAR
call HealingEffect
waitforvisualfinish
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG, 3, 10, 0, RGB_BLACK
end
SnatchMoveTrySwapFromSubstitute:
createvisualtask AnimTask_IsAttackerBehindSubstitute, 2
jumprettrue SnatchMoveSwapSubstituteForMon
SnatchMoveTrySwapFromSubstituteEnd:
waitforvisualfinish
return
SnatchMoveSwapSubstituteForMon:
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, TRUE
waitforvisualfinish
goto SnatchMoveTrySwapFromSubstituteEnd
SnatchMoveTrySwapToSubstitute:
createvisualtask AnimTask_IsAttackerBehindSubstitute, 2
jumprettrue SnatchMoveSwapMonForSubstitute
SnatchMoveTrySwapToSubstituteEnd:
waitforvisualfinish
return
SnatchMoveSwapMonForSubstitute:
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE
waitforvisualfinish
goto SnatchMoveTrySwapToSubstituteEnd
@ Healthbox blue flash effect on level up
Special_LevelUp:
playsewithpan SE_EXP_MAX, 0
createvisualtask AnimTask_LoadHealthboxPalsForLevelUp, 2
delay 0
createvisualtask AnimTask_FlashHealthboxOnLevelUp, 5, 0, 0
waitforvisualfinish
createvisualtask AnimTask_FreeHealthboxPalsForLevelUp, 2
end
Special_SwitchOutPlayerMon:
createvisualtask AnimTask_SwitchOutBallEffect, 2
delay 10
createvisualtask AnimTask_SwitchOutShrinkMon, 2
end
Special_SwitchOutOpponentMon:
createvisualtask AnimTask_SwitchOutBallEffect, 2
delay 10
createvisualtask AnimTask_SwitchOutShrinkMon, 2
end
Special_BallThrow:
createvisualtask AnimTask_LoadBallGfx, 2
delay 0
playsewithpan SE_BALL_THROW, 0
createvisualtask AnimTask_ThrowBall, 2
createvisualtask AnimTask_IsBallBlockedByTrainer, 2
jumpreteq -1, BallThrowTrainerBlock
BallThrowEnd:
waitforvisualfinish
createvisualtask AnimTask_FreeBallGfx, 2
end
BallThrowTrainerBlock:
loadspritegfx ANIM_TAG_IMPACT
delay 25
monbg ANIM_DEF_PARTNER
setalpha 12, 8
delay 0
playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -4, -20, ANIM_TARGET, 2
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
goto BallThrowEnd
Special_BallThrowWithTrainer:
createvisualtask AnimTask_LoadBallGfx, 2
delay 0
createvisualtask AnimTask_ThrowBall_StandingTrainer, 2
waitforvisualfinish
createvisualtask AnimTask_FreeBallGfx, 2
end
Special_SubstituteToMon:
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, TRUE
end
Special_MonToSubstitute:
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE
end
`;
moveAnimsContent = `
Move_AEROBLAST:
loadspritegfx ANIM_TAG_AIR_WAVE_2
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
call SetSkyBg
splitbgprio ANIM_TARGET
setalpha 12, 8
call AeroblastBeam
createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 5, 0, 50, 1
call AeroblastBeam
call AeroblastBeam
call AeroblastBeam
call AeroblastBeam
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
delay 0
call UnsetSkyBg
end
AeroblastBeam:
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 0, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 0, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 1, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 1, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 2, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 2, 0
delay 3
playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 14, -12, 0, -12, 15, 3, 0
createsprite gAirWaveCrescentSpriteTemplate, ANIM_ATTACKER, 2, 26, 8, 12, 8, 15, 3, 0
delay 3
return
Move_WATER_GUN:
loadspritegfx ANIM_TAG_SMALL_BUBBLES
loadspritegfx ANIM_TAG_WATER_IMPACT
monbg ANIM_DEF_PARTNER
splitbgprio ANIM_TARGET
setalpha 12, 8
createsprite gWaterGunProjectileSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 40, -25
playsewithpan SE_M_BUBBLE, SOUND_PAN_ATTACKER
waitforvisualfinish
createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 1, 0, 8, 1
createsprite gWaterHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, ANIM_TARGET, 2
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, 0, -15, 0, 15, 55
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 10
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, 15, -20, 0, 15, 50
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
delay 10
createsprite gWaterGunDropletSpriteTemplate, ANIM_ATTACKER, 2, -15, -10, 0, 10, 45
playsewithpan SE_M_CRABHAMMER, SOUND_PAN_TARGET
waitforvisualfinish
clearmonbg ANIM_DEF_PARTNER
blendoff
end
`;
let animTemplates = `
#include "global.h"
#include "battle_anim.h"
#include "palette.h"
#include "random.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimConfusionDuck(struct Sprite *);
static void AnimSimplePaletteBlend(struct Sprite *);
static void AnimSimplePaletteBlend_Step(struct Sprite *);
static void AnimComplexPaletteBlend(struct Sprite *);
static void AnimComplexPaletteBlend_Step1(struct Sprite *);
static void AnimComplexPaletteBlend_Step2(struct Sprite *);
static void AnimCirclingSparkle(struct Sprite *);
static void AnimShakeMonOrBattleTerrain(struct Sprite *);
static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *);
static void AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled(void);
static void AnimHitSplatBasic(struct Sprite *);
static void AnimHitSplatPersistent(struct Sprite *);
static void AnimHitSplatHandleInvert(struct Sprite *);
static void AnimHitSplatRandom(struct Sprite *);
static void AnimHitSplatOnMonEdge(struct Sprite *);
static void AnimCrossImpact(struct Sprite *);
static void AnimFlashingHitSplat(struct Sprite *);
static void AnimFlashingHitSplat_Step(struct Sprite *);
static void AnimConfusionDuck_Step(struct Sprite *);
static void BlendColorCycle(u8, u8, u8);
static void AnimTask_BlendColorCycleLoop(u8);
static void BlendColorCycleExclude(u8, u8, u8);
static void AnimTask_BlendColorCycleExcludeLoop(u8);
static void BlendColorCycleByTag(u8, u8, u8);
static void AnimTask_BlendColorCycleByTagLoop(u8);
static void AnimTask_FlashAnimTagWithColor_Step1(u8);
static void AnimTask_FlashAnimTagWithColor_Step2(u8);
static void AnimTask_ShakeBattleTerrain_Step(u8);
static const union AnimCmd sAnim_ConfusionDuck_0[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(4, 8),
ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
ANIMCMD_FRAME(8, 8),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_ConfusionDuck_1[] =
{
ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
ANIMCMD_FRAME(4, 8),
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_ConfusionDuck[] =
{
sAnim_ConfusionDuck_0,
sAnim_ConfusionDuck_1,
};
const struct SpriteTemplate gConfusionDuckSpriteTemplate =
{
.tileTag = ANIM_TAG_DUCK,
.paletteTag = ANIM_TAG_DUCK,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_ConfusionDuck,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimConfusionDuck,
};
const struct SpriteTemplate gSimplePaletteBlendSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSimplePaletteBlend,
};
const struct SpriteTemplate gComplexPaletteBlendSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimComplexPaletteBlend,
};
static const union AnimCmd sAnim_CirclingSparkle[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_CirclingSparkle[] =
{
sAnim_CirclingSparkle,
};
// Unused
static const struct SpriteTemplate sCirclingSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_4,
.paletteTag = ANIM_TAG_SPARKLE_4,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_CirclingSparkle,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCirclingSparkle,
};
const struct SpriteTemplate gShakeMonOrTerrainSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimShakeMonOrBattleTerrain,
};
static const union AffineAnimCmd sAffineAnim_HitSplat_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HitSplat_1[] =
{
AFFINEANIMCMD_FRAME(0xD8, 0xD8, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HitSplat_2[] =
{
AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HitSplat_3[] =
{
AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_HitSplat[] =
{
sAffineAnim_HitSplat_0,
sAffineAnim_HitSplat_1,
sAffineAnim_HitSplat_2,
sAffineAnim_HitSplat_3,
};
const struct SpriteTemplate gBasicHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatBasic,
};
const struct SpriteTemplate gHandleInvertHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatHandleInvert,
};
const struct SpriteTemplate gWaterHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_WATER_IMPACT,
.paletteTag = ANIM_TAG_WATER_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatBasic,
};
const struct SpriteTemplate gRandomPosHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatRandom,
};
const struct SpriteTemplate gMonEdgeHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatOnMonEdge,
};
const struct SpriteTemplate gCrossImpactSpriteTemplate =
{
.tileTag = ANIM_TAG_CROSS_IMPACT,
.paletteTag = ANIM_TAG_CROSS_IMPACT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCrossImpact,
};
const struct SpriteTemplate gFlashingHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimFlashingHitSplat,
};
const struct SpriteTemplate gPersistHitSplatSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HitSplat,
.callback = AnimHitSplatPersistent,
};
// Moves a spinning duck around the mon's head.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: initial wave offset
// arg 3: wave period (higher means faster wave)
// arg 4: duration
static void AnimConfusionDuck(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->data[1] = -gBattleAnimArgs[3];
sprite->data[4] = 1;
}
else
{
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[4] = 0;
StartSpriteAnim(sprite, 1);
}
sprite->data[3] = gBattleAnimArgs[4];
sprite->callback = AnimConfusionDuck_Step;
sprite->callback(sprite);
}
static void AnimConfusionDuck_Step(struct Sprite *sprite)
{
sprite->x2 = Cos(sprite->data[0], 30);
sprite->y2 = Sin(sprite->data[0], 10);
if ((u16)sprite->data[0] < 128)
sprite->oam.priority = 1;
else
sprite->oam.priority = 3;
sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF;
if (++sprite->data[2] == sprite->data[3])
DestroyAnimSprite(sprite);
}
// Performs a simple color blend on a specified sprite.
// arg 0: palette selector
// arg 1: delay
// arg 2: start blend amount
// arg 3: end blend amount
// arg 4: blend color
static void AnimSimplePaletteBlend(struct Sprite *sprite)
{
u32 selectedPalettes = UnpackSelectedBattlePalettes(gBattleAnimArgs[0]);
BeginNormalPaletteFade(selectedPalettes, gBattleAnimArgs[1], gBattleAnimArgs[2], gBattleAnimArgs[3], gBattleAnimArgs[4]);
sprite->invisible = TRUE;
sprite->callback = AnimSimplePaletteBlend_Step;
}
// Unpacks a bitfield and returns a bitmask of its selected palettes.
// Bits 0-6 of the selector parameter result in the following palettes being selected:
// 0: F_PAL_BG, battle background palettes (BG palettes 1, 2, and 3)
// 1: F_PAL_ATTACKER, gBattleAnimAttacker OBJ palette
// 2: F_PAL_TARGET, gBattleAnimTarget OBJ palette
// 3: F_PAL_ATK_PARTNER, gBattleAnimAttacker partner OBJ palette
// 4: F_PAL_DEF_PARTNER, gBattleAnimTarget partner OBJ palette
// 5: F_PAL_ANIM_1, BG palette 8 (or 14, if in Contest)
// 6: F_PAL_ANIM_2, BG palette 9
u32 UnpackSelectedBattlePalettes(s16 selector)
{
bool8 battleBackground = selector & 1;
bool8 attacker = (selector >> 1) & 1;
bool8 target = (selector >> 2) & 1;
bool8 attackerPartner = (selector >> 3) & 1;
bool8 targetPartner = (selector >> 4) & 1;
bool8 anim1 = (selector >> 5) & 1;
bool8 anim2 = (selector >> 6) & 1;
return GetBattlePalettesMask(battleBackground, attacker, target, attackerPartner, targetPartner, anim1, anim2);
}
static void AnimSimplePaletteBlend_Step(struct Sprite *sprite)
{
if (!gPaletteFade.active)
DestroyAnimSprite(sprite);
}
static void AnimComplexPaletteBlend(struct Sprite *sprite)
{
u32 selectedPalettes;
sprite->data[0] = gBattleAnimArgs[1];
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[2];
sprite->data[3] = gBattleAnimArgs[3];
sprite->data[4] = gBattleAnimArgs[4];
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[6];
sprite->data[7] = gBattleAnimArgs[0];
selectedPalettes = UnpackSelectedBattlePalettes(sprite->data[7]);
BlendPalettes(selectedPalettes, gBattleAnimArgs[4], gBattleAnimArgs[3]);
sprite->invisible = TRUE;
sprite->callback = AnimComplexPaletteBlend_Step1;
}
static void AnimComplexPaletteBlend_Step1(struct Sprite *sprite)
{
u32 selectedPalettes;
if (sprite->data[0] > 0)
{
sprite->data[0]--;
return;
}
if (gPaletteFade.active)
return;
if (sprite->data[2] == 0)
{
sprite->callback = AnimComplexPaletteBlend_Step2;
return;
}
selectedPalettes = UnpackSelectedBattlePalettes(sprite->data[7]);
if (sprite->data[1] & 0x100)
BlendPalettes(selectedPalettes, sprite->data[4], sprite->data[3]);
else
BlendPalettes(selectedPalettes, sprite->data[6], sprite->data[5]);
sprite->data[1] ^= 0x100;
sprite->data[0] = sprite->data[1] & 0xFF;
sprite->data[2]--;
}
static void AnimComplexPaletteBlend_Step2(struct Sprite *sprite)
{
u32 selectedPalettes;
if (!gPaletteFade.active)
{
selectedPalettes = UnpackSelectedBattlePalettes(sprite->data[7]);
BlendPalettes(selectedPalettes, 0, 0);
DestroyAnimSprite(sprite);
}
}
static void AnimCirclingSparkle(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = 0;
sprite->data[1] = 10;
sprite->data[2] = 8;
sprite->data[3] = 40;
sprite->data[4] = 112;
sprite->data[5] = 0;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteInGrowingCircle;
sprite->callback(sprite);
}
// Task data for AnimTask_BlendColorCycle, AnimTask_BlendColorCycleExclude, and AnimTask_BlendColorCycleByTag
#define tPalSelector data[0] // AnimTask_BlendColorCycle
#define tPalTag data[0] // AnimTask_BlendColorCycleByTag
#define tDelay data[1]
#define tNumBlends data[2]
#define tInitialBlendY data[3]
#define tTargetBlendY data[4]
#define tBlendColor data[5]
#define tRestoreBlend data[8]
#define tPalSelectorHi data[9]
#define tPalSelectorLo data[10]
// Blends mon/screen to designated color or back alternately tNumBlends times
// Many uses of this task only set a tNumBlends of 2, which has the effect of blending to a color and back once
void AnimTask_BlendColorCycle(u8 taskId)
{
gTasks[taskId].tPalSelector = gBattleAnimArgs[0];
gTasks[taskId].tDelay = gBattleAnimArgs[1];
gTasks[taskId].tNumBlends = gBattleAnimArgs[2];
gTasks[taskId].tInitialBlendY = gBattleAnimArgs[3];
gTasks[taskId].tTargetBlendY = gBattleAnimArgs[4];
gTasks[taskId].tBlendColor = gBattleAnimArgs[5];
gTasks[taskId].tRestoreBlend = FALSE;
BlendColorCycle(taskId, 0, gTasks[taskId].tTargetBlendY);
gTasks[taskId].func = AnimTask_BlendColorCycleLoop;
}
static void BlendColorCycle(u8 taskId, u8 startBlendAmount, u8 targetBlendAmount)
{
u32 selectedPalettes = UnpackSelectedBattlePalettes(gTasks[taskId].tPalSelector);
BeginNormalPaletteFade(
selectedPalettes,
gTasks[taskId].tDelay,
startBlendAmount,
targetBlendAmount,
gTasks[taskId].tBlendColor);
gTasks[taskId].tNumBlends--;
gTasks[taskId].tRestoreBlend ^= 1;
}
static void AnimTask_BlendColorCycleLoop(u8 taskId)
{
u8 startBlendAmount, targetBlendAmount;
if (!gPaletteFade.active)
{
if (gTasks[taskId].tNumBlends > 0)
{
if (!gTasks[taskId].tRestoreBlend)
{
// Blend to designated color
startBlendAmount = gTasks[taskId].tInitialBlendY;
targetBlendAmount = gTasks[taskId].tTargetBlendY;
}
else
{
// Blend back to original color
startBlendAmount = gTasks[taskId].tTargetBlendY;
targetBlendAmount = gTasks[taskId].tInitialBlendY;
}
if (gTasks[taskId].tNumBlends == 1)
targetBlendAmount = 0;
BlendColorCycle(taskId, startBlendAmount, targetBlendAmount);
}
else
{
DestroyAnimVisualTask(taskId);
}
}
}
// See AnimTask_BlendColorCycle. Same, but excludes Attacker and Target
void AnimTask_BlendColorCycleExclude(u8 taskId)
{
int battler;
u32 selectedPalettes = 0;
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].tDelay = gBattleAnimArgs[1];
gTasks[taskId].tNumBlends = gBattleAnimArgs[2];
gTasks[taskId].tInitialBlendY = gBattleAnimArgs[3];
gTasks[taskId].tTargetBlendY = gBattleAnimArgs[4];
gTasks[taskId].tBlendColor = gBattleAnimArgs[5];
gTasks[taskId].tRestoreBlend = 0;
for (battler = 0; battler < gBattlersCount; battler++)
{
if (battler != gBattleAnimAttacker && battler != gBattleAnimTarget)
selectedPalettes |= 1 << (battler + 16);
}
if (gBattleAnimArgs[0] == 1)
selectedPalettes |= 0xE;
gTasks[taskId].tPalSelectorHi = selectedPalettes >> 16;
gTasks[taskId].tPalSelectorLo = selectedPalettes & 0xFF;
BlendColorCycleExclude(taskId, 0, gTasks[taskId].tTargetBlendY);
gTasks[taskId].func = AnimTask_BlendColorCycleExcludeLoop;
}
static void BlendColorCycleExclude(u8 taskId, u8 startBlendAmount, u8 targetBlendAmount)
{
u32 selectedPalettes = ((u16)gTasks[taskId].tPalSelectorHi << 16) | (u16)gTasks[taskId].tPalSelectorLo;
BeginNormalPaletteFade(
selectedPalettes,
gTasks[taskId].tDelay,
startBlendAmount,
targetBlendAmount,
gTasks[taskId].tBlendColor);
gTasks[taskId].tNumBlends--;
gTasks[taskId].tRestoreBlend ^= 1;
}
static void AnimTask_BlendColorCycleExcludeLoop(u8 taskId)
{
u8 startBlendAmount, targetBlendAmount;
if (!gPaletteFade.active)
{
if (gTasks[taskId].tNumBlends > 0)
{
if (!gTasks[taskId].tRestoreBlend)
{
// Blend to designated color
startBlendAmount = gTasks[taskId].tInitialBlendY;
targetBlendAmount = gTasks[taskId].tTargetBlendY;
}
else
{
// Blend back to original color
startBlendAmount = gTasks[taskId].tTargetBlendY;
targetBlendAmount = gTasks[taskId].tInitialBlendY;
}
if (gTasks[taskId].tNumBlends == 1)
targetBlendAmount = 0;
BlendColorCycleExclude(taskId, startBlendAmount, targetBlendAmount);
}
else
{
DestroyAnimVisualTask(taskId);
}
}
}
// See AnimTask_BlendColorCycle. Same, but selects palette by ANIM_TAG_*
void AnimTask_BlendColorCycleByTag(u8 taskId)
{
gTasks[taskId].tPalTag = gBattleAnimArgs[0];
gTasks[taskId].tDelay = gBattleAnimArgs[1];
gTasks[taskId].tNumBlends = gBattleAnimArgs[2];
gTasks[taskId].tInitialBlendY = gBattleAnimArgs[3];
gTasks[taskId].tTargetBlendY = gBattleAnimArgs[4];
gTasks[taskId].tBlendColor = gBattleAnimArgs[5];
gTasks[taskId].tRestoreBlend = FALSE;
BlendColorCycleByTag(taskId, 0, gTasks[taskId].tTargetBlendY);
gTasks[taskId].func = AnimTask_BlendColorCycleByTagLoop;
}
static void BlendColorCycleByTag(u8 taskId, u8 startBlendAmount, u8 targetBlendAmount)
{
u8 paletteIndex = IndexOfSpritePaletteTag(gTasks[taskId].tPalTag);
BeginNormalPaletteFade(
1 << (paletteIndex + 16),
gTasks[taskId].tDelay,
startBlendAmount,
targetBlendAmount,
gTasks[taskId].tBlendColor);
gTasks[taskId].tNumBlends--;
gTasks[taskId].tRestoreBlend ^= 1;
}
static void AnimTask_BlendColorCycleByTagLoop(u8 taskId)
{
u8 startBlendAmount, targetBlendAmount;
if (!gPaletteFade.active)
{
if (gTasks[taskId].tNumBlends > 0)
{
if (!gTasks[taskId].tRestoreBlend)
{
// Blend to designated color
startBlendAmount = gTasks[taskId].tInitialBlendY;
targetBlendAmount = gTasks[taskId].tTargetBlendY;
}
else
{
// Blend back to original color
startBlendAmount = gTasks[taskId].tTargetBlendY;
targetBlendAmount = gTasks[taskId].tInitialBlendY;
}
if (gTasks[taskId].tNumBlends == 1)
targetBlendAmount = 0;
BlendColorCycleByTag(taskId, startBlendAmount, targetBlendAmount);
}
else
{
DestroyAnimVisualTask(taskId);
}
}
}
#undef tPalSelector
#undef tPalTag
#undef tDelay
#undef tNumBlends
#undef tInitialBlendY
#undef tTargetBlendY
#undef tBlendColor
#undef tRestoreBlend
#undef tPalSelectorHi
#undef tPalSelectorLo
// Flashes the specified anim tag with given color. Used e.g. to flash the particles red in Hyper Beam
void AnimTask_FlashAnimTagWithColor(u8 taskId)
{
u8 paletteIndex;
gTasks[taskId].data[0] = gBattleAnimArgs[1];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
gTasks[taskId].data[4] = gBattleAnimArgs[4];
gTasks[taskId].data[5] = gBattleAnimArgs[5];
gTasks[taskId].data[6] = gBattleAnimArgs[6];
gTasks[taskId].data[7] = gBattleAnimArgs[0];
paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
BeginNormalPaletteFade(
1 << (paletteIndex + 16),
0,
gBattleAnimArgs[4],
gBattleAnimArgs[4],
gBattleAnimArgs[3]);
gTasks[taskId].func = AnimTask_FlashAnimTagWithColor_Step1;
}
static void AnimTask_FlashAnimTagWithColor_Step1(u8 taskId)
{
u32 selectedPalettes;
if (gTasks[taskId].data[0] > 0)
{
gTasks[taskId].data[0]--;
return;
}
if (gPaletteFade.active)
return;
if (gTasks[taskId].data[2] == 0)
{
gTasks[taskId].func = AnimTask_FlashAnimTagWithColor_Step2;
return;
}
selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
if (gTasks[taskId].data[1] & 0x100)
{
BeginNormalPaletteFade(
selectedPalettes,
0,
gTasks[taskId].data[4],
gTasks[taskId].data[4],
gTasks[taskId].data[3]);
}
else
{
BeginNormalPaletteFade(
selectedPalettes,
0,
gTasks[taskId].data[6],
gTasks[taskId].data[6],
gTasks[taskId].data[5]);
}
gTasks[taskId].data[1] ^= 0x100;
gTasks[taskId].data[0] = gTasks[taskId].data[1] & 0xFF;
gTasks[taskId].data[2]--;
}
static void AnimTask_FlashAnimTagWithColor_Step2(u8 taskId)
{
u32 selectedPalettes;
if (!gPaletteFade.active)
{
selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
BeginNormalPaletteFade(selectedPalettes, 0, 0, 0, RGB(0, 0, 0));
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_InvertScreenColor(u8 taskId)
{
u32 selectedPalettes = 0;
u8 attackerBattler = gBattleAnimAttacker;
u8 targetBattler = gBattleAnimTarget;
if (gBattleAnimArgs[0] & 0x100)
selectedPalettes = GetBattlePalettesMask(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
if (gBattleAnimArgs[1] & 0x100)
selectedPalettes |= (0x10000 << attackerBattler);
if (gBattleAnimArgs[2] & 0x100)
selectedPalettes |= (0x10000 << targetBattler);
InvertPlttBuffer(selectedPalettes);
DestroyAnimVisualTask(taskId);
}
// Unused
#define tTimer data[0]
#define tLength data[1]
#define tFlagsScenery data[2]
#define tFlagsAttacker data[3]
#define tFlagsTarget data[4]
#define tColorR data[5]
#define tColorG data[6]
#define tColorB data[7]
void AnimTask_TintPalettes(u8 taskId)
{
u8 attackerBattler;
u8 targetBattler;
u8 paletteIndex;
u32 selectedPalettes = 0;
if (gTasks[taskId].tTimer == 0)
{
gTasks[taskId].tFlagsScenery = gBattleAnimArgs[0];
gTasks[taskId].tFlagsAttacker = gBattleAnimArgs[1];
gTasks[taskId].tFlagsTarget = gBattleAnimArgs[2];
gTasks[taskId].tLength = gBattleAnimArgs[3];
gTasks[taskId].tColorR = gBattleAnimArgs[4];
gTasks[taskId].tColorG = gBattleAnimArgs[5];
gTasks[taskId].tColorB = gBattleAnimArgs[6];
}
gTasks[taskId].tTimer++;
attackerBattler = gBattleAnimAttacker;
targetBattler = gBattleAnimTarget;
if (gTasks[taskId].tFlagsScenery & (1 << 8))
selectedPalettes = PALETTES_BG;
if (gTasks[taskId].tFlagsScenery & 1)
{
paletteIndex = IndexOfSpritePaletteTag(gSprites[gHealthboxSpriteIds[attackerBattler]].template->paletteTag);
selectedPalettes |= (1 << paletteIndex) << 16;
}
if (gTasks[taskId].tFlagsAttacker & (1 << 8))
selectedPalettes |= (1 << attackerBattler) << 16;
if (gTasks[taskId].tFlagsTarget & (1 << 8))
selectedPalettes |= (1 << targetBattler) << 16;
TintPlttBuffer(selectedPalettes, gTasks[taskId].tColorR, gTasks[taskId].tColorG, gTasks[taskId].tColorB);
if (gTasks[taskId].tTimer == gTasks[taskId].tLength)
{
UnfadePlttBuffer(selectedPalettes);
DestroyAnimVisualTask(taskId);
}
}
#undef tTimer
#undef tLength
#undef tFlagsScenery
#undef tFlagsAttacker
#undef tFlagsTarget
#undef tColorR
#undef tColorG
#undef tColorB
static void AnimShakeMonOrBattleTerrain(struct Sprite *sprite)
{
u16 var0;
sprite->invisible = TRUE;
sprite->data[0] = -gBattleAnimArgs[0];
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[3] = gBattleAnimArgs[2];
switch (gBattleAnimArgs[3])
{
case 0:
StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_X);
break;
case 1:
StoreSpriteCallbackInData6(sprite, (void *)&gBattle_BG3_Y);
break;
case 2:
StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetX);
break;
default:
StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetY);
break;
}
sprite->data[4] = *(u16 *)(sprite->data[6] | (sprite->data[7] << 16));
sprite->data[5] = gBattleAnimArgs[3];
var0 = sprite->data[5] - 2;
if (var0 < 2)
AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled();
sprite->callback = AnimShakeMonOrBattleTerrain_Step;
}
static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *sprite)
{
u8 i;
u16 var0;
if (sprite->data[3] > 0)
{
sprite->data[3]--;
if (sprite->data[1] > 0)
{
sprite->data[1]--;
}
else
{
sprite->data[1] = sprite->data[2];
*(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) += sprite->data[0];
sprite->data[0] = -sprite->data[0];
}
}
else
{
*(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) = sprite->data[4];
var0 = sprite->data[5] - 2;
if (var0 < 2)
{
for (i = 0; i < gBattlersCount; i++)
gSprites[gBattlerSpriteIds[i]].coordOffsetEnabled = FALSE;
}
DestroyAnimSprite(sprite);
}
}
static void AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled(void)
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = FALSE;
gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = FALSE;
if (gBattleAnimArgs[4] == 2)
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = TRUE;
gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = TRUE;
}
else
{
if (gBattleAnimArgs[4] == 0)
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = TRUE;
else
gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = TRUE;
}
}
// Task data for AnimTask_ShakeBattleTerrain
#define tXOffset data[0]
#define tYOffset data[1]
#define tNumShakes data[2]
#define tTimer data[3]
#define tShakeDelay data[8]
// Can shake battle terrain back and forth on the X or down and back to original pos on Y (cant shake up from orig pos)
// arg0: x offset of shake
// arg1: y offset of shake
// arg2: number of shakes
// arg3: time between shakes
void AnimTask_ShakeBattleTerrain(u8 taskId)
{
gTasks[taskId].tXOffset = gBattleAnimArgs[0];
gTasks[taskId].tYOffset = gBattleAnimArgs[1];
gTasks[taskId].tNumShakes = gBattleAnimArgs[2];
gTasks[taskId].tTimer = gBattleAnimArgs[3];
gTasks[taskId].tShakeDelay = gBattleAnimArgs[3];
gBattle_BG3_X = gBattleAnimArgs[0];
gBattle_BG3_Y = gBattleAnimArgs[1];
gTasks[taskId].func = AnimTask_ShakeBattleTerrain_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeBattleTerrain_Step(u8 taskId)
{
if (gTasks[taskId].tTimer == 0)
{
if (gBattle_BG3_X == gTasks[taskId].tXOffset)
gBattle_BG3_X = -gTasks[taskId].tXOffset;
else
gBattle_BG3_X = gTasks[taskId].tXOffset;
if (gBattle_BG3_Y == -gTasks[taskId].tYOffset)
gBattle_BG3_Y = 0;
else
gBattle_BG3_Y = -gTasks[taskId].tYOffset;
gTasks[taskId].tTimer = gTasks[taskId].tShakeDelay;
if (--gTasks[taskId].tNumShakes == 0)
{
gBattle_BG3_X = 0;
gBattle_BG3_Y = 0;
DestroyAnimVisualTask(taskId);
}
}
else
{
gTasks[taskId].tTimer--;
}
}
#undef tXOffset
#undef tYOffset
#undef tNumShakes
#undef tTimer
#undef tShakeDelay
static void AnimHitSplatBasic(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Same as basic hit splat but takes a length of time to persist for (arg4)
static void AnimHitSplatPersistent(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSpriteAfterTimer);
}
// For paired hit splats whose position is inverted when used by the opponent on the player.
// Used by Twineedle and Spike Cannon
static void AnimHitSplatHandleInvert(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER && !IsContest())
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
AnimHitSplatBasic(sprite);
}
static void AnimHitSplatRandom(struct Sprite *sprite)
{
if (gBattleAnimArgs[1] == -1)
gBattleAnimArgs[1] = Random2() & 3;
StartSpriteAffineAnim(sprite, gBattleAnimArgs[1]);
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->x2 += (Random2() % 48) - 24;
sprite->y2 += (Random2() % 24) - 12;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
static void AnimHitSplatOnMonEdge(struct Sprite *sprite)
{
sprite->data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
sprite->x = gSprites[sprite->data[0]].x + gSprites[sprite->data[0]].x2;
sprite->y = gSprites[sprite->data[0]].y + gSprites[sprite->data[0]].y2;
sprite->x2 = gBattleAnimArgs[1];
sprite->y2 = gBattleAnimArgs[2];
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
static void AnimCrossImpact(struct Sprite *sprite)
{
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[3];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = WaitAnimForDuration;
}
static void AnimFlashingHitSplat(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = AnimFlashingHitSplat_Step;
}
static void AnimFlashingHitSplat_Step(struct Sprite *sprite)
{
sprite->invisible ^= 1;
if (sprite->data[0]++ > 12)
DestroyAnimSprite(sprite);
}
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "palette.h"
#include "random.h"
#include "scanline_effect.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "util.h"
#include "constants/battle.h"
#include "constants/rgb.h"
static void AnimRainDrop(struct Sprite *);
static void AnimRainDrop_Step(struct Sprite *);
static void AnimWaterBubbleProjectile(struct Sprite *);
static void AnimWaterBubbleProjectile_Step1(struct Sprite *);
static void AnimWaterBubbleProjectile_Step2(struct Sprite *);
static void AnimWaterBubbleProjectile_Step3(struct Sprite *);
static void AnimAuroraBeamRings(struct Sprite *);
static void AnimAuroraBeamRings_Step(struct Sprite *);
static void AnimToTargetInSinWave(struct Sprite *);
static void AnimToTargetInSinWave_Step(struct Sprite *);
static void AnimHydroCannonCharge(struct Sprite *);
static void AnimHydroCannonCharge_Step(struct Sprite *);
static void AnimHydroCannonBeam(struct Sprite *);
static void AnimWaterGunDroplet(struct Sprite *);
static void AnimSmallBubblePair(struct Sprite *);
static void AnimSmallBubblePair_Step(struct Sprite *);
static void AnimSmallDriftingBubbles(struct Sprite *);
static void AnimSmallDriftingBubbles_Step(struct Sprite *);
static void AnimSmallWaterOrb(struct Sprite *);
static void AnimWaterSpoutRain(struct Sprite *);
static void AnimWaterSpoutRainHit(struct Sprite *);
static void AnimWaterSportDroplet(struct Sprite *);
static void AnimWaterSportDroplet_Step(struct Sprite *);
static void AnimWaterPulseBubble(struct Sprite *);
static void AnimWaterPulseBubble_Step(struct Sprite *);
static void AnimWaterPulseRingBubble(struct Sprite *);
static void AnimWaterPulseRing_Step(struct Sprite *);
static void AnimTask_RotateAuroraRingColors_Step(u8);
static void AnimTask_RunSinAnimTimer(u8);
static void AnimTask_CreateSurfWave_Step1(u8);
static void AnimTask_CreateSurfWave_Step2(u8);
static void AnimTask_SurfWaveScanlineEffect(u8);
static void AnimTask_WaterSpoutLaunch_Step(u8);
static void AnimTask_WaterSpoutRain_Step(u8);
static u8 GetWaterSpoutPowerForAnim(void);
static void CreateWaterSpoutLaunchDroplets(struct Task *, u8);
static void CreateWaterSpoutRainDroplet(struct Task *, u8);
static void AnimTask_WaterSport_Step(u8);
static void CreateWaterSportDroplet(struct Task *);
static void CreateWaterPulseRingBubbles(struct Sprite *, int, int);
static const u8 sUnusedWater_Gfx[] = INCBIN_U8("graphics/battle_anims/unused/water_gfx.4bpp");
static const u8 sUnusedWater[] = INCBIN_U8("graphics/battle_anims/unused/water.bin");
static const union AnimCmd sAnim_RainDrop[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(8, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(24, 6),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(40, 2),
ANIMCMD_FRAME(48, 2),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_RainDrop[] =
{
sAnim_RainDrop,
};
const struct SpriteTemplate gRainDropSpriteTemplate =
{
.tileTag = ANIM_TAG_RAIN_DROPS,
.paletteTag = ANIM_TAG_RAIN_DROPS,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = sAnims_RainDrop,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRainDrop,
};
static const union AffineAnimCmd sAffineAnim_WaterBubbleProjectile[] =
{
AFFINEANIMCMD_FRAME(0xFFFB, 0xFFFB, 0, 10),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_WaterBubbleProjectile[] =
{
sAffineAnim_WaterBubbleProjectile,
};
static const union AnimCmd sAnim_WaterBubbleProjectile[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_WaterBubbleProjectile[] =
{
sAnim_WaterBubbleProjectile,
};
const struct SpriteTemplate gWaterBubbleProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_BUBBLE,
.paletteTag = ANIM_TAG_BUBBLE,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = sAnims_WaterBubbleProjectile,
.images = NULL,
.affineAnims = sAffineAnims_WaterBubbleProjectile,
.callback = AnimWaterBubbleProjectile,
};
static const union AnimCmd sAnim_AuroraBeamRing_0[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_AuroraBeamRing_1[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_AuroraBeamRing[] =
{
sAnim_AuroraBeamRing_0,
sAnim_AuroraBeamRing_1,
};
static const union AffineAnimCmd sAffineAnim_AuroraBeamRing[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1),
AFFINEANIMCMD_FRAME(0x60, 0x60, 0, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_AuroraBeamRing[] =
{
sAffineAnim_AuroraBeamRing,
};
const struct SpriteTemplate gAuroraBeamRingSpriteTemplate =
{
.tileTag = ANIM_TAG_RAINBOW_RINGS,
.paletteTag = ANIM_TAG_RAINBOW_RINGS,
.oam = &gOamData_AffineDouble_ObjNormal_8x16,
.anims = sAnims_AuroraBeamRing,
.images = NULL,
.affineAnims = sAffineAnims_AuroraBeamRing,
.callback = AnimAuroraBeamRings,
};
static const union AnimCmd sAnim_WaterMudOrb[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(4, 1),
ANIMCMD_FRAME(8, 1),
ANIMCMD_FRAME(12, 1),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gAnims_WaterMudOrb[] =
{
sAnim_WaterMudOrb,
};
const struct SpriteTemplate gHydroPumpOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_WATER_ORB,
.paletteTag = ANIM_TAG_WATER_ORB,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gAnims_WaterMudOrb,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
const struct SpriteTemplate gMudShotOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_BROWN_ORB,
.paletteTag = ANIM_TAG_BROWN_ORB,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gAnims_WaterMudOrb,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
const struct SpriteTemplate gSignalBeamRedOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_GLOWY_RED_ORB,
.paletteTag = ANIM_TAG_GLOWY_RED_ORB,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
const struct SpriteTemplate gSignalBeamGreenOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_GLOWY_GREEN_ORB,
.paletteTag = ANIM_TAG_GLOWY_GREEN_ORB,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
static const union AnimCmd sAnim_FlamethrowerFlame[] =
{
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(48, 2),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_FlamethrowerFlame[] =
{
sAnim_FlamethrowerFlame,
};
const struct SpriteTemplate gFlamethrowerFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlamethrowerFlame,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
const struct SpriteTemplate gPsywaveRingSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_RING,
.paletteTag = ANIM_TAG_BLUE_RING,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gGrowingRingAffineAnimTable,
.callback = AnimToTargetInSinWave,
};
static const union AffineAnimCmd sAffineAnim_HydroCannonCharge[] =
{
AFFINEANIMCMD_FRAME(0x3, 0x3, 10, 50),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 10),
AFFINEANIMCMD_FRAME(0xFFEC, 0xFFEC, -10, 20),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HydroCannonBeam[] =
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_HydroCannonCharge[] =
{
sAffineAnim_HydroCannonCharge,
};
static const union AffineAnimCmd *const sAffineAnims_HydroCannonBeam[] =
{
sAffineAnim_HydroCannonBeam,
};
const struct SpriteTemplate gHydroCannonChargeSpriteTemplate =
{
.tileTag = ANIM_TAG_WATER_ORB,
.paletteTag = ANIM_TAG_WATER_ORB,
.oam = &gOamData_AffineDouble_ObjBlend_16x16,
.anims = gAnims_WaterMudOrb,
.images = NULL,
.affineAnims = sAffineAnims_HydroCannonCharge,
.callback = AnimHydroCannonCharge,
};
const struct SpriteTemplate gHydroCannonBeamSpriteTemplate =
{
.tileTag = ANIM_TAG_WATER_ORB,
.paletteTag = ANIM_TAG_WATER_ORB,
.oam = &gOamData_AffineDouble_ObjBlend_16x16,
.anims = gAnims_WaterMudOrb,
.images = NULL,
.affineAnims = sAffineAnims_HydroCannonBeam,
.callback = AnimHydroCannonBeam,
};
static const union AnimCmd sAnim_WaterBubble[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_WaterGunDroplet[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
const union AnimCmd *const gAnims_WaterBubble[] =
{
sAnim_WaterBubble,
};
static const union AnimCmd *const sAnims_WaterGunDroplet[] =
{
sAnim_WaterGunDroplet,
};
const struct SpriteTemplate gWaterGunProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gAnims_WaterBubble,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThrowProjectile,
};
const struct SpriteTemplate gWaterGunDropletSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineDouble_ObjBlend_16x16,
.anims = sAnims_WaterGunDroplet,
.images = NULL,
.affineAnims = gAffineAnims_Droplet,
.callback = AnimWaterGunDroplet,
};
const struct SpriteTemplate gSmallBubblePairSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS, // ice_crystals_4, which are bubbles
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gAnims_SmallBubblePair,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSmallBubblePair,
};
const struct SpriteTemplate gSmallDriftingBubblesSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSmallDriftingBubbles,
};
// Used by Water Spout / Water Sport
const struct SpriteTemplate gSmallWaterOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_GLOWY_BLUE_ORB,
.paletteTag = ANIM_TAG_GLOWY_BLUE_ORB,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSmallWaterOrb,
};
static const union AnimCmd sAnim_WaterPulseBubble_0[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_WaterPulseBubble_1[] =
{
ANIMCMD_FRAME(9, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_WeatherBallWaterDown[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_WaterPulseBubble[] =
{
sAnim_WaterPulseBubble_0,
sAnim_WaterPulseBubble_1,
};
static const union AnimCmd *const sAnims_WeatherBallWaterDown[] =
{
sAnim_WeatherBallWaterDown,
};
static const union AffineAnimCmd sAffineAnim_WaterPulseRingBubble_0[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 15),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_WaterPulseRingBubble_1[] =
{
AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 15),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_WeatherBallWaterDown[] =
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 15),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_WaterPulseRingBubble[] =
{
sAffineAnim_WaterPulseRingBubble_0,
sAffineAnim_WaterPulseRingBubble_1,
};
static const union AffineAnimCmd *const sAffineAnims_WeatherBallWaterDown[] =
{
sAffineAnim_WeatherBallWaterDown,
};
const struct SpriteTemplate gWaterPulseBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = sAnims_WaterPulseBubble,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWaterPulseBubble,
};
const struct SpriteTemplate gWaterPulseRingBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineNormal_ObjNormal_8x8,
.anims = sAnims_WaterPulseBubble,
.images = NULL,
.affineAnims = sAffineAnims_WaterPulseRingBubble,
.callback = AnimWaterPulseRingBubble,
};
const struct SpriteTemplate gWeatherBallWaterDownSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = sAnims_WeatherBallWaterDown,
.images = NULL,
.affineAnims = sAffineAnims_WeatherBallWaterDown,
.callback = AnimWeatherBallDown,
};
void AnimTask_CreateRaindrops(u8 taskId)
{
u8 x, y;
if (gTasks[taskId].data[0] == 0)
{
gTasks[taskId].data[1] = gBattleAnimArgs[0];
gTasks[taskId].data[2] = gBattleAnimArgs[1];
gTasks[taskId].data[3] = gBattleAnimArgs[2];
}
gTasks[taskId].data[0]++;
if (gTasks[taskId].data[0] % gTasks[taskId].data[2] == 1)
{
x = Random2() % DISPLAY_WIDTH;
y = Random2() % (DISPLAY_HEIGHT / 2);
CreateSprite(&gRainDropSpriteTemplate, x, y, 4);
}
if (gTasks[taskId].data[0] == gTasks[taskId].data[3])
DestroyAnimVisualTask(taskId);
}
static void AnimRainDrop(struct Sprite *sprite)
{
sprite->callback = AnimRainDrop_Step;
}
static void AnimRainDrop_Step(struct Sprite *sprite)
{
if (++sprite->data[0] <= 13)
{
sprite->x2++;
sprite->y2 += 4;
}
if (sprite->animEnded)
DestroySprite(sprite);
}
// For water bubbles that move to a dest, as in Bubble/Bubblebeam
static void AnimWaterBubbleProjectile(struct Sprite *sprite)
{
u8 spriteId;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->animPaused = TRUE;
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->animPaused = TRUE;
}
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[6];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
spriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy);
sprite->data[5] = spriteId;
sprite->x -= Sin((u8)gBattleAnimArgs[4], gBattleAnimArgs[2]);
sprite->y -= Cos((u8)gBattleAnimArgs[4], gBattleAnimArgs[3]);
gSprites[spriteId].data[0] = gBattleAnimArgs[2];
gSprites[spriteId].data[1] = gBattleAnimArgs[3];
gSprites[spriteId].data[2] = gBattleAnimArgs[5];
gSprites[spriteId].data[3] = (u8)gBattleAnimArgs[4] * 256;
gSprites[spriteId].data[4] = gBattleAnimArgs[6];
sprite->callback = AnimWaterBubbleProjectile_Step1;
sprite->callback(sprite);
}
static void AnimWaterBubbleProjectile_Step1(struct Sprite *sprite)
{
u8 otherSpriteId = sprite->data[5];
u8 timer = gSprites[otherSpriteId].data[4];
u16 trigIndex = gSprites[otherSpriteId].data[3];
sprite->data[0] = 1;
AnimTranslateLinear(sprite);
sprite->x2 += Sin(trigIndex >> 8, gSprites[otherSpriteId].data[0]);
sprite->y2 += Cos(trigIndex >> 8, gSprites[otherSpriteId].data[1]);
gSprites[otherSpriteId].data[3] = trigIndex + gSprites[otherSpriteId].data[2];
if (--timer != 0)
{
gSprites[otherSpriteId].data[4] = timer;
}
else
{
sprite->callback = AnimWaterBubbleProjectile_Step2;
DestroySprite(&gSprites[otherSpriteId]);
}
}
static void AnimWaterBubbleProjectile_Step2(struct Sprite *sprite)
{
sprite->animPaused = FALSE;
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, AnimWaterBubbleProjectile_Step3);
}
static void AnimWaterBubbleProjectile_Step3(struct Sprite *sprite)
{
sprite->data[0] = 10;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
static void AnimAuroraBeamRings(struct Sprite *sprite)
{
s16 unkArg;
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
unkArg = -gBattleAnimArgs[2];
else
unkArg = gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + unkArg;
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
InitAnimLinearTranslation(sprite);
sprite->callback = AnimAuroraBeamRings_Step;
sprite->affineAnimPaused = TRUE;
sprite->callback(sprite);
}
static void AnimAuroraBeamRings_Step(struct Sprite *sprite)
{
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
{
StartSpriteAnim(sprite, 1);
sprite->affineAnimPaused = FALSE;
}
if (AnimTranslateLinear(sprite))
DestroyAnimSprite(sprite);
}
// Updates the palette on the rainbow rings used in Aurora Beam to make them appear to be rotating counterclockwise
void AnimTask_RotateAuroraRingColors(u8 taskId)
{
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[2] = IndexOfSpritePaletteTag(ANIM_TAG_RAINBOW_RINGS) * 16 + 256;
gTasks[taskId].func = AnimTask_RotateAuroraRingColors_Step;
}
static void AnimTask_RotateAuroraRingColors_Step(u8 taskId)
{
int i;
u16 palIndex;
if (++gTasks[taskId].data[10] == 3)
{
u16 rgbBuffer;
gTasks[taskId].data[10] = 0;
palIndex = gTasks[taskId].data[2] + 1;
rgbBuffer = gPlttBufferFaded[palIndex];
for (i = 1; i < 8; i++)
gPlttBufferFaded[palIndex + i - 1] = gPlttBufferFaded[palIndex + i];
gPlttBufferFaded[palIndex + 7] = rgbBuffer;
}
if (++gTasks[taskId].data[11] == gTasks[taskId].data[0])
DestroyAnimVisualTask(taskId);
}
// For animating undulating beam attacks (e.g. Flamethrower, Hydro Pump, Signal Beam)
static void AnimToTargetInSinWave(struct Sprite *sprite)
{
u16 retArg;
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = 30;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->data[5] = 0xD200 / sprite->data[0];
sprite->data[7] = gBattleAnimArgs[3];
retArg = gBattleAnimArgs[7];
if (gBattleAnimArgs[7] > 127)
{
sprite->data[6] = (retArg - 127) * 256;
sprite->data[7] = -sprite->data[7];
}
else
{
sprite->data[6] = retArg * 256;
}
sprite->callback = AnimToTargetInSinWave_Step;
sprite->callback(sprite);
}
static void AnimToTargetInSinWave_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
DestroyAnimSprite(sprite);
sprite->y2 += Sin(sprite->data[6] >> 8, sprite->data[7]);
if ((sprite->data[6] + sprite->data[5]) >> 8 > 127)
{
sprite->data[6] = 0;
sprite->data[7] = -sprite->data[7];
}
else
{
sprite->data[6] += sprite->data[5];
}
}
void AnimTask_StartSinAnimTimer(u8 taskId)
{
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gBattleAnimArgs[7] = 0;
gTasks[taskId].func = AnimTask_RunSinAnimTimer;
}
static void AnimTask_RunSinAnimTimer(u8 taskId)
{
gBattleAnimArgs[7] = (gBattleAnimArgs[7] + 3) & 0xFF;
if (--gTasks[taskId].data[0] == 0)
DestroyAnimVisualTask(taskId);
}
// Flashing blue orbs grow in size near the attacker. First stage of Hydro Cannon
static void AnimHydroCannonCharge(struct Sprite *sprite)
{
u8 priority;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
sprite->y2 = -10;
priority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
if (!IsContest())
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x2 = 10;
sprite->subpriority = priority + 2;
}
else
{
sprite->x2 = -10;
sprite->subpriority = priority - 2;
}
}
else
{
sprite->x2 = -10;
sprite->subpriority = priority + 2;
}
sprite->callback = AnimHydroCannonCharge_Step;
}
static void AnimHydroCannonCharge_Step(struct Sprite *sprite)
{
if (sprite->affineAnimEnded)
DestroyAnimSprite(sprite);
}
// Flashing blue orbs move from the attacker to the target. Second stage of Hydro Cannon
static void AnimHydroCannonBeam(struct Sprite *sprite)
{
bool8 animType;
u8 coordType;
if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
{
gBattleAnimArgs[0] *= -1;
if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_LEFT)
gBattleAnimArgs[0] *= -1;
}
if ((gBattleAnimArgs[5] & 0xFF00) == 0)
animType = TRUE;
else
animType = FALSE;
if ((u8)gBattleAnimArgs[5] == 0)
coordType = BATTLER_COORD_Y_PIC_OFFSET;
else
coordType = BATTLER_COORD_Y;
InitSpritePosToAnimAttacker(sprite, animType);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, coordType) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Water droplet appears and drips down. Used by Water Gun on impact
static void AnimWaterGunDroplet(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
sprite->data[4] = sprite->y + gBattleAnimArgs[4];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimSmallBubblePair(struct Sprite *sprite)
{
if (gBattleAnimArgs[3] != ANIM_ATTACKER)
InitSpritePosToAnimTarget(sprite, TRUE);
else
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[7] = gBattleAnimArgs[2];
sprite->callback = AnimSmallBubblePair_Step;
}
static void AnimSmallBubblePair_Step(struct Sprite *sprite)
{
sprite->data[0] = (sprite->data[0] + 11) & 0xFF;
sprite->x2 = Sin(sprite->data[0], 4);
sprite->data[1] += 48;
sprite->y2 = -(sprite->data[1] >> 8);
if (--sprite->data[7] == -1)
DestroyAnimSprite(sprite);
}
void AnimTask_CreateSurfWave(u8 taskId)
{
struct BattleAnimBgData animBg;
u8 taskId2;
u16 *x;
u16 *y;
x = &gBattle_BG1_X;
y = &gBattle_BG1_Y;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 1);
GetBattleAnimBg1Data(&animBg);
if (!IsContest())
{
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
AnimLoadCompressedBgTilemap(animBg.bgId, gBattleAnimBgTilemap_SurfOpponent);
else
AnimLoadCompressedBgTilemap(animBg.bgId, gBattleAnimBgTilemap_SurfPlayer);
}
else
{
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimBgTilemap_SurfContest, TRUE);
}
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_Surf, animBg.tilesOffset);
if (gBattleAnimArgs[0] == 0)
LoadCompressedPalette(gBattleAnimBgPalette_Surf, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
else
LoadCompressedPalette(gBattleAnimBackgroundImageMuddyWater_Pal, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
taskId2 = CreateTask(AnimTask_SurfWaveScanlineEffect, gTasks[taskId].priority + 1);
gTasks[taskId].data[15] = taskId2;
gTasks[taskId2].data[0] = 0;
gTasks[taskId2].data[1] = 0x1000;
gTasks[taskId2].data[2] = 0x1000;
if (IsContest())
{
*x = -80;
*y = -48;
gTasks[taskId].data[0] = 2;
gTasks[taskId].data[1] = 1;
gTasks[taskId2].data[3] = 0;
}
else if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
{
*x = -224;
*y = 256;
gTasks[taskId].data[0] = 2;
gTasks[taskId].data[1] = -1;
gTasks[taskId2].data[3] = 1;
}
else
{
*x = 0;
*y = -48;
gTasks[taskId].data[0] = -2;
gTasks[taskId].data[1] = 1;
gTasks[taskId2].data[3] = 0;
}
SetGpuReg(REG_OFFSET_BG1HOFS, *x);
SetGpuReg(REG_OFFSET_BG1VOFS, *y);
if (gTasks[taskId2].data[3] == 0)
{
gTasks[taskId2].data[4] = 48;
gTasks[taskId2].data[5] = 112;
}
else
{
gTasks[taskId2].data[4] = 0;
gTasks[taskId2].data[5] = 0;
}
gTasks[taskId].data[6] = 1;
gTasks[taskId].func = AnimTask_CreateSurfWave_Step1;
}
static void AnimTask_CreateSurfWave_Step1(u8 taskId)
{
struct BattleAnimBgData animBg;
u8 i;
u16 rgbBuffer;
u16 *BGptrX = &gBattle_BG1_X;
u16 *BGptrY = &gBattle_BG1_Y;
*BGptrX += gTasks[taskId].data[0];
*BGptrY += gTasks[taskId].data[1];
GetBattleAnimBg1Data(&animBg);
gTasks[taskId].data[2] += gTasks[taskId].data[1];
if (++gTasks[taskId].data[5] == 4)
{
rgbBuffer = gPlttBufferFaded[animBg.paletteId * 16 + 7];
for (i = 6; i != 0; i--)
{
gPlttBufferFaded[animBg.paletteId * 16 + 1 + i] = gPlttBufferFaded[animBg.paletteId * 16 + 1 + i - 1]; // 1 + i - 1 is needed to match for some bizarre reason
}
gPlttBufferFaded[animBg.paletteId * 16 + 1] = rgbBuffer;
gTasks[taskId].data[5] = 0;
}
if (++gTasks[taskId].data[6] > 1)
{
gTasks[taskId].data[6] = 0;
if (++gTasks[taskId].data[3] <= 13)
{
gTasks[gTasks[taskId].data[15]].data[1] = (s16)((gTasks[taskId].data[3]) | ((16 - gTasks[taskId].data[3]) << 8));
gTasks[taskId].data[4]++;
}
if (gTasks[taskId].data[3] > 54)
{
gTasks[taskId].data[4]--;
gTasks[gTasks[taskId].data[15]].data[1] = (s16)((gTasks[taskId].data[4]) | ((16 - gTasks[taskId].data[4]) << 8));
}
}
if (!(gTasks[gTasks[taskId].data[15]].data[1] & 0x1F))
{
gTasks[taskId].data[0] = gTasks[gTasks[taskId].data[15]].data[1] & 0x1F;
gTasks[taskId].func = AnimTask_CreateSurfWave_Step2;
}
}
static void AnimTask_CreateSurfWave_Step2(u8 taskId)
{
u16 *BGptrX = &gBattle_BG1_X;
u16 *BGptrY = &gBattle_BG1_Y;
if (gTasks[taskId].data[0] == 0)
{
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
gTasks[taskId].data[0]++;
}
else
{
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
*BGptrX = 0;
*BGptrY = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
gTasks[gTasks[taskId].data[15]].data[15] = -1;
DestroyAnimVisualTask(taskId);
}
}
static void AnimTask_SurfWaveScanlineEffect(u8 taskId)
{
s16 i;
struct ScanlineEffectParams params;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
for (i = 0; i < task->data[4]; i++)
gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[1][i] = task->data[2];
for (i = task->data[4]; i < task->data[5]; i++)
gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[1][i] = task->data[1];
for (i = task->data[5]; i < 160; i++)
gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[1][i] = task->data[2];
if (task->data[4] == 0)
gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[1][i] = task->data[1];
else
gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[1][i] = task->data[2];
params.dmaDest = &REG_BLDALPHA;
params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
params.initState = 1;
params.unused9 = 0;
ScanlineEffect_SetParams(params);
task->data[0]++;
break;
case 1:
if (task->data[3] == 0)
{
if (--task->data[4] <= 0)
{
task->data[4] = 0;
task->data[0]++;
}
}
else if (++task->data[5] > 111)
{
task->data[0]++;
}
for (i = 0; i < task->data[4]; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[2];
for (i = task->data[4]; i < task->data[5]; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[1];
for (i = task->data[5]; i < 160; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[2];
break;
case 2:
for (i = 0; i < task->data[4]; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[2];
for (i = task->data[4]; i < task->data[5]; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[1];
for (i = task->data[5]; i < 160; i++)
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[2];
if (task->data[15] == -1)
{
ScanlineEffect_Stop();
DestroyTask(taskId);
}
break;
}
}
static void AnimSmallDriftingBubbles(struct Sprite *sprite)
{
s16 randData;
s16 randData2;
sprite->oam.tileNum += 8;
InitSpritePosToAnimTarget(sprite, TRUE);
randData = (Random2() & 0xFF) | 256;
randData2 = (Random2() & 0x1FF);
if (randData2 > 255)
randData2 = 256 - randData2;
sprite->data[1] = randData;
sprite->data[2] = randData2;
sprite->callback = AnimSmallDriftingBubbles_Step;
}
static void AnimSmallDriftingBubbles_Step(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
if (sprite->data[1] & 1)
sprite->x2 = -(sprite->data[3] >> 8);
else
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
if (++sprite->data[0] == 21)
DestroyAnimSprite(sprite);
}
void AnimTask_WaterSpoutLaunch(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[5] = gSprites[task->data[15]].y;
task->data[1] = GetWaterSpoutPowerForAnim();
PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL);
task->func = AnimTask_WaterSpoutLaunch_Step;
}
static void AnimTask_WaterSpoutLaunch_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
PrepareEruptAnimTaskData(task, task->data[15], 0x100, 0x100, 0xE0, 0x200, 32);
task->data[0]++;
case 1:
if (++task->data[3] > 1)
{
task->data[3] = 0;
if (++task->data[4] & 1)
{
gSprites[task->data[15]].x2 = 3;
gSprites[task->data[15]].y++;
}
else
{
gSprites[task->data[15]].x2 = -3;
}
}
if (UpdateEruptAnimTask(task) == 0)
{
SetBattlerSpriteYOffsetFromYScale(task->data[15]);
gSprites[task->data[15]].x2 = 0;
task->data[3] = 0;
task->data[4] = 0;
task->data[0]++;
}
break;
case 2:
if (++task->data[3] > 4)
{
PrepareEruptAnimTaskData(task, task->data[15], 0xE0, 0x200, 0x180, 0xE0, 8);
task->data[3] = 0;
task->data[0]++;
}
break;
case 3:
if (UpdateEruptAnimTask(task) == 0)
{
task->data[3] = 0;
task->data[4] = 0;
task->data[0]++;
}
break;
case 4:
CreateWaterSpoutLaunchDroplets(task, taskId);
task->data[0]++;
case 5:
if (++task->data[3] > 1)
{
task->data[3] = 0;
if (++task->data[4] & 1)
gSprites[task->data[15]].y2 += 2;
else
gSprites[task->data[15]].y2 -= 2;
if (task->data[4] == 10)
{
PrepareEruptAnimTaskData(task, task->data[15], 0x180, 0xE0, 0x100, 0x100, 8);
task->data[3] = 0;
task->data[4] = 0;
task->data[0]++;
}
}
break;
case 6:
gSprites[task->data[15]].y--;
if (UpdateEruptAnimTask(task) == 0)
{
ResetSpriteRotScale(task->data[15]);
gSprites[task->data[15]].y = task->data[5];
task->data[4] = 0;
task->data[0]++;
}
break;
case 7:
if (task->data[2] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
// Returns a value 0-3 relative to which quarter HP the attacker is in
// A higher number results in more water sprites during the Water Spout animation
static u8 GetWaterSpoutPowerForAnim(void)
{
u8 i;
u16 hp;
u16 maxhp;
u16 partyIndex;
struct Pokemon *slot;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
partyIndex = gBattlerPartyIndexes[gBattleAnimAttacker];
slot = &gPlayerParty[partyIndex];
maxhp = GetMonData(slot, MON_DATA_MAX_HP);
hp = GetMonData(slot, MON_DATA_HP);
maxhp /= 4;
}
else
{
partyIndex = gBattlerPartyIndexes[gBattleAnimAttacker];
slot = &gEnemyParty[partyIndex];
maxhp = GetMonData(slot, MON_DATA_MAX_HP);
hp = GetMonData(slot, MON_DATA_HP);
maxhp /= 4;
}
for (i = 0; i < 3; i++)
{
if (hp < maxhp * (i + 1))
return i;
}
return 3;
}
static void CreateWaterSpoutLaunchDroplets(struct Task *task, u8 taskId)
{
s16 i;
s16 attackerCoordX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
s16 attackerCoordY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
s16 trigIndex = 172;
u8 subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1;
s16 increment = 4 - task->data[1];
u8 spriteId;
if (increment <= 0)
increment = 1;
for (i = 0; i < 20; i += increment)
{
spriteId = CreateSprite(&gSmallWaterOrbSpriteTemplate, attackerCoordX, attackerCoordY, subpriority);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[1] = i;
gSprites[spriteId].data[2] = attackerCoordX * 16;
gSprites[spriteId].data[3] = attackerCoordY * 16;
gSprites[spriteId].data[4] = Cos(trigIndex, 64);
gSprites[spriteId].data[5] = Sin(trigIndex, 64);
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 2;
if (task->data[2] & 1)
AnimSmallWaterOrb(&gSprites[spriteId]);
task->data[2]++;
}
trigIndex = (trigIndex + increment * 2);
trigIndex &= 0xFF;
}
}
static void AnimSmallWaterOrb(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->data[4] += (sprite->data[1] % 6) * 3;
sprite->data[5] += (sprite->data[1] % 3) * 3;
sprite->data[0]++;
case 1:
sprite->data[2] += sprite->data[4];
sprite->data[3] += sprite->data[5];
sprite->x = sprite->data[2] >> 4;
sprite->y = sprite->data[3] >> 4;
if (sprite->x < -8 || sprite->x > 248 || sprite->y < -8 || sprite->y > 120)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
DestroySprite(sprite);
}
break;
}
}
void AnimTask_WaterSpoutRain(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[1] = GetWaterSpoutPowerForAnim();
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
task->data[4] = 136;
task->data[6] = 40;
}
else
{
task->data[4] = 16;
task->data[6] = 80;
}
task->data[5] = 98;
task->data[7] = task->data[4] + 49;
task->data[12] = task->data[1] * 5 + 5;
task->func = AnimTask_WaterSpoutRain_Step;
}
static void AnimTask_WaterSpoutRain_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 taskId2;
switch (task->data[0])
{
case 0:
if (++task->data[2] > 2)
{
task->data[2] = 0;
CreateWaterSpoutRainDroplet(task, taskId);
}
if (task->data[10] != 0 && task->data[13] == 0)
{
gBattleAnimArgs[0] = ANIM_TARGET;
gBattleAnimArgs[1] = 0;
gBattleAnimArgs[2] = 12;
taskId2 = CreateTask(AnimTask_HorizontalShake, 80);
if (taskId2 != TASK_NONE)
{
gTasks[taskId2].func(taskId2);
gAnimVisualTaskCount++;
}
gBattleAnimArgs[0] = ANIM_DEF_PARTNER;
taskId2 = CreateTask(AnimTask_HorizontalShake, 80);
if (taskId2 != TASK_NONE)
{
gTasks[taskId2].func(taskId2);
gAnimVisualTaskCount++;
}
task->data[13] = 1;
}
if (task->data[11] >= task->data[12])
task->data[0]++;
break;
case 1:
if (task->data[9] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void CreateWaterSpoutRainDroplet(struct Task *task, u8 taskId)
{
u16 yPosArg = ((gSineTable[task->data[8]] + 3) >> 4) + task->data[6];
u8 spriteId = CreateSprite(&gSmallWaterOrbSpriteTemplate, task->data[7], 0, 0);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].callback = AnimWaterSpoutRain;
gSprites[spriteId].data[5] = yPosArg;
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 9;
task->data[9]++;
}
task->data[11]++;
task->data[8] = (task->data[8] + 39) & 0xFF;
task->data[7] = (ISO_RANDOMIZE2(task->data[7]) % task->data[5]) + task->data[4];
}
static void AnimWaterSpoutRain(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->y += 8;
if (sprite->y >= sprite->data[5])
{
gTasks[sprite->data[6]].data[10] = 1;
sprite->data[1] = CreateSprite(&gWaterHitSplatSpriteTemplate, sprite->x, sprite->y, 1);
if (sprite->data[1] != MAX_SPRITES)
{
StartSpriteAffineAnim(&gSprites[sprite->data[1]], 3);
gSprites[sprite->data[1]].data[6] = sprite->data[6];
gSprites[sprite->data[1]].data[7] = sprite->data[7];
gSprites[sprite->data[1]].callback = AnimWaterSpoutRainHit;
}
DestroySprite(sprite);
}
}
}
static void AnimWaterSpoutRainHit(struct Sprite *sprite)
{
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
sprite->invisible ^= 1;
if (++sprite->data[2] == 12)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
}
}
void AnimTask_WaterSport(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
task->data[7] = (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) ? 1 : -1;
if (IsContest())
task->data[7] *= -1;
task->data[5] = task->data[3] + task->data[7] * 8;
task->data[6] = task->data[4] - task->data[7] * 8;
task->data[9] = -32;
task->data[1] = 0;
task->data[0] = 0;
task->func = AnimTask_WaterSport_Step;
}
static void AnimTask_WaterSport_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
CreateWaterSportDroplet(task);
if (task->data[10] != 0)
task->data[0]++;
break;
case 1:
CreateWaterSportDroplet(task);
if (++task->data[1] > 16)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 2:
CreateWaterSportDroplet(task);
task->data[5] += task->data[7] * 6;
if (!(task->data[5] >= -16 && task->data[5] <= 256))
{
if (++task->data[12] > 2)
{
task->data[13] = 1;
task->data[0] = 6;
task->data[1] = 0;
}
else
{
task->data[1] = 0;
task->data[0]++;
}
}
break;
case 3:
CreateWaterSportDroplet(task);
task->data[6] -= task->data[7] * 2;
if (++task->data[1] > 7)
task->data[0]++;
break;
case 4:
CreateWaterSportDroplet(task);
task->data[5] -= task->data[7] * 6;
if (!(task->data[5] >= -16 && task->data[5] <= 256))
{
task->data[12]++;
task->data[1] = 0;
task->data[0]++;
}
break;
case 5:
CreateWaterSportDroplet(task);
task->data[6] -= task->data[7] * 2;
if (++task->data[1] > 7)
task->data[0] = 2;
break;
case 6:
if (task->data[8] == 0)
task->data[0]++;
break;
default:
DestroyAnimVisualTask(taskId);
break;
}
}
static void CreateWaterSportDroplet(struct Task *task)
{
u8 spriteId;
if (++task->data[2] > 1)
{
task->data[2] = 0;
spriteId = CreateSprite(&gSmallWaterOrbSpriteTemplate, task->data[3], task->data[4], 10);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[0] = 16;
gSprites[spriteId].data[2] = task->data[5];
gSprites[spriteId].data[4] = task->data[6];
gSprites[spriteId].data[5] = task->data[9];
InitAnimArcTranslation(&gSprites[spriteId]);
gSprites[spriteId].callback = AnimWaterSportDroplet;
task->data[8]++;
}
}
}
static void AnimWaterSportDroplet(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->data[0] = 6;
sprite->data[2] = (Random2() & 0x1F) - 16 + sprite->x;
sprite->data[4] = (Random2() & 0x1F) - 16 + sprite->y;
sprite->data[5] = ~(Random2() & 7);
InitAnimArcTranslation(sprite);
sprite->callback = AnimWaterSportDroplet_Step;
}
}
static void AnimWaterSportDroplet_Step(struct Sprite *sprite)
{
u16 i;
if (TranslateAnimHorizontalArc(sprite))
{
for (i = 0; i < NUM_TASKS; i++)
{
if (gTasks[i].func == AnimTask_WaterSport_Step)
{
gTasks[i].data[10] = 1;
gTasks[i].data[8]--;
DestroySprite(sprite);
}
}
}
}
static void AnimWaterPulseBubble(struct Sprite *sprite)
{
sprite->x = gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[3] = gBattleAnimArgs[5];
sprite->callback = AnimWaterPulseBubble_Step;
}
static void AnimWaterPulseBubble_Step(struct Sprite *sprite)
{
sprite->data[4] -= sprite->data[0];
sprite->y2 = sprite->data[4] / 10;
sprite->data[5] = (sprite->data[5] + sprite->data[1]) & 0xFF;
sprite->x2 = Sin(sprite->data[5], sprite->data[2]);
if (--sprite->data[3] == 0)
DestroyAnimSprite(sprite);
}
static void AnimWaterPulseRingBubble(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] >> 7;
sprite->y2 = sprite->data[4] >> 7;
if (--sprite->data[0] == 0)
{
FreeSpriteOamMatrix(sprite);
DestroySprite(sprite);
}
}
void AnimWaterPulseRing(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[3] = gBattleAnimArgs[2];
sprite->data[4] = gBattleAnimArgs[3];
sprite->callback = AnimWaterPulseRing_Step;
}
static void AnimWaterPulseRing_Step(struct Sprite *sprite)
{
int xDiff = sprite->data[1] - sprite->x;
int yDiff = sprite->data[2] - sprite->y;
sprite->x2 = (sprite->data[0] * xDiff) / sprite->data[3];
sprite->y2 = (sprite->data[0] * yDiff) / sprite->data[3];
if (++sprite->data[5] == sprite->data[4])
{
sprite->data[5] = 0;
CreateWaterPulseRingBubbles(sprite, xDiff, yDiff);
}
if (sprite->data[3] == sprite->data[0])
DestroyAnimSprite(sprite);
sprite->data[0]++;
}
static void CreateWaterPulseRingBubbles(struct Sprite *sprite, int xDiff, int yDiff)
{
s16 combinedX;
s16 combinedY;
s16 i;
s16 something;
s16 unusedVar = 1; //unusedVar is needed to match
s16 randomSomethingY;
s16 randomSomethingX;
u8 spriteId;
something = sprite->data[0] / 2;
combinedX = sprite->x + sprite->x2;
combinedY = sprite->y + sprite->y2;
if (yDiff < 0)
unusedVar *= -1; //Needed to match
randomSomethingY = yDiff + (Random2() % 10) - 5;
randomSomethingX = -xDiff + (Random2() % 10) - 5;
for (i = 0; i <= 0; i++)
{
spriteId = CreateSprite(&gWaterPulseRingBubbleSpriteTemplate, combinedX, combinedY + something, 130);
gSprites[spriteId].data[0] = 20;
gSprites[spriteId].data[1] = randomSomethingY;
gSprites[spriteId].subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1;
if (randomSomethingX < 0)
gSprites[spriteId].data[2] = -randomSomethingX;
else
gSprites[spriteId].data[2] = randomSomethingX;
}
for (i = 0; i <= 0; i++)
{
spriteId = CreateSprite(&gWaterPulseRingBubbleSpriteTemplate, combinedX, combinedY - something, 130);
gSprites[spriteId].data[0] = 20;
gSprites[spriteId].data[1] = randomSomethingY;
gSprites[spriteId].subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1;
if (randomSomethingX > 0)
gSprites[spriteId].data[2] = -randomSomethingX;
else
gSprites[spriteId].data[2] = randomSomethingX;
}
}
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "bg.h"
#include "contest.h"
#include "data.h"
#include "decompress.h"
#include "dma3.h"
#include "gpu_regs.h"
#include "malloc.h"
#include "palette.h"
#include "pokemon_icon.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "util.h"
#include "constants/battle_anim.h"
#define IS_DOUBLE_BATTLE() ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
extern const struct OamData gOamData_AffineNormal_ObjNormal_64x64;
static void AnimTranslateLinear_WithFollowup_SetCornerVecX(struct Sprite *sprite);
static void AnimFastTranslateLinearWaitEnd(struct Sprite *sprite);
static void AnimThrowProjectile_Step(struct Sprite *sprite);
static void AnimBattlerTrace(struct Sprite *sprite);
static void AnimWeatherBallUp_Step(struct Sprite *sprite);
static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId);
static void AnimTask_BlendPalInAndOutSetup(struct Task *task);
static void AnimTask_AlphaFadeIn_Step(u8 taskId);
static void AnimTask_AttackerPunchWithTrace_Step(u8 taskId);
static void AnimTask_BlendMonInAndOut_Step(u8 taskId);
static bool8 ShouldRotScaleSpeciesBeFlipped(void);
static void CreateBattlerTrace(struct Task *task, u8 taskId);
EWRAM_DATA static union AffineAnimCmd *sAnimTaskAffineAnim = NULL;
static const struct UCoords8 sBattlerCoords[][MAX_BATTLERS_COUNT] =
{
{ // Single battle
{ 72, 80 },
{ 176, 40 },
{ 48, 40 },
{ 112, 80 },
},
{ // Double battle
{ 32, 80 },
{ 200, 40 },
{ 90, 88 },
{ 152, 32 },
},
};
// One entry for each of the four Castform forms.
const struct MonCoords gCastformFrontSpriteCoords[NUM_CASTFORM_FORMS] =
{
[CASTFORM_NORMAL] = { .size = MON_COORDS_SIZE(32, 32), .y_offset = 17 },
[CASTFORM_FIRE] = { .size = MON_COORDS_SIZE(48, 48), .y_offset = 9 },
[CASTFORM_WATER] = { .size = MON_COORDS_SIZE(32, 48), .y_offset = 9 },
[CASTFORM_ICE] = { .size = MON_COORDS_SIZE(64, 48), .y_offset = 8 },
};
static const u8 sCastformElevations[NUM_CASTFORM_FORMS] =
{
[CASTFORM_NORMAL] = 13,
[CASTFORM_FIRE] = 14,
[CASTFORM_WATER] = 13,
[CASTFORM_ICE] = 13,
};
// Y position of the backsprite for each of the four Castform forms.
static const u8 sCastformBackSpriteYCoords[NUM_CASTFORM_FORMS] =
{
[CASTFORM_NORMAL] = 0,
[CASTFORM_FIRE] = 0,
[CASTFORM_WATER] = 0,
[CASTFORM_ICE] = 0,
};
// Placeholders for pokemon sprites to be created for a move animation effect (e.g. Role Play / Snatch)
#define TAG_MOVE_EFFECT_MON_1 55125
#define TAG_MOVE_EFFECT_MON_2 55126
static const struct SpriteTemplate sSpriteTemplates_MoveEffectMons[] =
{
{
.tileTag = TAG_MOVE_EFFECT_MON_1,
.paletteTag = TAG_MOVE_EFFECT_MON_1,
.oam = &gOamData_AffineNormal_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
},
{
.tileTag = TAG_MOVE_EFFECT_MON_2,
.paletteTag = TAG_MOVE_EFFECT_MON_2,
.oam = &gOamData_AffineNormal_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
}
};
static const struct SpriteSheet sSpriteSheets_MoveEffectMons[] =
{
{ gMiscBlank_Gfx, MON_PIC_SIZE, TAG_MOVE_EFFECT_MON_1, },
{ gMiscBlank_Gfx, MON_PIC_SIZE, TAG_MOVE_EFFECT_MON_2, },
};
u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType)
{
u8 retVal;
u16 species;
struct BattleSpriteInfo *spriteInfo;
if (IsContest())
{
if (coordType == BATTLER_COORD_Y_PIC_OFFSET && battlerId == 3)
coordType = BATTLER_COORD_Y;
}
switch (coordType)
{
case BATTLER_COORD_X:
case BATTLER_COORD_X_2:
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x;
break;
case BATTLER_COORD_Y:
retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
break;
case BATTLER_COORD_Y_PIC_OFFSET:
case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT:
default:
if (IsContest())
{
if (gContestResources->moveAnim->hasTargetAnim)
species = gContestResources->moveAnim->targetSpecies;
else
species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
}
}
if (coordType == BATTLER_COORD_Y_PIC_OFFSET)
retVal = GetBattlerSpriteFinal_Y(battlerId, species, TRUE);
else
retVal = GetBattlerSpriteFinal_Y(battlerId, species, FALSE);
break;
}
return retVal;
}
u8 GetBattlerYDelta(u8 battlerId, u16 species)
{
u16 letter;
u32 personality;
struct BattleSpriteInfo *spriteInfo;
u8 ret;
u16 coordSpecies;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER || IsContest())
{
if (species == SPECIES_UNOWN)
{
if (IsContest())
{
if (gContestResources->moveAnim->hasTargetAnim)
personality = gContestResources->moveAnim->targetPersonality;
else
personality = gContestResources->moveAnim->personality;
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
else
personality = gTransformedPersonalities[battlerId];
}
letter = GET_UNOWN_LETTER(personality);
if (!letter)
coordSpecies = species;
else
coordSpecies = letter + SPECIES_UNOWN_B - 1;
ret = gMonBackPicCoords[coordSpecies].y_offset;
}
else if (species == SPECIES_CASTFORM)
{
ret = sCastformBackSpriteYCoords[gBattleMonForms[battlerId]];
}
else if (species > NUM_SPECIES)
{
ret = gMonBackPicCoords[0].y_offset;
}
else
{
ret = gMonBackPicCoords[species].y_offset;
}
}
else
{
if (species == SPECIES_UNOWN)
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
else
personality = gTransformedPersonalities[battlerId];
letter = GET_UNOWN_LETTER(personality);
if (!letter)
coordSpecies = species;
else
coordSpecies = letter + SPECIES_UNOWN_B - 1;
ret = gMonFrontPicCoords[coordSpecies].y_offset;
}
else if (species == SPECIES_CASTFORM)
{
ret = gCastformFrontSpriteCoords[gBattleMonForms[battlerId]].y_offset;
}
else if (species > NUM_SPECIES)
{
ret = gMonFrontPicCoords[0].y_offset;
}
else
{
ret = gMonFrontPicCoords[species].y_offset;
}
}
return ret;
}
u8 GetBattlerElevation(u8 battlerId, u16 species)
{
u8 ret = 0;
if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
{
if (!IsContest())
{
if (species == SPECIES_CASTFORM)
ret = sCastformElevations[gBattleMonForms[battlerId]];
else if (species > NUM_SPECIES)
ret = gEnemyMonElevation[0];
else
ret = gEnemyMonElevation[species];
}
}
return ret;
}
u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3)
{
u16 offset;
u8 y;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER || IsContest())
{
offset = GetBattlerYDelta(battlerId, species);
}
else
{
offset = GetBattlerYDelta(battlerId, species);
offset -= GetBattlerElevation(battlerId, species);
}
y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y;
if (a3)
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
y += 8;
if (y > DISPLAY_HEIGHT - MON_PIC_HEIGHT + 8)
y = DISPLAY_HEIGHT - MON_PIC_HEIGHT + 8;
}
return y;
}
u8 GetBattlerSpriteCoord2(u8 battlerId, u8 coordType)
{
u16 species;
struct BattleSpriteInfo *spriteInfo;
if (coordType == BATTLER_COORD_Y_PIC_OFFSET || coordType == BATTLER_COORD_Y_PIC_OFFSET_DEFAULT)
{
if (IsContest())
{
if (gContestResources->moveAnim->hasTargetAnim)
species = gContestResources->moveAnim->targetSpecies;
else
species = gContestResources->moveAnim->species;
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = gAnimBattlerSpecies[battlerId];
else
species = spriteInfo[battlerId].transformSpecies;
}
if (coordType == BATTLER_COORD_Y_PIC_OFFSET)
return GetBattlerSpriteFinal_Y(battlerId, species, TRUE);
else
return GetBattlerSpriteFinal_Y(battlerId, species, FALSE);
}
else
{
return GetBattlerSpriteCoord(battlerId, coordType);
}
}
u8 GetBattlerSpriteDefault_Y(u8 battlerId)
{
return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET_DEFAULT);
}
u8 GetSubstituteSpriteDefault_Y(u8 battlerId)
{
u16 y;
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 16;
else
y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 17;
return y;
}
u8 GetBattlerYCoordWithElevation(u8 battlerId)
{
u16 species;
u8 y;
struct BattleSpriteInfo *spriteInfo;
y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y);
if (!IsContest())
{
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
}
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
y -= GetBattlerElevation(battlerId, species);
}
return y;
}
u8 GetAnimBattlerSpriteId(u8 animBattler)
{
u8 *sprites;
if (animBattler == ANIM_ATTACKER)
{
if (IsBattlerSpritePresent(gBattleAnimAttacker))
{
sprites = gBattlerSpriteIds;
return sprites[gBattleAnimAttacker];
}
else
{
return SPRITE_NONE;
}
}
else if (animBattler == ANIM_TARGET)
{
if (IsBattlerSpritePresent(gBattleAnimTarget))
{
sprites = gBattlerSpriteIds;
return sprites[gBattleAnimTarget];
}
else
{
return SPRITE_NONE;
}
}
else if (animBattler == ANIM_ATK_PARTNER)
{
if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
return SPRITE_NONE;
else
return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)];
}
else
{
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)];
else
return SPRITE_NONE;
}
}
void StoreSpriteCallbackInData6(struct Sprite *sprite, void (*callback)(struct Sprite *))
{
sprite->data[6] = (u32)(callback) & 0xffff;
sprite->data[7] = (u32)(callback) >> 16;
}
void SetCallbackToStoredInData6(struct Sprite *sprite)
{
u32 callback = (u16)sprite->data[6] | (sprite->data[7] << 16);
sprite->callback = (void (*)(struct Sprite *))callback;
}
// Sprite data for TranslateSpriteInCircle/Ellipse and related
#define sCirclePos data[0]
#define sAmplitude data[1]
#define sCircleSpeed data[2]
#define sDuration data[3]
// TranslateSpriteInGrowingCircle
#define sAmplitudeSpeed data[4]
#define sAmplitudeChange data[5]
// TranslateSpriteInEllipse
#define sAmplitudeX sAmplitude
#define sAmplitudeY data[4]
// TranslateSpriteInLissajousCurve
#define sCirclePosX sCirclePos
#define sCircleSpeedX sCircleSpeed
#define sCirclePosY data[4]
#define sCircleSpeedY data[5]
void TranslateSpriteInCircle(struct Sprite *sprite)
{
if (sprite->sDuration)
{
sprite->x2 = Sin(sprite->sCirclePos, sprite->sAmplitude);
sprite->y2 = Cos(sprite->sCirclePos, sprite->sAmplitude);
sprite->sCirclePos += sprite->sCircleSpeed;
if (sprite->sCirclePos >= 0x100)
sprite->sCirclePos -= 0x100;
else if (sprite->sCirclePos < 0)
sprite->sCirclePos += 0x100;
sprite->sDuration--;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void TranslateSpriteInGrowingCircle(struct Sprite *sprite)
{
if (sprite->sDuration)
{
sprite->x2 = Sin(sprite->sCirclePos, (sprite->sAmplitudeChange >> 8) + sprite->sAmplitude);
sprite->y2 = Cos(sprite->sCirclePos, (sprite->sAmplitudeChange >> 8) + sprite->sAmplitude);
sprite->sCirclePos += sprite->sCircleSpeed;
sprite->sAmplitudeChange += sprite->sAmplitudeSpeed;
if (sprite->sCirclePos >= 0x100)
sprite->sCirclePos -= 0x100;
else if (sprite->sCirclePos < 0)
sprite->sCirclePos += 0x100;
sprite->sDuration--;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
// Unused
// Exact shape depends on arguments. Can move in a figure-8-like pattern, or circular, etc.
static void TranslateSpriteInLissajousCurve(struct Sprite *sprite)
{
if (sprite->sDuration)
{
sprite->x2 = Sin(sprite->sCirclePosX, sprite->sAmplitude);
sprite->y2 = Cos(sprite->sCirclePosY, sprite->sAmplitude);
sprite->sCirclePosX += sprite->sCircleSpeedX;
sprite->sCirclePosY += sprite->sCircleSpeedY;
if (sprite->sCirclePosX >= 0x100)
sprite->sCirclePosX -= 0x100;
else if (sprite->sCirclePosX < 0)
sprite->sCirclePosX += 0x100;
if (sprite->sCirclePosY >= 0x100)
sprite->sCirclePosY -= 0x100;
else if (sprite->sCirclePosY < 0)
sprite->sCirclePosY += 0x100;
sprite->sDuration--;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void TranslateSpriteInEllipse(struct Sprite *sprite)
{
if (sprite->sDuration)
{
sprite->x2 = Sin(sprite->sCirclePos, sprite->sAmplitudeX);
sprite->y2 = Cos(sprite->sCirclePos, sprite->sAmplitudeY);
sprite->sCirclePos += sprite->sCircleSpeed;
if (sprite->sCirclePos >= 0x100)
sprite->sCirclePos -= 0x100;
else if (sprite->sCirclePos < 0)
sprite->sCirclePos += 0x100;
sprite->sDuration--;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
#undef sCirclePos
#undef sAmplitude
#undef sCircleSpeed
#undef sDuration
#undef sAmplitudeSpeed
#undef sAmplitudeChange
#undef sAmplitudeX
#undef sAmplitudeY
#undef sCirclePosX
#undef sCircleSpeedX
#undef sCirclePosY
#undef sCircleSpeedY
// Simply waits until the sprite's data[0] hits zero.
// This is used to let sprite anims or affine anims to run for a designated
// duration.
void WaitAnimForDuration(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
sprite->data[0]--;
else
SetCallbackToStoredInData6(sprite);
}
// Sprite data for ConvertPosDataToTranslateLinearData
#define sStepsX data[0]
#define sStartX data[1]
#define sTargetX data[2]
#define sStartY data[3]
#define sTargetY data[4]
// Sprite data for TranslateSpriteLinear
#define sMoveSteps data[0]
#define sSpeedX data[1]
#define sSpeedY data[2]
// Functionally unused
static void AnimPosToTranslateLinear(struct Sprite *sprite)
{
ConvertPosDataToTranslateLinearData(sprite);
sprite->callback = TranslateSpriteLinear;
sprite->callback(sprite);
}
void ConvertPosDataToTranslateLinearData(struct Sprite *sprite)
{
s16 old;
int xDiff;
if (sprite->sStartX > sprite->sTargetX)
sprite->sStepsX = -sprite->sStepsX;
xDiff = sprite->sTargetX - sprite->sStartX;
old = sprite->sStepsX;
sprite->sMoveSteps = abs(xDiff / sprite->sStepsX);
sprite->sSpeedY = (sprite->sTargetY - sprite->sStartY) / sprite->sMoveSteps;
sprite->sSpeedX = old;
}
void TranslateSpriteLinear(struct Sprite *sprite)
{
if (sprite->sMoveSteps > 0)
{
sprite->sMoveSteps--;
sprite->x2 += sprite->sSpeedX;
sprite->y2 += sprite->sSpeedY;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void TranslateSpriteLinearFixedPoint(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
static void TranslateSpriteLinearFixedPointIconFrame(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
}
else
{
SetCallbackToStoredInData6(sprite);
}
UpdateMonIconFrame(sprite);
}
// Unused
static void TranslateSpriteToBattleTargetPos(struct Sprite *sprite)
{
sprite->sStartX = sprite->x + sprite->x2;
sprite->sStartY = sprite->y + sprite->y2;
sprite->sTargetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->sTargetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = AnimPosToTranslateLinear;
}
// Same as TranslateSpriteLinear but takes an id to specify which sprite to move
void TranslateSpriteLinearById(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
gSprites[sprite->data[3]].x2 += sprite->data[1];
gSprites[sprite->data[3]].y2 += sprite->data[2];
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void TranslateSpriteLinearByIdFixedPoint(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
gSprites[sprite->data[5]].x2 = sprite->data[3] >> 8;
gSprites[sprite->data[5]].y2 = sprite->data[4] >> 8;
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void TranslateSpriteLinearAndFlicker(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
sprite->x2 = sprite->data[2] >> 8;
sprite->data[2] += sprite->data[1];
sprite->y2 = sprite->data[4] >> 8;
sprite->data[4] += sprite->data[3];
if (sprite->data[0] % sprite->data[5] == 0)
{
if (sprite->data[5])
sprite->invisible ^= 1;
}
}
else
{
SetCallbackToStoredInData6(sprite);
}
}
void DestroySpriteAndMatrix(struct Sprite *sprite)
{
FreeSpriteOamMatrix(sprite);
DestroyAnimSprite(sprite);
}
// Unused
static void TranslateSpriteToBattleAttackerPos(struct Sprite *sprite)
{
sprite->sStartX = sprite->x + sprite->x2;
sprite->sStartY = sprite->y + sprite->y2;
sprite->sTargetX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->sTargetY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = AnimPosToTranslateLinear;
}
#undef sStepsX
#undef sStartX
#undef sTargetX
#undef sStartY
#undef sTargetY
// Unused
static void EndUnkPaletteAnim(struct Sprite *sprite)
{
PaletteStruct_ResetById(sprite->data[5]);
DestroySpriteAndMatrix(sprite);
}
void RunStoredCallbackWhenAffineAnimEnds(struct Sprite *sprite)
{
if (sprite->affineAnimEnded)
SetCallbackToStoredInData6(sprite);
}
void RunStoredCallbackWhenAnimEnds(struct Sprite *sprite)
{
if (sprite->animEnded)
SetCallbackToStoredInData6(sprite);
}
void DestroyAnimSpriteAndDisableBlend(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
void DestroyAnimVisualTaskAndDisableBlend(u8 taskId)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
}
void SetSpriteCoordsToAnimAttackerCoords(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
// Sets the initial x offset of the anim sprite depending on the horizontal orientation
// of the two involved mons.
void SetAnimSpriteInitialXOffset(struct Sprite *sprite, s16 xOffset)
{
u16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
u16 targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
if (attackerX > targetX)
{
sprite->x -= xOffset;
}
else if (attackerX < targetX)
{
sprite->x += xOffset;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= xOffset;
else
sprite->x += xOffset;
}
}
void InitAnimArcTranslation(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimLinearTranslation(sprite);
sprite->data[6] = 0x8000 / sprite->data[0];
sprite->data[7] = 0;
}
bool8 TranslateAnimHorizontalArc(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
return TRUE;
sprite->data[7] += sprite->data[6];
sprite->y2 += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]);
return FALSE;
}
bool8 TranslateAnimVerticalArc(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
return TRUE;
sprite->data[7] += sprite->data[6];
sprite->x2 += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]);
return FALSE;
}
void SetSpritePrimaryCoordsFromSecondaryCoords(struct Sprite *sprite)
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
}
void InitSpritePosToAnimTarget(struct Sprite *sprite, bool8 respectMonPicOffsets)
{
// Battle anim sprites are automatically created at the anim target's center, which
// is why there is no else clause for the "respectMonPicOffsets" check.
if (!respectMonPicOffsets)
{
sprite->x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y);
}
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
}
void InitSpritePosToAnimAttacker(struct Sprite *sprite, bool8 respectMonPicOffsets)
{
if (!respectMonPicOffsets)
{
sprite->x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
}
u8 GetBattlerSide(u8 battlerId)
{
return GET_BATTLER_SIDE2(battlerId);
}
u8 GetBattlerPosition(u8 battlerId)
{
return gBattlerPositions[battlerId];
}
u8 GetBattlerAtPosition(u8 position)
{
u8 i;
for (i = 0; i < gBattlersCount; i++)
{
if (gBattlerPositions[i] == position)
break;
}
return i;
}
bool8 IsBattlerSpritePresent(u8 battlerId)
{
if (IsContest())
{
if (gBattleAnimAttacker == battlerId)
return TRUE;
else if (gBattleAnimTarget == battlerId)
return TRUE;
else
return FALSE;
}
else
{
if (gBattlerPositions[battlerId] == 0xff)
{
return FALSE;
}
else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0)
return TRUE;
}
else
{
if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0)
return TRUE;
}
}
return FALSE;
}
bool8 IsDoubleBattle(void)
{
return IS_DOUBLE_BATTLE();
}
#define BG_ANIM_PAL_1 8
#define BG_ANIM_PAL_2 9
#define BG_ANIM_PAL_CONTEST 14
void GetBattleAnimBg1Data(struct BattleAnimBgData *out)
{
if (IsContest())
{
out->bgTiles = gBattleAnimBgTileBuffer;
out->bgTilemap = (u16 *)gBattleAnimBgTilemapBuffer;
out->paletteId = BG_ANIM_PAL_CONTEST;
out->bgId = 1;
out->tilesOffset = 0;
out->unused = 0;
}
else
{
out->bgTiles = gBattleAnimBgTileBuffer;
out->bgTilemap = (u16 *)gBattleAnimBgTilemapBuffer;
out->paletteId = BG_ANIM_PAL_1;
out->bgId = 1;
out->tilesOffset = 0x200;
out->unused = 0;
}
}
void GetBattleAnimBgData(struct BattleAnimBgData *out, u32 bgId)
{
if (IsContest())
{
out->bgTiles = gBattleAnimBgTileBuffer;
out->bgTilemap = (u16 *)gBattleAnimBgTilemapBuffer;
out->paletteId = BG_ANIM_PAL_CONTEST;
out->bgId = 1;
out->tilesOffset = 0;
out->unused = 0;
}
else if (bgId == 1)
{
GetBattleAnimBg1Data(out);
}
else
{
out->bgTiles = gBattleAnimBgTileBuffer;
out->bgTilemap = (u16 *)gBattleAnimBgTilemapBuffer;
out->paletteId = BG_ANIM_PAL_2;
out->bgId = 2;
out->tilesOffset = 0x300;
out->unused = 0;
}
}
void GetBgDataForTransform(struct BattleAnimBgData *out, u8 battlerId)
{
out->bgTiles = gBattleAnimBgTileBuffer;
out->bgTilemap = (u16 *)gBattleAnimBgTilemapBuffer;
if (IsContest())
{
out->paletteId = BG_ANIM_PAL_CONTEST;
out->bgId = 1;
out->tilesOffset = 0;
out->unused = 0;
}
else if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
{
out->paletteId = BG_ANIM_PAL_1;
out->bgId = 1;
out->tilesOffset = 0x200;
out->unused = 0;
}
else
{
out->paletteId = BG_ANIM_PAL_2;
out->bgId = 2;
out->tilesOffset = 0x300;
out->unused = 0;
}
}
void ClearBattleAnimBg(u32 bgId)
{
struct BattleAnimBgData bgAnimData;
GetBattleAnimBgData(&bgAnimData, bgId);
CpuFill32(0, bgAnimData.bgTiles, 0x2000);
LoadBgTiles(bgAnimData.bgId, bgAnimData.bgTiles, 0x2000, bgAnimData.tilesOffset);
FillBgTilemapBufferRect(bgAnimData.bgId, 0, 0, 0, 32, 64, 17);
CopyBgTilemapBufferToVram(bgAnimData.bgId);
}
void AnimLoadCompressedBgGfx(u32 bgId, const u32 *src, u32 tilesOffset)
{
CpuFill32(0, gBattleAnimBgTileBuffer, 0x2000);
LZDecompressWram(src, gBattleAnimBgTileBuffer);
LoadBgTiles(bgId, gBattleAnimBgTileBuffer, 0x2000, tilesOffset);
}
static void InitAnimBgTilemapBuffer(u32 bgId, const void *src)
{
FillBgTilemapBufferRect(bgId, 0, 0, 0, 32, 64, 17);
CopyToBgTilemapBuffer(bgId, src, 0, 0);
}
void AnimLoadCompressedBgTilemap(u32 bgId, const void *src)
{
InitAnimBgTilemapBuffer(bgId, src);
CopyBgTilemapBufferToVram(bgId);
}
void AnimLoadCompressedBgTilemapHandleContest(struct BattleAnimBgData *data, const void *src, bool32 largeScreen)
{
InitAnimBgTilemapBuffer(data->bgId, src);
if (IsContest() == TRUE)
RelocateBattleBgPal(data->paletteId, data->bgTilemap, 0, largeScreen);
CopyBgTilemapBufferToVram(data->bgId);
}
u8 GetBattleBgPaletteNum(void)
{
if (IsContest())
return 1;
else
return 2;
}
void UpdateAnimBg3ScreenSize(bool8 largeScreenSize)
{
if (!largeScreenSize || IsContest())
{
SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 0);
SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 1);
}
else
{
SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 1);
SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 0);
}
}
void Trade_MoveSelectedMonToTarget(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitSpriteDataForLinearTranslation(sprite);
sprite->callback = TranslateSpriteLinearFixedPointIconFrame;
sprite->callback(sprite);
}
void InitSpriteDataForLinearTranslation(struct Sprite *sprite)
{
s16 x = (sprite->data[2] - sprite->data[1]) << 8;
s16 y = (sprite->data[4] - sprite->data[3]) << 8;
sprite->data[1] = x / sprite->data[0];
sprite->data[2] = y / sprite->data[0];
sprite->data[4] = 0;
sprite->data[3] = 0;
}
void InitAnimLinearTranslation(struct Sprite *sprite)
{
int x = sprite->data[2] - sprite->data[1];
int y = sprite->data[4] - sprite->data[3];
bool8 movingLeft = x < 0;
bool8 movingUp = y < 0;
u16 xDelta = abs(x) << 8;
u16 yDelta = abs(y) << 8;
xDelta = xDelta / sprite->data[0];
yDelta = yDelta / sprite->data[0];
if (movingLeft)
xDelta |= 1;
else
xDelta &= ~1;
if (movingUp)
yDelta |= 1;
else
yDelta &= ~1;
sprite->data[1] = xDelta;
sprite->data[2] = yDelta;
sprite->data[4] = 0;
sprite->data[3] = 0;
}
void StartAnimLinearTranslation(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimLinearTranslation(sprite);
sprite->callback = AnimTranslateLinear_WithFollowup;
sprite->callback(sprite);
}
// Unused
static void StartAnimLinearTranslation_SetCornerVecX(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimLinearTranslation(sprite);
sprite->callback = AnimTranslateLinear_WithFollowup_SetCornerVecX;
sprite->callback(sprite);
}
bool8 AnimTranslateLinear(struct Sprite *sprite)
{
u16 v1, v2, x, y;
if (!sprite->data[0])
return TRUE;
v1 = sprite->data[1];
v2 = sprite->data[2];
x = sprite->data[3];
y = sprite->data[4];
x += v1;
y += v2;
if (v1 & 1)
sprite->x2 = -(x >> 8);
else
sprite->x2 = x >> 8;
if (v2 & 1)
sprite->y2 = -(y >> 8);
else
sprite->y2 = y >> 8;
sprite->data[3] = x;
sprite->data[4] = y;
sprite->data[0]--;
return FALSE;
}
void AnimTranslateLinear_WithFollowup(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
SetCallbackToStoredInData6(sprite);
}
// Functionally unused
static void AnimTranslateLinear_WithFollowup_SetCornerVecX(struct Sprite *sprite)
{
AnimSetCenterToCornerVecX(sprite);
if (AnimTranslateLinear(sprite))
SetCallbackToStoredInData6(sprite);
}
void InitAnimLinearTranslationWithSpeed(struct Sprite *sprite)
{
int v1 = abs(sprite->data[2] - sprite->data[1]) << 8;
sprite->data[0] = v1 / sprite->data[0];
InitAnimLinearTranslation(sprite);
}
void InitAnimLinearTranslationWithSpeedAndPos(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimLinearTranslationWithSpeed(sprite);
sprite->callback = AnimTranslateLinear_WithFollowup;
sprite->callback(sprite);
}
static void InitAnimFastLinearTranslation(struct Sprite *sprite)
{
int xDiff = sprite->data[2] - sprite->data[1];
int yDiff = sprite->data[4] - sprite->data[3];
bool8 x_sign = xDiff < 0;
bool8 y_sign = yDiff < 0;
u16 x2 = abs(xDiff) << 4;
u16 y2 = abs(yDiff) << 4;
x2 /= sprite->data[0];
y2 /= sprite->data[0];
if (x_sign)
x2 |= 1;
else
x2 &= ~1;
if (y_sign)
y2 |= 1;
else
y2 &= ~1;
sprite->data[1] = x2;
sprite->data[2] = y2;
sprite->data[4] = 0;
sprite->data[3] = 0;
}
void InitAndRunAnimFastLinearTranslation(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimFastLinearTranslation(sprite);
sprite->callback = AnimFastTranslateLinearWaitEnd;
sprite->callback(sprite);
}
bool8 AnimFastTranslateLinear(struct Sprite *sprite)
{
u16 v1, v2, x, y;
if (!sprite->data[0])
return TRUE;
v1 = sprite->data[1];
v2 = sprite->data[2];
x = sprite->data[3];
y = sprite->data[4];
x += v1;
y += v2;
if (v1 & 1)
sprite->x2 = -(x >> 4);
else
sprite->x2 = x >> 4;
if (v2 & 1)
sprite->y2 = -(y >> 4);
else
sprite->y2 = y >> 4;
sprite->data[3] = x;
sprite->data[4] = y;
sprite->data[0]--;
return FALSE;
}
static void AnimFastTranslateLinearWaitEnd(struct Sprite *sprite)
{
if (AnimFastTranslateLinear(sprite))
SetCallbackToStoredInData6(sprite);
}
void InitAnimFastLinearTranslationWithSpeed(struct Sprite *sprite)
{
int xDiff = abs(sprite->data[2] - sprite->data[1]) << 4;
sprite->data[0] = xDiff / sprite->data[0];
InitAnimFastLinearTranslation(sprite);
}
void InitAnimFastLinearTranslationWithSpeedAndPos(struct Sprite *sprite)
{
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
InitAnimFastLinearTranslationWithSpeed(sprite);
sprite->callback = AnimFastTranslateLinearWaitEnd;
sprite->callback(sprite);
}
void SetSpriteRotScale(u8 spriteId, s16 xScale, s16 yScale, u16 rotation)
{
int i;
struct ObjAffineSrcData src;
struct OamMatrix matrix;
src.xScale = xScale;
src.yScale = yScale;
src.rotation = rotation;
if (ShouldRotScaleSpeciesBeFlipped())
src.xScale = -src.xScale;
i = gSprites[spriteId].oam.matrixNum;
ObjAffineSet(&src, &matrix, 1, 2);
gOamMatrices[i].a = matrix.a;
gOamMatrices[i].b = matrix.b;
gOamMatrices[i].c = matrix.c;
gOamMatrices[i].d = matrix.d;
}
// Pokémon in Contests (except Unown) should be flipped.
static bool8 ShouldRotScaleSpeciesBeFlipped(void)
{
if (IsContest())
{
if (gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].data[2] == SPECIES_UNOWN)
return FALSE;
else
return TRUE;
}
else
{
return FALSE;
}
}
void PrepareBattlerSpriteForRotScale(u8 spriteId, u8 objMode)
{
u8 battlerId = gSprites[spriteId].data[0];
if (IsContest() || IsBattlerSpriteVisible(battlerId))
gSprites[spriteId].invisible = FALSE;
gSprites[spriteId].oam.objMode = objMode;
gSprites[spriteId].affineAnimPaused = TRUE;
if (!IsContest() && !gSprites[spriteId].oam.affineMode)
gSprites[spriteId].oam.matrixNum = gBattleSpritesDataPtr->healthBoxesData[battlerId].matrixNum;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
}
void ResetSpriteRotScale(u8 spriteId)
{
SetSpriteRotScale(spriteId, 0x100, 0x100, 0);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_NORMAL;
gSprites[spriteId].affineAnimPaused = FALSE;
CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
}
// Sets the sprite's y offset equal to the y displacement caused by the
// matrix's rotation.
void SetBattlerSpriteYOffsetFromRotation(u8 spriteId)
{
u16 matrixNum = gSprites[spriteId].oam.matrixNum;
// The "c" component of the battler sprite matrix contains the sine of the rotation angle divided by some scale amount.
s16 c = gOamMatrices[matrixNum].c;
if (c < 0)
c = -c;
gSprites[spriteId].y2 = c >> 3;
}
void TrySetSpriteRotScale(struct Sprite *sprite, bool8 recalcCenterVector, s16 xScale, s16 yScale, u16 rotation)
{
int i;
struct ObjAffineSrcData src;
struct OamMatrix matrix;
if (sprite->oam.affineMode & 1)
{
sprite->affineAnimPaused = TRUE;
if (recalcCenterVector)
CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
src.xScale = xScale;
src.yScale = yScale;
src.rotation = rotation;
if (ShouldRotScaleSpeciesBeFlipped())
src.xScale = -src.xScale;
i = sprite->oam.matrixNum;
ObjAffineSet(&src, &matrix, 1, 2);
gOamMatrices[i].a = matrix.a;
gOamMatrices[i].b = matrix.b;
gOamMatrices[i].c = matrix.c;
gOamMatrices[i].d = matrix.d;
}
}
void ResetSpriteRotScale_PreserveAffine(struct Sprite *sprite)
{
TrySetSpriteRotScale(sprite, TRUE, 0x100, 0x100, 0);
sprite->affineAnimPaused = FALSE;
CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
}
static u16 ArcTan2_(s16 x, s16 y)
{
return ArcTan2(x, y);
}
u16 ArcTan2Neg(s16 x, s16 y)
{
u16 var = ArcTan2_(x, y);
return -var;
}
void SetGrayscaleOrOriginalPalette(u16 paletteNum, bool8 restoreOriginalColor)
{
int i;
struct PlttData *originalColor;
struct PlttData *destColor;
u16 average;
paletteNum *= 16;
if (!restoreOriginalColor)
{
for (i = 0; i < 16; i++)
{
originalColor = (struct PlttData *)&gPlttBufferUnfaded[paletteNum + i];
average = originalColor->r + originalColor->g + originalColor->b;
average /= 3;
destColor = (struct PlttData *)&gPlttBufferFaded[paletteNum + i];
destColor->r = average;
destColor->g = average;
destColor->b = average;
}
}
else
{
CpuCopy32(&gPlttBufferUnfaded[paletteNum], &gPlttBufferFaded[paletteNum], 32);
}
}
u32 GetBattlePalettesMask(bool8 battleBackground, bool8 attacker, bool8 target, bool8 attackerPartner, bool8 targetPartner, bool8 anim1, bool8 anim2)
{
u32 selectedPalettes = 0;
u32 shift;
if (battleBackground)
{
if (!IsContest())
selectedPalettes = 0xe; // Palettes 1, 2, and 3
else
selectedPalettes = 1 << GetBattleBgPaletteNum();
}
if (attacker)
{
shift = gBattleAnimAttacker + 16;
selectedPalettes |= 1 << shift;
}
if (target)
{
shift = gBattleAnimTarget + 16;
selectedPalettes |= 1 << shift;
}
if (attackerPartner)
{
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
{
shift = BATTLE_PARTNER(gBattleAnimAttacker) + 16;
selectedPalettes |= 1 << shift;
}
}
if (targetPartner)
{
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
{
shift = BATTLE_PARTNER(gBattleAnimTarget) + 16;
selectedPalettes |= 1 << shift;
}
}
if (anim1)
{
if (!IsContest())
selectedPalettes |= 1 << BG_ANIM_PAL_1;
else
selectedPalettes |= 1 << BG_ANIM_PAL_CONTEST;
}
if (anim2)
{
if (!IsContest())
selectedPalettes |= 1 << BG_ANIM_PAL_2;
}
return selectedPalettes;
}
u32 GetBattleMonSpritePalettesMask(u8 playerLeft, u8 playerRight, u8 opponentLeft, u8 opponentRight)
{
u32 selectedPalettes = 0;
u32 shift;
if (IsContest())
{
if (playerLeft)
{
selectedPalettes |= 1 << 18;
return selectedPalettes;
}
}
else
{
if (playerLeft)
{
if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
{
selectedPalettes |= 1 << (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) + 16);
}
}
if (playerRight)
{
if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)))
{
shift = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) + 16;
selectedPalettes |= 1 << shift;
}
}
if (opponentLeft)
{
if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)))
{
shift = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT) + 16;
selectedPalettes |= 1 << shift;
}
}
if (opponentRight)
{
if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)))
{
shift = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT) + 16;
selectedPalettes |= 1 << shift;
}
}
}
return selectedPalettes;
}
u8 GetSpritePalIdxByBattler(u8 battler)
{
return battler;
}
// Unused
static u8 GetSpritePalIdxByPosition(u8 position)
{
return GetBattlerAtPosition(position);
}
void AnimSpriteOnMonPos(struct Sprite *sprite)
{
bool8 var;
if (!sprite->data[0])
{
if (!gBattleAnimArgs[3])
var = TRUE;
else
var = FALSE;
if (!gBattleAnimArgs[2])
InitSpritePosToAnimAttacker(sprite, var);
else
InitSpritePosToAnimTarget(sprite, var);
sprite->data[0]++;
}
else if (sprite->animEnded || sprite->affineAnimEnded)
{
DestroySpriteAndMatrix(sprite);
}
}
// Linearly translates a sprite to a target position on the
// other mon's sprite.
// arg 0: initial x offset
// arg 1: initial y offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: duration
// arg 5: lower 8 bits = location on attacking mon, upper 8 bits = location on target mon pick to target
void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite)
{
bool8 respectMonPicOffsets;
u8 coordType;
if (!(gBattleAnimArgs[5] & 0xff00))
respectMonPicOffsets = TRUE;
else
respectMonPicOffsets = FALSE;
if (!(gBattleAnimArgs[5] & 0xff))
coordType = BATTLER_COORD_Y_PIC_OFFSET;
else
coordType = BATTLER_COORD_Y;
InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, coordType) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
void AnimThrowProjectile(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker))
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
sprite->callback = AnimThrowProjectile_Step;
}
static void AnimThrowProjectile_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
void AnimTravelDiagonally(struct Sprite *sprite)
{
bool8 r4;
u8 battlerId, coordType;
if (!gBattleAnimArgs[6])
{
r4 = TRUE;
coordType = BATTLER_COORD_Y_PIC_OFFSET;
}
else
{
r4 = FALSE;
coordType = BATTLER_COORD_Y;
}
if (gBattleAnimArgs[5] == ANIM_ATTACKER)
{
InitSpritePosToAnimAttacker(sprite, r4);
battlerId = gBattleAnimAttacker;
}
else
{
InitSpritePosToAnimTarget(sprite, r4);
battlerId = gBattleAnimTarget;
}
if (GetBattlerSide(gBattleAnimAttacker))
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
InitSpritePosToAnimTarget(sprite, r4);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(battlerId, coordType) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
s16 CloneBattlerSpriteWithBlend(u8 animBattler)
{
u16 i;
u8 spriteId = GetAnimBattlerSpriteId(animBattler);
if (spriteId != SPRITE_NONE)
{
for (i = 0; i < MAX_SPRITES; i++)
{
if (!gSprites[i].inUse)
{
gSprites[i] = gSprites[spriteId];
gSprites[i].oam.objMode = ST_OAM_OBJ_BLEND;
gSprites[i].invisible = FALSE;
return i;
}
}
}
return -1;
}
void DestroySpriteWithActiveSheet(struct Sprite *sprite)
{
sprite->usingSheet = TRUE;
DestroySprite(sprite);
}
// Only used to fade Moonlight moon sprite in
void AnimTask_AlphaFadeIn(u8 taskId)
{
s16 v1 = 0;
s16 v2 = 0;
if (gBattleAnimArgs[2] > gBattleAnimArgs[0])
v2 = 1;
if (gBattleAnimArgs[2] < gBattleAnimArgs[0])
v2 = -1;
if (gBattleAnimArgs[3] > gBattleAnimArgs[1])
v1 = 1;
if (gBattleAnimArgs[3] < gBattleAnimArgs[1])
v1 = -1;
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = gBattleAnimArgs[4];
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = gBattleAnimArgs[0];
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = v2;
gTasks[taskId].data[6] = v1;
gTasks[taskId].data[7] = gBattleAnimArgs[2];
gTasks[taskId].data[8] = gBattleAnimArgs[3];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gBattleAnimArgs[0], gBattleAnimArgs[1]));
gTasks[taskId].func = AnimTask_AlphaFadeIn_Step;
}
static void AnimTask_AlphaFadeIn_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (++task->data[0] > task->data[1])
{
task->data[0] = 0;
if (++task->data[2] & 1)
{
if (task->data[3] != task->data[7])
task->data[3] += task->data[5];
}
else
{
if (task->data[4] != task->data[8])
task->data[4] += task->data[6];
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
if (task->data[3] == task->data[7] && task->data[4] == task->data[8])
{
DestroyAnimVisualTask(taskId);
return;
}
}
}
// Linearly blends a mon's sprite colors with a target color with increasing
// strength, and then blends out to the original color.
// arg 0: anim bank
// arg 1: blend color
// arg 2: target blend coefficient
// arg 3: initial delay
// arg 4: number of times to blend in and out
void AnimTask_BlendMonInAndOut(u8 task)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
{
DestroyAnimVisualTask(task);
return;
}
gTasks[task].data[0] = OBJ_PLTT_ID(gSprites[spriteId].oam.paletteNum) + 1;
AnimTask_BlendPalInAndOutSetup(&gTasks[task]);
}
static void AnimTask_BlendPalInAndOutSetup(struct Task *task)
{
task->data[1] = gBattleAnimArgs[1];
task->data[2] = 0;
task->data[3] = gBattleAnimArgs[2];
task->data[4] = 0;
task->data[5] = gBattleAnimArgs[3];
task->data[6] = 0;
task->data[7] = gBattleAnimArgs[4];
task->func = AnimTask_BlendMonInAndOut_Step;
}
static void AnimTask_BlendMonInAndOut_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (++task->data[4] >= task->data[5])
{
task->data[4] = 0;
if (!task->data[6])
{
task->data[2]++;
BlendPalette(task->data[0], 15, task->data[2], task->data[1]);
if (task->data[2] == task->data[3])
task->data[6] = 1;
}
else
{
task->data[2]--;
BlendPalette(task->data[0], 15, task->data[2], task->data[1]);
if (!task->data[2])
{
if (--task->data[7])
{
task->data[4] = 0;
task->data[6] = 0;
}
else
{
DestroyAnimVisualTask(taskId);
return;
}
}
}
}
}
// See AnimTask_BlendMonInAndOut. Same, but ANIM_TAG_* instead of mon
void AnimTask_BlendPalInAndOutByTag(u8 task)
{
u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
if (palette == 0xff)
{
DestroyAnimVisualTask(task);
return;
}
gTasks[task].data[0] = (palette * 0x10) + 0x101;
AnimTask_BlendPalInAndOutSetup(&gTasks[task]);
}
void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union AffineAnimCmd *affineAnimCmds)
{
task->data[7] = 0;
task->data[8] = 0;
task->data[9] = 0;
task->data[15] = spriteId;
task->data[10] = 0x100;
task->data[11] = 0x100;
task->data[12] = 0;
StorePointerInVars(&task->data[13], &task->data[14], affineAnimCmds);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
}
bool8 RunAffineAnimFromTaskData(struct Task *task)
{
sAnimTaskAffineAnim = &((union AffineAnimCmd *)LoadPointerFromVars(task->data[13], task->data[14]))[task->data[7]];
switch (sAnimTaskAffineAnim->type)
{
default:
if (!sAnimTaskAffineAnim->frame.duration)
{
task->data[10] = sAnimTaskAffineAnim->frame.xScale;
task->data[11] = sAnimTaskAffineAnim->frame.yScale;
task->data[12] = sAnimTaskAffineAnim->frame.rotation;
task->data[7]++;
sAnimTaskAffineAnim++;
}
task->data[10] += sAnimTaskAffineAnim->frame.xScale;
task->data[11] += sAnimTaskAffineAnim->frame.yScale;
task->data[12] += sAnimTaskAffineAnim->frame.rotation;
SetSpriteRotScale(task->data[15], task->data[10], task->data[11], task->data[12]);
SetBattlerSpriteYOffsetFromYScale(task->data[15]);
if (++task->data[8] >= sAnimTaskAffineAnim->frame.duration)
{
task->data[8] = 0;
task->data[7]++;
}
break;
case AFFINEANIMCMDTYPE_JUMP:
task->data[7] = sAnimTaskAffineAnim->jump.target;
break;
case AFFINEANIMCMDTYPE_LOOP:
if (sAnimTaskAffineAnim->loop.count)
{
if (task->data[9])
{
if (!--task->data[9])
{
task->data[7]++;
break;
}
}
else
{
task->data[9] = sAnimTaskAffineAnim->loop.count;
}
if (!task->data[7])
{
break;
}
for (;;)
{
task->data[7]--;
sAnimTaskAffineAnim--;
if (sAnimTaskAffineAnim->type == AFFINEANIMCMDTYPE_LOOP)
{
task->data[7]++;
return TRUE;
}
if (!task->data[7])
return TRUE;
}
}
task->data[7]++;
break;
case AFFINEANIMCMDTYPE_END:
gSprites[task->data[15]].y2 = 0;
ResetSpriteRotScale(task->data[15]);
return FALSE;
}
return TRUE;
}
// Sets the sprite's y offset equal to the y displacement caused by the
// matrix's scale in the y dimension.
void SetBattlerSpriteYOffsetFromYScale(u8 spriteId)
{
int var = MON_PIC_HEIGHT - GetBattlerYDeltaFromSpriteId(spriteId) * 2;
u16 matrix = gSprites[spriteId].oam.matrixNum;
int var2 = SAFE_DIV(var << 8, gOamMatrices[matrix].d);
if (var2 > MON_PIC_HEIGHT * 2)
var2 = MON_PIC_HEIGHT * 2;
gSprites[spriteId].y2 = (var - var2) / 2;
}
// Sets the sprite's y offset equal to the y displacement caused by another sprite
// matrix's scale in the y dimension.
void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId)
{
int var = MON_PIC_HEIGHT - GetBattlerYDeltaFromSpriteId(otherSpriteId) * 2;
u16 matrix = gSprites[spriteId].oam.matrixNum;
int var2 = SAFE_DIV(var << 8, gOamMatrices[matrix].d);
if (var2 > MON_PIC_HEIGHT * 2)
var2 = MON_PIC_HEIGHT * 2;
gSprites[spriteId].y2 = (var - var2) / 2;
}
static u16 GetBattlerYDeltaFromSpriteId(u8 spriteId)
{
struct BattleSpriteInfo *spriteInfo;
u8 battlerId = gSprites[spriteId].data[0];
u16 species;
u16 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (gBattlerSpriteIds[i] == spriteId)
{
if (IsContest())
{
species = gContestResources->moveAnim->species;
return gMonBackPicCoords[species].y_offset;
}
else
{
if (GetBattlerSide(i) == B_SIDE_PLAYER)
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
if (species == SPECIES_CASTFORM)
return sCastformBackSpriteYCoords[gBattleMonForms[battlerId]];
else
return gMonBackPicCoords[species].y_offset;
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
else
species = spriteInfo[battlerId].transformSpecies;
if (species == SPECIES_CASTFORM)
return sCastformElevations[gBattleMonForms[battlerId]];
else
return gMonFrontPicCoords[species].y_offset;
}
}
}
}
return MON_PIC_HEIGHT;
}
void StorePointerInVars(s16 *lo, s16 *hi, const void *ptr)
{
*lo = ((intptr_t) ptr) & 0xffff;
*hi = (((intptr_t) ptr) >> 16) & 0xffff;
}
void *LoadPointerFromVars(s16 lo, s16 hi)
{
return (void *)((u16)lo | ((u16)hi << 16));
}
void PrepareEruptAnimTaskData(struct Task *task, u8 spriteId, s16 xScaleStart, s16 yScaleStart, s16 xScaleEnd, s16 yScaleEnd, u16 duration)
{
task->data[8] = duration;
task->data[15] = spriteId;
task->data[9] = xScaleStart;
task->data[10] = yScaleStart;
task->data[13] = xScaleEnd;
task->data[14] = yScaleEnd;
task->data[11] = (xScaleEnd - xScaleStart) / duration;
task->data[12] = (yScaleEnd - yScaleStart) / duration;
}
u8 UpdateEruptAnimTask(struct Task *task)
{
if (!task->data[8])
return 0;
if (--task->data[8] != 0)
{
task->data[9] += task->data[11];
task->data[10] += task->data[12];
}
else
{
task->data[9] = task->data[13];
task->data[10] = task->data[14];
}
SetSpriteRotScale(task->data[15], task->data[9], task->data[10], 0);
if (task->data[8])
SetBattlerSpriteYOffsetFromYScale(task->data[15]);
else
gSprites[task->data[15]].y2 = 0;
return task->data[8];
}
void AnimTask_GetFrustrationPowerLevel(u8 taskId)
{
u16 powerLevel;
if (gAnimFriendship <= 30)
powerLevel = 0;
else if (gAnimFriendship <= 100)
powerLevel = 1;
else if (gAnimFriendship <= 200)
powerLevel = 2;
else
powerLevel = 3;
gBattleAnimArgs[ARG_RET_ID] = powerLevel;
DestroyAnimVisualTask(taskId);
}
// Unused
static void SetPriorityForVisibleBattlers(u8 priority)
{
if (IsBattlerSpriteVisible(gBattleAnimTarget))
gSprites[gBattlerSpriteIds[gBattleAnimTarget]].oam.priority = priority;
if (IsBattlerSpriteVisible(gBattleAnimAttacker))
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].oam.priority = priority;
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]].oam.priority = priority;
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority = priority;
}
void InitPrioritiesForVisibleBattlers(void)
{
int i;
for (i = 0; i < gBattlersCount; i++)
{
if (IsBattlerSpriteVisible(i))
{
gSprites[gBattlerSpriteIds[i]].subpriority = GetBattlerSpriteSubpriority(i);
gSprites[gBattlerSpriteIds[i]].oam.priority = 2;
}
}
}
u8 GetBattlerSpriteSubpriority(u8 battlerId)
{
u8 position;
u8 subpriority;
if (IsContest())
{
if (battlerId == 2)
return 30;
else
return 40;
}
else
{
position = GetBattlerPosition(battlerId);
if (position == B_POSITION_PLAYER_LEFT)
subpriority = 30;
else if (position == B_POSITION_PLAYER_RIGHT)
subpriority = 20;
else if (position == B_POSITION_OPPONENT_LEFT)
subpriority = 40;
else
subpriority = 50;
}
return subpriority;
}
u8 GetBattlerSpriteBGPriority(u8 battlerId)
{
u8 position = GetBattlerPosition(battlerId);
if (IsContest())
return 2;
else if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT)
return GetAnimBgAttribute(2, BG_ANIM_PRIORITY);
else
return GetAnimBgAttribute(1, BG_ANIM_PRIORITY);
}
u8 GetBattlerSpriteBGPriorityRank(u8 battlerId)
{
if (!IsContest())
{
u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT)
return 2;
else
return 1;
}
return 1;
}
// Create pokemon sprite to be used for a move animation effect (e.g. Role Play / Snatch)
u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId, bool32 ignoreDeoxysForm)
{
u8 spriteId;
u16 sheet = LoadSpriteSheet(&sSpriteSheets_MoveEffectMons[id]);
u16 palette = AllocSpritePalette(sSpriteTemplates_MoveEffectMons[id].paletteTag);
if (gMonSpritesGfxPtr != NULL && gMonSpritesGfxPtr->buffer == NULL)
gMonSpritesGfxPtr->buffer = AllocZeroed(MON_PIC_SIZE * MAX_MON_PIC_FRAMES);
if (!isBackpic)
{
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
if (ignoreDeoxysForm == TRUE || ShouldIgnoreDeoxysForm(5, battlerId) == TRUE || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0)
LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
gMonSpritesGfxPtr->buffer,
species,
personality,
TRUE);
else
LoadSpecialPokePic_2(&gMonFrontPicTable[species],
gMonSpritesGfxPtr->buffer,
species,
personality,
TRUE);
}
else
{
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP);
if (ignoreDeoxysForm == TRUE || ShouldIgnoreDeoxysForm(5, battlerId) == TRUE || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0)
LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species],
gMonSpritesGfxPtr->buffer,
species,
personality,
FALSE);
else
LoadSpecialPokePic_2(&gMonBackPicTable[species],
gMonSpritesGfxPtr->buffer,
species,
personality,
FALSE);
}
RequestDma3Copy(gMonSpritesGfxPtr->buffer, (void *)(OBJ_VRAM0 + (sheet * 0x20)), MON_PIC_SIZE, 1);
FREE_AND_SET_NULL(gMonSpritesGfxPtr->buffer);
if (!isBackpic)
spriteId = CreateSprite(&sSpriteTemplates_MoveEffectMons[id], x, y + gMonFrontPicCoords[species].y_offset, subpriority);
else
spriteId = CreateSprite(&sSpriteTemplates_MoveEffectMons[id], x, y + gMonBackPicCoords[species].y_offset, subpriority);
if (IsContest())
{
gSprites[spriteId].affineAnims = gAffineAnims_BattleSpriteContest;
StartSpriteAffineAnim(&gSprites[spriteId], BATTLER_AFFINE_NORMAL);
}
return spriteId;
}
void DestroySpriteAndFreeResources_(struct Sprite *sprite)
{
DestroySpriteAndFreeResources(sprite);
}
s16 GetBattlerSpriteCoordAttr(u8 battlerId, u8 attr)
{
u16 species;
u32 personality;
u16 letter;
u16 unownSpecies;
int ret;
const struct MonCoords *coords;
struct BattleSpriteInfo *spriteInfo;
if (IsContest())
{
if (gContestResources->moveAnim->hasTargetAnim)
{
species = gContestResources->moveAnim->targetSpecies;
personality = gContestResources->moveAnim->targetPersonality;
}
else
{
species = gContestResources->moveAnim->species;
personality = gContestResources->moveAnim->personality;
}
if (species == SPECIES_UNOWN)
{
letter = GET_UNOWN_LETTER(personality);
if (!letter)
unownSpecies = SPECIES_UNOWN;
else
unownSpecies = letter + SPECIES_UNOWN_B - 1;
coords = &gMonBackPicCoords[unownSpecies];
}
else if (species == SPECIES_CASTFORM)
{
coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]];
}
else if (species <= SPECIES_EGG)
{
coords = &gMonBackPicCoords[species];
}
else
{
coords = &gMonBackPicCoords[0];
}
}
else
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
{
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
}
else
{
species = spriteInfo[battlerId].transformSpecies;
personality = gTransformedPersonalities[battlerId];
}
if (species == SPECIES_UNOWN)
{
letter = GET_UNOWN_LETTER(personality);
if (!letter)
unownSpecies = SPECIES_UNOWN;
else
unownSpecies = letter + SPECIES_UNOWN_B - 1;
coords = &gMonBackPicCoords[unownSpecies];
}
else if (species > NUM_SPECIES)
{
coords = &gMonBackPicCoords[0];
}
else
{
coords = &gMonBackPicCoords[species];
}
}
else
{
spriteInfo = gBattleSpritesDataPtr->battlerData;
if (!spriteInfo[battlerId].transformSpecies)
{
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY);
}
else
{
species = spriteInfo[battlerId].transformSpecies;
personality = gTransformedPersonalities[battlerId];
}
if (species == SPECIES_UNOWN)
{
letter = GET_UNOWN_LETTER(personality);
if (!letter)
unownSpecies = SPECIES_UNOWN;
else
unownSpecies = letter + SPECIES_UNOWN_B - 1;
coords = &gMonFrontPicCoords[unownSpecies];
}
else if (species == SPECIES_CASTFORM)
{
coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]];
}
else if (species > NUM_SPECIES)
{
coords = &gMonFrontPicCoords[0];
}
else
{
coords = &gMonFrontPicCoords[species];
}
}
}
switch (attr)
{
case BATTLER_COORD_ATTR_HEIGHT:
return GET_MON_COORDS_HEIGHT(coords->size);
case BATTLER_COORD_ATTR_WIDTH:
return GET_MON_COORDS_WIDTH(coords->size);
case BATTLER_COORD_ATTR_LEFT:
return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) - (GET_MON_COORDS_WIDTH(coords->size) / 2);
case BATTLER_COORD_ATTR_RIGHT:
return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + (GET_MON_COORDS_WIDTH(coords->size) / 2);
case BATTLER_COORD_ATTR_TOP:
return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) - (GET_MON_COORDS_HEIGHT(coords->size) / 2);
case BATTLER_COORD_ATTR_BOTTOM:
return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y_PIC_OFFSET) + (GET_MON_COORDS_HEIGHT(coords->size) / 2);
case BATTLER_COORD_ATTR_RAW_BOTTOM:
ret = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 31;
return ret - coords->y_offset;
default:
return 0;
}
}
void SetAverageBattlerPositions(u8 battlerId, bool8 respectMonPicOffsets, s16 *x, s16 *y)
{
u8 xCoordType, yCoordType;
s16 battlerX, battlerY;
s16 partnerX, partnerY;
if (!respectMonPicOffsets)
{
xCoordType = BATTLER_COORD_X;
yCoordType = BATTLER_COORD_Y;
}
else
{
xCoordType = BATTLER_COORD_X_2;
yCoordType = BATTLER_COORD_Y_PIC_OFFSET;
}
battlerX = GetBattlerSpriteCoord(battlerId, xCoordType);
battlerY = GetBattlerSpriteCoord(battlerId, yCoordType);
if (IsDoubleBattle() && !IsContest())
{
partnerX = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), xCoordType);
partnerY = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), yCoordType);
}
else
{
partnerX = battlerX;
partnerY = battlerY;
}
*x = (battlerX + partnerX) / 2;
*y = (battlerY + partnerY) / 2;
}
u8 CreateInvisibleSpriteCopy(int battlerId, u8 spriteId, int species)
{
u8 newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy);
gSprites[newSpriteId] = gSprites[spriteId];
gSprites[newSpriteId].usingSheet = TRUE;
gSprites[newSpriteId].oam.priority = 0;
gSprites[newSpriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
gSprites[newSpriteId].oam.tileNum = gSprites[spriteId].oam.tileNum;
gSprites[newSpriteId].callback = SpriteCallbackDummy;
return newSpriteId;
}
void AnimTranslateLinearAndFlicker_Flipped(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker))
{
sprite->x -= gBattleAnimArgs[0];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
sprite->hFlip = TRUE;
}
else
{
sprite->x += gBattleAnimArgs[0];
}
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
sprite->data[5] = gBattleAnimArgs[5];
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteLinearAndFlicker;
}
// Used by three different unused battle anim sprite templates.
void AnimTranslateLinearAndFlicker(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[0];
gBattleAnimArgs[3] *= -1;
}
else
{
sprite->x += gBattleAnimArgs[0];
}
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
sprite->data[5] = gBattleAnimArgs[5];
StartSpriteAnim(sprite, gBattleAnimArgs[6]);
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteLinearAndFlicker;
}
// Used by Detect/Disable
void AnimSpinningSparkle(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker))
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Task and sprite data for AnimTask_AttackerPunchWithTrace
#define tBattlerSpriteId data[0]
#define tMoveSpeed data[1]
#define tState data[2]
#define tCounter data[3]
#define tPaletteNum data[4]
#define tNumTracesActive data[5]
#define tPriority data[6]
#define sActiveTime data[0]
#define sTaskId data[1]
#define sSpriteId data[2]
// Slides attacker to right and back with a cloned trace of the specified color
// arg0: Trace palette blend color
// arg1: Trace palette blend coeff
void AnimTask_AttackerPunchWithTrace(u8 taskId)
{
u16 src;
u16 dest;
struct Task *task = &gTasks[taskId];
task->tBattlerSpriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->tMoveSpeed = (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) ? -8 : 8;
task->tState = 0;
task->tCounter = 0;
gSprites[task->tBattlerSpriteId].x2 -= task->tBattlerSpriteId;
task->tPaletteNum = AllocSpritePalette(ANIM_TAG_BENT_SPOON);
task->tNumTracesActive = 0;
dest = OBJ_PLTT_ID2(task->tPaletteNum);
src = OBJ_PLTT_ID2(gSprites[task->tBattlerSpriteId].oam.paletteNum);
// Set trace's priority based on battler's subpriority
task->tPriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
if (task->tPriority == 20 || task->tPriority == 40)
task->tPriority = 2;
else
task->tPriority = 3;
CpuCopy32(&gPlttBufferUnfaded[src], &gPlttBufferFaded[dest], PLTT_SIZE_4BPP);
BlendPalette(dest, 16, gBattleAnimArgs[1], gBattleAnimArgs[0]);
task->func = AnimTask_AttackerPunchWithTrace_Step;
}
static void AnimTask_AttackerPunchWithTrace_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
// Move forward
CreateBattlerTrace(task, taskId);
gSprites[task->tBattlerSpriteId].x2 += task->tMoveSpeed;
if (++task->tCounter == 5)
{
task->tCounter--;
task->tState++;
}
break;
case 1:
// Move back (do same number of traces as before)
CreateBattlerTrace(task, taskId);
gSprites[task->tBattlerSpriteId].x2 -= task->tMoveSpeed;
if (--task->tCounter == 0)
{
gSprites[task->tBattlerSpriteId].x2 = 0;
task->tState++;
}
break;
case 2:
if (task->tNumTracesActive == 0)
{
FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
DestroyAnimVisualTask(taskId);
}
break;
}
}
static void CreateBattlerTrace(struct Task *task, u8 taskId)
{
s16 spriteId = CloneBattlerSpriteWithBlend(0);
if (spriteId >= 0)
{
gSprites[spriteId].oam.priority = task->tPriority;
gSprites[spriteId].oam.paletteNum = task->tPaletteNum;
gSprites[spriteId].sActiveTime = 8;
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sSpriteId = spriteId;
gSprites[spriteId].x2 = gSprites[task->tBattlerSpriteId].x2;
gSprites[spriteId].callback = AnimBattlerTrace;
task->tNumTracesActive++;
}
}
// Just waits until destroyed
static void AnimBattlerTrace(struct Sprite *sprite)
{
if (--sprite->sActiveTime == 0)
{
gTasks[sprite->sTaskId].tNumTracesActive--;
DestroySpriteWithActiveSheet(sprite);
}
}
#undef tBattlerSpriteId
#undef tMoveSpeed
#undef tState
#undef tCounter
#undef tPaletteNum
#undef tNumTracesActive
#undef tPriority
#undef sActiveTime
#undef sTaskId
#undef sSpriteId
void AnimWeatherBallUp(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->data[0] = 5;
else
sprite->data[0] = -10;
sprite->data[1] = -40;
sprite->callback = AnimWeatherBallUp_Step;
}
static void AnimWeatherBallUp_Step(struct Sprite *sprite)
{
sprite->data[2] += sprite->data[0];
sprite->data[3] += sprite->data[1];
sprite->x2 = sprite->data[2] / 10;
sprite->y2 = sprite->data[3] / 10;
if (sprite->data[1] < -20)
sprite->data[1]++;
if (sprite->y + sprite->y2 < -32)
DestroyAnimSprite(sprite);
}
void AnimWeatherBallDown(struct Sprite *sprite)
{
int x;
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = sprite->x + gBattleAnimArgs[4];
sprite->data[4] = sprite->y + gBattleAnimArgs[5];
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
x = (u16)gBattleAnimArgs[4] + 30;
sprite->x += x;
sprite->y = gBattleAnimArgs[5] - 20;
}
else
{
x = (u16)gBattleAnimArgs[4] - 30;
sprite->x += x;
sprite->y = gBattleAnimArgs[5] - 80;
}
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
#include "global.h"
#include "battle_anim.h"
#include "constants/rgb.h"
#include "trig.h"
#include "constants/songs.h"
#include "sound.h"
static void AnimLightning(struct Sprite *);
static void AnimLightning_Step(struct Sprite *);
static void AnimUnusedSpinningFist(struct Sprite *);
static void AnimUnusedSpinningFist_Step(struct Sprite *);
static void AnimUnusedCirclingShock(struct Sprite *);
static void AnimSparkElectricity(struct Sprite *);
static void AnimZapCannonSpark(struct Sprite *);
static void AnimZapCannonSpark_Step(struct Sprite *);
static void AnimThunderboltOrb(struct Sprite *);
static void AnimThunderboltOrb_Step(struct Sprite *);
static void AnimSparkElectricityFlashing(struct Sprite *);
static void AnimSparkElectricityFlashing_Step(struct Sprite *);
static void AnimElectricity(struct Sprite *);
static void AnimTask_ElectricBolt_Step(u8 taskId);
static void AnimElectricBoltSegment(struct Sprite *);
static void AnimThunderWave(struct Sprite *);
static void AnimThunderWave_Step(struct Sprite *);
static void AnimTask_ElectricChargingParticles_Step(u8 taskId);
static void AnimElectricChargingParticles(struct Sprite *);
static void AnimElectricChargingParticles_Step(struct Sprite *);
static void AnimGrowingChargeOrb(struct Sprite *);
static void AnimElectricPuff(struct Sprite *);
static void AnimVoltTackleOrbSlide(struct Sprite *);
static void AnimVoltTackleOrbSlide_Step(struct Sprite *);
static bool8 CreateVoltTackleBolt(struct Task *task, u8 taskId);
static void AnimVoltTackleBolt(struct Sprite *);
static void AnimGrowingShockWaveOrb(struct Sprite *);
static bool8 CreateShockWaveBoltSprite(struct Task *task, u8 taskId);
static void AnimShockWaveProgressingBolt(struct Sprite *);
static bool8 CreateShockWaveLightningSprite(struct Task *task, u8 taskId);
static void AnimShockWaveLightning(struct Sprite *sprite);
static const union AnimCmd sAnim_Lightning[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 8),
ANIMCMD_FRAME(48, 5),
ANIMCMD_FRAME(64, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_Lightning[] =
{
sAnim_Lightning,
};
const struct SpriteTemplate gLightningSpriteTemplate =
{
.tileTag = ANIM_TAG_LIGHTNING,
.paletteTag = ANIM_TAG_LIGHTNING,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_Lightning,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLightning,
};
static const union AffineAnimCmd sAffineAnim_UnusedSpinningFist[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 20),
AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 60),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_UnusedSpinningFist[] =
{
sAffineAnim_UnusedSpinningFist,
};
// Unused
static const struct SpriteTemplate sUnusedSpinningFistSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_UnusedSpinningFist,
.callback = AnimUnusedSpinningFist,
};
static const union AnimCmd sAnim_UnusedCirclingShock[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_FRAME(64, 5),
ANIMCMD_FRAME(80, 5),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_UnusedCirclingShock[] =
{
sAnim_UnusedCirclingShock,
};
// Unused
static const struct SpriteTemplate sUnusedCirclingShockSpriteTemplate =
{
.tileTag = ANIM_TAG_SHOCK,
.paletteTag = ANIM_TAG_SHOCK,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_UnusedCirclingShock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedCirclingShock,
};
const struct SpriteTemplate gSparkElectricitySpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK_2,
.paletteTag = ANIM_TAG_SPARK_2,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSparkElectricity,
};
const struct SpriteTemplate gZapCannonBallSpriteTemplate =
{
.tileTag = ANIM_TAG_BLACK_BALL_2,
.paletteTag = ANIM_TAG_BLACK_BALL_2,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
static const union AffineAnimCmd sAffineAnim_FlashingSpark[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_FlashingSpark[] =
{
sAffineAnim_FlashingSpark,
};
const struct SpriteTemplate gZapCannonSparkSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK_2,
.paletteTag = ANIM_TAG_SPARK_2,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_FlashingSpark,
.callback = AnimZapCannonSpark,
};
static const union AnimCmd sAnim_ThunderboltOrb[] =
{
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 6),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_ThunderboltOrb[] =
{
sAnim_ThunderboltOrb,
};
static const union AffineAnimCmd sAffineAnim_ThunderboltOrb[] =
{
AFFINEANIMCMD_FRAME(0xE8, 0xE8, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 10),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_ThunderboltOrb[] =
{
sAffineAnim_ThunderboltOrb,
};
const struct SpriteTemplate gThunderboltOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_SHOCK_3,
.paletteTag = ANIM_TAG_SHOCK_3,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_ThunderboltOrb,
.images = NULL,
.affineAnims = sAffineAnims_ThunderboltOrb,
.callback = AnimThunderboltOrb,
};
const struct SpriteTemplate gSparkElectricityFlashingSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK_2,
.paletteTag = ANIM_TAG_SPARK_2,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_FlashingSpark,
.callback = AnimSparkElectricityFlashing,
};
const struct SpriteTemplate gElectricitySpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK_2,
.paletteTag = ANIM_TAG_SPARK_2,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimElectricity,
};
const struct SpriteTemplate gElectricBoltSegmentSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK,
.paletteTag = ANIM_TAG_SPARK,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimElectricBoltSegment,
};
const struct SpriteTemplate gThunderWaveSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK_H,
.paletteTag = ANIM_TAG_SPARK_H,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThunderWave,
};
static const s8 sElectricChargingParticleCoordOffsets[][2] =
{
{ 58, -60},
{-56, -36},
{ 8, -56},
{-16, 56},
{ 58, -10},
{-58, 10},
{ 48, -18},
{-8, 56},
{ 16, -56},
{-58, -42},
{ 58, 30},
{-48, 40},
{ 12, -48},
{ 48, -12},
{-56, 18},
{ 48, 48},
};
static const union AnimCmd sAnim_ElectricChargingParticles_0[] =
{
ANIMCMD_FRAME(3, 1),
ANIMCMD_FRAME(2, 1),
ANIMCMD_FRAME(1, 1),
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_ElectricChargingParticles_1[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(1, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(3, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ElectricChargingParticles[] =
{
sAnim_ElectricChargingParticles_0,
sAnim_ElectricChargingParticles_1,
};
const struct SpriteTemplate gElectricChargingParticlesSpriteTemplate =
{
.tileTag = ANIM_TAG_ELECTRIC_ORBS,
.paletteTag = ANIM_TAG_ELECTRIC_ORBS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = sAnims_ElectricChargingParticles,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
static const union AffineAnimCmd sAffineAnim_GrowingElectricOrb_0[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 60),
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFC, 0, 5),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 5),
AFFINEANIMCMD_LOOP(10),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_GrowingElectricOrb_1[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 30),
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFC, 0, 5),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 5),
AFFINEANIMCMD_JUMP(3),
};
static const union AffineAnimCmd sAffineAnim_GrowingElectricOrb_2[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 30),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 30),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_GrowingElectricOrb[] =
{
sAffineAnim_GrowingElectricOrb_0,
sAffineAnim_GrowingElectricOrb_1,
sAffineAnim_GrowingElectricOrb_2,
};
const struct SpriteTemplate gGrowingChargeOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_GrowingElectricOrb,
.callback = AnimGrowingChargeOrb,
};
static const union AnimCmd sAnim_ElectricPuff[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ElectricPuff[] =
{
sAnim_ElectricPuff,
};
const struct SpriteTemplate gElectricPuffSpriteTemplate =
{
.tileTag = ANIM_TAG_ELECTRICITY,
.paletteTag = ANIM_TAG_ELECTRICITY,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_ElectricPuff,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimElectricPuff,
};
const struct SpriteTemplate gVoltTackleOrbSlideSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_GrowingElectricOrb,
.callback = AnimVoltTackleOrbSlide,
};
static const union AnimCmd sAnim_VoltTackleBolt_0[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_END,
};
static const union AnimCmd sAnim_VoltTackleBolt_1[] =
{
ANIMCMD_FRAME(2, 3),
ANIMCMD_END,
};
static const union AnimCmd sAnim_VoltTackleBolt_2[] =
{
ANIMCMD_FRAME(4, 3),
ANIMCMD_END,
};
static const union AnimCmd sAnim_VoltTackleBolt_3[] =
{
ANIMCMD_FRAME(6, 3),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_VoltTackleBolt[] =
{
sAnim_VoltTackleBolt_0,
sAnim_VoltTackleBolt_1,
sAnim_VoltTackleBolt_2,
sAnim_VoltTackleBolt_3,
};
static const union AffineAnimCmd sAffineAnim_VoltTackleBolt[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_VoltTackleBolt[] =
{
sAffineAnim_VoltTackleBolt,
};
const struct SpriteTemplate gVoltTackleBoltSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK,
.paletteTag = ANIM_TAG_SPARK,
.oam = &gOamData_AffineDouble_ObjNormal_8x16,
.anims = sAnims_VoltTackleBolt,
.images = NULL,
.affineAnims = sAffineAnims_VoltTackleBolt,
.callback = AnimVoltTackleBolt,
};
const struct SpriteTemplate gGrowingShockWaveOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_GrowingElectricOrb,
.callback = AnimGrowingShockWaveOrb,
};
const struct SpriteTemplate gShockWaveProgressingBoltSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARK,
.paletteTag = ANIM_TAG_SPARK,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimShockWaveProgressingBolt,
};
static void AnimLightning(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->callback = AnimLightning_Step;
}
static void AnimLightning_Step(struct Sprite *sprite)
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimUnusedSpinningFist(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->callback = AnimUnusedSpinningFist_Step;
}
static void AnimUnusedSpinningFist_Step(struct Sprite *sprite)
{
if (sprite->affineAnimEnded)
DestroySpriteAndMatrix(sprite);
}
static void AnimUnusedCirclingShock(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[0];
sprite->y -= gBattleAnimArgs[1];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteInCircle;
}
static void AnimSparkElectricity(struct Sprite *sprite)
{
u8 battler;
u32 matrixNum;
s16 sineVal;
switch (gBattleAnimArgs[4])
{
case ANIM_ATTACKER:
battler = gBattleAnimAttacker;
break;
case ANIM_TARGET:
default:
battler = gBattleAnimTarget;
break;
case ANIM_ATK_PARTNER:
if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
battler = gBattleAnimAttacker;
else
battler = BATTLE_PARTNER(gBattleAnimAttacker);
break;
case ANIM_DEF_PARTNER:
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
battler = BATTLE_PARTNER(gBattleAnimTarget);
else
battler = gBattleAnimTarget;
break;
}
if (gBattleAnimArgs[5] == 0)
{
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->x2 = (gSineTable[gBattleAnimArgs[0]] * gBattleAnimArgs[1]) >> 8;
sprite->y2 = (gSineTable[gBattleAnimArgs[0] + 64] * gBattleAnimArgs[1]) >> 8;
if (gBattleAnimArgs[6] & 1)
sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
matrixNum = sprite->oam.matrixNum;
sineVal = gSineTable[gBattleAnimArgs[2]];
gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[gBattleAnimArgs[2] + 64];
gOamMatrices[matrixNum].b = sineVal;
gOamMatrices[matrixNum].c = -sineVal;
sprite->data[0] = gBattleAnimArgs[3];
sprite->callback = DestroyAnimSpriteAfterTimer;
}
static void AnimZapCannonSpark(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->data[5] = gBattleAnimArgs[2];
sprite->data[6] = gBattleAnimArgs[5];
sprite->data[7] = gBattleAnimArgs[4];
sprite->oam.tileNum += gBattleAnimArgs[6] * 4;
sprite->callback = AnimZapCannonSpark_Step;
sprite->callback(sprite);
}
static void AnimZapCannonSpark_Step(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->x2 += Sin(sprite->data[7], sprite->data[5]);
sprite->y2 += Cos(sprite->data[7], sprite->data[5]);
sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
if(!(sprite->data[7] % 3))
sprite->invisible ^= 1;
}
else
DestroyAnimSprite(sprite);
}
static void AnimThunderboltOrb_Step(struct Sprite *sprite)
{
if (--sprite->data[5] == -1)
{
sprite->invisible ^= 1;
sprite->data[5] = sprite->data[4];
}
if (sprite->data[3]-- <= 0)
DestroyAnimSprite(sprite);
}
static void AnimThunderboltOrb(struct Sprite *sprite)
{
if (IsContest() || GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
sprite->data[3] = gBattleAnimArgs[0];
sprite->data[4] = gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[3];
sprite->callback = AnimThunderboltOrb_Step;
}
static void AnimSparkElectricityFlashing(struct Sprite *sprite)
{
u8 battler;
sprite->data[0] = gBattleAnimArgs[3];
if (gBattleAnimArgs[7] & 0x8000)
battler = gBattleAnimTarget;
else
battler = gBattleAnimAttacker;
if (IsContest() || GetBattlerSide(battler) == B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->data[4] = gBattleAnimArgs[7] & 0x7FFF;
sprite->data[5] = gBattleAnimArgs[2];
sprite->data[6] = gBattleAnimArgs[5];
sprite->data[7] = gBattleAnimArgs[4];
sprite->oam.tileNum += gBattleAnimArgs[6] * 4;
sprite->callback = AnimSparkElectricityFlashing_Step;
sprite->callback(sprite);
}
static void AnimSparkElectricityFlashing_Step(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[7], sprite->data[5]);
sprite->y2 = Cos(sprite->data[7], sprite->data[5]);
sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
if (sprite->data[7] % sprite->data[4] == 0)
sprite->invisible ^= TRUE;
if (sprite->data[0]-- <= 0)
DestroyAnimSprite(sprite);
}
// Electricity arcs around the target. Used for Paralysis and various electric move hits
static void AnimElectricity(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->oam.tileNum += gBattleAnimArgs[3] * 4;
if (gBattleAnimArgs[3] == 1)
sprite->oam.matrixNum = ST_OAM_HFLIP;
else if (gBattleAnimArgs[3] == 2)
sprite->oam.matrixNum = ST_OAM_VFLIP;
sprite->data[0] = gBattleAnimArgs[2];
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// The vertical falling thunder bolt used in Thunder Wave/Shock/Bolt
void AnimTask_ElectricBolt(u8 taskId)
{
gTasks[taskId].data[0] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[0];
gTasks[taskId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].func = AnimTask_ElectricBolt_Step;
}
static void AnimTask_ElectricBolt_Step(u8 taskId)
{
u16 r8;
u16 r2;
s16 r12;
u8 spriteId = 0;
u8 r7 = 0;
u8 sp = gTasks[taskId].data[2];
s16 x = gTasks[taskId].data[0];
s16 y = gTasks[taskId].data[1];
if (!gTasks[taskId].data[2])
{
r8 = 0;
r2 = 1;
r12 = 16;
}
else
{
r12 = 16;
r8 = 8;
r2 = 4;
}
switch (gTasks[taskId].data[10])
{
case 0:
r12 *= 1;
spriteId = CreateSprite(&gElectricBoltSegmentSpriteTemplate, x, y + r12, 2);
r7++;
break;
case 2:
r12 *= 2;
r8 += r2;
spriteId = CreateSprite(&gElectricBoltSegmentSpriteTemplate, x, y + r12, 2);
r7++;
break;
case 4:
r12 *= 3;
r8 += r2 * 2;
spriteId = CreateSprite(&gElectricBoltSegmentSpriteTemplate, x, y + r12, 2);
r7++;
break;
case 6:
r12 *= 4;
r8 += r2 * 3;
spriteId = CreateSprite(&gElectricBoltSegmentSpriteTemplate, x, y + r12, 2);
r7++;
break;
case 8:
r12 *= 5;
spriteId = CreateSprite(&gElectricBoltSegmentSpriteTemplate, x, y + r12, 2);
r7++;
break;
case 10:
DestroyAnimVisualTask(taskId);
return;
}
if (r7)
{
gSprites[spriteId].oam.tileNum += r8;
gSprites[spriteId].data[0] = sp;
gSprites[spriteId].callback(&gSprites[spriteId]);
}
gTasks[taskId].data[10]++;
}
static void AnimElectricBoltSegment(struct Sprite *sprite)
{
if (!sprite->data[0])
{
sprite->oam.shape = SPRITE_SHAPE(8x16);
sprite->oam.size = SPRITE_SIZE(8x16);
}
else
{
sprite->oam.shape = SPRITE_SHAPE(16x16);
sprite->oam.size = SPRITE_SIZE(16x16);
}
if (++sprite->data[1] == 15)
DestroySprite(sprite);
}
// The horizontal bands of electricity used in Thunder Wave
static void AnimThunderWave(struct Sprite *sprite)
{
u8 spriteId;
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
spriteId = CreateSprite(&gThunderWaveSpriteTemplate, sprite->x + 32, sprite->y, sprite->subpriority);
gSprites[spriteId].oam.tileNum += 8;
gAnimVisualTaskCount++;
gSprites[spriteId].callback = AnimThunderWave_Step;
sprite->callback = AnimThunderWave_Step;
}
static void AnimThunderWave_Step(struct Sprite *sprite)
{
if (++sprite->data[0] == 3)
{
sprite->data[0] = 0;
sprite->invisible ^= 1;
}
if (++sprite->data[1] == 51)
DestroyAnimSprite(sprite);
}
// Animates small electric orbs moving from around the battler inward. For Charge/Shock Wave
void AnimTask_ElectricChargingParticles(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[15] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->data[15] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
task->data[6] = gBattleAnimArgs[1];
task->data[7] = 0;
task->data[8] = 0;
task->data[9] = 0;
task->data[10] = 0;
task->data[11] = gBattleAnimArgs[3];
task->data[12] = 0;
task->data[13] = gBattleAnimArgs[2];
task->func = AnimTask_ElectricChargingParticles_Step;
}
static void AnimTask_ElectricChargingParticles_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (task->data[6])
{
if (++task->data[12] > task->data[13])
{
u8 spriteId;
task->data[12] = 0;
spriteId = CreateSprite(&gElectricChargingParticlesSpriteTemplate, task->data[14], task->data[15], 2);
if (spriteId != MAX_SPRITES)
{
struct Sprite *sprite = &gSprites[spriteId];
sprite->x += sElectricChargingParticleCoordOffsets[task->data[9]][0];
sprite->y += sElectricChargingParticleCoordOffsets[task->data[9]][1];
sprite->data[0] = 40 - task->data[8] * 5;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[14];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[15];
sprite->data[5] = taskId;
InitAnimLinearTranslation(sprite);
StoreSpriteCallbackInData6(sprite, AnimElectricChargingParticles);
sprite->callback = RunStoredCallbackWhenAnimEnds;
if (++task->data[9] > 15)
task->data[9] = 0;
if (++task->data[10] >= task->data[11])
{
task->data[10] = 0;
if (task->data[8] <= 5)
task->data[8]++;
}
task->data[7]++;
task->data[6]--;
}
}
}
else if(task->data[7] == 0)
DestroyAnimVisualTask(taskId);
}
static void AnimElectricChargingParticles_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
{
gTasks[sprite->data[5]].data[7]--;
DestroySprite(sprite);
}
}
static void AnimElectricChargingParticles(struct Sprite *sprite)
{
StartSpriteAnim(sprite, 1);
sprite->callback = AnimElectricChargingParticles_Step;
}
static void AnimGrowingChargeOrb(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
// The quick electric burst at the end of Charge / during the Volt Tackle hit
static void AnimElectricPuff(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->x2 = gBattleAnimArgs[1];
sprite->y2 = gBattleAnimArgs[2];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
// Creates an orb of electricity that grows then slides off-screen. The attacker slides with it
static void AnimVoltTackleOrbSlide(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, 1);
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[6] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
sprite->data[7] = 16;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
sprite->data[7] *= -1;
sprite->callback = AnimVoltTackleOrbSlide_Step;
}
static void AnimVoltTackleOrbSlide_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (++sprite->data[1] > 40)
sprite->data[0]++;
break;
case 1:
sprite->x += sprite->data[7];
gSprites[sprite->data[6]].x2 += sprite->data[7];
if ((u16)(sprite->x + 80) > 400)
DestroySpriteAndMatrix(sprite);
}
}
void AnimTask_VoltTackleAttackerReappear(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
task->data[14] = -32;
task->data[13] = 2;
}
else
{
task->data[14] = 32;
task->data[13] = -2;
}
gSprites[task->data[15]].x2 = task->data[14];
task->data[0]++;
break;
case 1:
if (++task->data[1] > 1)
{
task->data[1] = 0;
gSprites[task->data[15]].invisible ^= 1;
if (task->data[14])
{
task->data[14] += task->data[13];
gSprites[task->data[15]].x2 = task->data[14];
}
else
task->data[0]++;
}
break;
case 2:
if (++task->data[1] > 1)
{
task->data[1] = 0;
gSprites[task->data[15]].invisible ^= 1;
if (++task->data[2] == 8)
task->data[0]++;
}
break;
case 3:
gSprites[task->data[15]].invisible = FALSE;
DestroyAnimVisualTask(taskId);
}
}
// The horizontal bolts of electricity for Volt Tackle
void AnimTask_VoltTackleBolt(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch(task->data[0])
{
case 0:
task->data[1] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
switch (gBattleAnimArgs[0])
{
case 0:
task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[5] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
task->data[4] = (task->data[1] * 128) + 120;
break;
case 4:
task->data[3] = 120 - (task->data[1] * 128);
task->data[5] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
task->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) - (task->data[1] * 32);
break;
default:
if ((gBattleAnimArgs[0] & 1) != 0)
{
task->data[3] = 256;
task->data[4] = -16;
}
else
{
task->data[3] = -16;
task->data[4] = 256;
}
if (task->data[1] == 1)
{
task->data[5] = 80 - gBattleAnimArgs[0] * 10;
}
else
{
u16 temp;
task->data[5] = gBattleAnimArgs[0] * 10 + 40;
temp = task->data[3];
task->data[3] = task->data[4];
task->data[4] = temp;
}
}
if (task->data[3] < task->data[4])
{
task->data[1] = 1;
task->data[6] = 0;
}
else
{
task->data[1] = -1;
task->data[6] = 3;
}
task->data[0]++;
break;
case 1:
if (++task->data[2] > 0)
{
task->data[2] = 0;
if (CreateVoltTackleBolt(task, taskId) || CreateVoltTackleBolt(task, taskId))
task->data[0]++;
}
break;
case 2:
if (task->data[7] == 0)
DestroyAnimVisualTask(taskId);
}
}
static bool8 CreateVoltTackleBolt(struct Task *task, u8 taskId)
{
u8 spriteId = CreateSprite(&gVoltTackleBoltSpriteTemplate, task->data[3], task->data[5], 35);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 7;
task->data[7]++;
}
task->data[6] += task->data[1];
if (task->data[6] < 0)
task->data[6] = 3;
if (task->data[6] > 3)
task->data[6] = 0;
task->data[3] += task->data[1] * 16;
if ((task->data[1] == 1 && task->data[3] >= task->data[4])
|| (task->data[1] == -1 && task->data[3] <= task->data[4]))
{
return TRUE;
}
else
{
return FALSE;
}
}
static void AnimVoltTackleBolt(struct Sprite *sprite)
{
if (++sprite->data[0] > 12)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
}
static void AnimGrowingShockWaveOrb(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
StartSpriteAffineAnim(sprite, 2);
sprite->data[0]++;
break;
case 1:
if (sprite->affineAnimEnded)
DestroySpriteAndMatrix(sprite);
break;
}
}
// Thin bolt of electricity that moves up and down toward the target. Used by Shock Wave
void AnimTask_ShockWaveProgressingBolt(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[6] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[7] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
task->data[8] = 4;
task->data[10] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->data[9] = (task->data[10] - task->data[6]) / 5;
task->data[4] = 7;
task->data[5] = -1;
task->data[11] = 12;
task->data[12] = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
task->data[13] = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
task->data[14] = task->data[12];
task->data[15] = (task->data[13] - task->data[12]) / 3;
task->data[0]++;
break;
case 1:
if (++task->data[1] > 0)
{
task->data[1] = 0;
if (CreateShockWaveBoltSprite(task, taskId))
{
if (task->data[2] == 5)
task->data[0] = 3;
else
task->data[0]++;
}
}
if (task->data[11])
task->data[11]--;
break;
case 2:
if (task->data[11])
task->data[11]--;
if (++task->data[1] > 4)
{
task->data[1] = 0;
if (task->data[2] & 1)
{
task->data[7] = 4;
task->data[8] = 68;
task->data[4] = 0;
task->data[5] = 1;
}
else
{
task->data[7] = 68;
task->data[8] = 4;
task->data[4] = 7;
task->data[5] = -1;
}
if (task->data[11])
task->data[0] = 4;
else
task->data[0] = 1;
}
break;
case 3:
if (task->data[3] == 0)
DestroyAnimVisualTask(taskId);
break;
case 4:
if (task->data[11])
task->data[11]--;
else
task->data[0] = 1;
break;
}
}
static bool8 CreateShockWaveBoltSprite(struct Task *task, u8 taskId)
{
u8 spriteId = CreateSprite(&gShockWaveProgressingBoltSpriteTemplate, task->data[6], task->data[7], 35);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].oam.tileNum += task->data[4];
task->data[4] += task->data[5];
if (task->data[4] < 0)
task->data[4] = 7;
if (task->data[4] > 7)
task->data[4] = 0;
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 3;
task->data[3]++;
}
if (task->data[4] == 0 && task->data[5] > 0)
{
task->data[14] += task->data[15];
PlaySE12WithPanning(SE_M_THUNDERBOLT, task->data[14]);
}
if ((task->data[5] < 0 && task->data[7] <= task->data[8])
|| (task->data[5] > 0 && task->data[7] >= task->data[8]))
{
task->data[2]++;
task->data[6] += task->data[9];
return TRUE;
}
else
{
task->data[7] += task->data[5] * 8;
return FALSE;
}
}
// Just runs timer for sprite. See AnimTask_ShockWaveProgressingBolt
static void AnimShockWaveProgressingBolt(struct Sprite *sprite)
{
if (++sprite->data[0] > 12)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
DestroySprite(sprite);
}
}
void AnimTask_ShockWaveLightning(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[15] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 32;
task->data[14] = task->data[15];
while (task->data[14] > 16)
{
task->data[14] -= 32;
}
task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->data[12] = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 2;
task->data[0]++;
break;
case 1:
if (++task->data[1] > 1)
{
task->data[1] = 0;
if (CreateShockWaveLightningSprite(task, taskId))
task->data[0]++;
}
break;
case 2:
if (task->data[10] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static bool8 CreateShockWaveLightningSprite(struct Task *task, u8 taskId)
{
u8 spriteId = CreateSprite(&gLightningSpriteTemplate, task->data[13], task->data[14], task->data[12]);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].callback = AnimShockWaveLightning;
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 10;
task->data[10]++;
}
if (task->data[14] >= task->data[15])
return TRUE;
task->data[14] += 32;
return FALSE;
}
static void AnimShockWaveLightning(struct Sprite *sprite)
{
if (sprite->animEnded)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
DestroySprite(sprite);
}
}
#include "global.h"
#include "battle_anim.h"
#include "palette.h"
#include "trig.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
#include "random.h"
extern const struct SpriteTemplate gFlashingHitSplatSpriteTemplate;
static void AnimEllipticalGust(struct Sprite *);
static void AnimEllipticalGust_Step(struct Sprite *);
static void AnimGustToTarget(struct Sprite *);
static void AnimGustToTarget_Step(struct Sprite *);
static void AnimAirWaveCrescent(struct Sprite *);
static void AnimFlyBallUp(struct Sprite *);
static void AnimFlyBallUp_Step(struct Sprite *);
static void AnimFlyBallAttack(struct Sprite *);
static void AnimFlyBallAttack_Step(struct Sprite *);
static void AnimFallingFeather(struct Sprite *);
static void AnimFallingFeather_Step(struct Sprite *);
static void AnimWhirlwindLine_Step(struct Sprite *);
static void AnimUnusedBubbleThrow(struct Sprite *);
static void AnimWhirlwindLine(struct Sprite *);
static void AnimBounceBallShrink(struct Sprite *);
static void AnimBounceBallLand(struct Sprite *);
static void AnimDiveBall(struct Sprite *);
static void AnimDiveBall_Step1(struct Sprite *);
static void AnimDiveBall_Step2(struct Sprite *);
static void AnimDiveWaterSplash(struct Sprite *);
static void AnimSprayWaterDroplet(struct Sprite *);
static void AnimSprayWaterDroplet_Step(struct Sprite *);
static void AnimUnusedFlashingLight(struct Sprite *);
static void AnimUnusedFlashingLight_Step(struct Sprite *);
static void AnimSkyAttackBird(struct Sprite *);
static void AnimSkyAttackBird_Step(struct Sprite *);
static void AnimTask_AnimateGustTornadoPalette_Step(u8);
const struct SpriteTemplate gEllipticalGustSpriteTemplate =
{
.tileTag = ANIM_TAG_GUST,
.paletteTag = ANIM_TAG_GUST,
.oam = &gOamData_AffineOff_ObjNormal_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEllipticalGust,
};
static const union AffineAnimCmd sAffineAnim_GustToTarget[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xA, 0x0, 0, 24),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_GustToTarget[] =
{
sAffineAnim_GustToTarget,
};
const struct SpriteTemplate gGustToTargetSpriteTemplate =
{
.tileTag = ANIM_TAG_GUST,
.paletteTag = ANIM_TAG_GUST,
.oam = &gOamData_AffineNormal_ObjNormal_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_GustToTarget,
.callback = AnimGustToTarget,
};
static const union AnimCmd sAffineAnim_AirWaveCrescent[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(0, 3, .hFlip = TRUE),
ANIMCMD_FRAME(0, 3, .vFlip = TRUE),
ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAffineAnims_AirWaveCrescent[] =
{
sAffineAnim_AirWaveCrescent,
};
const struct SpriteTemplate gAirWaveCrescentSpriteTemplate =
{
.tileTag = ANIM_TAG_AIR_WAVE_2,
.paletteTag = ANIM_TAG_AIR_WAVE_2,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = sAffineAnims_AirWaveCrescent,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimAirWaveCrescent,
};
static const union AffineAnimCmd sAffineAnim_FlyBallUp[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_FlyBallUp[] =
{
sAffineAnim_FlyBallUp,
};
static const union AffineAnimCmd sAffineAnim_FlyBallAttack_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 50, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlyBallAttack_1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -40, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_FlyBallAttack[] =
{
sAffineAnim_FlyBallAttack_0,
sAffineAnim_FlyBallAttack_1,
};
const struct SpriteTemplate gFlyBallUpSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_SHADOW,
.paletteTag = ANIM_TAG_ROUND_SHADOW,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_FlyBallUp,
.callback = AnimFlyBallUp,
};
const struct SpriteTemplate gFlyBallAttackSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_SHADOW,
.paletteTag = ANIM_TAG_ROUND_SHADOW,
.oam = &gOamData_AffineNormal_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_FlyBallAttack,
.callback = AnimFlyBallAttack,
};
static const union AnimCmd sAnim_FallingFeather_0[] =
{
ANIMCMD_FRAME(0, 0),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FallingFeather_1[] =
{
ANIMCMD_FRAME(16, 0, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_FallingFeather[] =
{
sAnim_FallingFeather_0,
sAnim_FallingFeather_1,
};
const struct SpriteTemplate gFallingFeatherSpriteTemplate =
{
.tileTag = ANIM_TAG_WHITE_FEATHER,
.paletteTag = ANIM_TAG_WHITE_FEATHER,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_FallingFeather,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFallingFeather,
};
// Unused
static const struct SpriteTemplate sUnusedBubbleThrowSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedBubbleThrow,
};
static const union AnimCmd sAnim_WhirlwindLines[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_FRAME(8, 1),
ANIMCMD_FRAME(16, 1),
ANIMCMD_FRAME(8, 1, .hFlip = TRUE),
ANIMCMD_FRAME(0, 1, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_WhirlwindLines[] =
{
sAnim_WhirlwindLines,
};
const struct SpriteTemplate gWhirlwindLineSpriteTemplate =
{
.tileTag = ANIM_TAG_WHIRLWIND_LINES,
.paletteTag = ANIM_TAG_WHIRLWIND_LINES,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = sAnims_WhirlwindLines,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWhirlwindLine,
};
static const union AffineAnimCmd sAffineAnim_BounceBallShrink[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
AFFINEANIMCMD_FRAME(0xFFEC, 0x0, 0, 7),
AFFINEANIMCMD_FRAME(0xFFEC, 0xFFEC, 0, 5),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_BounceBallShrink[] =
{
sAffineAnim_BounceBallShrink,
};
const struct SpriteTemplate gBounceBallShrinkSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_SHADOW,
.paletteTag = ANIM_TAG_ROUND_SHADOW,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_BounceBallShrink,
.callback = AnimBounceBallShrink,
};
static const union AffineAnimCmd sAffineAnim_BounceBallLand[] =
{
AFFINEANIMCMD_FRAME(0xA0, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_BounceBallLand[] =
{
sAffineAnim_BounceBallLand,
};
const struct SpriteTemplate gBounceBallLandSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_SHADOW,
.paletteTag = ANIM_TAG_ROUND_SHADOW,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_BounceBallLand,
.callback = AnimBounceBallLand,
};
static const union AffineAnimCmd sAffineAnim_DiveBall[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_DiveBall[] =
{
sAffineAnim_DiveBall,
};
const struct SpriteTemplate gDiveBallSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_SHADOW,
.paletteTag = ANIM_TAG_ROUND_SHADOW,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_DiveBall,
.callback = AnimDiveBall,
};
static const union AffineAnimCmd sAnim_Unused[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x0, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x20, 0, 12),
AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 11),
AFFINEANIMCMD_END,
};
// Unused
static const union AffineAnimCmd *const sAnims_Unused[] =
{
sAnim_Unused,
};
const struct SpriteTemplate gDiveWaterSplashSpriteTemplate =
{
.tileTag = ANIM_TAG_SPLASH,
.paletteTag = ANIM_TAG_SPLASH,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDiveWaterSplash,
};
const struct SpriteTemplate gSprayWaterDropletSpriteTemplate =
{
.tileTag = ANIM_TAG_SWEAT_BEAD,
.paletteTag = ANIM_TAG_SWEAT_BEAD,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSprayWaterDroplet,
};
// Unused
static const struct SpriteTemplate sUnusedFlashingLightSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedFlashingLight,
};
const struct SpriteTemplate gSkyAttackBirdSpriteTemplate =
{
.tileTag = ANIM_TAG_BIRD,
.paletteTag = ANIM_TAG_BIRD,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSkyAttackBird,
};
static void AnimEllipticalGust(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->y += 20;
sprite->data[1] = 191;
sprite->callback = AnimEllipticalGust_Step;
sprite->callback(sprite);
}
static void AnimEllipticalGust_Step(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[1], 32);
sprite->y2 = Cos(sprite->data[1], 8);
sprite->data[1] += 5;
sprite->data[1] &= 0xFF;
if (++sprite->data[0] == 71)
DestroyAnimSprite(sprite);
}
// Animates the palette on the gust tornado to make it look like its spinning
void AnimTask_AnimateGustTornadoPalette(u8 taskId)
{
gTasks[taskId].data[0] = gBattleAnimArgs[1];
gTasks[taskId].data[1] = gBattleAnimArgs[0];
gTasks[taskId].data[2] = IndexOfSpritePaletteTag(ANIM_TAG_GUST);
gTasks[taskId].func = AnimTask_AnimateGustTornadoPalette_Step;
}
static void AnimTask_AnimateGustTornadoPalette_Step(u8 taskId)
{
u8 data2;
u16 temp;
int i, base;
if (gTasks[taskId].data[10]++ == gTasks[taskId].data[1])
{
gTasks[taskId].data[10] = 0;
data2 = gTasks[taskId].data[2];
temp = gPlttBufferFaded[16 * data2 + 0x108];
i = 7;
base = data2 * 16;
do
{
gPlttBufferFaded[base + 0x101 + i] = gPlttBufferFaded[base + 0x100 + i];
i--;
} while (i > 0);
gPlttBufferFaded[base + 0x101] = temp;
}
if (--gTasks[taskId].data[0] == 0)
DestroyAnimVisualTask(taskId);
}
static void AnimGustToTarget(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
InitAnimLinearTranslation(sprite);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, AnimGustToTarget_Step);
}
static void AnimGustToTarget_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
DestroyAnimSprite(sprite);
}
static void AnimAirWaveCrescent(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
if (IsContest())
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[4];
if (gBattleAnimArgs[6] == 0)
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]);
}
sprite->data[2] = sprite->data[2] + gBattleAnimArgs[2];
sprite->data[4] = sprite->data[4] + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
SeekSpriteAnim(sprite, gBattleAnimArgs[5]);
}
static void AnimFlyBallUp(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->callback = AnimFlyBallUp_Step;
gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
}
static void AnimFlyBallUp_Step(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
}
else
{
sprite->data[2] += sprite->data[1];
sprite->y2 -= (sprite->data[2] >> 8);
}
if (sprite->y + sprite->y2 < -32)
DestroyAnimSprite(sprite);
}
static void AnimFlyBallAttack(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x = DISPLAY_WIDTH + 32;
sprite->y = -32;
StartSpriteAffineAnim(sprite, 1);
}
else
{
sprite->x = -32;
sprite->y = -32;
}
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->callback = AnimFlyBallAttack_Step;
}
static void AnimFlyBallAttack_Step(struct Sprite *sprite)
{
sprite->data[0] = 1;
AnimTranslateLinear(sprite);
if (((u16)sprite->data[3] >> 8) > 200)
{
sprite->x += sprite->x2;
sprite->x2 = 0;
sprite->data[3] &= 0xFF;
}
if (sprite->x + sprite->x2 < -32
|| sprite->x + sprite->x2 > DISPLAY_WIDTH + 32
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT)
{
gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = FALSE;
DestroyAnimSprite(sprite);
}
}
void DestroyAnimSpriteAfterTimer(struct Sprite *sprite)
{
if (sprite->data[0]-- <= 0)
{
if (sprite->oam.affineMode & ST_OAM_AFFINE_ON_MASK)
{
FreeOamMatrix(sprite->oam.matrixNum);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
}
DestroySprite(sprite);
gAnimVisualTaskCount--;
}
}
struct FeatherDanceData
{
u16 unk0_0a:1;
u16 unk0_0b:1;
u16 unk0_0c:1;
u16 unk0_0d:1;
u16 unk0_1:4;
u16 unk1:8;
u16 unk2;
s16 unk4;
u16 unk6;
u16 unk8;
u16 unkA;
u8 unkC[2];
u16 unkE_0:1;
u16 unkE_1:15;
};
static void AnimFallingFeather(struct Sprite *sprite)
{
u8 battler, matrixNum, sinIndex;
s16 spriteCoord;
struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data;
if (gBattleAnimArgs[7] & 0x100)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_HEIGHT) + gBattleAnimArgs[0];
spriteCoord = GetBattlerSpriteCoord(battler, BATTLER_COORD_ATTR_WIDTH);
sprite->y = spriteCoord + gBattleAnimArgs[1];
data->unk8 = sprite->y << 8;
data->unkE_1 = spriteCoord + gBattleAnimArgs[6];
data->unk0_0c = 1;
data->unk2 = gBattleAnimArgs[2] & 0xFF;
data->unkA = (gBattleAnimArgs[2] >> 8) & 0xFF;
data->unk4 = gBattleAnimArgs[3];
data->unk6 = gBattleAnimArgs[4];
*(u16 *)(data->unkC) = gBattleAnimArgs[5];
if (data->unk2 >= 64 && data->unk2 <= 191)
{
if (!IsContest())
sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
else
sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
data->unkE_0 = 0;
if (!(data->unk4 & 0x8000))
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = 1;
sprite->animEnded = 0;
}
}
else
{
sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
data->unkE_0 = 1;
if (data->unk4 & 0x8000)
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = 1;
sprite->animEnded = 0;
}
}
data->unk0_1 = data->unk2 >> 6;
sprite->x2 = (gSineTable[data->unk2] * data->unkC[0]) >> 8;
matrixNum = sprite->oam.matrixNum;
sinIndex = (-sprite->x2 >> 1) + data->unkA;
spriteCoord = gSineTable[sinIndex];
gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64];
gOamMatrices[matrixNum].b = spriteCoord;
gOamMatrices[matrixNum].c = -spriteCoord;
sprite->callback = AnimFallingFeather_Step;
}
static void AnimFallingFeather_Step(struct Sprite *sprite)
{
u8 matrixNum, sinIndex;
s16 sinVal = 0;
struct FeatherDanceData *data = (struct FeatherDanceData *)sprite->data;
if (data->unk0_0a)
{
if (data->unk1-- % 256 == 0)
{
data->unk0_0a = 0;
data->unk1 = 0;
}
}
else
{
switch (data->unk2 / 64)
{
case 0:
if ((u8)data->unk0_1 == 1) //casts to u8 here are necessary for matching
{
data->unk0_0d = 1;
data->unk0_0a = 1;
data->unk1 = 0;
}
else if ((u8)data->unk0_1 == 3)
{
data->unk0_0b ^= 1;
data->unk0_0a = 1;
data->unk1 = 0;
}
else if (data->unk0_0d)
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = TRUE;
sprite->animEnded = FALSE;
if (data->unk0_0c)
{
if (!IsContest())
{
if (!data->unkE_0)
{
sprite->oam.priority--;
data->unkE_0 ^= 1;
}
else
{
sprite->oam.priority++;
data->unkE_0 ^= 1;
}
}
else
{
if (!data->unkE_0)
{
sprite->subpriority -= 12;
data->unkE_0 ^= 1;
}
else
{
sprite->subpriority += 12;
data->unkE_0 ^= 1;
}
}
}
data->unk0_0d = 0;
}
data->unk0_1 = 0;
break;
case 1:
if ((u8)data->unk0_1 == 0)
{
data->unk0_0d = 1;
data->unk0_0a = 1;
data->unk1 = 0;
}
else if ((u8)data->unk0_1 == 2)
{
data->unk0_0a = 1;
data->unk1 = 0;
}
else if (data->unk0_0d)
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = TRUE;
sprite->animEnded = FALSE;
if (data->unk0_0c)
{
if (!IsContest())
{
if (!data->unkE_0)
{
sprite->oam.priority--;
data->unkE_0 ^= 1;
}
else
{
sprite->oam.priority++;
data->unkE_0 ^= 1;
}
}
else
{
if (!data->unkE_0)
{
sprite->subpriority -= 12;
data->unkE_0 ^= 1;
}
else
{
sprite->subpriority += 12;
data->unkE_0 ^= 1;
}
}
}
data->unk0_0d = 0;
}
data->unk0_1 = 1;
break;
case 2:
if ((u8)data->unk0_1 == 3)
{
data->unk0_0d = 1;
data->unk0_0a = 1;
data->unk1 = 0;
}
else if ((u8)data->unk0_1 == 1)
{
data->unk0_0a = 1;
data->unk1 = 0;
}
else if (data->unk0_0d)
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = TRUE;
sprite->animEnded = FALSE;
if (data->unk0_0c)
{
if (!IsContest())
{
if (!data->unkE_0)
{
sprite->oam.priority--;
data->unkE_0 ^= 1;
}
else
{
sprite->oam.priority++;
data->unkE_0 ^= 1;
}
}
else
{
if (!data->unkE_0)
{
sprite->subpriority -= 12;
data->unkE_0 ^= 1;
}
else
{
sprite->subpriority += 12;
data->unkE_0 ^= 1;
}
}
}
data->unk0_0d = 0;
}
data->unk0_1 = 2;
break;
case 3:
if ((u8)data->unk0_1 == 2)
{
data->unk0_0d = 1;
}
else if ((u8)data->unk0_1 == 0)
{
data->unk0_0b ^= 1;
data->unk0_0a = 1;
data->unk1 = 0;
}
else if (data->unk0_0d)
{
sprite->hFlip ^= 1;
sprite->animNum = sprite->hFlip;
sprite->animBeginning = TRUE;
sprite->animEnded = FALSE;
if (data->unk0_0c)
{
if (!IsContest())
{
if (!data->unkE_0)
{
sprite->oam.priority--;
data->unkE_0 ^= 1;
}
else
{
sprite->oam.priority++;
data->unkE_0 ^= 1;
}
}
else
{
if (!data->unkE_0)
{
sprite->subpriority -= 12;
data->unkE_0 ^= 1;
}
else
{
sprite->subpriority += 12;
data->unkE_0 ^= 1;
}
}
}
data->unk0_0d = 0;
}
data->unk0_1 = 3;
break;
}
sprite->x2 = ((s32)data->unkC[data->unk0_0b] * gSineTable[data->unk2]) >> 8;
matrixNum = sprite->oam.matrixNum;
sinIndex = (-sprite->x2 >> 1) + data->unkA;
sinVal = gSineTable[sinIndex];
gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[sinIndex + 64];
gOamMatrices[matrixNum].b = sinVal;
gOamMatrices[matrixNum].c = -sinVal;
data->unk8 += data->unk6;
sprite->y = data->unk8 >> 8;
if (data->unk4 & 0x8000)
data->unk2 = (data->unk2 - (data->unk4 & 0x7FFF)) & 0xFF;
else
data->unk2 = (data->unk2 + (data->unk4 & 0x7FFF)) & 0xFF;
if (sprite->y + sprite->y2 >= data->unkE_1)
{
sprite->data[0] = 0;
sprite->callback = DestroyAnimSpriteAfterTimer;
}
}
}
static void AnimUnusedBubbleThrow(struct Sprite *sprite)
{
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = TranslateAnimSpriteToTargetMonLocation;
}
static void AnimWhirlwindLine(struct Sprite * sprite)
{
u16 offset;
u8 mult;
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
if ((gBattleAnimArgs[2] == ANIM_ATTACKER && GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
|| (gBattleAnimArgs[2] == ANIM_TARGET && GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER))
{
sprite->x += 8;
}
SeekSpriteAnim(sprite, gBattleAnimArgs[4]);
sprite->x -= 32;
sprite->data[1] = 0x0ccc;
offset = gBattleAnimArgs[4];
mult = 12;
sprite->x2 += mult * offset;
sprite->data[0] = offset;
sprite->data[7] = gBattleAnimArgs[3];
sprite->callback = AnimWhirlwindLine_Step;
}
static void AnimWhirlwindLine_Step(struct Sprite *sprite)
{
sprite->x2 += sprite->data[1] >> 8;
if (++sprite->data[0] == 6)
{
sprite->data[0] = 0;
sprite->x2 = 0;
StartSpriteAnim(sprite, 0);
}
if (--sprite->data[7] == -1)
DestroyAnimSprite(sprite);
}
void AnimTask_DrillPeckHitSplats(u8 task)
{
if (!(gTasks[task].data[0] % 32))
{
gAnimVisualTaskCount++;
gBattleAnimArgs[0] = Sin(gTasks[task].data[0], -13);
gBattleAnimArgs[1] = Cos(gTasks[task].data[0], -13);
gBattleAnimArgs[2] = 1;
gBattleAnimArgs[3] = 3;
CreateSpriteAndAnimate(&gFlashingHitSplatSpriteTemplate,
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2),
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET),
3);
}
gTasks[task].data[0] += 8;
if (gTasks[task].data[0] > 255)
DestroyAnimVisualTask(task);
}
static void AnimBounceBallShrink(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
InitSpritePosToAnimAttacker(sprite, TRUE);
gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
++sprite->data[0];
break;
case 1:
if (sprite->affineAnimEnded)
DestroyAnimSprite(sprite);
break;
}
}
static void AnimBounceBallLand(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
sprite->y2 = -sprite->y - 32;
sprite->data[0]++;
break;
case 1:
sprite->y2 += 10;
if (sprite->y2 >= 0)
++sprite->data[0];
break;
case 2:
sprite->y2 -= 10;
if (sprite->y + sprite->y2 < -32)
{
gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = FALSE;
DestroyAnimSprite(sprite);
}
break;
}
}
static void AnimDiveBall(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->callback = AnimDiveBall_Step1;
gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
}
void AnimDiveBall_Step1(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
}
else if (sprite->y + sprite->y2 > -32)
{
sprite->data[2] += sprite->data[1];
sprite->y2 -= (sprite->data[2] >> 8);
}
else
{
sprite->invisible = TRUE;
if (sprite->data[3]++ > 20)
sprite->callback = AnimDiveBall_Step2;
}
}
static void AnimDiveBall_Step2(struct Sprite *sprite)
{
sprite->y2 += sprite->data[2] >> 8;
if (sprite->y + sprite->y2 > -32)
sprite->invisible = FALSE;
if (sprite->y2 > 0)
DestroyAnimSprite(sprite);
}
static void AnimDiveWaterSplash(struct Sprite *sprite)
{
u32 matrixNum;
int t1, t2;
switch (sprite->data[0])
{
case 0:
if (!gBattleAnimArgs[0])
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
}
sprite->data[1] = 0x200;
TrySetSpriteRotScale(sprite, FALSE, 0x100, sprite->data[1], 0);
sprite->data[0]++;
break;
case 1:
if (sprite->data[2] <= 11)
sprite->data[1] -= 40;
else
sprite->data[1] += 40;
sprite->data[2]++;
TrySetSpriteRotScale(sprite, FALSE, 0x100, sprite->data[1], 0);
matrixNum = sprite->oam.matrixNum;
t1 = 0x3D00;
t2 = t1 / gOamMatrices[matrixNum].d + 1;
if (t2 > 128)
t2 = 128;
t2 = (64 - t2) / 2;
sprite->y2 = t2;
if (sprite->data[2] == 24)
{
ResetSpriteRotScale_PreserveAffine(sprite);
DestroyAnimSprite(sprite);
}
break;
}
}
// Launches a water droplet away from the specified battler. Used by Astonish and Dive
static void AnimSprayWaterDroplet(struct Sprite *sprite)
{
int v1 = 0x1ff & Random2();
int v2 = 0x7f & Random2();
if (v1 % 2)
sprite->data[0] = 736 + v1;
else
sprite->data[0] = 736 - v1;
if (v2 % 2)
sprite->data[1] = 896 + v2;
else
sprite->data[1] = 896 - v2;
sprite->data[2] = gBattleAnimArgs[0];
if (sprite->data[2])
sprite->oam.matrixNum = ST_OAM_HFLIP;
if (gBattleAnimArgs[1] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 32;
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 32;
}
sprite->callback = AnimSprayWaterDroplet_Step;
}
static void AnimSprayWaterDroplet_Step(struct Sprite *sprite)
{
if (sprite->data[2] == 0)
{
sprite->x2 += sprite->data[0] >> 8;
sprite->y2 -= sprite->data[1] >> 8;
}
else
{
sprite->x2 -= sprite->data[0] >> 8;
sprite->y2 -= sprite->data[1] >> 8;
}
sprite->data[0] = sprite->data[0];
sprite->data[1] -= 32;
if (sprite->data[0] < 0)
sprite->data[0] = 0;
if (++sprite->data[3] == 31)
DestroyAnimSprite(sprite);
}
static void AnimUnusedFlashingLight(struct Sprite *sprite)
{
sprite->data[6] = 0;
sprite->data[7] = 64;
sprite->callback = AnimUnusedFlashingLight_Step;
}
static void AnimUnusedFlashingLight_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (++sprite->data[1] > 8)
{
sprite->data[1] = 0;
sprite->invisible ^= 1;
if (++sprite->data[2] > 5 && sprite->invisible)
sprite->data[0]++;
}
break;
case 1:
DestroyAnimSprite(sprite);
break;
}
}
static void AnimSkyAttackBird(struct Sprite *sprite)
{
u16 rotation;
s16 posx = sprite->x;
s16 posy = sprite->y;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[4] = sprite->x << 4;
sprite->data[5] = sprite->y << 4;
sprite->data[6] = ((posx - sprite->x) << 4) / 12;
sprite->data[7] = ((posy - sprite->y) << 4) / 12;
rotation = ArcTan2Neg(posx - sprite->x, posy - sprite->y);
rotation -= 16384;
TrySetSpriteRotScale(sprite, TRUE, 0x100, 0x100, rotation);
sprite->callback = AnimSkyAttackBird_Step;
}
void AnimSkyAttackBird_Step(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[6];
sprite->data[5] += sprite->data[7];
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
if (sprite->x > DISPLAY_WIDTH + 45 || sprite->x < -45
|| sprite->y > 157 || sprite->y < -45)
DestroySpriteAndMatrix(sprite);
}
// Unused
static void AnimTask_SetAttackerVisibility(u8 taskId)
{
if (gBattleAnimArgs[0] == 0)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = TRUE;
}
else
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = FALSE;
}
DestroyAnimVisualTask(taskId);
}
#include "global.h"
#include "battle_anim.h"
#include "constants/rgb.h"
#include "constants/songs.h"
#include "palette.h"
#include "sound.h"
#include "util.h"
#include "task.h"
#include "trig.h"
static void AnimFireSpiralInward(struct Sprite *);
static void AnimFireSpread(struct Sprite *);
static void AnimFirePlume(struct Sprite *);
static void AnimLargeFlame(struct Sprite *);
static void AnimLargeFlame_Step(struct Sprite *);
static void AnimUnusedSmallEmber(struct Sprite *);
static void AnimUnusedSmallEmber_Step(struct Sprite *);
static void AnimSunlight(struct Sprite *);
static void AnimEmberFlare(struct Sprite *);
static void AnimBurnFlame(struct Sprite *);
static void AnimFireRing(struct Sprite *);
static void AnimFireRing_Step1(struct Sprite *);
static void AnimFireRing_Step2(struct Sprite *);
static void AnimFireRing_Step3(struct Sprite *);
static void UpdateFireRingCircleOffset(struct Sprite *);
static void AnimFireCross(struct Sprite *);
static void AnimFireSpiralOutward(struct Sprite *);
static void AnimFireSpiralOutward_Step1(struct Sprite *);
static void AnimFireSpiralOutward_Step2(struct Sprite *);
static void AnimTask_EruptionLaunchRocks_Step(u8);
static void CreateEruptionLaunchRocks(u8, u8, u8);
static void AnimEruptionLaunchRock(struct Sprite *);
static u16 GetEruptionLaunchRockInitialYPos(u8);
static void InitEruptionLaunchRockCoordData(struct Sprite *, s16, s16);
static void UpdateEruptionLaunchRockPos(struct Sprite *);
static void AnimEruptionFallingRock(struct Sprite *);
static void AnimEruptionFallingRock_Step(struct Sprite *);
static void AnimWillOWispOrb(struct Sprite *);
static void AnimWillOWispOrb_Step(struct Sprite *);
static void AnimWillOWispFire(struct Sprite *);
static void AnimTask_MoveHeatWaveTargets_Step(u8);
static const union AnimCmd sAnim_FireSpiralSpread_0[] =
{
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_FireSpiralSpread_1[] =
{
ANIMCMD_FRAME(16, 4, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(48, 4, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_FireSpiralSpread[] =
{
sAnim_FireSpiralSpread_0,
sAnim_FireSpiralSpread_1,
};
const struct SpriteTemplate gFireSpiralInwardSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FireSpiralSpread,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralInward,
};
const struct SpriteTemplate gFireSpreadSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FireSpiralSpread,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpread,
};
static const union AnimCmd sAnim_LargeFlame[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_FRAME(80, 3),
ANIMCMD_FRAME(96, 3),
ANIMCMD_FRAME(112, 3),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_LargeFlame[] =
{
sAnim_LargeFlame,
};
static const union AnimCmd sAnim_FirePlume[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_FRAME(64, 5),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_FirePlume[] =
{
sAnim_FirePlume,
};
static const union AffineAnimCmd sAffineAnim_LargeFlame[] =
{
AFFINEANIMCMD_FRAME(0x32, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x20, 0x0, 0, 7),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_LargeFlame[] =
{
sAffineAnim_LargeFlame,
};
const struct SpriteTemplate gLargeFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_FIRE,
.paletteTag = ANIM_TAG_FIRE,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_LargeFlame,
.images = NULL,
.affineAnims = sAffineAnims_LargeFlame,
.callback = AnimLargeFlame,
};
const struct SpriteTemplate gLargeFlameScatterSpriteTemplate =
{
.tileTag = ANIM_TAG_FIRE,
.paletteTag = ANIM_TAG_FIRE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_LargeFlame,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLargeFlame,
};
const struct SpriteTemplate gFirePlumeSpriteTemplate =
{
.tileTag = ANIM_TAG_FIRE_PLUME,
.paletteTag = ANIM_TAG_FIRE_PLUME,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FirePlume,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFirePlume,
};
// Unused
static const struct SpriteTemplate sUnusedEmberFirePlumeSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FirePlume,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFirePlume,
};
static const union AnimCmd sAnim_UnusedSmallEmber[] =
{
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 6),
ANIMCMD_FRAME(48, 6),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_UnusedSmallEmber[] =
{
sAnim_UnusedSmallEmber,
};
// Unused
static const struct SpriteTemplate sUnusedSmallEmberSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_UnusedSmallEmber,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedSmallEmber,
};
static const union AffineAnimCmd sAffineAnim_SunlightRay[] =
{
AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0),
AFFINEANIMCMD_FRAME(0x2, 0x2, 10, 1),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_SunlightRay[] =
{
sAffineAnim_SunlightRay,
};
const struct SpriteTemplate gSunlightRaySpriteTemplate =
{
.tileTag = ANIM_TAG_SUNLIGHT,
.paletteTag = ANIM_TAG_SUNLIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_SunlightRay,
.callback = AnimSunlight,
};
static const union AnimCmd sAnim_BasicFire[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gAnims_BasicFire[] =
{
sAnim_BasicFire,
};
const struct SpriteTemplate gEmberSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
const struct SpriteTemplate gEmberFlareSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEmberFlare,
};
const struct SpriteTemplate gBurnFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBurnFlame,
};
const struct SpriteTemplate gFireBlastRingSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireRing,
};
static const union AnimCmd sAnim_FireBlastCross[] =
{
ANIMCMD_FRAME(32, 6),
ANIMCMD_FRAME(48, 6),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_FireBlastCross[] =
{
sAnim_FireBlastCross,
};
static const union AffineAnimCmd sAffineAnim_Unused_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Unused_1[] =
{
AFFINEANIMCMD_FRAME(0xA0, 0xA0, 0, 0),
AFFINEANIMCMD_END,
};
// Unused
static const union AffineAnimCmd *const sAffineAnims_Unused[] =
{
sAffineAnim_Unused_0,
sAffineAnim_Unused_1,
};
const struct SpriteTemplate gFireBlastCrossSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FireBlastCross,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireCross,
};
const struct SpriteTemplate gFireSpiralOutwardSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFireSpiralOutward,
};
const struct SpriteTemplate gWeatherBallFireDownSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWeatherBallDown,
};
const struct SpriteTemplate gEruptionLaunchRockSpriteTemplate =
{
.tileTag = ANIM_TAG_WARM_ROCK,
.paletteTag = ANIM_TAG_WARM_ROCK,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEruptionLaunchRock,
};
static const s16 sEruptionLaunchRockSpeeds[][2] =
{
{-2, -5},
{-1, -1},
{ 3, -6},
{ 4, -2},
{ 2, -8},
{-5, -5},
{ 4, -7},
};
const struct SpriteTemplate gEruptionFallingRockSpriteTemplate =
{
.tileTag = ANIM_TAG_WARM_ROCK,
.paletteTag = ANIM_TAG_WARM_ROCK,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEruptionFallingRock,
};
static const union AnimCmd sAnim_WillOWispOrb_0[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(12, 5),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_WillOWispOrb_1[] =
{
ANIMCMD_FRAME(16, 5),
ANIMCMD_END,
};
static const union AnimCmd sAnim_WillOWispOrb_2[] =
{
ANIMCMD_FRAME(20, 5),
ANIMCMD_END,
};
static const union AnimCmd sAnim_WillOWispOrb_3[] =
{
ANIMCMD_FRAME(20, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_WillOWispOrb[] =
{
sAnim_WillOWispOrb_0,
sAnim_WillOWispOrb_1,
sAnim_WillOWispOrb_2,
sAnim_WillOWispOrb_3,
};
const struct SpriteTemplate gWillOWispOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_WISP_ORB,
.paletteTag = ANIM_TAG_WISP_ORB,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_WillOWispOrb,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWillOWispOrb,
};
static const union AnimCmd sAnim_WillOWispFire[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_WillOWispFire[] =
{
sAnim_WillOWispFire,
};
const struct SpriteTemplate gWillOWispFireSpriteTemplate =
{
.tileTag = ANIM_TAG_WISP_FIRE,
.paletteTag = ANIM_TAG_WISP_FIRE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_WillOWispFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWillOWispFire,
};
// Directions for shaking up/down or left/right in AnimTask_ShakeTargetInPattern
// Only first 10 values are ever accessed.
// First pattern results in larger shakes, second results in faster oscillation
static const s8 sShakeDirsPattern0[16] =
{
-1, -1, 0, 1, 1, 0, 0, -1, -1, 1, 1, 0, 0, -1, 0, 1,
};
static const s8 sShakeDirsPattern1[16] =
{
-1, 0, 1, 0, -1, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 1,
};
// For the first stage of Fire Punch
static void AnimFireSpiralInward(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 0x3C;
sprite->data[2] = 0x9;
sprite->data[3] = 0x1E;
sprite->data[4] = 0xFE00;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteInGrowingCircle;
sprite->callback(sprite);
}
// For the impact spread of fire sprites for moves like Blaze Kick or Fire Punch
static void AnimFireSpread(struct Sprite *sprite)
{
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
sprite->callback = TranslateSpriteLinearFixedPoint;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimFirePlume(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker))
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] = -gBattleAnimArgs[4];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[4];
}
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[4] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[5];
sprite->callback = AnimLargeFlame_Step;
}
static void AnimLargeFlame(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker))
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[4];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] = -gBattleAnimArgs[4];
}
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[4] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[5];
sprite->callback = AnimLargeFlame_Step;
}
static void AnimLargeFlame_Step(struct Sprite *sprite)
{
if (++sprite->data[0] < sprite->data[4])
{
sprite->x2 += sprite->data[2];
sprite->y2 += sprite->data[3];
}
if (sprite->data[0] == sprite->data[1])
DestroySpriteAndMatrix(sprite);
}
static void AnimUnusedSmallEmber(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker))
{
sprite->x -= gBattleAnimArgs[0];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->subpriority = 8;
}
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[3] = gBattleAnimArgs[5];
sprite->data[4] = gBattleAnimArgs[6];
sprite->data[5] = 0;
sprite->callback = AnimUnusedSmallEmber_Step;
}
static void AnimUnusedSmallEmber_Step(struct Sprite *sprite)
{
if (sprite->data[3])
{
if(sprite->data[5] > 10000)
sprite->subpriority = 1;
sprite->x2 = Sin(sprite->data[0], sprite->data[1] + (sprite->data[5] >> 8));
sprite->y2 = Cos(sprite->data[0], sprite->data[1] + (sprite->data[5] >> 8));
sprite->data[0] += sprite->data[2];
sprite->data[5] += sprite->data[4];
if (sprite->data[0] > 255)
sprite->data[0] -= 256;
else if (sprite->data[0] < 0)
sprite->data[0] += 256;
sprite->data[3]--;
}
else
{
DestroySpriteAndMatrix(sprite);
}
}
// Sunlight from Sunny Day / sunny weather
static void AnimSunlight(struct Sprite *sprite)
{
sprite->x = 0;
sprite->y = 0;
sprite->data[0] = 60;
sprite->data[2] = 140;
sprite->data[4] = 80;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Animates the secondary effect of MOVE_EMBER, where the flames grow and slide
// horizontally a bit.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
// arg 5: ? (todo: something related to which mon the pixel offsets are based on)
// arg 6: ? (todo: something related to which mon the pixel offsets are based on)
static void AnimEmberFlare(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)
&& (gBattleAnimAttacker == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)
|| gBattleAnimAttacker == GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)))
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->callback = AnimTravelDiagonally;
sprite->callback(sprite);
}
static void AnimBurnFlame(struct Sprite *sprite)
{
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->callback = AnimTravelDiagonally;
}
// Animates the a fire sprite in the first-half of the MOVE_FIRE_BLAST
// animation. The fire sprite first moves in a circle around the mon,
// and then it is translated towards the target mon, while still rotating.
// Lastly, it moves in a circle around the target mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: initial wave offset
//void AnimFireRing(struct Sprite *sprite)
void AnimFireRing(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[7] = gBattleAnimArgs[2];
sprite->data[0] = 0;
sprite->callback = AnimFireRing_Step1;
}
static void AnimFireRing_Step1(struct Sprite *sprite)
{
UpdateFireRingCircleOffset(sprite);
if (++sprite->data[0] == 0x12)
{
sprite->data[0] = 0x19;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->callback = AnimFireRing_Step2;
}
}
static void AnimFireRing_Step2(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
{
sprite->data[0] = 0;
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->y2 = 0;
sprite->x2 = 0;
sprite->callback = AnimFireRing_Step3;
sprite->callback(sprite);
}
else
{
sprite->x2 += Sin(sprite->data[7], 28);
sprite->y2 += Cos(sprite->data[7], 28);
sprite->data[7] = (sprite->data[7] + 20) & 0xFF;
}
}
static void AnimFireRing_Step3(struct Sprite *sprite)
{
UpdateFireRingCircleOffset(sprite);
if (++sprite->data[0] == 0x1F)
DestroyAnimSprite(sprite);
}
static void UpdateFireRingCircleOffset(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[7], 28);
sprite->y2 = Cos(sprite->data[7], 28);
sprite->data[7] = (sprite->data[7] + 20) & 0xFF;
}
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
// arg 3: x delta
// arg 4: y delta
// AnimFireCross(struct Sprite *sprite)
static void AnimFireCross(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteLinear;
}
static void AnimFireSpiralOutward(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[3];
sprite->invisible = TRUE;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimFireSpiralOutward_Step1);
}
static void AnimFireSpiralOutward_Step1(struct Sprite *sprite)
{
sprite->invisible = FALSE;
sprite->data[0] = sprite->data[1];
sprite->data[1] = 0;
sprite->callback = AnimFireSpiralOutward_Step2;
sprite->callback(sprite);
}
static void AnimFireSpiralOutward_Step2(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[1], sprite->data[2] >> 8);
sprite->y2 = Cos(sprite->data[1], sprite->data[2] >> 8);
sprite->data[1] = (sprite->data[1] + 10) & 0xFF;
sprite->data[2] += 0xD0;
if (--sprite->data[0] == -1)
DestroyAnimSprite(sprite);
}
#define IDX_ACTIVE_SPRITES 6 // Used by the sprite callback to modify the number of active sprites
#define tState data[0]
#define tTimer1 data[1]
#define tTimer2 data[2]
#define tTimer3 data[3]
#define tAttackerY data[4]
#define tAttackerSide data[5]
#define tActiveSprites data[IDX_ACTIVE_SPRITES]
// data[8]-data[15] used by PrepareEruptAnimTaskData / UpdateEruptAnimTask
#define tAttackerSpriteId data[15]
#define sSpeedDelay data[0]
#define sLaunchStage data[1]
#define sX data[2]
#define sY data[3]
#define sSpeedX data[4]
#define sSpeedY data[5]
#define sTaskId data[6]
#define sActiveSpritesIdx data[7]
// Animates first stage of Eruption where the attacker squishes and launches rocks away from themself
void AnimTask_EruptionLaunchRocks(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->tAttackerSpriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->tState = 0;
task->tTimer1 = 0;
task->tTimer2 = 0;
task->tTimer3 = 0;
task->tAttackerY = gSprites[task->tAttackerSpriteId].y;
task->tAttackerSide = GetBattlerSide(gBattleAnimAttacker);
task->tActiveSprites = 0;
PrepareBattlerSpriteForRotScale(task->tAttackerSpriteId, ST_OAM_OBJ_NORMAL);
task->func = AnimTask_EruptionLaunchRocks_Step;
}
static void AnimTask_EruptionLaunchRocks_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
PrepareEruptAnimTaskData(task, task->tAttackerSpriteId, 0x100, 0x100, 0xE0, 0x200, 32);
task->tState++;
case 1:
if (++task->tTimer1 > 1)
{
task->tTimer1 = 0;
if (++task->tTimer2 & 1)
gSprites[task->tAttackerSpriteId].x2 = 3;
else
gSprites[task->tAttackerSpriteId].x2 = -3;
}
if (task->tAttackerSide != B_SIDE_PLAYER)
{
if (++task->tTimer3 > 4)
{
task->tTimer3 = 0;
gSprites[task->tAttackerSpriteId].y++;
}
}
if(!UpdateEruptAnimTask(task))
{
SetBattlerSpriteYOffsetFromYScale(task->tAttackerSpriteId);
gSprites[task->tAttackerSpriteId].x2 = 0;
task->tTimer1 = 0;
task->tTimer2 = 0;
task->tTimer3 = 0;
task->tState++;
}
break;
case 2:
if (++task->tTimer1 > 4)
{
if (task->tAttackerSide != B_SIDE_PLAYER)
PrepareEruptAnimTaskData(task, task->tAttackerSpriteId, 0xE0, 0x200, 0x180, 0xF0, 6);
else
PrepareEruptAnimTaskData(task, task->tAttackerSpriteId, 0xE0, 0x200, 0x180, 0xC0, 6);
task->tTimer1 = 0;
task->tState++;
}
break;
case 3:
if (!UpdateEruptAnimTask(task))
{
CreateEruptionLaunchRocks(task->tAttackerSpriteId, taskId, IDX_ACTIVE_SPRITES);
task->tState++;
}
break;
case 4:
if (++task->tTimer1 > 1)
{
task->tTimer1 = 0;
if (++task->tTimer2 & 1)
gSprites[task->tAttackerSpriteId].y2 += 3;
else
gSprites[task->tAttackerSpriteId].y2 -= 3;
}
if (++task->tTimer3 > 24)
{
if (task->tAttackerSide != B_SIDE_PLAYER)
PrepareEruptAnimTaskData(task, task->tAttackerSpriteId, 0x180, 0xF0, 0x100, 0x100, 8);
else
PrepareEruptAnimTaskData(task, task->tAttackerSpriteId, 0x180, 0xC0, 0x100, 0x100, 8);
if (task->tTimer2 & 1)
gSprites[task->tAttackerSpriteId].y2 -= 3;
task->tTimer1 = 0;
task->tTimer2 = 0;
task->tTimer3 = 0;
task->tState++;
}
break;
case 5:
if (task->tAttackerSide != B_SIDE_PLAYER)
gSprites[task->tAttackerSpriteId].y--;
if (!UpdateEruptAnimTask(task))
{
gSprites[task->tAttackerSpriteId].y = task->tAttackerY;
ResetSpriteRotScale(task->tAttackerSpriteId);
task->tTimer2 = 0;
task->tState++;
}
break;
case 6:
if (task->tActiveSprites == 0)
DestroyAnimVisualTask(taskId);
break;
default:
break;
}
}
static void CreateEruptionLaunchRocks(u8 spriteId, u8 taskId, u8 activeSpritesIdx)
{
u16 i, j;
s8 sign;
u16 y = GetEruptionLaunchRockInitialYPos(spriteId);
u16 x = gSprites[spriteId].x;
if(GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
x -= 12;
sign = 1;
}
else
{
x += 16;
sign = -1;
}
for (i = 0, j = 0; i <= 6; i++)
{
u8 spriteId = CreateSprite(&gEruptionLaunchRockSpriteTemplate, x, y, 2);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].oam.tileNum += j * 4 + 0x40;
if (++j >= 5)
j = 0;
InitEruptionLaunchRockCoordData(&gSprites[spriteId], sEruptionLaunchRockSpeeds[i][0] * sign, sEruptionLaunchRockSpeeds[i][1]);
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sActiveSpritesIdx = activeSpritesIdx;
gTasks[taskId].data[activeSpritesIdx]++;
}
}
}
static void AnimEruptionLaunchRock(struct Sprite *sprite)
{
UpdateEruptionLaunchRockPos(sprite);
if (sprite->invisible)
{
gTasks[sprite->sTaskId].data[sprite->sActiveSpritesIdx]--;
DestroySprite(sprite);
}
}
static u16 GetEruptionLaunchRockInitialYPos(u8 spriteId)
{
s16 y = gSprites[spriteId].y + gSprites[spriteId].y2 + gSprites[spriteId].centerToCornerVecY;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
y += 74;
else
y += 44;
return y;
}
static void InitEruptionLaunchRockCoordData(struct Sprite *sprite, s16 speedX, s16 speedY)
{
sprite->sSpeedDelay = 0;
sprite->sLaunchStage = 0;
sprite->sX = (u16)sprite->x * 8;
sprite->sY = (u16)sprite->y * 8;
sprite->sSpeedX = speedX * 8;
sprite->sSpeedY = speedY * 8;
}
static void UpdateEruptionLaunchRockPos(struct Sprite *sprite)
{
int extraLaunchSpeed;
if (++sprite->sSpeedDelay > 2)
{
sprite->sSpeedDelay = 0;
++sprite->sLaunchStage;
extraLaunchSpeed = (u16)sprite->sLaunchStage * (u16)sprite->sLaunchStage;
sprite->sY += extraLaunchSpeed;
}
sprite->sX += sprite->sSpeedX;
sprite->x = sprite->sX >> 3;
sprite->sY += sprite->sSpeedY;
sprite->y = sprite->sY >> 3;
if (sprite->x < -8 || sprite->x > DISPLAY_WIDTH + 8 || sprite->y < -8 || sprite->y > 120)
sprite->invisible = TRUE;
}
#undef IDX_ACTIVE_SPRITES
#undef tState
#undef tTimer1
#undef tTimer2
#undef tTimer3
#undef tAttackerY
#undef tAttackerSide
#undef tActiveSprites
#undef tAttackerSpriteId
#undef sSpeedDelay
#undef sLaunchStage
#undef sX
#undef sY
#undef sSpeedX
#undef sSpeedY
#undef sTaskId
#undef sActiveSpritesIdx
#define sState data[0]
#define sBounceTimer data[1]
#define sBounceDir data[2]
#define sEndTimer data[3]
#define sFallDelay data[6]
#define sTargetY data[7]
static void AnimEruptionFallingRock(struct Sprite *sprite)
{
sprite->x = gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1];
sprite->sState = 0;
sprite->sBounceTimer = 0;
sprite->sBounceDir = 0;
sprite->sFallDelay = gBattleAnimArgs[2];
sprite->sTargetY = gBattleAnimArgs[3];
sprite->oam.tileNum += gBattleAnimArgs[4] * 16;
sprite->callback = AnimEruptionFallingRock_Step;
}
static void AnimEruptionFallingRock_Step(struct Sprite *sprite)
{
switch (sprite->sState)
{
case 0:
// Wait to begin falling
if (sprite->sFallDelay != 0)
{
sprite->sFallDelay--;
return;
}
sprite->sState++;
// fall through
case 1:
// Rock is falling
sprite->y += 8;
if (sprite->y >= sprite->sTargetY)
{
sprite->y = sprite->sTargetY;
sprite->sState++;
}
break;
case 2:
// Bounce up and down on landing spot
if (++sprite->sBounceTimer > 1)
{
sprite->sBounceTimer = 0;
if ((++sprite->sBounceDir & 1) != 0)
sprite->y2 = -3;
else
sprite->y2 = 3;
}
if (++sprite->sEndTimer > 16)
DestroyAnimSprite(sprite);
break;
}
}
#undef sState
#undef sBounceTimer
#undef sBounceDir
#undef sEndTimer
#undef sFallDelay
#undef sTargetY
static void AnimWillOWispOrb(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
InitSpritePosToAnimAttacker(sprite, FALSE);
StartSpriteAnim(sprite, gBattleAnimArgs[2]);
sprite->data[7] = gBattleAnimArgs[2];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->data[4] = 4;
}
else
{
sprite->data[4] = -4;
}
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
sprite->data[0]++;
break;
case 1:
sprite->data[1] += 192;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->y2 = -(sprite->data[1] >> 8);
}
else
{
sprite->y2 = sprite->data[1] >> 8;
}
sprite->x2 = Sin(sprite->data[2], sprite->data[4]);
sprite->data[2] = (sprite->data[2] + 4) & 0xFF;
if (++sprite->data[3] == 1)
{
sprite->data[3] = 0;
sprite->data[0]++;
}
break;
case 2:
sprite->x2 = Sin(sprite->data[2], sprite->data[4]);
sprite->data[2] = (sprite->data[2] + 4) & 0xFF;
if (++sprite->data[3] == 31)
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 256;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslationWithSpeed(sprite);
sprite->callback = AnimWillOWispOrb_Step;
}
break;
}
}
static void AnimWillOWispOrb_Step(struct Sprite *sprite)
{
s16 initialData5;
s16 newData5;
if (!AnimTranslateLinear(sprite))
{
sprite->x2 += Sin(sprite->data[5], 16);
initialData5 = sprite->data[5];
sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
newData5 = sprite->data[5];
if ((initialData5 == 0 || initialData5 > 196) && newData5 > 0 && sprite->data[7] == 0)
{
PlaySE12WithPanning(SE_M_FLAME_WHEEL, gAnimCustomPanning);
}
}
else
{
DestroyAnimSprite(sprite);
}
}
static void AnimWillOWispFire(struct Sprite *sprite)
{
if (!sprite->data[0])
{
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[0] += 1;
}
sprite->data[3] += 0xC0 * 2;
sprite->data[4] += 0xA0;
sprite->x2 = Sin(sprite->data[1], sprite->data[3] >> 8);
sprite->y2 = Cos(sprite->data[1], sprite->data[4] >> 8);
sprite->data[1] = (sprite->data[1] + 7) & 0xFF;
if (!IsContest())
{
if (sprite->data[1] < 64 || sprite->data[1] > 195)
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
else
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1;
}
else
{
if (sprite->data[1] < 64 || sprite->data[1] > 195)
sprite->subpriority = 0x1D;
else
sprite->subpriority = 0x1F;
}
if (++sprite->data[2] > 0x14)
sprite->invisible ^= 1;
if (sprite->data[2] == 0x1E)
DestroyAnimSprite(sprite);
}
void AnimTask_MoveHeatWaveTargets(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[12] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
task->data[13] = IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)) + 1;
task->data[14] = GetAnimBattlerSpriteId(ANIM_TARGET);
task->data[15] = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER);
task->func = AnimTask_MoveHeatWaveTargets_Step;
}
static void AnimTask_MoveHeatWaveTargets_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[10] += task->data[12] * 2;
if (++task->data[1] >= 2)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
task->data[11] = 2;
else
task->data[11] = -2;
}
for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
{
gSprites[task->data[task->data[3] + 14]].x2 = task->data[10] + task->data[11];
}
if (++task->data[9] == 16)
{
task->data[9] = 0;
task->data[0]++;
}
break;
case 1:
if (++task->data[1] >= 5)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
task->data[11] = 2;
else
task->data[11] = -2;
}
for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
{
gSprites[task->data[task->data[3] + 14]].x2 = task->data[10] + task->data[11];
}
if (++task->data[9] == 96)
{
task->data[9] = 0;
task->data[0]++;
}
break;
case 2:
task->data[10] -= task->data[12] * 2;
if (++task->data[1] >= 2)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
task->data[11] = 2;
else
task->data[11] = -2;
}
for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
{
gSprites[task->data[task->data[3] + 14]].x2 = task->data[10] + task->data[11];
}
if (++task->data[9] == 16)
{
task->data[0]++;
}
break;
case 3:
for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
{
gSprites[task->data[task->data[3] + 14]].x2 = 0;
}
DestroyAnimVisualTask(taskId);
break;
}
}
// Used to add a color mask to the battle background.
// arg 0: opacity
// arg 1: color code
void AnimTask_BlendBackground(u8 taskId)
{
struct BattleAnimBgData animBg;
GetBattleAnimBg1Data(&animBg);
BlendPalette(BG_PLTT_ID(animBg.paletteId), 16, gBattleAnimArgs[0], gBattleAnimArgs[1]);
DestroyAnimVisualTask(taskId);
}
#define tShakeNum data[0]
#define tMaxShakes data[1]
#define tShakeOffset data[2] // Never read, gBattleAnimArgs[1] is used directly instead
#define tVertical data[3]
#define tPatternId data[4]
// Shakes target horizontally or vertically tMaxShakes times, following a set pattern of alternations
void AnimTask_ShakeTargetInPattern(u8 taskId)
{
s8 dir;
u8 spriteId;
if (gTasks[taskId].tShakeNum == 0)
{
gTasks[taskId].tMaxShakes = gBattleAnimArgs[0];
gTasks[taskId].tShakeOffset = gBattleAnimArgs[1];
gTasks[taskId].tVertical = gBattleAnimArgs[2];
gTasks[taskId].tPatternId = gBattleAnimArgs[3];
}
gTasks[taskId].tShakeNum++;
spriteId = gBattlerSpriteIds[gBattleAnimTarget];
if (gTasks[taskId].tPatternId == 0)
dir = sShakeDirsPattern0[gTasks[taskId].tShakeNum % 10];
else
dir = sShakeDirsPattern1[gTasks[taskId].tShakeNum % 10];
if (gTasks[taskId].tVertical == TRUE)
gSprites[spriteId].y2 = gBattleAnimArgs[1] * dir < 0 ? -(gBattleAnimArgs[1] * dir) : gBattleAnimArgs[1] * dir;
else
gSprites[spriteId].x2 = gBattleAnimArgs[1] * dir;
if (gTasks[taskId].tShakeNum == gTasks[taskId].tMaxShakes)
{
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
}
}
#include "global.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "random.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimUnusedHumanoidFoot(struct Sprite *);
static void AnimSlideHandOrFootToTarget(struct Sprite *);
static void AnimJumpKick(struct Sprite *);
static void AnimBasicFistOrFoot(struct Sprite *);
static void AnimFistOrFootRandomPos(struct Sprite *);
static void AnimFistOrFootRandomPos_Step(struct Sprite *);
static void AnimCrossChopHand(struct Sprite *);
static void AnimCrossChopHand_Step(struct Sprite *);
static void AnimSlidingKick(struct Sprite *);
static void AnimSlidingKick_Step(struct Sprite *);
static void AnimSpinningKickOrPunch(struct Sprite *);
static void AnimStompFoot(struct Sprite *);
static void AnimStompFoot_Step(struct Sprite *);
static void AnimStompFoot_End(struct Sprite *);
static void AnimDizzyPunchDuck(struct Sprite *);
static void AnimBrickBreakWall(struct Sprite *);
static void AnimBrickBreakWall_Step(struct Sprite *);
static void AnimBrickBreakWallShard(struct Sprite *);
static void AnimBrickBreakWallShard_Step(struct Sprite *);
static void AnimSuperpowerOrb(struct Sprite *);
static void AnimSuperpowerOrb_Step(struct Sprite *);
static void AnimSuperpowerRock(struct Sprite *);
static void AnimSuperpowerRock_Step1(struct Sprite *);
static void AnimSuperpowerRock_Step2(struct Sprite *);
static void AnimSuperpowerFireball(struct Sprite *);
static void AnimArmThrustHit(struct Sprite *);
static void AnimArmThrustHit_Step(struct Sprite *sprite);
static void AnimRevengeScratch(struct Sprite *);
static void AnimFocusPunchFist(struct Sprite *);
static void AnimSpinningKickOrPunchFinish(struct Sprite *);
extern struct SpriteTemplate gBasicHitSplatSpriteTemplate;
// Unused
static const struct SpriteTemplate sUnusedHumanoidFootSpriteTemplate =
{
.tileTag = ANIM_TAG_HUMANOID_FOOT,
.paletteTag = ANIM_TAG_HUMANOID_FOOT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedHumanoidFoot,
};
static const union AnimCmd sAnim_Fist[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FootWide[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FootTall[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_HandLeft[] =
{
ANIMCMD_FRAME(48, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_HandRight[] =
{
ANIMCMD_FRAME(48, 1, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_HandsAndFeet[] =
{
sAnim_Fist,
sAnim_FootWide,
sAnim_FootTall,
sAnim_HandLeft,
sAnim_HandRight,
};
const struct SpriteTemplate gKarateChopSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSlideHandOrFootToTarget,
};
const struct SpriteTemplate gJumpKickSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimJumpKick,
};
const struct SpriteTemplate gFistFootSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBasicFistOrFoot,
};
const struct SpriteTemplate gFistFootRandomPosSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFistOrFootRandomPos,
};
const struct SpriteTemplate gCrossChopHandSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = &sAnims_HandsAndFeet[3],
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCrossChopHand,
};
const struct SpriteTemplate gSlidingKickSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = &sAnims_HandsAndFeet[1],
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSlidingKick,
};
static const union AffineAnimCmd sAffineAnim_SpinningHandOrFoot[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 20, 1),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_SpinningHandOrFoot[] =
{
sAffineAnim_SpinningHandOrFoot,
};
// Blaze Kick / Meteor Mash
const struct SpriteTemplate gSpinningHandOrFootSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = sAffineAnims_SpinningHandOrFoot,
.callback = AnimSpinningKickOrPunch,
};
static const union AffineAnimCmd sAffineAnim_MegaPunchKick[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFC, 20, 1),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_MegaPunchKick[] =
{
sAffineAnim_MegaPunchKick,
};
const struct SpriteTemplate gMegaPunchKickSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = sAffineAnims_MegaPunchKick,
.callback = AnimSpinningKickOrPunch,
};
const struct SpriteTemplate gStompFootSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = &sAnims_HandsAndFeet[1],
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimStompFoot,
};
const struct SpriteTemplate gDizzyPunchDuckSpriteTemplate =
{
.tileTag = ANIM_TAG_DUCK,
.paletteTag = ANIM_TAG_DUCK,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDizzyPunchDuck,
};
const struct SpriteTemplate gBrickBreakWallSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_LIGHT_WALL,
.paletteTag = ANIM_TAG_BLUE_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBrickBreakWall,
};
const struct SpriteTemplate gBrickBreakWallShardSpriteTemplate =
{
.tileTag = ANIM_TAG_TORN_METAL,
.paletteTag = ANIM_TAG_TORN_METAL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBrickBreakWallShard,
};
static const union AffineAnimCmd sAffineAnim_SuperpowerOrb[] =
{
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 64),
AFFINEANIMCMD_FRAME(0xFFFA, 0xFFFA, 0, 8),
AFFINEANIMCMD_FRAME(0x6, 0x6, 0, 8),
AFFINEANIMCMD_JUMP(2),
};
static const union AffineAnimCmd *const sAffineAnims_SuperpowerOrb[] =
{
sAffineAnim_SuperpowerOrb,
};
const struct SpriteTemplate gSuperpowerOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_SuperpowerOrb,
.callback = AnimSuperpowerOrb,
};
const struct SpriteTemplate gSuperpowerRockSpriteTemplate =
{
.tileTag = ANIM_TAG_FLAT_ROCK,
.paletteTag = ANIM_TAG_FLAT_ROCK,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSuperpowerRock,
};
const struct SpriteTemplate gSuperpowerFireballSpriteTemplate =
{
.tileTag = ANIM_TAG_METEOR,
.paletteTag = ANIM_TAG_METEOR,
.oam = &gOamData_AffineOff_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSuperpowerFireball,
};
const struct SpriteTemplate gArmThrustHandSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimArmThrustHit,
};
static const union AnimCmd sAnim_RevengeSmallScratch_0[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_END,
};
static const union AnimCmd sAnim_RevengeSmallScratch_1[] =
{
ANIMCMD_FRAME(0, 4, .vFlip = TRUE),
ANIMCMD_FRAME(16, 4, .vFlip = TRUE),
ANIMCMD_FRAME(32, 4, .vFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_RevengeSmallScratch_2[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_RevengeSmallScratch[] =
{
sAnim_RevengeSmallScratch_0,
sAnim_RevengeSmallScratch_1,
sAnim_RevengeSmallScratch_2,
};
const struct SpriteTemplate gRevengeSmallScratchSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_SCRATCH,
.paletteTag = ANIM_TAG_PURPLE_SCRATCH,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_RevengeSmallScratch,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRevengeScratch,
};
static const union AnimCmd sAnim_RevengeBigScratch_0[] =
{
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(64, 6),
ANIMCMD_END,
};
static const union AnimCmd sAnim_RevengeBigScratch_1[] =
{
ANIMCMD_FRAME(0, 6, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(64, 6, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_RevengeBigScratch_2[] =
{
ANIMCMD_FRAME(0, 6, .hFlip = TRUE),
ANIMCMD_FRAME(64, 6, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_RevengeBigScratch[] =
{
sAnim_RevengeBigScratch_0,
sAnim_RevengeBigScratch_1,
sAnim_RevengeBigScratch_2,
};
const struct SpriteTemplate gRevengeBigScratchSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_SWIPE,
.paletteTag = ANIM_TAG_PURPLE_SWIPE,
.oam = &gOamData_AffineOff_ObjNormal_64x64,
.anims = sAnims_RevengeBigScratch,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRevengeScratch,
};
static const union AffineAnimCmd sAffineAnim_FocusPunchFist[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
AFFINEANIMCMD_FRAME(0xFFE0, 0xFFE0, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_FocusPunchFist[] =
{
sAffineAnim_FocusPunchFist,
};
const struct SpriteTemplate gFocusPunchFistSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_HandsAndFeet,
.images = NULL,
.affineAnims = sAffineAnims_FocusPunchFist,
.callback = AnimFocusPunchFist,
};
static void AnimUnusedHumanoidFoot(struct Sprite *sprite)
{
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = 15;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimSlideHandOrFootToTarget(struct Sprite *sprite)
{
if (gBattleAnimArgs[7] == 1 && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
StartSpriteAnim(sprite, gBattleAnimArgs[6]);
gBattleAnimArgs[6] = 0;
AnimTravelDiagonally(sprite);
}
static void AnimJumpKick(struct Sprite *sprite)
{
if (IsContest())
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
AnimSlideHandOrFootToTarget(sprite);
}
// Displays a basic fist or foot sprite for a given duration.
// Used by many fighting moves (and elemental "punch" moves).
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
// arg 3: ? (todo: related to initial pixel offsets)
// arg 4: anim num
static void AnimBasicFistOrFoot(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[4]);
if (gBattleAnimArgs[3] == 0)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimFistOrFootRandomPos(struct Sprite *sprite)
{
u8 battler;
s16 xMod, yMod;
s16 x, y;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
if (gBattleAnimArgs[2] < 0)
gBattleAnimArgs[2] = Random2() % 5;
StartSpriteAnim(sprite, gBattleAnimArgs[2]);
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET);
xMod = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_WIDTH) / 2;
yMod = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_HEIGHT) / 4;
x = Random2() % xMod;
y = Random2() % yMod;
if (Random2() & 1)
x *= -1;
if (Random2() & 1)
y *= -1;
if (GET_BATTLER_SIDE2(battler) == B_SIDE_PLAYER)
y += 0xFFF0;
sprite->x += x;
sprite->y += y;
sprite->data[0] = gBattleAnimArgs[1];
sprite->data[7] = CreateSprite(&gBasicHitSplatSpriteTemplate, sprite->x, sprite->y, sprite->subpriority + 1);
if (sprite->data[7] != MAX_SPRITES)
{
StartSpriteAffineAnim(&gSprites[sprite->data[7]], 0);
gSprites[sprite->data[7]].callback = SpriteCallbackDummy;
}
sprite->callback = AnimFistOrFootRandomPos_Step;
}
static void AnimFistOrFootRandomPos_Step(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
if (sprite->data[7] != MAX_SPRITES)
{
FreeOamMatrix(gSprites[sprite->data[7]].oam.matrixNum);
DestroySprite(&gSprites[sprite->data[7]]);
}
DestroyAnimSprite(sprite);
}
else
{
sprite->data[0]--;
}
}
static void AnimCrossChopHand(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = 30;
if (gBattleAnimArgs[2] == 0)
{
sprite->data[2] = sprite->x - 20;
}
else
{
sprite->data[2] = sprite->x + 20;
sprite->hFlip = 1;
}
sprite->data[4] = sprite->y - 20;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimCrossChopHand_Step);
}
static void AnimCrossChopHand_Step(struct Sprite *sprite)
{
if (++sprite->data[5] == 11)
{
sprite->data[2] = sprite->x - sprite->x2;
sprite->data[4] = sprite->y - sprite->y2;
sprite->data[0] = 8;
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
}
// Rolling Kick / Low Kick
static void AnimSlidingKick(struct Sprite *sprite)
{
if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget && GetBattlerPosition(gBattleAnimTarget) < B_POSITION_PLAYER_RIGHT)
gBattleAnimArgs[0] *= -1;
InitSpritePosToAnimTarget(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y;
InitAnimLinearTranslation(sprite);
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[4];
sprite->data[7] = 0;
sprite->callback = AnimSlidingKick_Step;
}
static void AnimSlidingKick_Step(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->y2 += Sin(sprite->data[7] >> 8, sprite->data[5]);
sprite->data[7] += sprite->data[6];
}
else
{
DestroyAnimSprite(sprite);
}
}
// Animates the spinning, shrinking kick or punch, which then
// reappears at full size. Used by moves such as MOVE_MEGA_PUNCH and MOVE_MEGA_KICK.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: anim num
// arg 3: spin duration
static void AnimSpinningKickOrPunch(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
StartSpriteAnim(sprite, gBattleAnimArgs[2]);
sprite->data[0] = gBattleAnimArgs[3];
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimSpinningKickOrPunchFinish);
}
static void AnimSpinningKickOrPunchFinish(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, 0);
sprite->affineAnimPaused = 1;
sprite->data[0] = 20;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Animates MOVE_STOMP's foot that slides downward.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: initial wait duration
static void AnimStompFoot(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->callback = AnimStompFoot_Step;
}
static void AnimStompFoot_Step(struct Sprite *sprite)
{
if (--sprite->data[0] == -1)
{
sprite->data[0] = 6;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimStompFoot_End);
}
}
static void AnimStompFoot_End(struct Sprite *sprite)
{
sprite->data[0] = 15;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimDizzyPunchDuck(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
sprite->data[0]++;
}
else
{
sprite->data[4] += sprite->data[1];
sprite->x2 = sprite->data[4] >> 8;
sprite->y2 = Sin(sprite->data[3], sprite->data[2]);
sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
if (sprite->data[3] > 100)
sprite->invisible = sprite->data[3] % 2;
if (sprite->data[3] > 120)
DestroyAnimSprite(sprite);
}
}
// The wall that appears when Brick Break is going to shatter the target's defensive wall
static void AnimBrickBreakWall(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
}
sprite->x += gBattleAnimArgs[1];
sprite->y += gBattleAnimArgs[2];
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[3] = 0;
sprite->callback = AnimBrickBreakWall_Step;
}
static void AnimBrickBreakWall_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (--sprite->data[1] == 0)
{
if (sprite->data[2] == 0)
DestroyAnimSprite(sprite);
else
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
sprite->data[3]++;
if (sprite->data[3] & 1)
sprite->x2 = 2;
else
sprite->x2 = -2;
}
if (--sprite->data[2] == 0)
DestroyAnimSprite(sprite);
break;
}
}
// Piece of shattered defensive wall flies off. Used by Brick Break when the target has a defensive wall
static void AnimBrickBreakWallShard(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[2];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[3];
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[2];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[3];
}
sprite->oam.tileNum += gBattleAnimArgs[1] * 16;
sprite->data[0] = 0;
switch (gBattleAnimArgs[1])
{
case 0:
sprite->data[6] = -3;
sprite->data[7] = -3;
break;
case 1:
sprite->data[6] = 3;
sprite->data[7] = -3;
break;
case 2:
sprite->data[6] = -3;
sprite->data[7] = 3;
break;
case 3:
sprite->data[6] = 3;
sprite->data[7] = 3;
break;
default:
DestroyAnimSprite(sprite);
return;
}
sprite->callback = AnimBrickBreakWallShard_Step;
}
static void AnimBrickBreakWallShard_Step(struct Sprite *sprite)
{
sprite->x += sprite->data[6];
sprite->y += sprite->data[7];
if (++sprite->data[0] > 40)
DestroyAnimSprite(sprite);
}
static void AnimSuperpowerOrb(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattlerAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattlerAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
sprite->data[7] = gBattleAnimTarget;
}
else
{
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
sprite->data[7] = gBattleAnimAttacker;
}
sprite->data[0] = 0;
sprite->data[1] = 12;
sprite->data[2] = 8;
sprite->callback = AnimSuperpowerOrb_Step;
}
static void AnimSuperpowerOrb_Step(struct Sprite *sprite)
{
if (++sprite->data[0] == 180)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
sprite->data[0] = 16;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(sprite->data[7], BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(sprite->data[7], BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = AnimTranslateLinear_WithFollowup;
}
}
// Floating rock that flies off to hit the target. Used by Superpower
static void AnimSuperpowerRock(struct Sprite *sprite)
{
sprite->x = gBattleAnimArgs[0];
sprite->y = 120;
sprite->data[0] = gBattleAnimArgs[3];
StorePointerInVars(&sprite->data[4], &sprite->data[5], (void *)(sprite->y << 8));
sprite->data[6] = gBattleAnimArgs[1];
sprite->oam.tileNum += gBattleAnimArgs[2] * 4;
sprite->callback = AnimSuperpowerRock_Step1;
}
static void AnimSuperpowerRock_Step1(struct Sprite *sprite)
{
void *var0;
if (sprite->data[0] != 0)
{
var0 = LoadPointerFromVars(sprite->data[4], sprite->data[5]);
var0 -= sprite->data[6];
StorePointerInVars(&sprite->data[4], &sprite->data[5], var0);
var0 = (void *)(((intptr_t)var0) >> 8);
sprite->y = (intptr_t)var0;
if (sprite->y < -8)
DestroyAnimSprite(sprite);
else
sprite->data[0]--;
}
else
{
s16 pos0 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
s16 pos1 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
s16 pos2 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
s16 pos3 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = pos2 - pos0;
sprite->data[1] = pos3 - pos1;
sprite->data[2] = sprite->x << 4;
sprite->data[3] = sprite->y << 4;
sprite->callback = AnimSuperpowerRock_Step2;
}
}
static void AnimSuperpowerRock_Step2(struct Sprite *sprite)
{
u16 edgeX;
sprite->data[2] += sprite->data[0];
sprite->data[3] += sprite->data[1];
sprite->x = sprite->data[2] >> 4;
sprite->y = sprite->data[3] >> 4;
edgeX = sprite->x + 8;
if (edgeX > 256 || sprite->y < -8 || sprite->y > 120)
DestroyAnimSprite(sprite);
}
static void AnimSuperpowerFireball(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattlerAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattlerAttacker, BATTLER_COORD_Y_PIC_OFFSET);
battler = gBattleAnimTarget;
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
}
else
{
battler = gBattleAnimAttacker;
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
}
if (IsContest())
sprite->oam.matrixNum |= ST_OAM_HFLIP;
else if (GetBattlerSide(battler) == B_SIDE_PLAYER)
sprite->oam.matrixNum |= (ST_OAM_HFLIP | ST_OAM_VFLIP);
sprite->data[0] = 16;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = AnimTranslateLinear_WithFollowup;
}
static void AnimArmThrustHit_Step(struct Sprite *sprite)
{
if (sprite->data[0] == sprite->data[4])
DestroyAnimSprite(sprite);
sprite->data[0]++;
}
static void AnimArmThrustHit(struct Sprite *sprite)
{
u8 turn;
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[0];
sprite->data[3] = gBattleAnimArgs[1];
sprite->data[4] = gBattleAnimArgs[2];
turn = gAnimMoveTurn;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
turn++;
if (turn & 1)
{
sprite->data[2] = -sprite->data[2];
sprite->data[1]++;
}
StartSpriteAnim(sprite, sprite->data[1]);
sprite->x2 = sprite->data[2];
sprite->y2 = sprite->data[3];
sprite->callback = AnimArmThrustHit_Step;
}
static void AnimRevengeScratch(struct Sprite *sprite)
{
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
if (IsContest())
{
StartSpriteAnim(sprite, 2);
}
else if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
StartSpriteAnim(sprite, 1);
}
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Fist shrinks toward target and shakes
static void AnimFocusPunchFist(struct Sprite *sprite)
{
if (sprite->affineAnimEnded)
{
sprite->data[1] = (sprite->data[1] + 40) & 0xFF;
sprite->x2 = Sin(sprite->data[1], 2);
if (++sprite->data[0] > 40)
DestroyAnimSprite(sprite);
}
}
void AnimTask_MoveSkyUppercutBg(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
UpdateAnimBg3ScreenSize(FALSE);
task->data[8] = gBattleAnimArgs[0];
task->data[0]++;
break;
case 1:
if (--task->data[8] == -1)
task->data[0]++;
break;
case 2:
default:
task->data[9] += 1280;
break;
}
task->data[10] += 2816;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
gBattle_BG3_X += task->data[9] >> 8;
else
gBattle_BG3_X -= task->data[9] >> 8;
gBattle_BG3_Y += task->data[10] >> 8;
task->data[9] &= 0xFF;
task->data[10] &= 0xFF;
if (gBattleAnimArgs[7] == -1)
{
gBattle_BG3_X = 0;
gBattle_BG3_Y = 0;
UpdateAnimBg3ScreenSize(TRUE);
DestroyAnimVisualTask(taskId);
}
}
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "palette.h"
#include "constants/rgb.h"
#include "scanline_effect.h"
#include "constants/songs.h"
#include "sound.h"
#include "trig.h"
#include "util.h"
static void AnimConfuseRayBallBounce(struct Sprite *);
static void AnimConfuseRayBallBounce_Step1(struct Sprite *);
static void AnimConfuseRayBallBounce_Step2(struct Sprite *);
static void UpdateConfuseRayBallBlend(struct Sprite *);
static void AnimConfuseRayBallSpiral(struct Sprite *);
static void AnimConfuseRayBallSpiral_Step(struct Sprite *);
static void AnimTask_NightShadeClone_Step1(u8 taskId);
static void AnimTask_NightShadeClone_Step2(u8 taskId);
static void AnimShadowBall(struct Sprite *);
static void AnimShadowBall_Step(struct Sprite *);
static void AnimLick(struct Sprite *);
static void AnimLick_Step(struct Sprite *);
static void AnimTask_NightmareClone_Step(u8 taskId);
static void AnimTask_SpiteTargetShadow_Step1(u8 taskId);
static void AnimTask_SpiteTargetShadow_Step2(u8 taskId);
static void AnimTask_SpiteTargetShadow_Step3(u8 taskId);
static void AnimDestinyBondWhiteShadow(struct Sprite *);
static void AnimDestinyBondWhiteShadow_Step(struct Sprite *);
static void AnimTask_DestinyBondWhiteShadow_Step(u8 taskId);
static void AnimTask_CurseStretchingBlackBg_Step1(u8 taskId);
static void AnimTask_CurseStretchingBlackBg_Step2(u8 taskId);
static void AnimCurseNail(struct Sprite *);
static void AnimCurseNail_Step1(struct Sprite *);
static void AnimCurseNail_Step2(struct Sprite *);
static void AnimCurseNail_End(struct Sprite *);
static void AnimGhostStatusSprite(struct Sprite *);
static void AnimGhostStatusSprite_Step(struct Sprite *);
static void AnimTask_GrudgeFlames_Step(u8 taskId);
static void AnimGrudgeFlame(struct Sprite *);
static void AnimMonMoveCircular(struct Sprite *);
static void AnimMonMoveCircular_Step(struct Sprite *);
static const union AffineAnimCmd sAffineAnim_ConfuseRayBallBounce[] =
{
AFFINEANIMCMD_FRAME(0x1E, 0x1E, 10, 5),
AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 10, 5),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_ConfuseRayBallBounce[] =
{
sAffineAnim_ConfuseRayBallBounce,
};
const struct SpriteTemplate gConfuseRayBallBounceSpriteTemplate =
{
.tileTag = ANIM_TAG_YELLOW_BALL,
.paletteTag = ANIM_TAG_YELLOW_BALL,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_ConfuseRayBallBounce,
.callback = AnimConfuseRayBallBounce,
};
const struct SpriteTemplate gConfuseRayBallSpiralSpriteTemplate =
{
.tileTag = ANIM_TAG_YELLOW_BALL,
.paletteTag = ANIM_TAG_YELLOW_BALL,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimConfuseRayBallSpiral,
};
static const union AffineAnimCmd sAffineAnim_ShadowBall[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_ShadowBall[] =
{
sAffineAnim_ShadowBall,
};
const struct SpriteTemplate gShadowBallSpriteTemplate =
{
.tileTag = ANIM_TAG_SHADOW_BALL,
.paletteTag = ANIM_TAG_SHADOW_BALL,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_ShadowBall,
.callback = AnimShadowBall,
};
static const union AnimCmd sAnim_Lick[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(8, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(24, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_Lick[] =
{
sAnim_Lick,
};
const struct SpriteTemplate gLickSpriteTemplate =
{
.tileTag = ANIM_TAG_LICK,
.paletteTag = ANIM_TAG_LICK,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = sAnims_Lick,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLick,
};
static const union AffineAnimCmd sAffineAnim_Unused[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
AFFINEANIMCMD_END,
};
// Unused
static const union AffineAnimCmd *const sAffineAnims_Unused[] =
{
sAffineAnim_Unused,
};
const struct SpriteTemplate gDestinyBondWhiteShadowSpriteTemplate =
{
.tileTag = ANIM_TAG_WHITE_SHADOW,
.paletteTag = ANIM_TAG_WHITE_SHADOW,
.oam = &gOamData_AffineOff_ObjBlend_64x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDestinyBondWhiteShadow,
};
const struct SpriteTemplate gCurseNailSpriteTemplate =
{
.tileTag = ANIM_TAG_NAIL,
.paletteTag = ANIM_TAG_NAIL,
.oam = &gOamData_AffineOff_ObjBlend_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCurseNail,
};
const struct SpriteTemplate gCurseGhostSpriteTemplate =
{
.tileTag = ANIM_TAG_GHOSTLY_SPIRIT,
.paletteTag = ANIM_TAG_GHOSTLY_SPIRIT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGhostStatusSprite,
};
const struct SpriteTemplate gNightmareDevilSpriteTemplate =
{
.tileTag = ANIM_TAG_DEVIL,
.paletteTag = ANIM_TAG_DEVIL,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGhostStatusSprite,
};
static const union AnimCmd sAnim_GrudgeFlame[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(8, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(24, 4),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_GrudgeFlame[] =
{
sAnim_GrudgeFlame,
};
const struct SpriteTemplate gGrudgeFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_FLAME,
.paletteTag = ANIM_TAG_PURPLE_FLAME,
.oam = &gOamData_AffineOff_ObjBlend_16x32,
.anims = sAnims_GrudgeFlame,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGrudgeFlame,
};
// Unused
static const struct SpriteTemplate sMonMoveCircularSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMonMoveCircular,
};
static void AnimConfuseRayBallBounce(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslationWithSpeed(sprite);
sprite->callback = AnimConfuseRayBallBounce_Step1;
sprite->data[6] = 16;
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]);
}
static void AnimConfuseRayBallBounce_Step1(struct Sprite *sprite)
{
s16 r0;
s16 r2;
UpdateConfuseRayBallBlend(sprite);
if (AnimTranslateLinear(sprite))
{
sprite->callback = AnimConfuseRayBallBounce_Step2;
return;
}
sprite->x2 += Sin(sprite->data[5], 10);
sprite->y2 += Cos(sprite->data[5], 15);
r2 = sprite->data[5];
sprite->data[5] = (sprite->data[5] + 5) & 0xFF;
r0 = sprite->data[5];
if (r2 != 0 && r2 <= 196)
return;
if (r0 <= 0)
return;
PlaySE12WithPanning(SE_M_CONFUSE_RAY, gAnimCustomPanning);
}
static void AnimConfuseRayBallBounce_Step2(struct Sprite *sprite)
{
s16 r2;
s16 r0;
sprite->data[0] = 1;
AnimTranslateLinear(sprite);
sprite->x2 += Sin(sprite->data[5], 10);
sprite->y2 += Cos(sprite->data[5], 15);
r2 = sprite->data[5];
sprite->data[5] = (sprite->data[5] + 5) & 0xFF;
r0 = sprite->data[5];
if (r2 == 0 || r2 > 196)
{
if (r0 > 0)
PlaySE(SE_M_CONFUSE_RAY);
}
if (sprite->data[6] == 0)
{
sprite->invisible = TRUE;
sprite->callback = DestroyAnimSpriteAndDisableBlend;
}
else
UpdateConfuseRayBallBlend(sprite);
}
static void UpdateConfuseRayBallBlend(struct Sprite *sprite)
{
if (sprite->data[6] > 0xFF)
{
if (++sprite->data[6] == 0x10d)
sprite->data[6] = 0;
return;
}
if ((sprite->data[7]++ & 0xFF) == 0)
{
sprite->data[7] &= 0xff00;
if ((sprite->data[7] & 0x100) != 0)
sprite->data[6]++;
else
sprite->data[6]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], 16 - sprite->data[6]));
if (sprite->data[6] == 0 || sprite->data[6] == 16)
sprite->data[7] ^= 0x100;
if (sprite->data[6] == 0)
sprite->data[6] = 0x100;
}
}
static void AnimConfuseRayBallSpiral(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = AnimConfuseRayBallSpiral_Step;
sprite->callback(sprite);
}
static void AnimConfuseRayBallSpiral_Step(struct Sprite *sprite)
{
u16 temp1;
sprite->x2 = Sin(sprite->data[0], 32);
sprite->y2 = Cos(sprite->data[0], 8);
temp1 = sprite->data[0] - 65;
if (temp1 <= 130)
sprite->oam.priority = 2;
else
sprite->oam.priority = 1;
sprite->data[0] = (sprite->data[0] + 19) & 0xFF;
sprite->data[2] += 80;
sprite->y2 += sprite->data[2] >> 8;
sprite->data[7] += 1;
if (sprite->data[7] == 61)
DestroyAnimSprite(sprite);
}
// Creates a large transparent clone of the attacker centered on their position which shrinks to original size
void AnimTask_NightShadeClone(u8 taskId)
{
u8 spriteId;
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
SetSpriteRotScale(spriteId, 128, 128, 0);
gSprites[spriteId].invisible = FALSE;
gTasks[taskId].data[0] = 128;
gTasks[taskId].data[1] = *gBattleAnimArgs;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = 16;
gTasks[taskId].func = AnimTask_NightShadeClone_Step1;
}
static void AnimTask_NightShadeClone_Step1(u8 taskId)
{
gTasks[taskId].data[10] += 1;
if (gTasks[taskId].data[10] == 3)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[2] += 1;
gTasks[taskId].data[3] -= 1;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[2], gTasks[taskId].data[3]));
if (gTasks[taskId].data[2] != 9)
return;
gTasks[taskId].func = AnimTask_NightShadeClone_Step2;
}
}
static void AnimTask_NightShadeClone_Step2(u8 taskId)
{
u8 spriteId;
if (gTasks[taskId].data[1] > 0)
{
gTasks[taskId].data[1] -= 1;
return;
}
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gTasks[taskId].data[0] += 8;
if (gTasks[taskId].data[0] <= 0xFF)
{
SetSpriteRotScale(spriteId, gTasks[taskId].data[0], gTasks[taskId].data[0], 0);
}
else
{
ResetSpriteRotScale(spriteId);
DestroyAnimVisualTask(taskId);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
}
}
// Spins a sprite towards the target, pausing in the middle.
// Used in Shadow Ball.
// arg 0: duration step 1 (attacker -> center)
// arg 1: duration step 2 (spin center)
// arg 2: duration step 3 (center -> target)
static void AnimShadowBall(struct Sprite *sprite)
{
s16 oldPosX = sprite->x;
s16 oldPosY = sprite->y;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[3] = gBattleAnimArgs[2];
sprite->data[4] = sprite->x << 4;
sprite->data[5] = sprite->y << 4;
sprite->data[6] = ((oldPosX - sprite->x) << 4) / (gBattleAnimArgs[0] << 1);
sprite->data[7] = ((oldPosY - sprite->y) << 4) / (gBattleAnimArgs[0] << 1);
sprite->callback = AnimShadowBall_Step;
}
static void AnimShadowBall_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->data[4] += sprite->data[6];
sprite->data[5] += sprite->data[7];
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
sprite->data[1] -= 1;
if (sprite->data[1] > 0)
break;
sprite->data[0] += 1;
break;
case 1:
sprite->data[2] -= 1;
if (sprite->data[2] > 0)
break;
sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[4] = sprite->x << 4;
sprite->data[5] = sprite->y << 4;
sprite->data[6] = ((sprite->data[1] - sprite->x) << 4) / sprite->data[3];
sprite->data[7] = ((sprite->data[2] - sprite->y) << 4) / sprite->data[3];
sprite->data[0] += 1;
break;
case 2:
sprite->data[4] += sprite->data[6];
sprite->data[5] += sprite->data[7];
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
sprite->data[3] -= 1;
if (sprite->data[3] > 0)
break;
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] += 1;
break;
case 3:
DestroySpriteAndMatrix(sprite);
break;
}
}
static void AnimLick(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = AnimLick_Step;
}
static void AnimLick_Step(struct Sprite *sprite)
{
bool8 r5 = FALSE;
bool8 r6 = FALSE;
if (sprite->animEnded)
{
if (!sprite->invisible)
sprite->invisible = TRUE;
switch (sprite->data[0])
{
default:
r6 = TRUE;
break;
case 0:
if (sprite->data[1] == 2)
r5 = TRUE;
break;
case 1:
if (sprite->data[1] == 4)
r5 = TRUE;
break;
}
if (r5)
{
sprite->invisible ^= 1;
sprite->data[2]++;
sprite->data[1] = 0;
if (sprite->data[2] == 5)
{
sprite->data[2] = 0;
sprite->data[0]++;
}
}
else if (r6)
{
DestroyAnimSprite(sprite);
}
else
{
sprite->data[1]++;
}
}
}
// Creates a transparent clone of the target which drifts up and away to the side
void AnimTask_NightmareClone(u8 taskId)
{
struct Task *task;
task = &gTasks[taskId];
task->data[0] = CloneBattlerSpriteWithBlend(ANIM_TARGET);
if (task->data[0] < 0)
{
DestroyAnimVisualTask(taskId);
return;
}
task->data[1] = 0;
task->data[2] = 15;
task->data[3] = 2;
task->data[4] = 0;
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
gSprites[task->data[0]].data[0] = 80;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
gSprites[task->data[0]].data[1] = -144;
gSprites[task->data[0]].data[2] = 112;
}
else
{
gSprites[task->data[0]].data[1] = 144;
gSprites[task->data[0]].data[2] = -112;
}
gSprites[task->data[0]].data[3] = 0;
gSprites[task->data[0]].data[4] = 0;
StoreSpriteCallbackInData6(&gSprites[task->data[0]], SpriteCallbackDummy);
gSprites[task->data[0]].callback = TranslateSpriteLinearFixedPoint;
task->func = AnimTask_NightmareClone_Step;
}
static void AnimTask_NightmareClone_Step(u8 taskId)
{
struct Task *task;
task = &gTasks[taskId];
switch (task->data[4])
{
case 0:
task->data[1] += 1;
task->data[5] = task->data[1] & 3;
if (task->data[5] == 1)
if (task->data[2] > 0)
task->data[2] -= 1;
if (task->data[5] == 3)
if (task->data[3] <= 15)
task->data[3] += 1;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
if (task->data[3] != 16 || task->data[2] != 0)
break;
if (task->data[1] <= 80)
break;
DestroySpriteWithActiveSheet(&gSprites[task->data[0]]);
task->data[4] = 1;
break;
case 1:
if (++task->data[6] <= 1)
break;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
task->data[4] += 1;
break;
case 2:
DestroyAnimVisualTask(taskId);
break;
}
}
// Creates a blended copy of the target that wavers in front of them
void AnimTask_SpiteTargetShadow(u8 taskId)
{
struct Task *task;
task = &gTasks[taskId];
task->data[15] = 0;
task->func = AnimTask_SpiteTargetShadow_Step1;
task->func(taskId);
}
static void AnimTask_SpiteTargetShadow_Step1(u8 taskId)
{
s16 startLine;
struct Task *task = &gTasks[taskId];
u8 position = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
switch (task->data[15])
{
case 0:
task->data[14] = AllocSpritePalette(ANIM_TAG_BENT_SPOON);
if (task->data[14] == 0xFF || task->data[14] == 0xF)
{
DestroyAnimVisualTask(taskId);
}
else
{
task->data[0] = CloneBattlerSpriteWithBlend(ANIM_TARGET);
if (task->data[0] < 0)
{
FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
DestroyAnimVisualTask(taskId);
}
else
{
s16 mask2;
gSprites[task->data[0]].oam.paletteNum = task->data[14];
gSprites[task->data[0]].oam.objMode = ST_OAM_OBJ_NORMAL;
gSprites[task->data[0]].oam.priority = 3;
gSprites[task->data[0]].invisible = (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible);
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 16;
task->data[13] = GetAnimBattlerSpriteId(ANIM_TARGET);
task->data[4] = (gSprites[task->data[13]].oam.paletteNum + 16) * 16;
if (position == 1) {
u16 mask = DISPCNT_BG1_ON;
mask2 = mask;
}
else {
u16 mask = DISPCNT_BG2_ON;
mask2 = mask;
}
ClearGpuRegBits(REG_OFFSET_DISPCNT, mask2);
task->data[15]++;
}
}
break;
case 1:
task->data[14] = OBJ_PLTT_ID2(task->data[14]);
CpuCopy32(&gPlttBufferUnfaded[task->data[4]], &gPlttBufferFaded[task->data[14]], PLTT_SIZE_4BPP);
BlendPalette(task->data[4], 16, 10, RGB(13, 0, 15));
task->data[15]++;
break;
case 2:
startLine = gSprites[task->data[13]].y + gSprites[task->data[13]].y2 - 32;
if (startLine < 0)
startLine = 0;
if (position == 1)
task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, SCANLINE_EFFECT_REG_BG1HOFS, TRUE);
else
task->data[10] = ScanlineEffect_InitWave(startLine, startLine + 64, 2, 6, 0, SCANLINE_EFFECT_REG_BG2HOFS, TRUE);
task->data[15]++;
break;
case 3:
if (position == 1)
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1));
else
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG2));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
task->data[15]++;
break;
case 4:
if (position == 1)
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
task->func = AnimTask_SpiteTargetShadow_Step2;
task->data[15]++;
break;
default:
task->data[15]++;
break;
}
}
static void AnimTask_SpiteTargetShadow_Step2(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[1]++;
task->data[5] = task->data[1] & 1;
if (task->data[5] == 0)
task->data[2] = gSineTable[task->data[1]] / 18;
if (task->data[5] == 1)
task->data[3] = 16 - (gSineTable[task->data[1]] / 18);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[2], task->data[3]));
if (task->data[1] == 128)
{
task->data[15] = 0;
task->func = AnimTask_SpiteTargetShadow_Step3;
task->func(taskId);
}
}
static void AnimTask_SpiteTargetShadow_Step3(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 rank = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
switch (task->data[15])
{
case 0:
gScanlineEffect.state = 3;
task->data[14] = GetAnimBattlerSpriteId(ANIM_TARGET);
if (rank == 1)
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
break;
case 1:
BlendPalette(task->data[4], 16, 0, RGB(13, 0, 15));
break;
case 2:
gSprites[task->data[14]].invisible = TRUE;
DestroySpriteWithActiveSheet(&gSprites[task->data[0]]);
FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
if (rank == 1)
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
DestroyAnimVisualTask(taskId);
break;
}
task->data[15]++;
}
static void AnimDestinyBondWhiteShadow(struct Sprite *sprite)
{
s16 battler1X, battler1Y;
s16 battler2X, battler2Y;
s16 yDiff;
if (gBattleAnimArgs[0] == 0)
{
battler1X = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
battler1Y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 28;
battler2X = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
battler2Y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 28;
}
else
{
battler1X = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
battler1Y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 28;
battler2X = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
battler2Y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 28;
}
yDiff = battler2Y - battler1Y;
sprite->data[0] = battler1X * 16;
sprite->data[1] = battler1Y * 16;
sprite->data[2] = ((battler2X - battler1X) * 16) / gBattleAnimArgs[1];
sprite->data[3] = (yDiff * 16) / gBattleAnimArgs[1];
sprite->data[4] = gBattleAnimArgs[1];
sprite->data[5] = battler2X;
sprite->data[6] = battler2Y;
sprite->data[7] = sprite->data[4] / 2;
sprite->oam.priority = 2;
sprite->x = battler1X;
sprite->y = battler1Y;
sprite->callback = AnimDestinyBondWhiteShadow_Step;
sprite->invisible = TRUE;
}
static void AnimDestinyBondWhiteShadow_Step(struct Sprite *sprite)
{
if (sprite->data[4])
{
sprite->data[0] += sprite->data[2];
sprite->data[1] += sprite->data[3];
sprite->x = sprite->data[0] >> 4;
sprite->y = sprite->data[1] >> 4;
if (--sprite->data[4] == 0)
sprite->data[0] = 0;
}
}
void AnimTask_DestinyBondWhiteShadow(u8 taskId)
{
struct Task *task;
s16 battler;
u8 spriteId;
s16 baseX, baseY;
s16 x, y;
task = &gTasks[taskId];
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
task->data[5] = 0;
task->data[6] = 0;
task->data[7] = 0;
task->data[8] = 0;
task->data[9] = 16;
task->data[10] = gBattleAnimArgs[0];
baseX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
baseY = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM);
if (!IsContest())
{
for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
{
if (battler != gBattleAnimAttacker
&& battler != BATTLE_PARTNER(gBattleAnimAttacker)
&& IsBattlerSpriteVisible(battler))
{
spriteId = CreateSprite(&gDestinyBondWhiteShadowSpriteTemplate, baseX, baseY, 55);
if (spriteId != MAX_SPRITES)
{
x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_BOTTOM);
gSprites[spriteId].data[0] = baseX << 4;
gSprites[spriteId].data[1] = baseY << 4;
gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
gSprites[spriteId].data[4] = gBattleAnimArgs[1];
gSprites[spriteId].data[5] = x;
gSprites[spriteId].data[6] = y;
gSprites[spriteId].callback = AnimDestinyBondWhiteShadow_Step;
task->data[task->data[12] + 13] = spriteId;
task->data[12]++;
}
}
}
}
else
{
spriteId = CreateSprite(&gDestinyBondWhiteShadowSpriteTemplate, baseX, baseY, 55);
if (spriteId != MAX_SPRITES)
{
x = 48;
y = 40;
gSprites[spriteId].data[0] = baseX << 4;
gSprites[spriteId].data[1] = baseY << 4;
gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
gSprites[spriteId].data[4] = gBattleAnimArgs[1];
gSprites[spriteId].data[5] = x;
gSprites[spriteId].data[6] = y;
gSprites[spriteId].callback = AnimDestinyBondWhiteShadow_Step;
task->data[13] = spriteId;
task->data[12] = 1;
}
}
task->func = AnimTask_DestinyBondWhiteShadow_Step;
}
static void AnimTask_DestinyBondWhiteShadow_Step(u8 taskId)
{
u16 i;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (task->data[6] == 0)
{
if (++task->data[5] > 1)
{
task->data[5] = 0;
task->data[7]++;
if (task->data[7] & 1)
{
if (task->data[8] < 16)
task->data[8]++;
}
else
{
if (task->data[9])
task->data[9]--;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9]));
if (task->data[7] >= 24)
{
task->data[7] = 0;
task->data[6] = 1;
}
}
}
if (task->data[10])
task->data[10]--;
else if (task->data[6])
task->data[0]++;
break;
case 1:
if (++task->data[5] > 1)
{
task->data[5] = 0;
task->data[7]++;
if (task->data[7] & 1)
{
if (task->data[8])
task->data[8]--;
}
else
{
if (task->data[9] < 16)
task->data[9]++;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[8], task->data[9]));
if (task->data[8] == 0 && task->data[9] == 16)
{
for (i = 0; i < task->data[12]; i++)
DestroySprite(&gSprites[task->data[i + 13]]);
task->data[0]++;
}
}
break;
case 2:
if (++task->data[5] > 0)
task->data[0]++;
break;
case 3:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
break;
}
}
void AnimTask_CurseStretchingBlackBg(u8 taskId)
{
s16 startX, startY;
s16 leftDistance, topDistance, bottomDistance, rightDistance;
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) |
(WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR)));
SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ) |
(WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR)));
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_DARKEN));
SetGpuReg(REG_OFFSET_BLDY, 16);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER || IsContest())
startX = 40;
else
startX = 200;
gBattle_WIN0H = WIN_RANGE(startX, startX);
startY = 40;
gBattle_WIN0V = WIN_RANGE(startY, startY);
leftDistance = startX;
rightDistance = DISPLAY_WIDTH - startX;
topDistance = startY;
bottomDistance = 72;
gTasks[taskId].data[1] = leftDistance;
gTasks[taskId].data[2] = rightDistance;
gTasks[taskId].data[3] = topDistance;
gTasks[taskId].data[4] = bottomDistance;
gTasks[taskId].data[5] = startX;
gTasks[taskId].data[6] = startY;
gTasks[taskId].func = AnimTask_CurseStretchingBlackBg_Step1;
}
static void AnimTask_CurseStretchingBlackBg_Step1(u8 taskId)
{
s16 step;
s16 leftDistance, rightDistance, topDistance, bottomDistance;
s16 startX, startY;
u16 left, right, top, bottom;
u16 selectedPalettes;
step = gTasks[taskId].data[0];
gTasks[taskId].data[0]++;
leftDistance = gTasks[taskId].data[1];
rightDistance = gTasks[taskId].data[2];
topDistance = gTasks[taskId].data[3];
bottomDistance = gTasks[taskId].data[4];
startX = gTasks[taskId].data[5];
startY = gTasks[taskId].data[6];
if (step < 16)
{
left = startX - (leftDistance * 0.0625) * step;
right = startX + (rightDistance * 0.0625) * step;
top = startY - (topDistance * 0.0625) * step;
bottom = startY + (bottomDistance * 0.0625) * step;
}
else
{
left = 0;
right = DISPLAY_WIDTH;
top = 0;
bottom = 112;
selectedPalettes = GetBattlePalettesMask(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
BeginNormalPaletteFade(selectedPalettes, 0, 16, 16, RGB(0, 0, 0));
gTasks[taskId].func = AnimTask_CurseStretchingBlackBg_Step2;
}
gBattle_WIN0H = WIN_RANGE(left, right);
gBattle_WIN0V = WIN_RANGE(top, bottom);
}
static void AnimTask_CurseStretchingBlackBg_Step2(u8 taskId)
{
if (!gPaletteFade.active)
{
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, ((WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) |
(WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR)));
SetGpuReg(REG_OFFSET_WINOUT, ((WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR) |
(WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR)));
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
DestroyAnimVisualTask(taskId);
}
}
static void AnimCurseNail(struct Sprite *sprite)
{
s16 xDelta;
s16 xDelta2;
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
xDelta = 24;
xDelta2 = -2;
sprite->oam.matrixNum = ST_OAM_HFLIP;
}
else
{
xDelta = -24;
xDelta2 = 2;
}
sprite->x += xDelta;
sprite->data[1] = xDelta2;
sprite->data[0] = 60;
sprite->callback = AnimCurseNail_Step1;
}
static void AnimCurseNail_Step1(struct Sprite *sprite)
{
u16 var0;
if (sprite->data[0] > 0)
{
sprite->data[0]--;
}
else
{
sprite->x2 += sprite->data[1];
var0 = sprite->x2 + 7;
if (var0 > 14)
{
sprite->x += sprite->x2;
sprite->x2 = 0;
sprite->oam.tileNum += 8;
if (++sprite->data[2] == 3)
{
sprite->data[0] = 30;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimCurseNail_Step2);
}
else
{
sprite->data[0] = 40;
}
}
}
}
static void AnimCurseNail_Step2(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
sprite->data[0]++;
sprite->data[1] = 0;
sprite->data[2] = 0;
}
else if (sprite->data[1] < 2)
{
sprite->data[1]++;
}
else
{
sprite->data[1] = 0;
sprite->data[2]++;
SetGpuReg(REG_OFFSET_BLDALPHA, (16 - sprite->data[2]) | (sprite->data[2] << 8));
if (sprite->data[2] == 16)
{
sprite->invisible = TRUE;
sprite->callback = AnimCurseNail_End;
}
}
}
static void AnimCurseNail_End(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
DestroyAnimSprite(sprite);
}
static void AnimGhostStatusSprite(struct Sprite *sprite)
{
u16 coeffB;
u16 coeffA;
sprite->x2 = Sin(sprite->data[0], 12);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x2 = -sprite->x2;
sprite->data[0] = (sprite->data[0] + 6) & 0xFF;
sprite->data[1] += 0x100;
sprite->y2 = -(sprite->data[1] >> 8);
sprite->data[7]++;
if (sprite->data[7] == 1)
{
sprite->data[6] = 0x050B;
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[6]);
}
else if (sprite->data[7] > 30)
{
sprite->data[2]++;
coeffB = sprite->data[6] >> 8;
coeffA = sprite->data[6] & 0xFF;
if (++coeffB > 16)
coeffB = 16;
--coeffA;
if ((s16)coeffA < 0)
coeffA = 0;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(coeffA, coeffB));
sprite->data[6] = BLDALPHA_BLEND(coeffA, coeffB);
if (coeffB == 16 && coeffA == 0)
{
sprite->invisible = TRUE;
sprite->callback = AnimGhostStatusSprite_Step;
}
}
}
static void AnimGhostStatusSprite_Step(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
void AnimTask_GrudgeFlames(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 16;
task->data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[10] = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
task->data[11] = (GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2) + 8;
task->data[7] = 0;
task->data[5] = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
task->data[6] = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 2;
task->data[3] = 0;
task->data[4] = 16;
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
task->data[8] = 0;
task->func = AnimTask_GrudgeFlames_Step;
}
static void AnimTask_GrudgeFlames_Step(u8 taskId)
{
u16 i;
u8 spriteId;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
for (i = 0; i < 6; i++)
{
spriteId = CreateSprite(&gGrudgeFlameSpriteTemplate, task->data[9], task->data[10], task->data[6]);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER;
gSprites[spriteId].data[2] = (i * 42) & 0xFF;
gSprites[spriteId].data[3] = task->data[11];
gSprites[spriteId].data[5] = i * 6;
task->data[7]++;
}
}
task->data[0]++;
break;
case 1:
if (++task->data[1] & 1)
{
if (task->data[3] < 14)
task->data[3]++;
}
else
{
if (task->data[4] > 4)
task->data[4]--;
}
if (task->data[3] == 14 && task->data[4] == 4)
{
task->data[1] = 0;
task->data[0]++;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
break;
case 2:
if (++task->data[1] > 30)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 3:
if (++task->data[1] & 1)
{
if (task->data[3] > 0)
task->data[3]--;
}
else
{
if (task->data[4] < 16)
task->data[4]++;
}
if (task->data[3] == 0 && task->data[4] == 16)
{
task->data[8] = 1;
task->data[0]++;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
break;
case 4:
if (task->data[7] == 0)
task->data[0]++;
break;
case 5:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimGrudgeFlame(struct Sprite *sprite)
{
u16 index;
if (sprite->data[1] == 0)
sprite->data[2] += 2;
else
sprite->data[2] -= 2;
sprite->data[2] &= 0xFF;
sprite->x2 = Sin(sprite->data[2], sprite->data[3]);
index = sprite->data[2] - 65;
if (index < 127)
sprite->oam.priority = gTasks[sprite->data[0]].data[5] + 1;
else
sprite->oam.priority = gTasks[sprite->data[0]].data[5];
sprite->data[5]++;
sprite->data[6] = (sprite->data[5] * 8) & 0xFF;
sprite->y2 = Sin(sprite->data[6], 7);
if (gTasks[sprite->data[0]].data[8])
{
gTasks[sprite->data[0]].data[7]--;
DestroySprite(sprite);
}
}
static void AnimMonMoveCircular(struct Sprite *sprite)
{
sprite->invisible = TRUE;
sprite->data[5] = gBattlerSpriteIds[gBattleAnimAttacker];
sprite->data[0] = 128;
sprite->data[1] = 10;
sprite->data[2] = gBattleAnimArgs[0];
sprite->data[3] = gBattleAnimArgs[1];
sprite->callback = AnimMonMoveCircular_Step;
gSprites[sprite->data[5]].y += 8;
}
static void AnimMonMoveCircular_Step(struct Sprite *sprite)
{
if (sprite->data[3])
{
sprite->data[3]--;
gSprites[sprite->data[5]].x2 = Sin(sprite->data[0], sprite->data[1]);
gSprites[sprite->data[5]].y2 = Cos(sprite->data[0], sprite->data[1]);
sprite->data[0] += sprite->data[2];
if (sprite->data[0] > 255)
sprite->data[0] -= 256;
}
else
{
gSprites[sprite->data[5]].x2 = 0;
gSprites[sprite->data[5]].y2 = 0;
gSprites[sprite->data[5]].y -= 8;
sprite->callback = DestroySpriteAndMatrix;
}
}
#include "global.h"
#include "battle_anim.h"
#include "random.h"
#include "scanline_effect.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimBonemerangProjectile(struct Sprite *);
static void AnimBoneHitProjectile(struct Sprite *);
static void AnimDirtScatter(struct Sprite *);
static void AnimMudSportDirt(struct Sprite *);
static void AnimDirtPlumeParticle(struct Sprite *);
static void AnimDirtPlumeParticle_Step(struct Sprite *);
static void AnimDigDirtMound(struct Sprite *);
static void AnimBonemerangProjectile_Step(struct Sprite *);
static void AnimBonemerangProjectile_End(struct Sprite *);
static void AnimMudSportDirtRising(struct Sprite *);
static void AnimMudSportDirtFalling(struct Sprite *);
static void AnimTask_DigBounceMovement(u8);
static void AnimTask_DigEndBounceMovementSetInvisible(u8);
static void AnimTask_DigSetVisibleUnderground(u8);
static void AnimTask_DigRiseUpFromHole(u8);
static void SetDigScanlineEffect(u8, s16, s16);
static void AnimTask_ShakeTerrain(u8);
static void AnimTask_ShakeBattlers(u8);
static void SetBattlersXOffsetForShake(struct Task *);
static void WaitForFissureCompletion(u8);
static const union AffineAnimCmd sAffineAnim_Bonemerang[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 15, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd sAffineAnim_SpinningBone[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_Bonemerang[] =
{
sAffineAnim_Bonemerang,
};
static const union AffineAnimCmd *const sAffineAnims_SpinningBone[] =
{
sAffineAnim_SpinningBone,
};
const struct SpriteTemplate gBonemerangSpriteTemplate =
{
.tileTag = ANIM_TAG_BONE,
.paletteTag = ANIM_TAG_BONE,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_Bonemerang,
.callback = AnimBonemerangProjectile,
};
const struct SpriteTemplate gSpinningBoneSpriteTemplate =
{
.tileTag = ANIM_TAG_BONE,
.paletteTag = ANIM_TAG_BONE,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_SpinningBone,
.callback = AnimBoneHitProjectile,
};
const struct SpriteTemplate gSandAttackDirtSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDirtScatter,
};
static const union AnimCmd sAnim_MudSlapMud[] =
{
ANIMCMD_FRAME(1, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_MudSlapMud[] =
{
sAnim_MudSlapMud,
};
const struct SpriteTemplate gMudSlapMudSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_MudSlapMud,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDirtScatter,
};
const struct SpriteTemplate gMudsportMudSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMudSportDirt,
};
const struct SpriteTemplate gDirtPlumeSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDirtPlumeParticle,
};
const struct SpriteTemplate gDirtMoundSpriteTemplate =
{
.tileTag = ANIM_TAG_DIRT_MOUND,
.paletteTag = ANIM_TAG_DIRT_MOUND,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDigDirtMound,
};
// Moves a bone projectile towards the target mon, which moves like
// a boomerang. After hitting the target mon, it comes back to the user.
static void AnimBonemerangProjectile(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = 20;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[5] = -40;
InitAnimArcTranslation(sprite);
sprite->callback = AnimBonemerangProjectile_Step;
}
static void AnimBonemerangProjectile_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 20;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[5] = 40;
InitAnimArcTranslation(sprite);
sprite->callback = AnimBonemerangProjectile_End;
}
}
static void AnimBonemerangProjectile_End(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
// Moves a bone projectile towards the target mon, starting right next to
// the target mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
static void AnimBoneHitProjectile(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Moves a small dirt projectile towards the target mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
// arg 3: target x pixel offset
// arg 4: target y pixel offset
static void AnimDirtScatter(struct Sprite *sprite)
{
u8 targetXPos, targetYPos;
s16 xOffset, yOffset;
InitSpritePosToAnimAttacker(sprite, TRUE);
targetXPos = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X_2);
targetYPos = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
xOffset = Random2() & 0x1F;
yOffset = Random2() & 0x1F;
if (xOffset > 16)
xOffset = 16 - xOffset;
if (yOffset > 16)
yOffset = 16 - yOffset;
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = targetXPos + xOffset;
sprite->data[4] = targetYPos + yOffset;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
// Moves a particle of dirt in the Mud Sport animation.
// The dirt can either be rising upward, or falling down.
// arg 0: 0 = dirt is rising into the air, 1 = dirt is falling down
// arg 1: initial x pixel offset
// arg 2: initial y pixel offset
static void AnimMudSportDirt(struct Sprite *sprite)
{
sprite->oam.tileNum++;
if (gBattleAnimArgs[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[1] > 0 ? 1 : -1;
sprite->callback = AnimMudSportDirtRising;
}
else
{
sprite->x = gBattleAnimArgs[1];
sprite->y = gBattleAnimArgs[2];
sprite->y2 = -gBattleAnimArgs[2];
sprite->callback = AnimMudSportDirtFalling;
}
}
static void AnimMudSportDirtRising(struct Sprite *sprite)
{
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
sprite->x += sprite->data[0];
}
sprite->y -= 4;
if (sprite->y < -4)
DestroyAnimSprite(sprite);
}
static void AnimMudSportDirtFalling(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->y2 += 4;
if (sprite->y2 >= 0)
{
sprite->y2 = 0;
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[1] > 0)
{
sprite->data[1] = 0;
sprite->invisible ^= 1;
if (++sprite->data[2] == 10)
DestroyAnimSprite(sprite);
}
break;
}
}
void AnimTask_DigDownMovement(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[0] == FALSE)
task->func = AnimTask_DigBounceMovement;
else
task->func = AnimTask_DigEndBounceMovementSetInvisible;
task->func(taskId);
}
static void AnimTask_DigBounceMovement(u8 taskId)
{
u8 y;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
if (task->data[11] == 1)
{
task->data[12] = gBattle_BG1_X;
task->data[13] = gBattle_BG1_Y;
}
else
{
task->data[12] = gBattle_BG2_X;
task->data[13] = gBattle_BG2_Y;
}
y = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
task->data[14] = y - 32;
task->data[15] = y + 32;
if (task->data[14] < 0)
task->data[14] = 0;
gSprites[task->data[10]].invisible = TRUE;
task->data[0]++;
break;
case 1:
SetDigScanlineEffect(task->data[11], task->data[14], task->data[15]);
task->data[0]++;
break;
case 2:
task->data[2] = (task->data[2] + 6) & 0x7F;
if (++task->data[4] > 2)
{
task->data[4] = 0;
task->data[3]++;
}
task->data[5] = task->data[3] + (gSineTable[task->data[2]] >> 4);
if (task->data[11] == 1)
gBattle_BG1_Y = task->data[13] - task->data[5];
else
gBattle_BG2_Y = task->data[13] - task->data[5];
if (task->data[5] > 63)
{
task->data[5] = 120 - task->data[14];
if (task->data[11] == 1)
gBattle_BG1_Y = task->data[13] - task->data[5];
else
gBattle_BG2_Y = task->data[13] - task->data[5];
gSprites[task->data[10]].x2 = DISPLAY_WIDTH + 32 - gSprites[task->data[10]].x;
task->data[0]++;
}
break;
case 3:
gScanlineEffect.state = 3;
task->data[0]++;
break;
case 4:
DestroyAnimVisualTask(taskId);
gSprites[task->data[10]].invisible = TRUE;
break;
}
}
static void AnimTask_DigEndBounceMovementSetInvisible(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = TRUE;
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
gBattle_BG1_Y = 0;
else
gBattle_BG2_Y = 0;
DestroyAnimVisualTask(taskId);
}
void AnimTask_DigUpMovement(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[0] == FALSE)
task->func = AnimTask_DigSetVisibleUnderground;
else
task->func = AnimTask_DigRiseUpFromHole;
task->func(taskId);
}
static void AnimTask_DigSetVisibleUnderground(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[task->data[10]].invisible = FALSE;
gSprites[task->data[10]].x2 = 0;
gSprites[task->data[10]].y2 = DISPLAY_HEIGHT - gSprites[task->data[10]].y;
task->data[0]++;
break;
case 1:
DestroyAnimVisualTask(taskId);
}
}
static void AnimTask_DigRiseUpFromHole(u8 taskId)
{
u8 var0;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
if (task->data[11] == 1)
task->data[12] = gBattle_BG1_X;
else
task->data[12] = gBattle_BG2_X;
var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
task->data[14] = var0 - 32;
task->data[15] = var0 + 32;
task->data[0]++;
break;
case 1:
SetDigScanlineEffect(task->data[11], 0, task->data[15]);
task->data[0]++;
break;
case 2:
gSprites[task->data[10]].y2 = 96;
task->data[0]++;
break;
case 3:
gSprites[task->data[10]].y2 -= 8;
if (gSprites[task->data[10]].y2 == 0)
{
gScanlineEffect.state = 3;
task->data[0]++;
}
break;
case 4:
DestroyAnimVisualTask(taskId);
break;
}
}
static void SetDigScanlineEffect(u8 useBG1, s16 y, s16 endY)
{
s16 bgX;
struct ScanlineEffectParams scanlineParams;
if (useBG1 == 1)
{
bgX = gBattle_BG1_X;
scanlineParams.dmaDest = &REG_BG1HOFS;
}
else
{
bgX = gBattle_BG2_X;
scanlineParams.dmaDest = &REG_BG2HOFS;
}
if (y < 0)
y = 0;
while (y < endY)
{
gScanlineEffectRegBuffers[0][y] = bgX;
gScanlineEffectRegBuffers[1][y] = bgX;
y++;
}
while (y < 160)
{
gScanlineEffectRegBuffers[0][y] = bgX + 240;
gScanlineEffectRegBuffers[1][y] = bgX + 240;
y++;
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
ScanlineEffect_SetParams(scanlineParams);
}
// Moves a particle of dirt in a plume of dirt. Used in Fissure and Dig.
// arg 0: which mon (0 = attacker, 1 = target)
// arg 1: which side of mon (0 = left, 1 = right)
// arg 2: target x offset
// arg 3: target y offset
// arg 4: wave amplitude
// arg 5: duration
void AnimDirtPlumeParticle(struct Sprite *sprite)
{
s8 battler;
s16 xOffset;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
xOffset = 24;
if (gBattleAnimArgs[1] == 1)
{
xOffset *= -1;
gBattleAnimArgs[2] *= -1;
}
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + xOffset;
sprite->y = GetBattlerYCoordWithElevation(battler) + 30;
sprite->data[0] = gBattleAnimArgs[5];
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
sprite->data[4] = sprite->y + gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[4];
InitAnimArcTranslation(sprite);
sprite->callback = AnimDirtPlumeParticle_Step;
}
static void AnimDirtPlumeParticle_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
// Displays the dirt mound seen in the move Dig for set duration.
// The dirt mound image is too large for a single sprite, so two
// sprites are lined up next to each other.
// arg 0: which mon (0 = attacker, 1 = target)
// arg 1: oam tile num (0 = left half of image, 1 = right half of image)
// arg 2: duration
static void AnimDigDirtMound(struct Sprite *sprite)
{
s8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X) - 16 + (gBattleAnimArgs[1] * 32);
sprite->y = GetBattlerYCoordWithElevation(battler) + 32;
sprite->oam.tileNum += gBattleAnimArgs[1] * 8;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->data[0] = gBattleAnimArgs[2];
sprite->callback = WaitAnimForDuration;
}
#define tState data[0]
#define tDelay data[1]
#define tTimer data[2]
#define tMaxTime data[3]
#define tbattlerSpriteIds(i) data[9 + (i)]
#define tNumBattlers data[13] // AnimTask_ShakeBattlers
#define tInitialX data[13] // AnimTask_ShakeTerrain
#define tHorizOffset data[14]
#define tInitHorizOffset data[15]
// Shakes battler(s) or the battle terrain back and forth horizontally. Used by e.g. Earthquake, Eruption
// arg0: What to shake. 0-3 for any specific battler, MAX_BATTLERS_COUNT for all battlers, MAX_BATTLERS_COUNT + 1 for the terrain
// arg1: Shake intensity, used to calculate horizontal pixel offset (if 0, use move power instead)
// arg2: Length of time to shake for
void AnimTask_HorizontalShake(u8 taskId)
{
u16 i;
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[1] != 0)
task->tHorizOffset = task->tInitHorizOffset = gBattleAnimArgs[1] + 3;
else
task->tHorizOffset = task->tInitHorizOffset = (gAnimMovePower / 10) + 3;
task->tMaxTime = gBattleAnimArgs[2];
switch (gBattleAnimArgs[0])
{
case MAX_BATTLERS_COUNT + 1: // Shake terrain
task->tInitialX = gBattle_BG3_X;
task->func = AnimTask_ShakeTerrain;
break;
case MAX_BATTLERS_COUNT: // Shake all battlers
task->tNumBattlers = 0;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (IsBattlerSpriteVisible(i))
{
task->tbattlerSpriteIds(task->tNumBattlers) = gBattlerSpriteIds[i];
task->tNumBattlers++;
}
}
task->func = AnimTask_ShakeBattlers;
break;
default: // Shake specific battler
task->tbattlerSpriteIds(0) = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (task->tbattlerSpriteIds(0) == SPRITE_NONE)
{
DestroyAnimVisualTask(taskId);
}
else
{
task->tNumBattlers = 1;
task->func = AnimTask_ShakeBattlers;
}
break;
}
}
static void AnimTask_ShakeTerrain(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
if (++task->tDelay > 1)
{
task->tDelay = 0;
if ((task->tTimer & 1) == 0)
gBattle_BG3_X = task->tInitialX + task->tInitHorizOffset;
else
gBattle_BG3_X = task->tInitialX - task->tInitHorizOffset;
if (++task->tTimer == task->tMaxTime)
{
task->tTimer = 0;
task->tHorizOffset--;
task->tState++;
}
}
break;
case 1:
if (++task->tDelay > 1)
{
task->tDelay = 0;
if ((task->tTimer & 1) == 0)
gBattle_BG3_X = task->tInitialX + task->tHorizOffset;
else
gBattle_BG3_X = task->tInitialX - task->tHorizOffset;
if (++task->tTimer == 4)
{
task->tTimer = 0;
if (--task->tHorizOffset == 0)
task->tState++;
}
}
break;
case 2:
gBattle_BG3_X = task->tInitialX;
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimTask_ShakeBattlers(u8 taskId)
{
u16 i;
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
if (++task->tDelay > 1)
{
task->tDelay = 0;
SetBattlersXOffsetForShake(task);
if (++task->tTimer == task->tMaxTime)
{
task->tTimer = 0;
task->tHorizOffset--;
task->tState++;
}
}
break;
case 1:
if (++task->tDelay > 1)
{
task->tDelay = 0;
SetBattlersXOffsetForShake(task);
if (++task->tTimer == 4)
{
task->tTimer = 0;
if (--task->tHorizOffset == 0)
task->tState++;
}
}
break;
case 2:
for (i = 0; i < task->tNumBattlers; i++)
gSprites[task->tbattlerSpriteIds(i)].x2 = 0;
DestroyAnimVisualTask(taskId);
break;
}
}
static void SetBattlersXOffsetForShake(struct Task *task)
{
u16 i;
u16 xOffset;
if ((task->tTimer & 1) == 0)
xOffset = (task->tHorizOffset / 2) + (task->tHorizOffset & 1);
else
xOffset = -(task->tHorizOffset / 2);
for (i = 0; i < task->tNumBattlers; i++)
{
gSprites[task->tbattlerSpriteIds(i)].x2 = xOffset;
}
}
#undef tState
#undef tDelay
#undef tTimer
#undef tMaxTime
#undef tbattlerSpriteIds
#undef tNumBattlers
#undef tInitialX
#undef tHorizOffset
#undef tInitHorizOffset
void AnimTask_IsPowerOver99(u8 taskId)
{
gBattleAnimArgs[15] = gAnimMovePower > 99;
DestroyAnimVisualTask(taskId);
}
void AnimTask_PositionFissureBgOnBattler(u8 taskId)
{
struct Task *newTask;
u8 battler = (gBattleAnimArgs[0] & ANIM_TARGET) ? gBattleAnimTarget : gBattleAnimAttacker;
if (gBattleAnimArgs[0] > ANIM_TARGET)
battler = BATTLE_PARTNER(battler);
newTask = &gTasks[CreateTask(WaitForFissureCompletion, gBattleAnimArgs[1])];
newTask->data[1] = (32 - GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2)) & 0x1FF;
newTask->data[2] = (64 - GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET)) & 0xFF;
gBattle_BG3_X = newTask->data[1];
gBattle_BG3_Y = newTask->data[2];
newTask->data[3] = gBattleAnimArgs[2];
DestroyAnimVisualTask(taskId);
}
static void WaitForFissureCompletion(u8 taskId)
{
struct Task *task = &gTasks[taskId];
// Holds the BG3 offsets until gBattleAnimArgs[7]
// is set to a special terminator value.
if (gBattleAnimArgs[7] == task->data[3])
{
gBattle_BG3_X = 0;
gBattle_BG3_Y = 0;
DestroyTask(taskId);
}
else
{
gBattle_BG3_X = task->data[1];
gBattle_BG3_Y = task->data[2];
}
}
#include "global.h"
#include "battle_anim.h"
#include "bg.h"
#include "field_weather.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "main.h"
#include "palette.h"
#include "random.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
struct HailStruct {
s32 x:10;
s32 y:10;
s32 bPosition:8;
s32 unk3:4;
};
static void AnimUnusedIceCrystalThrow(struct Sprite *);
static void AnimUnusedIceCrystalThrow_Step(struct Sprite *);
static void AnimIcePunchSwirlingParticle(struct Sprite *);
static void AnimIceBeamParticle(struct Sprite *);
static void AnimIceEffectParticle(struct Sprite *);
static void AnimFlickerIceEffectParticle(struct Sprite *);
static void AnimSwirlingSnowball(struct Sprite *);
static void AnimSwirlingSnowball_Step1(struct Sprite *);
static void AnimSwirlingSnowball_Step2(struct Sprite *);
static void AnimSwirlingSnowball_End(struct Sprite *);
static void AnimMoveParticleBeyondTarget(struct Sprite *);
static void AnimWiggleParticleTowardsTarget(struct Sprite *);
static void AnimWaveFromCenterOfTarget(struct Sprite *);
static void InitSwirlingFogAnim(struct Sprite *);
static void AnimSwirlingFogAnim(struct Sprite *);
static void AnimThrowMistBall(struct Sprite *);
static void InitPoisonGasCloudAnim(struct Sprite *);
static void MovePoisonGasCloud(struct Sprite *);
static void AnimHailBegin(struct Sprite *);
static void AnimHailContinue(struct Sprite *);
static void InitIceBallAnim(struct Sprite *);
static void AnimThrowIceBall(struct Sprite *);
static void InitIceBallParticle(struct Sprite *);
static void AnimIceBallParticle(struct Sprite *);
static void AnimTask_HazeScrollingFog_Step(u8);
static void AnimTask_MistBallFog_Step(u8);
static void AnimTask_Hail2(u8);
static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c);
static const union AnimCmd sAnim_Unused[] =
{
ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
ANIMCMD_FRAME(1, 5, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_Unused[] =
{
sAnim_Unused,
};
// Unused
static const struct SpriteTemplate sUnusedIceCrystalThrowSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedIceCrystalThrow,
};
static const union AnimCmd sAnim_IceCrystalLargeChunk[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_IceCrystalLarge[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_IceCrystalSmall[] =
{
ANIMCMD_FRAME(6, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Snowball[] =
{
ANIMCMD_FRAME(7, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_BlizzardIceCrystal[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_SmallBubblePair[] =
{
ANIMCMD_FRAME(12, 6),
ANIMCMD_FRAME(13, 6),
ANIMCMD_JUMP(0),
};
// Unused, contains just the top left corner of the large ice crystal
static const union AnimCmd *const sAnims_IceCrystalLargeChunk[] =
{
sAnim_IceCrystalLargeChunk,
};
static const union AnimCmd *const sAnims_IceCrystalLarge[] =
{
sAnim_IceCrystalLarge,
};
static const union AnimCmd *const sAnims_IceCrystalSmall[] =
{
sAnim_IceCrystalSmall,
};
static const union AnimCmd *const sAnims_Snowball[] =
{
sAnim_Snowball,
};
static const union AnimCmd *const sAnims_BlizzardIceCrystal[] =
{
sAnim_BlizzardIceCrystal,
};
const union AnimCmd *const gAnims_SmallBubblePair[] =
{
sAnim_SmallBubblePair,
};
static const union AffineAnimCmd sAffineAnim_IceCrystalSpiralInwardLarge[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 40, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_IceCrystalSpiralInwardLarge[] =
{
sAffineAnim_IceCrystalSpiralInwardLarge,
};
const struct SpriteTemplate gIceCrystalSpiralInwardLarge =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineDouble_ObjBlend_8x16,
.anims = sAnims_IceCrystalLarge,
.images = NULL,
.affineAnims = sAffineAnims_IceCrystalSpiralInwardLarge,
.callback = AnimIcePunchSwirlingParticle,
};
const struct SpriteTemplate gIceCrystalSpiralInwardSmall =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjBlend_8x8,
.anims = sAnims_IceCrystalSmall,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimIcePunchSwirlingParticle,
};
static const union AffineAnimCmd sAffineAnim_IceBeamInnerCrystal[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_IceBeamInnerCrystal[] =
{
sAffineAnim_IceBeamInnerCrystal,
};
const struct SpriteTemplate gIceBeamInnerCrystalSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineNormal_ObjBlend_8x16,
.anims = sAnims_IceCrystalLarge,
.images = NULL,
.affineAnims = sAffineAnims_IceBeamInnerCrystal,
.callback = AnimIceBeamParticle,
};
const struct SpriteTemplate gIceBeamOuterCrystalSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjBlend_8x8,
.anims = sAnims_IceCrystalSmall,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimIceBeamParticle,
};
static const union AffineAnimCmd sAffineAnim_IceCrystalHit[] =
{
AFFINEANIMCMD_FRAME(0xCE, 0xCE, 0, 0),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_IceCrystalHit[] =
{
sAffineAnim_IceCrystalHit,
};
const struct SpriteTemplate gIceCrystalHitLargeSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineNormal_ObjBlend_8x16,
.anims = sAnims_IceCrystalLarge,
.images = NULL,
.affineAnims = sAffineAnims_IceCrystalHit,
.callback = AnimIceEffectParticle,
};
const struct SpriteTemplate gIceCrystalHitSmallSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineNormal_ObjBlend_8x8,
.anims = sAnims_IceCrystalSmall,
.images = NULL,
.affineAnims = sAffineAnims_IceCrystalHit,
.callback = AnimIceEffectParticle,
};
const struct SpriteTemplate gSwirlingSnowballSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = sAnims_Snowball,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSwirlingSnowball,
};
const struct SpriteTemplate gBlizzardIceCrystalSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_BlizzardIceCrystal,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMoveParticleBeyondTarget,
};
const struct SpriteTemplate gPowderSnowSnowballSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = sAnims_Snowball,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMoveParticleBeyondTarget,
};
static const union AnimCmd sAnim_IceGroundSpike[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(6, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_IceGroundSpike[] =
{
sAnim_IceGroundSpike,
};
const struct SpriteTemplate gIceGroundSpikeSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_SPIKES,
.paletteTag = ANIM_TAG_ICE_SPIKES,
.oam = &gOamData_AffineOff_ObjBlend_8x16,
.anims = sAnims_IceGroundSpike,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWaveFromCenterOfTarget,
};
static const union AnimCmd sAnim_Cloud[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_Cloud[] =
{
sAnim_Cloud,
};
const struct SpriteTemplate gMistCloudSpriteTemplate =
{
.tileTag = ANIM_TAG_MIST_CLOUD,
.paletteTag = ANIM_TAG_MIST_CLOUD,
.oam = &gOamData_AffineOff_ObjBlend_32x16,
.anims = sAnims_Cloud,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = InitSwirlingFogAnim,
};
const struct SpriteTemplate gSmogCloudSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.oam = &gOamData_AffineOff_ObjBlend_32x16,
.anims = sAnims_Cloud,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = InitSwirlingFogAnim,
};
static const u8 sHazeBlendAmounts[] =
{
0, 1, 2, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 8, 8, 8, 9,
};
const struct SpriteTemplate gMistBallSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThrowMistBall,
};
static const u8 sMistBlendAmounts[] =
{
0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
};
const struct SpriteTemplate gPoisonGasCloudSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
.oam = &gOamData_AffineOff_ObjBlend_32x16,
.anims = sAnims_Cloud,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = InitPoisonGasCloudAnim,
};
static const struct HailStruct sHailCoordData[] =
{
{.x = 100, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 2},
{.x = 85, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 0},
{.x = 242, .y = 120, .bPosition = B_POSITION_OPPONENT_LEFT, .unk3 = 1},
{.x = 66, .y = 120, .bPosition = B_POSITION_PLAYER_RIGHT, .unk3 = 1},
{.x = 182, .y = 120, .bPosition = B_POSITION_OPPONENT_RIGHT, .unk3 = 0},
{.x = 60, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 2},
{.x = 214, .y = 120, .bPosition = B_POSITION_OPPONENT_LEFT, .unk3 = 0},
{.x = 113, .y = 120, .bPosition = B_POSITION_PLAYER_LEFT, .unk3 = 1},
{.x = 210, .y = 120, .bPosition = B_POSITION_OPPONENT_RIGHT, .unk3 = 1},
{.x = 38, .y = 120, .bPosition = B_POSITION_PLAYER_RIGHT, .unk3 = 0},
};
static const union AffineAnimCmd sAffineAnim_HailParticle_0[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HailParticle_1[] =
{
AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_HailParticle_2[] =
{
AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_WeatherBallIceDown[] =
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_HailParticle[] =
{
sAffineAnim_HailParticle_0,
sAffineAnim_HailParticle_1,
sAffineAnim_HailParticle_2,
};
static const union AffineAnimCmd *const sAffineAnims_WeatherBallIceDown[] =
{
sAffineAnim_WeatherBallIceDown,
};
const struct SpriteTemplate gHailParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_HAIL,
.paletteTag = ANIM_TAG_HAIL,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_HailParticle,
.callback = AnimHailBegin,
};
const struct SpriteTemplate gWeatherBallIceDownSpriteTemplate =
{
.tileTag = ANIM_TAG_HAIL,
.paletteTag = ANIM_TAG_HAIL,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_WeatherBallIceDown,
.callback = AnimWeatherBallDown,
};
static const union AnimCmd sAnim_IceBallChunk_0[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_IceBallChunk_1[] =
{
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_IceBallChunk[] =
{
sAnim_IceBallChunk_0,
sAnim_IceBallChunk_1,
};
static const union AffineAnimCmd sAffineAnim_IceBallChunk_0[] =
{
AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_IceBallChunk_1[] =
{
AFFINEANIMCMD_FRAME(0x118, 0x118, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_IceBallChunk_2[] =
{
AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_IceBallChunk_3[] =
{
AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_IceBallChunk_4[] =
{
AFFINEANIMCMD_FRAME(0x1C0, 0x1C0, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_IceBallChunk[] =
{
sAffineAnim_IceBallChunk_0,
sAffineAnim_IceBallChunk_1,
sAffineAnim_IceBallChunk_2,
sAffineAnim_IceBallChunk_3,
sAffineAnim_IceBallChunk_4,
};
const struct SpriteTemplate gIceBallChunkSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CHUNK,
.paletteTag = ANIM_TAG_ICE_CHUNK,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_IceBallChunk,
.images = NULL,
.affineAnims = sAffineAnims_IceBallChunk,
.callback = InitIceBallAnim,
};
const struct SpriteTemplate gIceBallImpactShardSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CRYSTALS,
.paletteTag = ANIM_TAG_ICE_CRYSTALS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = sAnims_IceCrystalSmall,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = InitIceBallParticle,
};
// Unused
static void AnimUnusedIceCrystalThrow(struct Sprite *sprite)
{
s16 targetX, targetY, attackerX, attackerY;
sprite->oam.tileNum += 7;
targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = gBattleAnimArgs[0] + attackerX;
sprite->data[2] = gBattleAnimArgs[2] + targetX;
sprite->data[3] = gBattleAnimArgs[1] + attackerY;
sprite->data[4] = gBattleAnimArgs[3] + targetY;
ConvertPosDataToTranslateLinearData(sprite);
for (;(targetX >= -32 && targetX <= DISPLAY_WIDTH + 32) && (targetY >= -32 && targetY <= DISPLAY_HEIGHT + 32);
targetX += sprite->data[1], targetY += sprite->data[2])
;
sprite->data[1] = -sprite->data[1];
sprite->data[2] = -sprite->data[2];
for (;(attackerX >= -32 && attackerX <= DISPLAY_WIDTH + 32) && (attackerY >= -32 && attackerY <= DISPLAY_HEIGHT + 32);
attackerX += sprite->data[1], attackerY += sprite->data[2])
;
sprite->x = attackerX;
sprite->y = attackerY;
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = attackerX;
sprite->data[2] = targetX;
sprite->data[3] = attackerY;
sprite->data[4] = targetY;
ConvertPosDataToTranslateLinearData(sprite);
sprite->data[3] = gBattleAnimArgs[5];
sprite->data[4] = gBattleAnimArgs[6];
sprite->callback = AnimUnusedIceCrystalThrow_Step;
}
static void AnimUnusedIceCrystalThrow_Step(struct Sprite *sprite)
{
if (sprite->data[0] != 0)
{
sprite->data[5] += sprite->data[1];
sprite->data[6] += sprite->data[2];
sprite->x2 = sprite->data[5];
sprite->y2 = sprite->data[6];
sprite->x2 += Sin(sprite->data[7], sprite->data[3]);
sprite->y2 += Sin(sprite->data[7], sprite->data[3]);
sprite->data[7] = (sprite->data[7] + sprite->data[4]) & 0xFF;
sprite->data[0]--;
}
else
{
DestroyAnimSprite(sprite);
}
}
// Animates the swirling ice crystals in Ice Punch.
// arg 0: initial position angle around circle (0-256)
static void AnimIcePunchSwirlingParticle(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 60;
sprite->data[2] = 9;
sprite->data[3] = 30;
sprite->data[4] = -512;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteInGrowingCircle;
sprite->callback(sprite);
}
// Animates the ice particles in Ice Beam.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: duration
static void AnimIceBeamParticle(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->data[2] -= gBattleAnimArgs[2];
else
sprite->data[2] += gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->data[0] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = StartAnimLinearTranslation;
}
// Animates the ice crystals at the end of Ice Punch, Ice Beam, Tri Attack,
// Weather Ball (Hail), Blizzard, and Powder Snow.
// arg 0: target x offset
// arg 1: target y offset
// arg 2: ??? unknown boolean
static void AnimIceEffectParticle(struct Sprite *sprite)
{
if (gBattleAnimArgs[2] == 0)
{
InitSpritePosToAnimTarget(sprite, TRUE);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
StoreSpriteCallbackInData6(sprite, AnimFlickerIceEffectParticle);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
static void AnimFlickerIceEffectParticle(struct Sprite *sprite)
{
sprite->invisible ^= 1;
sprite->data[0] += 1;
if (sprite->data[0] == 20)
DestroySpriteAndMatrix(sprite);
}
// Animates the small snowballs that swirl around the target in Blizzard and Icy Wind.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: particle speed
// arg 5: multiple targets? (boolean)
static void AnimSwirlingSnowball(struct Sprite *sprite)
{
int i;
s16 tempDataHolder[8];
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
if (!gBattleAnimArgs[5])
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]);
}
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->data[2] -= gBattleAnimArgs[2];
else
sprite->data[2] += gBattleAnimArgs[2];
for (i = 0; i < 8; i++)
tempDataHolder[i] = sprite->data[i];
InitAnimFastLinearTranslationWithSpeed(sprite);
sprite->data[1] ^= 1;
sprite->data[2] ^= 1;
while (1)
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
break;
}
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
for (i = 0; i < 8; i++)
sprite->data[i] = tempDataHolder[i];
sprite->callback = InitAnimFastLinearTranslationWithSpeedAndPos;
StoreSpriteCallbackInData6(sprite, AnimSwirlingSnowball_Step1);
}
static void AnimSwirlingSnowball_Step1(struct Sprite *sprite)
{
s16 tempVar;
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 128;
tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
sprite->data[3] = Sin(sprite->data[0], tempVar);
sprite->data[4] = Cos(sprite->data[0], 0xF);
sprite->data[5] = 0;
sprite->callback = AnimSwirlingSnowball_Step2;
sprite->callback(sprite);
}
static void AnimSwirlingSnowball_Step2(struct Sprite *sprite)
{
s16 tempVar;
tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
if (sprite->data[5] <= 31)
{
sprite->x2 = Sin(sprite->data[0], tempVar) - sprite->data[3];
sprite->y2 = Cos(sprite->data[0], 15) - sprite->data[4];
sprite->data[0] = (sprite->data[0] + 16) & 0xFF;
sprite->data[5] += 1;
}
else
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[4] = 0;
sprite->data[3] = 0;
sprite->callback = AnimSwirlingSnowball_End;
}
}
static void AnimSwirlingSnowball_End(struct Sprite *sprite)
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if (sprite->x + sprite->x2 > 256
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > 256
|| sprite->y + sprite->y2 < -16)
DestroyAnimSprite(sprite);
}
// Moves particles towards the target mon and off the screen. Used to animate
// the large snowballs in Blizzard and the small snowballs in Powder Snow.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: speed
// arg 5: wave amplitude
// arg 6: wave frequency
// arg 7: multiple targets? (boolean)
static void AnimMoveParticleBeyondTarget(struct Sprite *sprite)
{
int i;
s16 tempDataHolder[8];
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
if (!gBattleAnimArgs[7])
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]);
}
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->data[2] -= gBattleAnimArgs[2];
else
sprite->data[2] += gBattleAnimArgs[2];
sprite->data[4] += gBattleAnimArgs[3];
InitAnimFastLinearTranslationWithSpeed(sprite);
for (i = 0; i < 8; i++)
tempDataHolder[i] = sprite->data[i];
sprite->data[1] ^= 1;
sprite->data[2] ^= 1;
while (1)
{
sprite->data[0] = 1;
AnimFastTranslateLinear(sprite);
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
break;
}
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
for (i = 0; i < 8; i++)
sprite->data[i] = tempDataHolder[i];
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[6];
sprite->callback = AnimWiggleParticleTowardsTarget;
}
// Moves particles in a sine wave towards the target.
static void AnimWiggleParticleTowardsTarget(struct Sprite *sprite)
{
AnimFastTranslateLinear(sprite);
if (sprite->data[0] == 0)
sprite->data[0] = 1;
sprite->y2 += Sin(sprite->data[7], sprite->data[5]);
sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
if (sprite->data[0] == 1)
{
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
DestroyAnimSprite(sprite);
}
}
// Animates the ice pilar wave used by Icy Wind.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: ??? unknown boolean
static void AnimWaveFromCenterOfTarget(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
if (gBattleAnimArgs[2] == 0)
{
InitSpritePosToAnimTarget(sprite, FALSE);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->data[0]++;
}
else
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
}
// Animates the fog that swirls around the mon in Mist and Smog.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: change in y pixels per rotation
// arg 3: duration
// arg 4: animate on opponent? (boolean)
// arg 5: ??? unknown boolean
static void InitSwirlingFogAnim(struct Sprite *sprite)
{
s16 tempVar;
u8 battler;
if (gBattleAnimArgs[4] == 0)
{
if (gBattleAnimArgs[5] == 0)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
}
else
{
SetAverageBattlerPositions(gBattleAnimAttacker, FALSE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
battler = gBattleAnimAttacker;
}
else
{
if (gBattleAnimArgs[5] == 0)
{
InitSpritePosToAnimTarget(sprite, FALSE);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
battler = gBattleAnimTarget;
}
sprite->data[7] = battler;
if (gBattleAnimArgs[5] == 0 || !IsDoubleBattle())
tempVar = 0x20;
else
tempVar = 0x40;
sprite->data[6] = tempVar;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
sprite->y += 8;
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + gBattleAnimArgs[2];
InitAnimLinearTranslation(sprite);
sprite->data[5] = 64;
sprite->callback = AnimSwirlingFogAnim;
sprite->callback(sprite);
}
// Animates swirling fog initialized by InitSwirlingFogAnim.
static void AnimSwirlingFogAnim(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->x2 += Sin(sprite->data[5], sprite->data[6]);
sprite->y2 += Cos(sprite->data[5], -6);
if ((u16)(sprite->data[5] - 64) <= 0x7F)
sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]);
else
sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]) + 1;
sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
// Adds moving foggy overlay. Used by Haze.
void AnimTask_HazeScrollingFog(u8 taskId)
{
struct BattleAnimBgData animBg;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
LoadBgTiles(animBg.bgId, gWeatherFogHorizontalTiles, 0x800, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimFogTilemap, FALSE);
LoadPalette(&gFogPalette, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].func = AnimTask_HazeScrollingFog_Step;
}
static void AnimTask_HazeScrollingFog_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
gBattle_BG1_X += -1;
gBattle_BG1_Y += 0;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[9]++;
gTasks[taskId].data[11] = sHazeBlendAmounts[gTasks[taskId].data[9]];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 9)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 0x51)
{
gTasks[taskId].data[11] = 9;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
gTasks[taskId].data[12]++;
// fall through
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}
// Throws the ball in Mist Ball.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: targey x offset
// arg 3: target y offset
// arg 4: duration
// arg 5: ??? unknown (seems to vibrate target mon somehow)
static void AnimThrowMistBall(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = TranslateAnimSpriteToTargetMonLocation;
}
// Displays misty background in Mist Ball.
void AnimTask_MistBallFog(u8 taskId)
{
struct BattleAnimBgData animBg;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
LoadBgTiles(animBg.bgId, gWeatherFogHorizontalTiles, 0x800, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimFogTilemap, FALSE);
LoadPalette(&gFogPalette, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].data[15] = -1;
gTasks[taskId].func = AnimTask_MistBallFog_Step;
}
static void AnimTask_MistBallFog_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
gBattle_BG1_X += gTasks[taskId].data[15];
gBattle_BG1_Y += 0;
switch (gTasks[taskId].data[12])
{
case 0:
gTasks[taskId].data[9] += 1;
gTasks[taskId].data[11] = sMistBlendAmounts[gTasks[taskId].data[9]];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 17 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 5)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
break;
case 1:
if (++gTasks[taskId].data[11] == 0x51)
{
gTasks[taskId].data[11] = 5;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11] -= 1;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
gTasks[taskId].data[12]++;
// fall through
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}
// Initializes gas clouds in the Poison Gas animation.
// arg 0: duration
// arg 1: ? target x offset
// arg 2: ? target y offset
// arg 3: ? swirl start x
// arg 4: ? swirl start y
// arg 5: ??? unknown
// arg 6: ??? unknown
// arg 7: ??? unknown boolean
static void InitPoisonGasCloudAnim(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[0];
if (GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2))
sprite->data[7] = 0x8000;
if (GET_BATTLER_SIDE2(gBattleAnimTarget) == B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
if ((sprite->data[7] & 0x8000) && GET_BATTLER_SIDE2(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1;
sprite->data[6] = 1;
}
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (gBattleAnimArgs[7])
{
sprite->data[1] = sprite->x + gBattleAnimArgs[1];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[3];
sprite->data[3] = sprite->y + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[4];
sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
}
else
{
sprite->data[1] = sprite->x + gBattleAnimArgs[1];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[3];
sprite->data[3] = sprite->y + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[4];
sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
}
if (IsContest())
{
sprite->data[6] = 1;
sprite->subpriority = 0x80;
}
InitAnimLinearTranslation(sprite);
sprite->callback = MovePoisonGasCloud;
}
static void MovePoisonGasCloud(struct Sprite *sprite)
{
int value;
switch (sprite->data[7] & 0xFF)
{
case 0:
AnimTranslateLinear(sprite);
value = gSineTable[sprite->data[5]];
sprite->x2 += value >> 4;
if (sprite->data[6])
sprite->data[5] = (sprite->data[5] - 8) & 0xFF;
else
sprite->data[5] = (sprite->data[5] + 8) & 0xFF;
if (sprite->data[0] <= 0)
{
sprite->data[0] = 80;
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->y += sprite->y2;
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + 29;
sprite->data[7]++;
if (IsContest())
sprite->data[5] = 80;
else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
sprite->data[5] = 204;
else
sprite->data[5] = 80;
sprite->y2 = 0;
value = gSineTable[sprite->data[5]];
sprite->x2 = value >> 3;
sprite->data[5] = (sprite->data[5] + 2) & 0xFF;
InitAnimLinearTranslation(sprite);
}
break;
case 1:
AnimTranslateLinear(sprite);
value = gSineTable[sprite->data[5]];
sprite->x2 += value >> 3;
sprite->y2 += (gSineTable[sprite->data[5] + 0x40] * -3) >> 8;
if (!IsContest())
{
u16 var0 = sprite->data[5] - 0x40;
if (var0 <= 0x7F)
sprite->oam.priority = sprite->data[7] >> 8;
else
sprite->oam.priority = (sprite->data[7] >> 8) + 1;
sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
}
else
{
u16 var0 = sprite->data[5] - 0x40;
if (var0 <= 0x7F)
sprite->subpriority = 128;
else
sprite->subpriority = 140;
sprite->data[5] = (sprite->data[5] - 4) & 0xFF;
}
if (sprite->data[0] <= 0)
{
sprite->data[0] = 0x300;
sprite->data[1] = sprite->x += sprite->x2;
sprite->data[3] = sprite->y += sprite->y2;
sprite->data[4] = sprite->y + 4;
if (IsContest())
sprite->data[2] = -0x10;
else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
sprite->data[2] = 0x100;
else
sprite->data[2] = -0x10;
sprite->data[7]++;
sprite->x2 = sprite->y2 = 0;
InitAnimLinearTranslationWithSpeed(sprite);
}
break;
case 2:
if (AnimTranslateLinear(sprite))
{
if (sprite->oam.affineMode & 1)
{
FreeOamMatrix(sprite->oam.matrixNum);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
}
DestroySprite(sprite);
gAnimVisualTaskCount--;
}
break;
}
}
void AnimTask_Hail(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->func = AnimTask_Hail2;
}
static void AnimTask_Hail2(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[4] > 2)
{
task->data[4] = 0;
task->data[5] = 0;
task->data[2] = 0;
task->data[0]++;
}
break;
case 1:
if (task->data[5] == 0)
{
if (GenerateHailParticle(task->data[3], task->data[2], taskId, 1))
task->data[1]++;
if (++task->data[2] == 3)
{
if (++task->data[3] == 10)
task->data[0]++;
else
task->data[0]--;
}
else
{
task->data[5] = 1;
}
}
else
{
task->data[5]--;
}
break;
case 2:
if (task->data[1] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c)
{
u8 id;
s16 battlerX, battlerY;
s16 spriteX;
bool8 possibleBool = FALSE;
s8 unk = sHailCoordData[hailStructId].unk3;
if (unk != 2)
{
id = GetBattlerAtPosition(sHailCoordData[hailStructId].bPosition);
if (IsBattlerSpriteVisible(id))
{
possibleBool = TRUE;
battlerX = GetBattlerSpriteCoord(id, BATTLER_COORD_X_2);
battlerY = GetBattlerSpriteCoord(id, BATTLER_COORD_Y_PIC_OFFSET);
switch (unk)
{
case 0:
battlerX -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
battlerY -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
break;
case 1:
battlerX += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
battlerY += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
break;
}
}
else
{
battlerX = sHailCoordData[hailStructId].x;
battlerY = sHailCoordData[hailStructId].y;
}
}
else
{
battlerX = sHailCoordData[hailStructId].x;
battlerY = sHailCoordData[hailStructId].y;
}
spriteX = battlerX - ((battlerY + 8) / 2);
id = CreateSprite(&gHailParticleSpriteTemplate, spriteX, -8, 18);
if (id == MAX_SPRITES)
{
return FALSE;
}
else
{
StartSpriteAffineAnim(&gSprites[id], affineAnimNum);
gSprites[id].data[0] = possibleBool;
gSprites[id].data[3] = battlerX;
gSprites[id].data[4] = battlerY;
gSprites[id].data[5] = affineAnimNum;
gSprites[id].data[6] = taskId;
gSprites[id].data[7] = c;
return TRUE;
}
}
static void AnimHailBegin(struct Sprite *sprite)
{
u8 spriteId;
sprite->x += 4;
sprite->y += 8;
if (sprite->x < sprite->data[3] && sprite->y < sprite->data[4])
return;
if (sprite->data[0] == 1 && sprite->data[5] == 0)
{
spriteId = CreateSprite(&gIceCrystalHitLargeSpriteTemplate,
sprite->data[3], sprite->data[4], sprite->subpriority);
sprite->data[0] = spriteId;
if (spriteId != MAX_SPRITES)
{
gSprites[sprite->data[0]].callback = AnimHailContinue;
gSprites[sprite->data[0]].data[6] = sprite->data[6];
gSprites[sprite->data[0]].data[7] = sprite->data[7];
}
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
else
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
}
static void AnimHailContinue(struct Sprite *sprite)
{
if (++sprite->data[0] == 20)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
}
// Initializes the animation for Ice Ball.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: duration
// arg 5: arc height (negative)
static void InitIceBallAnim(struct Sprite *sprite)
{
u8 animNum = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
if (animNum > 4)
animNum = 4;
StartSpriteAffineAnim(sprite, animNum);
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
sprite->callback = AnimThrowIceBall;
}
// Throws the ball of ice in Ice Ball.
static void AnimThrowIceBall(struct Sprite *sprite)
{
if (!TranslateAnimHorizontalArc(sprite))
return;
StartSpriteAnim(sprite, 1);
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Initializes the particles that scatter at the end of the Ice Ball animation.
static void InitIceBallParticle(struct Sprite *sprite)
{
s16 randA, randB;
sprite->oam.tileNum += 8;
InitSpritePosToAnimTarget(sprite, TRUE);
randA = (Random2() & 0xFF) + 256;
randB = Random2() & 0x1FF;
if (randB > 0xFF)
randB = 256 - randB;
sprite->data[1] = randA;
sprite->data[2] = randB;
sprite->callback = AnimIceBallParticle;
}
// Animates the particles created by InitIceBallParticle.
static void AnimIceBallParticle(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
if (sprite->data[1] & 1)
sprite->x2 = -(sprite->data[3] >> 8);
else
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
if (++sprite->data[0] == 21)
DestroyAnimSprite(sprite);
}
void AnimTask_GetIceBallCounter(u8 taskId)
{
u8 arg = gBattleAnimArgs[0];
gBattleAnimArgs[arg] = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
DestroyAnimVisualTask(taskId);
}
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
static void AnimTask_ShakeMon_Step(u8 taskId);
static void AnimTask_ShakeMon2_Step(u8 taskId);
static void AnimTask_ShakeMonInPlace_Step(u8 taskId);
static void AnimTask_ShakeAndSinkMon_Step(u8 taskId);
static void AnimTask_TranslateMonElliptical_Step(u8 taskId);
static void DoHorizontalLunge(struct Sprite *sprite);
static void ReverseHorizontalLungeDirection(struct Sprite *sprite);
static void DoVerticalDip(struct Sprite *sprite);
static void ReverseVerticalDipDirection(struct Sprite *sprite);
static void SlideMonToOriginalPos(struct Sprite *sprite);
static void SlideMonToOriginalPos_Step(struct Sprite *sprite);
static void SlideMonToOffset(struct Sprite *sprite);
static void SlideMonToOffsetAndBack(struct Sprite *sprite);
static void SlideMonToOffsetAndBack_End(struct Sprite *sprite);
static void AnimTask_WindUpLunge_Step1(u8 taskId);
static void AnimTask_WindUpLunge_Step2(u8 taskId);
static void AnimTask_SwayMonStep(u8 taskId);
static void AnimTask_ScaleMonAndRestore_Step(u8 taskId);
static void AnimTask_RotateMonSpriteToSide_Step(u8 taskId);
static void AnimTask_ShakeTargetBasedOnMovePowerOrDmg_Step(u8 taskId);
static void AnimTask_SlideOffScreen_Step(u8 taskId);
const struct SpriteTemplate gHorizontalLungeSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = DoHorizontalLunge,
};
const struct SpriteTemplate gVerticalDipSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = DoVerticalDip,
};
const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SlideMonToOriginalPos,
};
const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SlideMonToOffset,
};
const struct SpriteTemplate gSlideMonToOffsetAndBackSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SlideMonToOffsetAndBack,
};
// Task to facilitate simple shaking of a pokemon's picture in battle.
// The shaking alternates between the original position and the target position.
// arg 0: anim battler
// arg 1: x pixel offset
// arg 2: y pixel offset
// arg 3: num times to shake
// arg 4: frame delay
void AnimTask_ShakeMon(u8 taskId)
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
{
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId].x2 = gBattleAnimArgs[1];
gSprites[spriteId].y2 = gBattleAnimArgs[2];
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[3];
gTasks[taskId].data[2] = gBattleAnimArgs[4];
gTasks[taskId].data[3] = gBattleAnimArgs[4];
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = gBattleAnimArgs[2];
gTasks[taskId].func = AnimTask_ShakeMon_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeMon_Step(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
if (gSprites[gTasks[taskId].data[0]].x2 == 0)
{
gSprites[gTasks[taskId].data[0]].x2 = gTasks[taskId].data[4];
}
else
{
gSprites[gTasks[taskId].data[0]].x2 = 0;
}
if (gSprites[gTasks[taskId].data[0]].y2 == 0)
{
gSprites[gTasks[taskId].data[0]].y2 = gTasks[taskId].data[5];
}
else
{
gSprites[gTasks[taskId].data[0]].y2 = 0;
}
gTasks[taskId].data[3] = gTasks[taskId].data[2];
if (--gTasks[taskId].data[1] == 0)
{
gSprites[gTasks[taskId].data[0]].x2 = 0;
gSprites[gTasks[taskId].data[0]].y2 = 0;
DestroyAnimVisualTask(taskId);
return;
}
}
else
{
gTasks[taskId].data[3]--;
}
}
// Task to facilitate simple shaking of a pokemon's picture in battle.
// The shaking alternates between the positive and negative versions of the specified pixel offsets.
// arg 0: anim battler
// arg 1: x pixel offset
// arg 2: y pixel offset
// arg 3: num times to shake
// arg 4: frame delay
void AnimTask_ShakeMon2(u8 taskId)
{
u8 spriteId;
bool8 abort = FALSE;
u8 battlerId;
if (gBattleAnimArgs[0] < MAX_BATTLERS_COUNT)
{
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
abort = TRUE;
}
else if (gBattleAnimArgs[0] != ANIM_ATTACKER_FORCE)
{
switch (gBattleAnimArgs[0])
{
case ANIM_PLAYER_LEFT:
battlerId = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
break;
case ANIM_PLAYER_RIGHT:
battlerId = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
break;
case ANIM_OPPONENT_LEFT:
battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
break;
case ANIM_OPPONENT_RIGHT:
default:
battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
break;
}
if (IsBattlerSpriteVisible(battlerId) == FALSE)
abort = TRUE;
spriteId = gBattlerSpriteIds[battlerId];
}
else
{
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
}
if (abort)
{
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId].x2 = gBattleAnimArgs[1];
gSprites[spriteId].y2 = gBattleAnimArgs[2];
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[3];
gTasks[taskId].data[2] = gBattleAnimArgs[4];
gTasks[taskId].data[3] = gBattleAnimArgs[4];
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = gBattleAnimArgs[2];
gTasks[taskId].func = AnimTask_ShakeMon2_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeMon2_Step(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
if (gSprites[gTasks[taskId].data[0]].x2 == gTasks[taskId].data[4])
gSprites[gTasks[taskId].data[0]].x2 = -gTasks[taskId].data[4];
else
gSprites[gTasks[taskId].data[0]].x2 = gTasks[taskId].data[4];
if (gSprites[gTasks[taskId].data[0]].y2 == gTasks[taskId].data[5])
gSprites[gTasks[taskId].data[0]].y2 = -gTasks[taskId].data[5];
else
gSprites[gTasks[taskId].data[0]].y2 = gTasks[taskId].data[5];
gTasks[taskId].data[3] = gTasks[taskId].data[2];
if (--gTasks[taskId].data[1] == 0)
{
gSprites[gTasks[taskId].data[0]].x2 = 0;
gSprites[gTasks[taskId].data[0]].y2 = 0;
DestroyAnimVisualTask(taskId);
return;
}
}
else
{
gTasks[taskId].data[3]--;
}
}
// Task to facilitate simple shaking of a pokemon's picture in battle.
// The shaking alternates between the positive and negative versions of the specified pixel offsets
// with respect to the current location of the mon's picture.
// arg 0: battler
// arg 1: x offset
// arg 2: y offset
// arg 3: num shakes
// arg 4: delay
void AnimTask_ShakeMonInPlace(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
{
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId].x2 += gBattleAnimArgs[1];
gSprites[spriteId].y2 += gBattleAnimArgs[2];
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[3];
gTasks[taskId].data[3] = 0;
gTasks[taskId].data[4] = gBattleAnimArgs[4];
gTasks[taskId].data[5] = gBattleAnimArgs[1] * 2;
gTasks[taskId].data[6] = gBattleAnimArgs[2] * 2;
gTasks[taskId].func = AnimTask_ShakeMonInPlace_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeMonInPlace_Step(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
if (gTasks[taskId].data[1] & 1)
{
gSprites[gTasks[taskId].data[0]].x2 += gTasks[taskId].data[5];
gSprites[gTasks[taskId].data[0]].y2 += gTasks[taskId].data[6];
}
else
{
gSprites[gTasks[taskId].data[0]].x2 -= gTasks[taskId].data[5];
gSprites[gTasks[taskId].data[0]].y2 -= gTasks[taskId].data[6];
}
gTasks[taskId].data[3] = gTasks[taskId].data[4];
if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2])
{
if (gTasks[taskId].data[1] & 1)
{
gSprites[gTasks[taskId].data[0]].x2 += gTasks[taskId].data[5] / 2;
gSprites[gTasks[taskId].data[0]].y2 += gTasks[taskId].data[6] / 2;
}
else
{
gSprites[gTasks[taskId].data[0]].x2 -= gTasks[taskId].data[5] / 2;
gSprites[gTasks[taskId].data[0]].y2 -= gTasks[taskId].data[6] / 2;
}
DestroyAnimVisualTask(taskId);
return;
}
}
else
{
gTasks[taskId].data[3]--;
}
}
// Shakes a mon bg horizontally and moves it downward linearly.
// arg 0: battler
// arg 1: x offset
// arg 2: frame delay between each movement
// arg 3: downward speed (subpixel)
// arg 4: duration
void AnimTask_ShakeAndSinkMon(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gSprites[spriteId].x2 = gBattleAnimArgs[1];
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
gTasks[taskId].data[4] = gBattleAnimArgs[4];
gTasks[taskId].func = AnimTask_ShakeAndSinkMon_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_ShakeAndSinkMon_Step(u8 taskId)
{
u8 spriteId = gTasks[taskId].data[0];
s16 x = gTasks[taskId].data[1];
if (gTasks[taskId].data[2] == gTasks[taskId].data[8]++)
{
gTasks[taskId].data[8] = 0;
if (gSprites[spriteId].x2 == x)
x = -x;
gSprites[spriteId].x2 += x;
}
gTasks[taskId].data[1] = x;
gTasks[taskId].data[9] += gTasks[taskId].data[3];
gSprites[spriteId].y2 = gTasks[taskId].data[9] >> 8;
if (--gTasks[taskId].data[4] == 0)
{
DestroyAnimVisualTask(taskId);
return;
}
}
// Moves a mon bg picture along an elliptical path that begins
// and ends at the mon's origin location.
// arg 0: battler
// arg 1: ellipse width
// arg 2: ellipse height
// arg 3: num loops
// arg 4: speed (valid values are 0-5)
void AnimTask_TranslateMonElliptical(u8 taskId)
{
u8 i;
u8 wavePeriod = 1;
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (gBattleAnimArgs[4] > 5)
gBattleAnimArgs[4] = 5;
for (i = 0; i < gBattleAnimArgs[4]; i++)
{
wavePeriod <<= 1;
}
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
gTasks[taskId].data[4] = wavePeriod;
gTasks[taskId].func = AnimTask_TranslateMonElliptical_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_TranslateMonElliptical_Step(u8 taskId)
{
u8 spriteId = gTasks[taskId].data[0];
gSprites[spriteId].x2 = Sin(gTasks[taskId].data[5], gTasks[taskId].data[1]);
gSprites[spriteId].y2 = -Cos(gTasks[taskId].data[5], gTasks[taskId].data[2]);
gSprites[spriteId].y2 += gTasks[taskId].data[2];
gTasks[taskId].data[5] += gTasks[taskId].data[4];
gTasks[taskId].data[5] &= 0xff;
if (gTasks[taskId].data[5] == 0)
gTasks[taskId].data[3]--;
if (gTasks[taskId].data[3] == 0)
{
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
return;
}
}
// Moves a mon bg picture along an elliptical path that begins
// and ends at the mon's origin location. Reverses the direction
// of the path if it's not on the player's side of the battle.
// arg 0: battler
// arg 1: ellipse width
// arg 2: ellipse height
// arg 3: num loops
// arg 4: speed (valid values are 0-5)
void AnimTask_TranslateMonEllipticalRespectSide(u8 taskId)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
AnimTask_TranslateMonElliptical(taskId);
}
// Performs a simple horizontal lunge, where the mon moves
// horizontally, and then moves back in the opposite direction.
// arg 0: duration of single lunge direction
// arg 1: x pixel delta that is applied each frame
static void DoHorizontalLunge(struct Sprite *sprite)
{
sprite->invisible = TRUE;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->data[1] = -gBattleAnimArgs[1];
else
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[2] = 0;
sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker];
sprite->data[4] = gBattleAnimArgs[0];
StoreSpriteCallbackInData6(sprite, ReverseHorizontalLungeDirection);
sprite->callback = TranslateSpriteLinearById;
}
static void ReverseHorizontalLungeDirection(struct Sprite *sprite)
{
sprite->data[0] = sprite->data[4];
sprite->data[1] = -sprite->data[1];
sprite->callback = TranslateSpriteLinearById;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Performs a simple vertical dipping motion, where moves vertically, and then
// moves back in the opposite direction.
// arg 0: duration of single dip direction
// arg 1: y pixel delta that is applied each frame
// arg 2: battler
static void DoVerticalDip(struct Sprite *sprite)
{
u8 spriteId;
sprite->invisible = TRUE;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = 0;
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[3] = spriteId;
sprite->data[4] = gBattleAnimArgs[0];
StoreSpriteCallbackInData6(sprite, ReverseVerticalDipDirection);
sprite->callback = TranslateSpriteLinearById;
}
static void ReverseVerticalDipDirection(struct Sprite *sprite)
{
sprite->data[0] = sprite->data[4];
sprite->data[2] = -sprite->data[2];
sprite->callback = TranslateSpriteLinearById;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Linearly slides a mon's bg picture back to its original sprite position.
// The sprite parameter is a dummy sprite used for facilitating the movement with its callback.
// arg 0: 1 = target or 0 = attacker
// arg 1: direction (0 = horizontal and vertical, 1 = horizontal only, 2 = vertical only)
// arg 2: duration
static void SlideMonToOriginalPos(struct Sprite *sprite)
{
u32 monSpriteId;
if (!gBattleAnimArgs[0])
monSpriteId = gBattlerSpriteIds[gBattleAnimAttacker];
else
monSpriteId = gBattlerSpriteIds[gBattleAnimTarget];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gSprites[monSpriteId].x + gSprites[monSpriteId].x2;
sprite->data[2] = gSprites[monSpriteId].x;
sprite->data[3] = gSprites[monSpriteId].y + gSprites[monSpriteId].y2;
sprite->data[4] = gSprites[monSpriteId].y;
InitSpriteDataForLinearTranslation(sprite);
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->data[5] = gSprites[monSpriteId].x2;
sprite->data[6] = gSprites[monSpriteId].y2;
sprite->invisible = TRUE;
if (gBattleAnimArgs[1] == 1)
sprite->data[2] = 0;
else if (gBattleAnimArgs[1] == 2)
sprite->data[1] = 0;
sprite->data[7] = gBattleAnimArgs[1];
sprite->data[7] |= monSpriteId << 8;
sprite->callback = SlideMonToOriginalPos_Step;
}
static void SlideMonToOriginalPos_Step(struct Sprite *sprite)
{
s8 monSpriteId;
u8 lo;
struct Sprite *monSprite;
lo = sprite->data[7] & 0xff;
monSpriteId = sprite->data[7] >> 8;
monSprite = &gSprites[monSpriteId];
if (sprite->data[0] == 0)
{
if (lo < 2)
monSprite->x2 = 0;
if (lo == 2 || lo == 0)
monSprite->y2 = 0;
DestroyAnimSprite(sprite);
}
else
{
sprite->data[0]--;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
monSprite->x2 = (s8)(sprite->data[3] >> 8) + sprite->data[5];
monSprite->y2 = (s8)(sprite->data[4] >> 8) + sprite->data[6];
}
}
// Linearly translates a mon to a target offset. The horizontal offset
// is mirrored for the opponent's pokemon, and the vertical offset
// is only mirrored if arg 3 is set to 1.
// arg 0: 0 = attacker, 1 = target
// arg 1: target x pixel offset
// arg 2: target y pixel offset
// arg 3: mirror vertical translation for opposite battle side
// arg 4: duration
static void SlideMonToOffset(struct Sprite *sprite)
{
u8 battler;
u8 monSpriteId;
if (!gBattleAnimArgs[0])
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
monSpriteId = gBattlerSpriteIds[battler];
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
if (gBattleAnimArgs[3] == 1)
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
}
}
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = gSprites[monSpriteId].x;
sprite->data[2] = gSprites[monSpriteId].x + gBattleAnimArgs[1];
sprite->data[3] = gSprites[monSpriteId].y;
sprite->data[4] = gSprites[monSpriteId].y + gBattleAnimArgs[2];
InitSpriteDataForLinearTranslation(sprite);
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->data[5] = monSpriteId;
sprite->invisible = TRUE;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteLinearByIdFixedPoint;
}
static void SlideMonToOffsetAndBack(struct Sprite *sprite)
{
u8 spriteId;
u8 battlerId;
sprite->invisible = TRUE;
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
battlerId = gBattleAnimAttacker;
else
battlerId = gBattleAnimTarget;
spriteId = gBattlerSpriteIds[battlerId];
if (GetBattlerSide(battlerId))
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
if (gBattleAnimArgs[3] == 1)
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
}
}
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = gSprites[spriteId].x + gSprites[spriteId].x2;
sprite->data[2] = sprite->data[1] + gBattleAnimArgs[1];
sprite->data[3] = gSprites[spriteId].y + gSprites[spriteId].y2;
sprite->data[4] = sprite->data[3] + gBattleAnimArgs[2];
InitSpriteDataForLinearTranslation(sprite);
sprite->data[3] = gSprites[spriteId].x2 << 8;
sprite->data[4] = gSprites[spriteId].y2 << 8;
sprite->data[5] = spriteId;
sprite->data[6] = gBattleAnimArgs[5];
if (!gBattleAnimArgs[5])
{
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
else
{
StoreSpriteCallbackInData6(sprite, SlideMonToOffsetAndBack_End);
}
sprite->callback = TranslateSpriteLinearByIdFixedPoint;
}
static void SlideMonToOffsetAndBack_End(struct Sprite *sprite)
{
gSprites[sprite->data[5]].x2 = 0;
gSprites[sprite->data[5]].y2 = 0;
DestroyAnimSprite(sprite);
}
// Task to facilitate a two-part translation animation, in which the sprite
// is first translated in an arc to one position. Then, it "lunges" to a target
// x offset. Used in TAKE_DOWN, for example.
// arg 0: anim bank
// arg 1: horizontal speed (subpixel)
// arg 2: wave amplitude
// arg 3: first duration
// arg 4: delay before starting lunge
// arg 5: target x offset for lunge
// arg 6: lunge duration
void AnimTask_WindUpLunge(u8 taskId)
{
s16 wavePeriod = 0x8000 / gBattleAnimArgs[3];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[5] = -gBattleAnimArgs[5];
}
gTasks[taskId].data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gTasks[taskId].data[1] = (gBattleAnimArgs[1] << 8) / gBattleAnimArgs[3];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
gTasks[taskId].data[4] = gBattleAnimArgs[4];
gTasks[taskId].data[5] = (gBattleAnimArgs[5] << 8) / gBattleAnimArgs[6];
gTasks[taskId].data[6] = gBattleAnimArgs[6];
gTasks[taskId].data[7] = wavePeriod;
gTasks[taskId].func = AnimTask_WindUpLunge_Step1;
}
static void AnimTask_WindUpLunge_Step1(u8 taskId)
{
u8 spriteId;
spriteId = gTasks[taskId].data[0];
gTasks[taskId].data[11] += gTasks[taskId].data[1];
gSprites[spriteId].x2 = gTasks[taskId].data[11] >> 8;
gSprites[spriteId].y2 = Sin((u8)(gTasks[taskId].data[10] >> 8), gTasks[taskId].data[2]);
gTasks[taskId].data[10] += gTasks[taskId].data[7];
if (--gTasks[taskId].data[3] == 0)
{
gTasks[taskId].func = AnimTask_WindUpLunge_Step2;
}
}
static void AnimTask_WindUpLunge_Step2(u8 taskId)
{
u8 spriteId;
if (gTasks[taskId].data[4] > 0)
{
gTasks[taskId].data[4]--;
}
else
{
spriteId = gTasks[taskId].data[0];
gTasks[taskId].data[12] += gTasks[taskId].data[5];
gSprites[spriteId].x2 = (gTasks[taskId].data[12] >> 8) + (gTasks[taskId].data[11] >> 8);
if (--gTasks[taskId].data[6] == 0)
{
DestroyAnimVisualTask(taskId);
return;
}
}
}
// To move a mon off-screen when pushed out by Roar/Whirlwind
void AnimTask_SlideOffScreen(u8 taskId)
{
u8 spriteId;
switch (gBattleAnimArgs[0])
{
case ANIM_ATTACKER:
case ANIM_TARGET:
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
break;
case ANIM_ATK_PARTNER:
if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
{
DestroyAnimVisualTask(taskId);
return;
}
spriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)];
break;
case ANIM_DEF_PARTNER:
if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
{
DestroyAnimVisualTask(taskId);
return;
}
spriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)];
break;
default:
DestroyAnimVisualTask(taskId);
return;
}
gTasks[taskId].data[0] = spriteId;
if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
{
gTasks[taskId].data[1] = gBattleAnimArgs[1];
}
else
{
gTasks[taskId].data[1] = -gBattleAnimArgs[1];
}
gTasks[taskId].func = AnimTask_SlideOffScreen_Step;
}
static void AnimTask_SlideOffScreen_Step(u8 taskId)
{
u8 spriteId = gTasks[taskId].data[0];
gSprites[spriteId].x2 += gTasks[taskId].data[1];
if (gSprites[spriteId].x2 + gSprites[spriteId].x < -32 || gSprites[spriteId].x2 + gSprites[spriteId].x > DISPLAY_WIDTH + 32)
{
DestroyAnimVisualTask(taskId);
return;
}
}
// Task that facilitates translating the mon bg picture back and forth
// in a swaying motion (uses Sine wave). It can sway either horizontally
// or vertically, but not both.
// arg 0: direction (0 = horizontal, 1 = vertical)
// arg 1: wave amplitude
// arg 2: wave period
// arg 3: num sways
// arg 4: which mon (0 = attacker, 1 = target)
void AnimTask_SwayMon(u8 taskId)
{
u8 spriteId;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]);
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[3];
gTasks[taskId].data[4] = spriteId;
if (gBattleAnimArgs[4] == 0)
gTasks[taskId].data[5] = gBattleAnimAttacker;
else
gTasks[taskId].data[5] = gBattleAnimTarget;
gTasks[taskId].data[12] = 1;
gTasks[taskId].func = AnimTask_SwayMonStep;
}
static void AnimTask_SwayMonStep(u8 taskId)
{
s16 sineValue;
u8 spriteId;
int waveIndex;
u16 sineIndex;
spriteId = gTasks[taskId].data[4];
sineIndex = gTasks[taskId].data[10] + gTasks[taskId].data[2];
gTasks[taskId].data[10] = sineIndex;
waveIndex = sineIndex >> 8;
sineValue = Sin(waveIndex, gTasks[taskId].data[1]);
if (gTasks[taskId].data[0] == 0)
{
gSprites[spriteId].x2 = sineValue;
}
else
{
if (GetBattlerSide(gTasks[taskId].data[5]) == B_SIDE_PLAYER)
{
gSprites[spriteId].y2 = (sineValue >= 0) ? sineValue : -sineValue;
}
else
{
gSprites[spriteId].y2 = (sineValue >= 0) ? -sineValue : sineValue;
}
}
if (((waveIndex >= 0x80u) && (gTasks[taskId].data[11] == 0) && (gTasks[taskId].data[12] == 1))
|| ((waveIndex < 0x7fu) && (gTasks[taskId].data[11] == 1) && (gTasks[taskId].data[12] == 0)))
{
gTasks[taskId].data[11] ^= 1;
gTasks[taskId].data[12] ^= 1;
if (--gTasks[taskId].data[3] == 0)
{
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
return;
}
}
}
// Scales a mon's sprite, and then scales back to its original dimensions.
// arg 0: x scale delta
// arg 1: y scale delta
// arg 2: duration
// arg 3: anim bank
// arg 4: sprite object mode
void AnimTask_ScaleMonAndRestore(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]);
PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]);
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].data[3] = gBattleAnimArgs[2];
gTasks[taskId].data[4] = spriteId;
gTasks[taskId].data[10] = 0x100;
gTasks[taskId].data[11] = 0x100;
gTasks[taskId].func = AnimTask_ScaleMonAndRestore_Step;
}
static void AnimTask_ScaleMonAndRestore_Step(u8 taskId)
{
u8 spriteId;
gTasks[taskId].data[10] += gTasks[taskId].data[0];
gTasks[taskId].data[11] += gTasks[taskId].data[1];
spriteId = gTasks[taskId].data[4];
SetSpriteRotScale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[11], 0);
if (--gTasks[taskId].data[2] == 0)
{
if (gTasks[taskId].data[3] > 0)
{
gTasks[taskId].data[0] = -gTasks[taskId].data[0];
gTasks[taskId].data[1] = -gTasks[taskId].data[1];
gTasks[taskId].data[2] = gTasks[taskId].data[3];
gTasks[taskId].data[3] = 0;
}
else
{
ResetSpriteRotScale(spriteId);
DestroyAnimVisualTask(taskId);
return;
}
}
}
void AnimTask_RotateMonSpriteToSide(u8 taskId)
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[0];
if (gBattleAnimArgs[3] != 1)
{
gTasks[taskId].data[3] = 0;
}
else
{
gTasks[taskId].data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1];
}
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = spriteId;
gTasks[taskId].data[6] = gBattleAnimArgs[3];
if (IsContest())
{
gTasks[taskId].data[7] = 1;
}
else
{
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
{
gTasks[taskId].data[7] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER;
}
else
{
gTasks[taskId].data[7] = GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER;
}
}
if (gTasks[taskId].data[7])
{
if (!IsContest())
{
gTasks[taskId].data[3] *= -1;
gTasks[taskId].data[4] *= -1;
}
}
gTasks[taskId].func = AnimTask_RotateMonSpriteToSide_Step;
}
// Rotates mon to side and back to original position. For Peck and when a held item activates
void AnimTask_RotateMonToSideAndRestore(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = gBattleAnimArgs[0];
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
{
if (GetBattlerSide(gBattleAnimAttacker))
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
}
}
else
{
if (GetBattlerSide(gBattleAnimTarget))
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
}
}
if (gBattleAnimArgs[3] != 1)
{
gTasks[taskId].data[3] = 0;
}
else
{
gTasks[taskId].data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1];
}
gTasks[taskId].data[4] = gBattleAnimArgs[1];
gTasks[taskId].data[5] = spriteId;
gTasks[taskId].data[6] = gBattleAnimArgs[3];
gTasks[taskId].data[7] = 1;
gTasks[taskId].data[3] *= -1;
gTasks[taskId].data[4] *= -1;
gTasks[taskId].func = AnimTask_RotateMonSpriteToSide_Step;
}
static void AnimTask_RotateMonSpriteToSide_Step(u8 taskId)
{
gTasks[taskId].data[3] += gTasks[taskId].data[4];
SetSpriteRotScale(gTasks[taskId].data[5], 0x100, 0x100, gTasks[taskId].data[3]);
if (gTasks[taskId].data[7])
{
SetBattlerSpriteYOffsetFromRotation(gTasks[taskId].data[5]);
}
if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2])
{
switch (gTasks[taskId].data[6])
{
case 1:
ResetSpriteRotScale(gTasks[taskId].data[5]);
case 0:
default:
DestroyAnimVisualTask(taskId);
return;
case 2:
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[4] *= -1;
gTasks[taskId].data[6] = 1;
break;
}
}
}
void AnimTask_ShakeTargetBasedOnMovePowerOrDmg(u8 taskId)
{
if (!gBattleAnimArgs[0])
{
gTasks[taskId].data[15] = gAnimMovePower / 12;
if (gTasks[taskId].data[15] < 1)
{
gTasks[taskId].data[15] = 1;
}
if (gTasks[taskId].data[15] > 16)
{
gTasks[taskId].data[15] = 16;
}
}
else
{
gTasks[taskId].data[15] = gAnimMoveDmg / 12;
if (gTasks[taskId].data[15] < 1)
{
gTasks[taskId].data[15] = 1;
}
if (gTasks[taskId].data[15] > 16)
{
gTasks[taskId].data[15] = 16;
}
}
gTasks[taskId].data[14] = gTasks[taskId].data[15] / 2;
gTasks[taskId].data[13] = gTasks[taskId].data[14] + (gTasks[taskId].data[15] & 1);
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[10] = gBattleAnimArgs[3];
gTasks[taskId].data[11] = gBattleAnimArgs[4];
gTasks[taskId].data[7] = GetAnimBattlerSpriteId(ANIM_TARGET);
gTasks[taskId].data[8] = gSprites[gTasks[taskId].data[7]].x2;
gTasks[taskId].data[9] = gSprites[gTasks[taskId].data[7]].y2;
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[2] = gBattleAnimArgs[2];
gTasks[taskId].func = AnimTask_ShakeTargetBasedOnMovePowerOrDmg_Step;
}
static void AnimTask_ShakeTargetBasedOnMovePowerOrDmg_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (++task->data[0] > task->data[1])
{
task->data[0] = 0;
task->data[12] = (task->data[12] + 1) & 1;
if (task->data[10])
{
if (task->data[12])
{
gSprites[task->data[7]].x2 = task->data[8] + task->data[13];
}
else
{
gSprites[task->data[7]].x2 = task->data[8] - task->data[14];
}
}
if (task->data[11])
{
if (task->data[12])
{
gSprites[task->data[7]].y2 = task->data[15];
}
else
{
gSprites[task->data[7]].y2 = 0;
}
}
if (!--task->data[2])
{
gSprites[task->data[7]].x2 = 0;
gSprites[task->data[7]].y2 = 0;
DestroyAnimVisualTask(taskId);
return;
}
}
}
#include "global.h"
#include "battle_anim.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimSludgeProjectile(struct Sprite *);
static void AnimSludgeProjectile_Step(struct Sprite *);
static void AnimAcidPoisonBubble(struct Sprite *);
static void AnimAcidPoisonBubble_Step(struct Sprite *);
static void AnimSludgeBombHitParticle(struct Sprite *);
static void AnimSludgeBombHitParticle_Step(struct Sprite *);
static void AnimAcidPoisonDroplet(struct Sprite *);
static void AnimBubbleEffect(struct Sprite *);
static void AnimBubbleEffect_Step(struct Sprite *);
static const union AnimCmd sAnim_ToxicBubble[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(24, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ToxicBubble[] =
{
sAnim_ToxicBubble,
};
const struct SpriteTemplate gToxicBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_TOXIC_BUBBLE,
.paletteTag = ANIM_TAG_TOXIC_BUBBLE,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = sAnims_ToxicBubble,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
static const union AnimCmd sAnim_PoisonProjectile[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_AcidPoisonDroplet[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_SludgeBombHit[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_PoisonProjectile[] =
{
sAnim_PoisonProjectile,
};
static const union AnimCmd *const sAnims_AcidPoisonDroplet[] =
{
sAnim_AcidPoisonDroplet,
};
static const union AnimCmd *const sAnims_SludgeBombHit[] =
{
sAnim_SludgeBombHit,
};
static const union AffineAnimCmd sAffineAnim_PoisonProjectile[] =
{
AFFINEANIMCMD_FRAME(0x160, 0x160, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10),
AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd sAffineAnim_SludgeBombHit[] =
{
AFFINEANIMCMD_FRAME(0xEC, 0xEC, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_PoisonProjectile[] =
{
sAffineAnim_PoisonProjectile,
};
static const union AffineAnimCmd *const sAffineAnims_SludgeBombHit[] =
{
sAffineAnim_SludgeBombHit,
};
const struct SpriteTemplate gSludgeProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = sAnims_PoisonProjectile,
.images = NULL,
.affineAnims = sAffineAnims_PoisonProjectile,
.callback = AnimSludgeProjectile,
};
const struct SpriteTemplate gAcidPoisonBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = sAnims_PoisonProjectile,
.images = NULL,
.affineAnims = sAffineAnims_PoisonProjectile,
.callback = AnimAcidPoisonBubble,
};
const struct SpriteTemplate gSludgeBombHitParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = sAnims_SludgeBombHit,
.images = NULL,
.affineAnims = sAffineAnims_SludgeBombHit,
.callback = AnimSludgeBombHitParticle,
};
static const union AffineAnimCmd sAffineAnim_AcidPoisonDroplet[] =
{
AFFINEANIMCMD_FRAME(0xFFF0, 0x10, 0, 6),
AFFINEANIMCMD_FRAME(0x10, 0xFFF0, 0, 6),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gAffineAnims_Droplet[] =
{
sAffineAnim_AcidPoisonDroplet,
};
const struct SpriteTemplate gAcidPoisonDropletSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = sAnims_AcidPoisonDroplet,
.images = NULL,
.affineAnims = gAffineAnims_Droplet,
.callback = AnimAcidPoisonDroplet,
};
static const union AffineAnimCmd sAffineAnim_Bubble[] =
{
AFFINEANIMCMD_FRAME(0x9C, 0x9C, 0, 0),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 20),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_Bubble[] =
{
sAffineAnim_Bubble,
};
const struct SpriteTemplate gPoisonBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_BUBBLE,
.paletteTag = ANIM_TAG_POISON_BUBBLE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = sAnims_PoisonProjectile,
.images = NULL,
.affineAnims = sAffineAnims_Bubble,
.callback = AnimBubbleEffect,
};
const struct SpriteTemplate gWaterBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = gAnims_WaterBubble,
.images = NULL,
.affineAnims = sAffineAnims_Bubble,
.callback = AnimBubbleEffect,
};
static void AnimSludgeProjectile(struct Sprite *sprite)
{
if (!gBattleAnimArgs[3])
StartSpriteAnim(sprite, 2);
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[5] = -30;
InitAnimArcTranslation(sprite);
sprite->callback = AnimSludgeProjectile_Step;
}
static void AnimSludgeProjectile_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
static void AnimAcidPoisonBubble(struct Sprite *sprite)
{
s16 l1, l2;
if (!gBattleAnimArgs[3])
StartSpriteAnim(sprite, 2);
InitSpritePosToAnimAttacker(sprite, TRUE);
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &l1, &l2);
if (GetBattlerSide(gBattleAnimAttacker))
gBattleAnimArgs[4] = -gBattleAnimArgs[4];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = l1 + gBattleAnimArgs[4];
sprite->data[4] = l2 + gBattleAnimArgs[5];
sprite->data[5] = -30;
InitAnimArcTranslation(sprite);
sprite->callback = AnimAcidPoisonBubble_Step;
}
static void AnimAcidPoisonBubble_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
static void AnimSludgeBombHitParticle(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x + gBattleAnimArgs[0];
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + gBattleAnimArgs[1];
InitSpriteDataForLinearTranslation(sprite);
sprite->data[5] = sprite->data[1] / gBattleAnimArgs[2];
sprite->data[6] = sprite->data[2] / gBattleAnimArgs[2];
sprite->callback = AnimSludgeBombHitParticle_Step;
}
static void AnimSludgeBombHitParticle_Step(struct Sprite *sprite)
{
TranslateSpriteLinearFixedPoint(sprite);
sprite->data[1] -= sprite->data[5];
sprite->data[2] -= sprite->data[6];
if (!sprite->data[0])
DestroyAnimSprite(sprite);
}
static void AnimAcidPoisonDroplet(struct Sprite *sprite)
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
sprite->data[4] = sprite->y + sprite->data[0];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Animates a bubble by rising upward, swaying side to side, and
// enlarging the sprite. This is used as an after-effect by poison-type
// moves, along with MOVE_BUBBLE, and MOVE_BUBBLEBEAM.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: 0 = single-target, 1 = multi-target
static void AnimBubbleEffect(struct Sprite *sprite)
{
if (!gBattleAnimArgs[2])
{
InitSpritePosToAnimTarget(sprite, TRUE);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->callback = AnimBubbleEffect_Step;
}
static void AnimBubbleEffect_Step(struct Sprite *sprite)
{
sprite->data[0] = (sprite->data[0] + 0xB) & 0xFF;
sprite->x2 = Sin(sprite->data[0], 4);
sprite->data[1] += 0x30;
sprite->y2 = -(sprite->data[1] >> 8);
if (sprite->affineAnimEnded)
DestroyAnimSprite(sprite);
}
#include "global.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "palette.h"
#include "sound.h"
#include "scanline_effect.h"
#include "trig.h"
#include "constants/rgb.h"
#include "constants/songs.h"
static void AnimDefensiveWall(struct Sprite *);
static void AnimDefensiveWall_Step1(struct Sprite *);
static void AnimDefensiveWall_Step2(struct Sprite *);
static void AnimDefensiveWall_Step3(struct Sprite *);
static void AnimDefensiveWall_Step4(struct Sprite *);
static void AnimDefensiveWall_Step5(struct Sprite *);
static void AnimWallSparkle(struct Sprite *);
static void AnimBentSpoon(struct Sprite *);
static void AnimQuestionMark(struct Sprite *);
static void AnimQuestionMark_Step1(struct Sprite *);
static void AnimQuestionMark_Step2(struct Sprite *);
static void AnimRedX(struct Sprite *);
static void AnimSkillSwapOrb(struct Sprite *);
static void AnimPsychoBoost(struct Sprite *);
static void AnimTask_MeditateStretchAttacker_Step(u8);
static void AnimTask_Teleport_Step(u8);
static void AnimTask_ImprisonOrbs_Step(u8);
static void AnimTask_SkillSwap_Step(u8);
static void AnimTask_ExtrasensoryDistortion_Step(u8);
static void AnimTask_TransparentCloneGrowAndShrink_Step(u8);
static const union AffineAnimCmd sAffineAnim_PsychUpSpiral[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0xFFFE, 0xFFFE, -10, 120),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_PsychUpSpiral[] =
{
sAffineAnim_PsychUpSpiral,
};
const struct SpriteTemplate gPsychUpSpiralSpriteTemplate =
{
.tileTag = ANIM_TAG_SPIRAL,
.paletteTag = ANIM_TAG_SPIRAL,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_PsychUpSpiral,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gLightScreenWallSpriteTemplate =
{
.tileTag = ANIM_TAG_GREEN_LIGHT_WALL,
.paletteTag = ANIM_TAG_GREEN_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDefensiveWall,
};
const struct SpriteTemplate gReflectWallSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_LIGHT_WALL,
.paletteTag = ANIM_TAG_BLUE_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDefensiveWall,
};
const struct SpriteTemplate gMirrorCoatWallSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_LIGHT_WALL,
.paletteTag = ANIM_TAG_RED_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDefensiveWall,
};
const struct SpriteTemplate gBarrierWallSpriteTemplate =
{
.tileTag = ANIM_TAG_GRAY_LIGHT_WALL,
.paletteTag = ANIM_TAG_GRAY_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDefensiveWall,
};
const struct SpriteTemplate gMagicCoatWallSpriteTemplate =
{
.tileTag = ANIM_TAG_ORANGE_LIGHT_WALL,
.paletteTag = ANIM_TAG_ORANGE_LIGHT_WALL,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDefensiveWall,
};
static const union AnimCmd sAnim_ReflectSparkle[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ReflectSparkle[] =
{
sAnim_ReflectSparkle,
};
const struct SpriteTemplate gReflectSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_4,
.paletteTag = ANIM_TAG_SPARKLE_4,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_ReflectSparkle,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWallSparkle,
};
static const union AnimCmd sAnim_SpecialScreenSparkle[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(12, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_SpecialScreenSparkle[] =
{
sAnim_SpecialScreenSparkle,
};
const struct SpriteTemplate gSpecialScreenSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_3,
.paletteTag = ANIM_TAG_SPARKLE_3,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_SpecialScreenSparkle,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWallSparkle,
};
const struct SpriteTemplate gGoldRingSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_RING,
.paletteTag = ANIM_TAG_GOLD_RING,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
static const union AnimCmd sAnim_BentSpoon_0[] =
{
ANIMCMD_FRAME(8, 60, .hFlip = TRUE),
ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
ANIMCMD_FRAME(8, 22, .hFlip = TRUE),
ANIMCMD_LOOP(0),
ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
ANIMCMD_FRAME(8, 5, .hFlip = TRUE),
ANIMCMD_LOOP(1),
ANIMCMD_FRAME(8, 22, .hFlip = TRUE),
ANIMCMD_FRAME(24, 3, .hFlip = TRUE),
ANIMCMD_FRAME(32, 3, .hFlip = TRUE),
ANIMCMD_FRAME(40, 22, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_BentSpoon_1[] =
{
ANIMCMD_FRAME(8, 60),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(8, 22),
ANIMCMD_LOOP(0),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_LOOP(1),
ANIMCMD_FRAME(8, 22),
ANIMCMD_FRAME(24, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(40, 22),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_BentSpoon[] =
{
sAnim_BentSpoon_0,
sAnim_BentSpoon_1,
};
const struct SpriteTemplate gBentSpoonSpriteTemplate =
{
.tileTag = ANIM_TAG_BENT_SPOON,
.paletteTag = ANIM_TAG_BENT_SPOON,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = sAnims_BentSpoon,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBentSpoon,
};
static const union AnimCmd sAnim_QuestionMark[] =
{
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 6),
ANIMCMD_FRAME(48, 6),
ANIMCMD_FRAME(64, 6),
ANIMCMD_FRAME(80, 6),
ANIMCMD_FRAME(96, 18),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_QuestionMark[] =
{
sAnim_QuestionMark,
};
static const union AffineAnimCmd sAffineAnim_QuestionMark[] =
{
AFFINEANIMCMD_FRAME(0, 0, 4, 4),
AFFINEANIMCMD_FRAME(0, 0, -4, 8),
AFFINEANIMCMD_FRAME(0, 0, 4, 4),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_QuestionMark[] =
{
sAffineAnim_QuestionMark,
};
const struct SpriteTemplate gQuestionMarkSpriteTemplate =
{
.tileTag = ANIM_TAG_AMNESIA,
.paletteTag = ANIM_TAG_AMNESIA,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_QuestionMark,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimQuestionMark,
};
static const union AffineAnimCmd sAffineAnim_MeditateStretchAttacker[] =
{
AFFINEANIMCMD_FRAME(-8, 10, 0, 16),
AFFINEANIMCMD_FRAME(18, -18, 0, 16),
AFFINEANIMCMD_FRAME(-20, 16, 0, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Teleport[] =
{
AFFINEANIMCMD_FRAME(64, -4, 0, 20),
AFFINEANIMCMD_FRAME(0, 0, 0, -56),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gImprisonOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_HOLLOW_ORB,
.paletteTag = ANIM_TAG_HOLLOW_ORB,
.oam = &gOamData_AffineOff_ObjBlend_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
const struct SpriteTemplate gRedXSpriteTemplate =
{
.tileTag = ANIM_TAG_X_SIGN,
.paletteTag = ANIM_TAG_X_SIGN,
.oam = &gOamData_AffineOff_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRedX,
};
static const union AffineAnimCmd sAffineAnim_SkillSwapOrb_0[] =
{
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd sAffineAnim_SkillSwapOrb_1[] =
{
AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd sAffineAnim_SkillSwapOrb_2[] =
{
AFFINEANIMCMD_FRAME(0xD0, 0xD0, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd sAffineAnim_SkillSwapOrb_3[] =
{
AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_SkillSwapOrb[] =
{
sAffineAnim_SkillSwapOrb_0,
sAffineAnim_SkillSwapOrb_1,
sAffineAnim_SkillSwapOrb_2,
sAffineAnim_SkillSwapOrb_3,
};
const struct SpriteTemplate gSkillSwapOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUEGREEN_ORB,
.paletteTag = ANIM_TAG_BLUEGREEN_ORB,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_SkillSwapOrb,
.callback = AnimSkillSwapOrb,
};
static const union AffineAnimCmd sAffineAnim_LusterPurgeCircle[] =
{
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 120),
AFFINEANIMCMD_END_ALT(1),
};
static const union AffineAnimCmd *const sAffineAnims_LusterPurgeCircle[] =
{
sAffineAnim_LusterPurgeCircle,
};
const struct SpriteTemplate gLusterPurgeCircleSpriteTemplate =
{
.tileTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_WHITE_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_LusterPurgeCircle,
.callback = AnimSpriteOnMonPos,
};
static const union AffineAnimCmd sAffineAnim_PsychoBoostOrb_0[] =
{
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 17),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 10),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10),
AFFINEANIMCMD_LOOP(4),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 5),
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 5),
AFFINEANIMCMD_LOOP(7),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_PsychoBoostOrb_1[] =
{
AFFINEANIMCMD_FRAME(0xFFEC, 0x18, 0, 15),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_PsychoBoostOrb[] =
{
sAffineAnim_PsychoBoostOrb_0,
sAffineAnim_PsychoBoostOrb_1,
};
const struct SpriteTemplate gPsychoBoostOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_PsychoBoostOrb,
.callback = AnimPsychoBoost,
};
// For the rectangular wall sprite used by Reflect, Mirror Coat, etc
static void AnimDefensiveWall(struct Sprite *sprite)
{
u8 isContest = IsContest();
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER || isContest)
{
sprite->oam.priority = 2;
sprite->subpriority = 200;
}
if (!isContest)
{
u8 battlerCopy;
u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
u8 rank = GetBattlerSpriteBGPriorityRank(battler);
int var0 = 1;
u8 toBG_2 = (rank ^ var0) != 0;
if (IsBattlerSpriteVisible(battler))
MoveBattlerSpriteToBG(battler, toBG_2, FALSE);
battler = BATTLE_PARTNER(battlerCopy);
if (IsBattlerSpriteVisible(battler))
MoveBattlerSpriteToBG(battler, toBG_2 ^ var0, FALSE);
}
if (!isContest && IsDoubleBattle())
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x = 72;
sprite->y = 80;
}
else
{
sprite->x = 176;
sprite->y = 40;
}
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
}
sprite->data[0] = 256 + IndexOfSpritePaletteTag(gBattleAnimArgs[2]) * 16;
if (isContest)
{
sprite->y += 9;
sprite->callback = AnimDefensiveWall_Step2;
sprite->callback(sprite);
}
else
{
sprite->callback = AnimDefensiveWall_Step1;
}
}
static void AnimDefensiveWall_Step1(struct Sprite *sprite)
{
u8 battler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (!sprite->data[7])
{
sprite->data[7] = 1;
return;
}
if (IsBattlerSpriteVisible(battler))
gSprites[gBattlerSpriteIds[battler]].invisible = TRUE;
battler = BATTLE_PARTNER(battler);
if (IsBattlerSpriteVisible(battler))
gSprites[gBattlerSpriteIds[battler]].invisible = TRUE;
sprite->callback = AnimDefensiveWall_Step2;
sprite->callback(sprite);
}
static void AnimDefensiveWall_Step2(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3]));
if (sprite->data[3] == 13)
sprite->callback = AnimDefensiveWall_Step3;
else
sprite->data[3]++;
}
static void AnimDefensiveWall_Step3(struct Sprite *sprite)
{
u16 color;
u16 startOffset;
int i;
if (++sprite->data[1] == 2)
{
sprite->data[1] = 0;
startOffset = sprite->data[0];
color = gPlttBufferFaded[startOffset + 8];
for (i = 8; i > 0; i--)
gPlttBufferFaded[startOffset + i] = gPlttBufferFaded[startOffset + i - 1];
gPlttBufferFaded[startOffset + 1] = color;
if (++sprite->data[2] == 16)
sprite->callback = AnimDefensiveWall_Step4;
}
}
static void AnimDefensiveWall_Step4(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[3], 16 - sprite->data[3]));
if (--sprite->data[3] == -1)
{
if (!IsContest())
{
u8 battlerCopy;
u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (IsBattlerSpriteVisible(battler))
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
battler = BATTLE_PARTNER(battlerCopy);
if (IsBattlerSpriteVisible(battler))
gSprites[gBattlerSpriteIds[battler]].invisible = FALSE;
}
sprite->invisible = TRUE;
sprite->callback = AnimDefensiveWall_Step5;
}
}
static void AnimDefensiveWall_Step5(struct Sprite *sprite)
{
if (!IsContest())
{
u8 battlerCopy;
u8 battler = battlerCopy = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
u8 rank = GetBattlerSpriteBGPriorityRank(battler);
int var0 = 1;
bool8 toBG2 = (rank ^ var0) != 0;
if (IsBattlerSpriteVisible(battler))
ResetBattleAnimBg(toBG2);
battler = BATTLE_PARTNER(battlerCopy);
if (IsBattlerSpriteVisible(battler))
ResetBattleAnimBg(toBG2 ^ var0);
}
sprite->callback = DestroyAnimSprite;
}
// Animates the sparkle that appears during Reflect or Light Screen/Mirror Coat
static void AnimWallSparkle(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
bool32 ignoreOffsets = gBattleAnimArgs[3];
bool8 respectMonPicOffsets = FALSE;
if (!ignoreOffsets)
respectMonPicOffsets = TRUE;
if (!IsContest() && IsDoubleBattle())
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x = 72 - gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1] + 80;
}
else
{
sprite->x = gBattleAnimArgs[0] + 176;
sprite->y = gBattleAnimArgs[1] + 40;
}
}
else
{
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, respectMonPicOffsets);
else
InitSpritePosToAnimTarget(sprite, respectMonPicOffsets);
}
sprite->data[0]++;
}
else
{
if (sprite->animEnded || sprite->affineAnimEnded)
DestroySpriteAndMatrix(sprite);
}
}
static void AnimBentSpoon(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
StartSpriteAnim(sprite, 1);
sprite->x -= 40;
sprite->y += 10;
sprite->data[1] = -1;
}
else
{
sprite->x += 40;
sprite->y -= 10;
sprite->data[1] = 1;
}
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
// Used by Amnesia
static void AnimQuestionMark(struct Sprite *sprite)
{
s16 x = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 2;
s16 y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / -2;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
x = -x;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + x;
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + y;
if (sprite->y < 16)
sprite->y = 16;
StoreSpriteCallbackInData6(sprite, AnimQuestionMark_Step1);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
static void AnimQuestionMark_Step1(struct Sprite *sprite)
{
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
sprite->affineAnims = sAffineAnims_QuestionMark;
sprite->data[0] = 0;
InitSpriteAffineAnim(sprite);
sprite->callback = AnimQuestionMark_Step2;
}
static void AnimQuestionMark_Step2(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (sprite->affineAnimEnded)
{
FreeOamMatrix(sprite->oam.matrixNum);
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
sprite->data[1] = 18;
sprite->data[0]++;
}
break;
case 1:
if (--sprite->data[1] == -1)
DestroyAnimSprite(sprite);
break;
}
}
void AnimTask_MeditateStretchAttacker(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[0] = spriteId;
PrepareAffineAnimInTaskData(task, spriteId, sAffineAnim_MeditateStretchAttacker);
task->func = AnimTask_MeditateStretchAttacker_Step;
}
static void AnimTask_MeditateStretchAttacker_Step(u8 taskId)
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
void AnimTask_Teleport(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[0] = spriteId;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 4 : 8;
PrepareAffineAnimInTaskData(task, task->data[0], sAffineAnim_Teleport);
task->func = AnimTask_Teleport_Step;
}
static void AnimTask_Teleport_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[1])
{
case 0:
RunAffineAnimFromTaskData(task);
if (++task->data[2] > 19)
task->data[1]++;
break;
case 1:
if (task->data[3] != 0)
{
gSprites[task->data[0]].y2 -= 8;
task->data[3]--;
}
else
{
gSprites[task->data[0]].invisible = TRUE;
gSprites[task->data[0]].x = DISPLAY_WIDTH + 32;
ResetSpriteRotScale(task->data[0]);
DestroyAnimVisualTask(taskId);
}
break;
}
}
void AnimTask_ImprisonOrbs(u8 taskId)
{
u16 var0, var1;
struct Task *task = &gTasks[taskId];
task->data[3] = 16;
task->data[4] = 0;
task->data[13] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
var0 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_WIDTH) / 3;
var1 = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 3;
task->data[12] = var0 > var1 ? var0 : var1;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
task->func = AnimTask_ImprisonOrbs_Step;
}
static void AnimTask_ImprisonOrbs_Step(u8 taskId)
{
u16 i;
u8 spriteId;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] > 8)
{
task->data[1] = 0;
spriteId = CreateSprite(&gImprisonOrbSpriteTemplate, task->data[13], task->data[14], 0);
task->data[task->data[2] + 8] = spriteId;
if (spriteId != MAX_SPRITES)
{
switch (task->data[2])
{
case 0:
gSprites[spriteId].x2 = task->data[12];
gSprites[spriteId].y2 = -task->data[12];
break;
case 1:
gSprites[spriteId].x2 = -task->data[12];
gSprites[spriteId].y2 = task->data[12];
break;
case 2:
gSprites[spriteId].x2 = task->data[12];
gSprites[spriteId].y2 = task->data[12];
break;
case 3:
gSprites[spriteId].x2 = -task->data[12];
gSprites[spriteId].y2 = -task->data[12];
break;
}
}
if (++task->data[2] == 5)
task->data[0]++;
}
break;
case 1:
if (task->data[1] & 1)
task->data[3]--;
else
task->data[4]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
if (++task->data[1] == 32)
{
for (i = 8; i < 13; i++)
{
if (task->data[i] != MAX_SPRITES)
DestroySprite(&gSprites[task->data[i]]);
}
task->data[0]++;
}
break;
case 2:
task->data[0]++;
break;
case 3:
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimRedX_Step(struct Sprite *sprite)
{
if (sprite->data[1] > sprite->data[0] - 10)
sprite->invisible = sprite->data[1] & 1;
if (sprite->data[1] == sprite->data[0])
DestroyAnimSprite(sprite);
sprite->data[1]++;
}
static void AnimRedX(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->data[0] = gBattleAnimArgs[1];
sprite->callback = AnimRedX_Step;
}
void AnimTask_SkillSwap(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (IsContest())
{
if (gBattleAnimArgs[0] == ANIM_TARGET)
{
task->data[10] = -10;
task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8;
task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8;
task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8;
task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8;
}
else
{
task->data[10] = 10;
task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8;
task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8;
task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8;
task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8;
}
}
else
{
if (gBattleAnimArgs[0] == 1)
{
task->data[10] = -10;
task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_LEFT) + 8;
task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) + 8;
task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_LEFT) + 8;
task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) + 8;
}
else
{
task->data[10] = 10;
task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_RIGHT) - 8;
task->data[12] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM) - 8;
task->data[13] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_RIGHT) - 8;
task->data[14] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM) - 8;
}
}
task->data[1] = 6;
task->func = AnimTask_SkillSwap_Step;
}
static void AnimTask_SkillSwap_Step(u8 taskId)
{
u8 spriteId;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] > 6)
{
task->data[1] = 0;
spriteId = CreateSprite(&gSkillSwapOrbSpriteTemplate, task->data[11], task->data[12], 0);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[0] = 16;
gSprites[spriteId].data[2] = task->data[13];
gSprites[spriteId].data[4] = task->data[14];
gSprites[spriteId].data[5] = task->data[10];
InitAnimArcTranslation(&gSprites[spriteId]);
StartSpriteAffineAnim(&gSprites[spriteId], task->data[2] & 3);
}
if (++task->data[2] == 12)
task->data[0]++;
}
break;
case 1:
if (++task->data[1] > 17)
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimSkillSwapOrb(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
}
}
// The scanline effect that distorts the target during Extrasensory by segmenting the mon vertically and shifting the slices
// arg0: Stage. Stage 0 is a slight right distortion, 1 is a medium left distortion, and 2 is a severe right distortion
void AnimTask_ExtrasensoryDistortion(u8 taskId)
{
s16 i;
u8 yOffset;
struct ScanlineEffectParams scanlineParams;
struct Task *task = &gTasks[taskId];
yOffset = GetBattlerYCoordWithElevation(gBattleAnimTarget);
task->data[14] = yOffset - 32;
switch (gBattleAnimArgs[0])
{
case 0:
task->data[11] = 2;
task->data[12] = 5;
task->data[13] = 64;
task->data[15] = yOffset + 32;
break;
case 1:
task->data[11] = 2;
task->data[12] = 5;
task->data[13] = 192;
task->data[15] = yOffset + 32;
break;
case 2:
task->data[11] = 4;
task->data[12] = 4;
task->data[13] = 0;
task->data[15] = yOffset + 32;
break;
}
if (task->data[14] < 0)
task->data[14] = 0;
if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1)
{
task->data[10] = gBattle_BG1_X;
scanlineParams.dmaDest = &REG_BG1HOFS;
}
else
{
task->data[10] = gBattle_BG2_X;
scanlineParams.dmaDest = &REG_BG2HOFS;
}
for (i = task->data[14]; i <= task->data[14] + 64; i++)
{
gScanlineEffectRegBuffers[0][i] = task->data[10];
gScanlineEffectRegBuffers[1][i] = task->data[10];
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
ScanlineEffect_SetParams(scanlineParams);
task->func = AnimTask_ExtrasensoryDistortion_Step;
}
static void AnimTask_ExtrasensoryDistortion_Step(u8 taskId)
{
s16 sineIndex, i;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
sineIndex = task->data[13];
i = task->data[14];
while (i <= task->data[15])
{
s16 var2 = (gSineTable[sineIndex] >> task->data[12]);
if (var2 > 0)
var2 += (task->data[1] & 3);
else if (var2 < 0)
var2 -= (task->data[1] & 3);
gScanlineEffectRegBuffers[0][i] = task->data[10] + var2;
gScanlineEffectRegBuffers[1][i] = task->data[10] + var2;
sineIndex += task->data[11];
i++;
}
if (++task->data[1] > 23)
task->data[0]++;
break;
case 1:
gScanlineEffect.state = 3;
task->data[0]++;
break;
case 2:
DestroyAnimVisualTask(taskId);
break;
}
}
// Creates a cloned transparent sprite of the battler that grows and then shrinks back to original size. Used by Extrasensory
// arg0: battler
void AnimTask_TransparentCloneGrowAndShrink(u8 taskId)
{
s16 spriteId;
s16 matrixNum;
struct Task *task = &gTasks[taskId];
matrixNum = AllocOamMatrix();
if (matrixNum == 0xFF)
{
DestroyAnimVisualTask(taskId);
return;
}
spriteId = CloneBattlerSpriteWithBlend(gBattleAnimArgs[0]);
if (spriteId < 0)
{
FreeOamMatrix(matrixNum);
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId].callback = SpriteCallbackDummy;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
gSprites[spriteId].oam.matrixNum = matrixNum;
gSprites[spriteId].affineAnimPaused = 1;
gSprites[spriteId].subpriority++;
SetSpriteRotScale(spriteId, 256, 256, 0);
CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
task->data[13] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
task->data[14] = matrixNum;
task->data[15] = spriteId;
task->func = AnimTask_TransparentCloneGrowAndShrink_Step;
}
static void AnimTask_TransparentCloneGrowAndShrink_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[1] += 4;
task->data[2] = 256 - (gSineTable[task->data[1]] >> 1);
SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0);
SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]);
if (task->data[1] == 48)
task->data[0]++;
break;
case 1:
task->data[1] -= 4;
task->data[2] = 256 - (gSineTable[task->data[1]] >> 1);
SetSpriteRotScale(task->data[15], task->data[2], task->data[2], 0);
SetBattlerSpriteYOffsetFromOtherYScale(task->data[15], task->data[13]);
if (task->data[1] == 0)
task->data[0]++;
break;
case 2:
DestroySpriteWithActiveSheet(&gSprites[task->data[15]]);
task->data[0]++;
break;
case 3:
FreeOamMatrix(task->data[14]);
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimPsychoBoost(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
if (IsContest())
sprite->y += 12;
sprite->data[1] = 8;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
sprite->data[0]++;
break;
case 1:
if (sprite->affineAnimEnded)
{
PlaySE12WithPanning(SE_M_TELEPORT, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
ChangeSpriteAffineAnim(sprite, 1);
sprite->data[0]++;
}
break;
case 2:
if (sprite->data[2]++ > 1)
{
sprite->data[2] = 0;
sprite->data[1]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
if (sprite->data[1] == 0)
{
sprite->data[0]++;
sprite->invisible = TRUE;
}
}
sprite->data[3] += 0x380;
sprite->y2 -= sprite->data[3] >> 8;
sprite->data[3] &= 0xFF;
break;
case 3:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
break;
}
}
#include "global.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "palette.h"
#include "sound.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
#include "constants/songs.h"
static void AnimFallingRock(struct Sprite *);
static void AnimFallingRock_Step(struct Sprite *);
static void AnimRockFragment(struct Sprite *);
static void AnimFlyingSandCrescent(struct Sprite *);
static void AnimRaiseSprite(struct Sprite *);
static void AnimTask_Rollout_Step(u8 taskId);
static void AnimRolloutParticle(struct Sprite *);
static void AnimRockTomb(struct Sprite *);
static void AnimRockTomb_Step(struct Sprite *sprite);
static void AnimRockBlastRock(struct Sprite *);
static void AnimRockScatter(struct Sprite *);
static void AnimRockScatter_Step(struct Sprite *sprite);
static void AnimParticleInVortex(struct Sprite *);
static void AnimParticleInVortex_Step(struct Sprite *sprite);
static void AnimTask_LoadSandstormBackground_Step(u8 taskId);
static void CreateRolloutDirtSprite(struct Task *task);
static u8 GetRolloutCounter(void);
static const union AnimCmd sAnim_FlyingRock_0[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FlyingRock_1[] =
{
ANIMCMD_FRAME(48, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FlyingRock_2[] =
{
ANIMCMD_FRAME(64, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_FlyingRock[] =
{
sAnim_FlyingRock_0,
sAnim_FlyingRock_1,
sAnim_FlyingRock_2,
};
const struct SpriteTemplate gFallingRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFallingRock,
};
const struct SpriteTemplate gRockFragmentSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlyingRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockFragment,
};
const struct SpriteTemplate gSwirlingDirtSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimParticleInVortex,
};
static const union AffineAnimCmd sAffineAnim_Whirlpool[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0),
AFFINEANIMCMD_FRAME(0x2, 0xFFFD, 0, 5),
AFFINEANIMCMD_FRAME(0xFFFE, 0x3, 0, 5),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_Whirlpool[] =
{
sAffineAnim_Whirlpool,
};
const struct SpriteTemplate gWhirlpoolSpriteTemplate =
{
.tileTag = ANIM_TAG_WATER_ORB,
.paletteTag = ANIM_TAG_WATER_ORB,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = gAnims_WaterMudOrb,
.images = NULL,
.affineAnims = sAffineAnims_Whirlpool,
.callback = AnimParticleInVortex,
};
const struct SpriteTemplate gFireSpinSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAnims_BasicFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimParticleInVortex,
};
const struct SpriteTemplate gFlyingSandCrescentSpriteTemplate =
{
.tileTag = ANIM_TAG_FLYING_DIRT,
.paletteTag = ANIM_TAG_FLYING_DIRT,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFlyingSandCrescent,
};
static const struct Subsprite sFlyingSandSubsprites[] =
{
{.x = -16, .y = 0, .shape = SPRITE_SHAPE(32x16), .size = SPRITE_SIZE(32x16), .tileOffset = 0, .priority = 1},
{.x = 16, .y = 0, .shape = SPRITE_SHAPE(32x16), .size = SPRITE_SIZE(32x16), .tileOffset = 8, .priority = 1},
};
static const struct SubspriteTable sFlyingSandSubspriteTable[] =
{
{ARRAY_COUNT(sFlyingSandSubsprites), sFlyingSandSubsprites},
};
static const union AnimCmd sAnim_Rock_Biggest[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Rock_Bigger[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Rock_Big[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Rock_Small[] =
{
ANIMCMD_FRAME(48, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Rock_Smaller[] =
{
ANIMCMD_FRAME(64, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Rock_Smallest[] =
{
ANIMCMD_FRAME(80, 1),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_BasicRock[] =
{
sAnim_Rock_Biggest,
sAnim_Rock_Bigger,
sAnim_Rock_Big,
sAnim_Rock_Small,
sAnim_Rock_Smaller,
sAnim_Rock_Smallest,
};
const struct SpriteTemplate gAncientPowerRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_BasicRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRaiseSprite,
};
const struct SpriteTemplate gRolloutMudSpriteTemplate =
{
.tileTag = ANIM_TAG_MUD_SAND,
.paletteTag = ANIM_TAG_MUD_SAND,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRolloutParticle,
};
const struct SpriteTemplate gRolloutRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRolloutParticle,
};
const struct SpriteTemplate gRockTombRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_BasicRock,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRockTomb,
};
static const union AffineAnimCmd sAffineAnim_BasicRock_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -5, 5),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd sAffineAnim_BasicRock_1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 5, 5),
AFFINEANIMCMD_JUMP(0),
};
static const union AffineAnimCmd *const sAffineAnims_BasicRock[] =
{
sAffineAnim_BasicRock_0,
sAffineAnim_BasicRock_1,
};
const struct SpriteTemplate gRockBlastRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_BasicRock,
.images = NULL,
.affineAnims = sAffineAnims_BasicRock,
.callback = AnimRockBlastRock,
};
const struct SpriteTemplate gRockScatterSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_BasicRock,
.images = NULL,
.affineAnims = sAffineAnims_BasicRock,
.callback = AnimRockScatter,
};
const struct SpriteTemplate gTwisterRockSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = &sAnims_BasicRock[4],
.images = NULL,
.affineAnims = sAffineAnims_BasicRock,
.callback = AnimMoveTwisterParticle,
};
const struct SpriteTemplate gWeatherBallRockDownSpriteTemplate =
{
.tileTag = ANIM_TAG_ROCKS,
.paletteTag = ANIM_TAG_ROCKS,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = &sAnims_BasicRock[2],
.images = NULL,
.affineAnims = sAffineAnims_BasicRock,
.callback = AnimWeatherBallDown,
};
static void AnimFallingRock(struct Sprite *sprite)
{
if (gBattleAnimArgs[3] != 0)
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y);
sprite->x += gBattleAnimArgs[0];
sprite->y += 14;
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
AnimateSprite(sprite);
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 4;
sprite->data[3] = 16;
sprite->data[4] = -70;
sprite->data[5] = gBattleAnimArgs[2];
StoreSpriteCallbackInData6(sprite, AnimFallingRock_Step);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}
static void AnimFallingRock_Step(struct Sprite *sprite)
{
sprite->x += sprite->data[5];
sprite->data[0] = 192;
sprite->data[1] = sprite->data[5];
sprite->data[2] = 4;
sprite->data[3] = 32;
sprite->data[4] = -24;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}
// Animates the rock particles that are shown on the impact for Rock Blast / Rock Smash
static void AnimRockFragment(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[5]);
AnimateSprite(sprite);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->y + gBattleAnimArgs[3];
InitSpriteDataForLinearTranslation(sprite);
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->callback = TranslateSpriteLinearFixedPoint;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
// Swirls particle in vortex. Used for moves like Fire Spin or Sand Tomb
static void AnimParticleInVortex(struct Sprite *sprite)
{
if (gBattleAnimArgs[6] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[3] = gBattleAnimArgs[5];
sprite->callback = AnimParticleInVortex_Step;
}
static void AnimParticleInVortex_Step(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[1];
sprite->y2 = -(sprite->data[4] >> 8);
sprite->x2 = Sin(sprite->data[5], sprite->data[3]);
sprite->data[5] = (sprite->data[5] + sprite->data[2]) & 0xFF;
if (--sprite->data[0] == -1)
{
DestroyAnimSprite(sprite);
}
}
void AnimTask_LoadSandstormBackground(u8 taskId)
{
int var0;
struct BattleAnimBgData animBg;
var0 = 0;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_Sandstorm, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimBgTilemap_Sandstorm, FALSE);
LoadCompressedPalette(gBattleAnimSpritePal_FlyingDirt, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
if (gBattleAnimArgs[0] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
var0 = 1;
gTasks[taskId].data[0] = var0;
gTasks[taskId].func = AnimTask_LoadSandstormBackground_Step;
}
static void AnimTask_LoadSandstormBackground_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
if (gTasks[taskId].data[0] == 0)
gBattle_BG1_X += -6;
else
gBattle_BG1_X += 6;
gBattle_BG1_Y += -1;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 7)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 101)
{
gTasks[taskId].data[11] = 7;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
gTasks[taskId].data[12]++;
break;
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}
// Animates the sprites that fly diagonally across the screen
// in Sandstorm and Heat Wave.
// arg 0: initial y pixel offset
// arg 1: projectile speed
// arg 2: y pixel drop
// arg 3: ??? unknown (possibly a color bit)
static void AnimFlyingSandCrescent(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
if (gBattleAnimArgs[3] != 0 && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x = DISPLAY_WIDTH + 64;
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
sprite->data[5] = 1;
sprite->oam.matrixNum = ST_OAM_HFLIP;
}
else
{
sprite->x = -64;
}
sprite->y = gBattleAnimArgs[0];
SetSubspriteTables(sprite, sFlyingSandSubspriteTable);
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[2];
sprite->data[0]++;
}
else
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 += (sprite->data[3] >> 8);
sprite->y2 += (sprite->data[4] >> 8);
sprite->data[3] &= 0xFF;
sprite->data[4] &= 0xFF;
if (sprite->data[5] == 0)
{
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 32)
{
sprite->callback = DestroyAnimSprite;
}
}
else if (sprite->x + sprite->x2 < -32)
{
sprite->callback = DestroyAnimSprite;
}
}
}
// Animates the rising rocks in Ancient Power.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: terminal y offset
// arg 3: duration
// arg 4: sprite size [1,5]
static void AnimRaiseSprite(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[4]);
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[2] = sprite->x;
sprite->data[4] = sprite->y + gBattleAnimArgs[2];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
void AnimTask_Rollout(u8 taskId)
{
u16 var0, var1, var2, var3;
u8 rolloutCounter;
int var5;
s16 pan1, pan2;
struct Task *task;
task = &gTasks[taskId];
var0 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
var1 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 24;
var2 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
var3 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 24;
if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget)
var3 = var1;
rolloutCounter = GetRolloutCounter();
if (rolloutCounter == 1)
task->data[8] = 32;
else
task->data[8] = 48 - (rolloutCounter * 8);
task->data[0] = 0;
task->data[11] = 0;
task->data[9] = 0;
task->data[12] = 1;
var5 = task->data[8];
if (var5 < 0)
var5 += 7;
task->data[10] = (var5 >> 3) - 1;
task->data[2] = var0 * 8;
task->data[3] = var1 * 8;
task->data[4] = ((var2 - var0) * 8) / task->data[8];
task->data[5] = ((var3 - var1) * 8) / task->data[8];
task->data[6] = 0;
task->data[7] = 0;
pan1 = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
pan2 = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
task->data[13] = pan1;
task->data[14] = (pan2 - pan1) / task->data[8];
task->data[1] = rolloutCounter;
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->func = AnimTask_Rollout_Step;
}
static void AnimTask_Rollout_Step(u8 taskId)
{
struct Task *task;
task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[6] -= task->data[4];
task->data[7] -= task->data[5];
gSprites[task->data[15]].x2 = task->data[6] >> 3;
gSprites[task->data[15]].y2 = task->data[7] >> 3;
if (++task->data[9] == 10)
{
task->data[11] = 20;
task->data[0]++;
}
PlaySE12WithPanning(SE_M_HEADBUTT, task->data[13]);
break;
case 1:
if (--task->data[11] == 0)
task->data[0]++;
break;
case 2:
if (--task->data[9] != 0)
{
task->data[6] += task->data[4];
task->data[7] += task->data[5];
}
else
{
task->data[6] = 0;
task->data[7] = 0;
task->data[0]++;
}
gSprites[task->data[15]].x2 = task->data[6] >> 3;
gSprites[task->data[15]].y2 = task->data[7] >> 3;
break;
case 3:
task->data[2] += task->data[4];
task->data[3] += task->data[5];
if (++task->data[9] >= task->data[10])
{
task->data[9] = 0;
CreateRolloutDirtSprite(task);
task->data[13] += task->data[14];
PlaySE12WithPanning(SE_M_DIG, task->data[13]);
}
if (--task->data[8] == 0)
{
task->data[0]++;
}
break;
case 4:
if (task->data[11] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void CreateRolloutDirtSprite(struct Task *task)
{
const struct SpriteTemplate *spriteTemplate;
int tileOffset;
u16 x, y;
u8 spriteId;
switch (task->data[1])
{
case 1:
spriteTemplate = &gRolloutMudSpriteTemplate;
tileOffset = 0;
break;
case 2:
case 3:
spriteTemplate = &gRolloutRockSpriteTemplate;
tileOffset = 80;
break;
case 4:
spriteTemplate = &gRolloutRockSpriteTemplate;
tileOffset = 64;
break;
case 5:
spriteTemplate = &gRolloutRockSpriteTemplate;
tileOffset = 48;
break;
default:
return;
}
x = task->data[2] >> 3;
y = task->data[3] >> 3;
x += (task->data[12] * 4);
spriteId = CreateSprite(spriteTemplate, x, y, 35);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[0] = 18;
gSprites[spriteId].data[2] = ((task->data[12] * 20) + x) + (task->data[1] * 3);
gSprites[spriteId].data[4] = y;
gSprites[spriteId].data[5] = -16 - (task->data[1] * 2);
gSprites[spriteId].oam.tileNum += tileOffset;
InitAnimArcTranslation(&gSprites[spriteId]);
task->data[11]++;
}
task->data[12] *= -1;
}
static void AnimRolloutParticle(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
u8 taskId = FindTaskIdByFunc(AnimTask_Rollout_Step);
if (taskId != TASK_NONE)
gTasks[taskId].data[11]--;
DestroySprite(sprite);
}
}
static u8 GetRolloutCounter(void)
{
u8 retVal = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer;
u8 var0 = retVal - 1;
if (var0 > 4)
retVal = 1;
return retVal;
}
static void AnimRockTomb(struct Sprite *sprite)
{
StartSpriteAnim(sprite, gBattleAnimArgs[4]);
sprite->x2 = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[3] -= gBattleAnimArgs[2];
sprite->data[0] = 3;
sprite->data[1] = gBattleAnimArgs[3];
sprite->callback = AnimRockTomb_Step;
sprite->invisible = TRUE;
}
static void AnimRockTomb_Step(struct Sprite *sprite)
{
sprite->invisible = FALSE;
if (sprite->data[3] != 0)
{
sprite->y2 = sprite->data[2] + sprite->data[3];
sprite->data[3] += sprite->data[0];
sprite->data[0]++;
if (sprite->data[3] > 0)
{
sprite->data[3] = 0;
}
}
else
{
if (--sprite->data[1] == 0)
DestroyAnimSprite(sprite);
}
}
static void AnimRockBlastRock(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
StartSpriteAffineAnim(sprite, 1);
TranslateAnimSpriteToTargetMonLocation(sprite);
}
static void AnimRockScatter(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[5] = gBattleAnimArgs[2];
StartSpriteAnim(sprite, gBattleAnimArgs[3]);
sprite->callback = AnimRockScatter_Step;
}
static void AnimRockScatter_Step(struct Sprite *sprite)
{
sprite->data[0] += 8;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 += sprite->data[3] / 40;
sprite->y2 -= Sin(sprite->data[0], sprite->data[5]);
if (sprite->data[0] > 140)
DestroyAnimSprite(sprite);
}
void AnimTask_GetSeismicTossDamageLevel(u8 taskId)
{
if (gAnimMoveDmg < 33)
gBattleAnimArgs[ARG_RET_ID] = 0;
if ((u32)gAnimMoveDmg - 33 < 33)
gBattleAnimArgs[ARG_RET_ID] = 1;
if (gAnimMoveDmg > 65)
gBattleAnimArgs[ARG_RET_ID] = 2;
DestroyAnimVisualTask(taskId);
}
void AnimTask_MoveSeismicTossBg(u8 taskId)
{
if (gTasks[taskId].data[0] == 0)
{
UpdateAnimBg3ScreenSize(FALSE);
gTasks[taskId].data[1] = 200;
}
gBattle_BG3_Y += gTasks[taskId].data[1] / 10;
gTasks[taskId].data[1] -= 3;
if (gTasks[taskId].data[0] == 120)
{
UpdateAnimBg3ScreenSize(TRUE);
DestroyAnimVisualTask(taskId);
}
gTasks[taskId].data[0]++;
}
void AnimTask_SeismicTossBgAccelerateDownAtEnd(u8 taskId)
{
if (gTasks[taskId].data[0] == 0)
{
UpdateAnimBg3ScreenSize(FALSE);
gTasks[taskId].data[0]++;
gTasks[taskId].data[2] = gBattle_BG3_Y;
}
gTasks[taskId].data[1] += 80;
gTasks[taskId].data[1] &= 0xFF;
gBattle_BG3_Y = gTasks[taskId].data[2] + Cos(4, gTasks[taskId].data[1]);
if (gBattleAnimArgs[7] == 0xFFF)
{
gBattle_BG3_Y = 0;
UpdateAnimBg3ScreenSize(TRUE);
DestroyAnimVisualTask(taskId);
}
}
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "decompress.h"
#include "gpu_regs.h"
#include "palette.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "util.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
extern const struct CompressedSpriteSheet gBattleAnimPicTable[];
extern const struct CompressedSpritePalette gBattleAnimPaletteTable[];
extern const u8 *const gBattleAnims_StatusConditions[];
extern const struct OamData gOamData_AffineOff_ObjNormal_8x8;
extern const struct OamData gOamData_AffineOff_ObjBlend_64x64;
static void Task_UpdateFlashingCircleImpacts(u8 taskId);
static void AnimTask_FrozenIceCube_Step1(u8 taskId);
static void AnimTask_FrozenIceCube_Step2(u8 taskId);
static void AnimTask_FrozenIceCube_Step3(u8 taskId);
static void AnimTask_FrozenIceCube_Step4(u8 taskId);
static void Task_DoStatusAnimation(u8 taskId);
static void AnimFlashingCircleImpact(struct Sprite *sprite);
static void AnimFlashingCircleImpact_Step(struct Sprite *sprite);
static const union AnimCmd sAnim_FlickeringOrb[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(4, 3),
ANIMCMD_FRAME(8, 3),
ANIMCMD_FRAME(12, 3),
ANIMCMD_JUMP(0)
};
static const union AnimCmd *const sAnims_FlickeringOrb[] =
{
sAnim_FlickeringOrb
};
// Unused
static const struct SpriteTemplate sFlickeringOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORB,
.paletteTag = ANIM_TAG_ORB,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_FlickeringOrb,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateLinearAndFlicker,
};
// Unused
static const struct SpriteTemplate sFlickeringOrbFlippedSpriteTemplate =
{
.tileTag = ANIM_TAG_ORB,
.paletteTag = ANIM_TAG_ORB,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_FlickeringOrb,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateLinearAndFlicker_Flipped,
};
static const union AnimCmd sAnim_WeatherBallNormal[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_JUMP(0)
};
static const union AnimCmd *const sAnims_WeatherBallNormal[] =
{
sAnim_WeatherBallNormal
};
const struct SpriteTemplate gWeatherBallUpSpriteTemplate =
{
.tileTag = ANIM_TAG_WEATHER_BALL,
.paletteTag = ANIM_TAG_WEATHER_BALL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_WeatherBallNormal,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWeatherBallUp,
};
const struct SpriteTemplate gWeatherBallNormalDownSpriteTemplate =
{
.tileTag = ANIM_TAG_WEATHER_BALL,
.paletteTag = ANIM_TAG_WEATHER_BALL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_WeatherBallNormal,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWeatherBallDown,
};
static const union AnimCmd sAnim_SpinningSparkle[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_END
};
static const union AnimCmd *const sAnims_SpinningSparkle[] =
{
sAnim_SpinningSparkle
};
const struct SpriteTemplate gSpinningSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_4,
.paletteTag = ANIM_TAG_SPARKLE_4,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_SpinningSparkle,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpinningSparkle,
};
// Unused
static const struct SpriteTemplate sFlickeringFootSpriteTemplate =
{
.tileTag = ANIM_TAG_MONSTER_FOOT,
.paletteTag = ANIM_TAG_MONSTER_FOOT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateLinearAndFlicker,
};
static const union AnimCmd sAnim_FlickeringImpact_0[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_JUMP(0)
};
static const union AnimCmd sAnim_FlickeringImpact_1[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_JUMP(0)
};
static const union AnimCmd sAnim_FlickeringImpact_2[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_JUMP(0)
};
static const union AnimCmd *const sAnims_FlickeringImpact[] =
{
sAnim_FlickeringImpact_0,
sAnim_FlickeringImpact_1,
sAnim_FlickeringImpact_2,
};
// Unused
static const struct SpriteTemplate sFlickeringImpactSpriteTemplate =
{
.tileTag = ANIM_TAG_IMPACT,
.paletteTag = ANIM_TAG_IMPACT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FlickeringImpact,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateLinearAndFlicker,
};
static const union AnimCmd sAnim_FlickeringShrinkOrb[] =
{
ANIMCMD_FRAME(0, 15),
ANIMCMD_JUMP(0)
};
static const union AnimCmd *const sAnims_FlickeringShrinkOrb[] =
{
sAnim_FlickeringShrinkOrb
};
static const union AffineAnimCmd sAffineAnim_FlickeringShrinkOrb[] =
{
AFFINEANIMCMD_FRAME(96, 96, 0, 0),
AFFINEANIMCMD_FRAME(2, 2, 0, 1),
AFFINEANIMCMD_JUMP(1)
};
static const union AffineAnimCmd *const sAffineAnims_FlickeringShrinkOrb[] =
{
sAffineAnim_FlickeringShrinkOrb
};
// Unused
static const struct SpriteTemplate sFlickeringShrinkOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORB,
.paletteTag = ANIM_TAG_ORB,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = sAnims_FlickeringShrinkOrb,
.images = NULL,
.affineAnims = sAffineAnims_FlickeringShrinkOrb,
.callback = AnimTranslateLinearAndFlicker_Flipped,
};
static const struct Subsprite sFrozenIceCubeSubsprites[] =
{
{
.x = -16,
.y = -16,
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64),
.tileOffset = 0,
.priority = 2
},
{
.x = -16,
.y = 48,
.shape = SPRITE_SHAPE(64x32),
.size = SPRITE_SIZE(64x32),
.tileOffset = 64,
.priority = 2
},
{
.x = 48,
.y = -16,
.shape = SPRITE_SHAPE(32x64),
.size = SPRITE_SIZE(32x64),
.tileOffset = 96,
.priority = 2
},
{
.x = 48,
.y = 48,
.shape = SPRITE_SHAPE(32x32),
.size = SPRITE_SIZE(32x32),
.tileOffset = 128,
.priority = 2
},
};
static const struct SubspriteTable sFrozenIceCubeSubspriteTable[] =
{
{ARRAY_COUNT(sFrozenIceCubeSubsprites), sFrozenIceCubeSubsprites},
};
static const struct SpriteTemplate sFrozenIceCubeSpriteTemplate =
{
.tileTag = ANIM_TAG_ICE_CUBE,
.paletteTag = ANIM_TAG_ICE_CUBE,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
static const struct SpriteTemplate sFlashingCircleImpactSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_IMPACT,
.paletteTag = ANIM_TAG_CIRCLE_IMPACT,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFlashingCircleImpact,
};
// Unused
static u8 Task_FlashingCircleImpacts(u8 battlerId, bool8 red)
{
u8 battlerSpriteId = gBattlerSpriteIds[battlerId];
u8 taskId = CreateTask(Task_UpdateFlashingCircleImpacts, 10);
u8 spriteId;
u8 i;
LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_CIRCLE_IMPACT)]);
LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_CIRCLE_IMPACT)]);
gTasks[taskId].data[0] = battlerId;
if (red)
{
gTasks[taskId].data[1] = RGB_RED;
for (i = 0; i < 10; i++)
{
spriteId = CreateSprite(&sFlashingCircleImpactSpriteTemplate, gSprites[battlerSpriteId].x, gSprites[battlerSpriteId].y + 32, 0);
gSprites[spriteId].data[0] = i * 51;
gSprites[spriteId].data[1] = -256;
gSprites[spriteId].invisible = TRUE;
if (i > 4)
gSprites[spriteId].data[6] = 21;
}
}
else
{
gTasks[taskId].data[1] = RGB_BLUE;
for (i = 0; i < 10; i++)
{
spriteId = CreateSprite(&sFlashingCircleImpactSpriteTemplate, gSprites[battlerSpriteId].x, gSprites[battlerSpriteId].y - 32, 0);
gSprites[spriteId].data[0] = i * 51;
gSprites[spriteId].data[1] = 256;
gSprites[spriteId].invisible = TRUE;
if (i > 4)
gSprites[spriteId].data[6] = 21;
}
}
gSprites[spriteId].data[7] = 1;
return taskId;
}
static void Task_UpdateFlashingCircleImpacts(u8 taskId)
{
if (gTasks[taskId].data[2] == 2)
{
gTasks[taskId].data[2] = 0;
BlendPalette(OBJ_PLTT_ID(gTasks[taskId].data[0]), 16, gTasks[taskId].data[4], gTasks[taskId].data[1]);
if (gTasks[taskId].data[5] == 0)
{
gTasks[taskId].data[4]++;
if (gTasks[taskId].data[4] > 8)
gTasks[taskId].data[5] ^= 1;
}
else
{
u16 var = gTasks[taskId].data[4];
gTasks[taskId].data[4]--;
if (gTasks[taskId].data[4] < 0)
{
gTasks[taskId].data[4] = var;
gTasks[taskId].data[5] ^= 1;
gTasks[taskId].data[3]++;
if (gTasks[taskId].data[3] == 2)
DestroyTask(taskId);
}
}
}
else
{
gTasks[taskId].data[2]++;
}
}
static void AnimFlashingCircleImpact(struct Sprite *sprite)
{
if (sprite->data[6] == 0)
{
sprite->invisible = FALSE;
sprite->callback = AnimFlashingCircleImpact_Step;
AnimFlashingCircleImpact_Step(sprite);
}
else
{
sprite->data[6]--;
}
}
static void AnimFlashingCircleImpact_Step(struct Sprite *sprite)
{
sprite->x2 = Cos(sprite->data[0], 32);
sprite->y2 = Sin(sprite->data[0], 8);
if (sprite->data[0] < 128)
sprite->subpriority = 29;
else
sprite->subpriority = 31;
sprite->data[0] = (sprite->data[0] + 8) & 0xFF;
sprite->data[5] += sprite->data[1];
sprite->y2 += sprite->data[5] >> 8;
sprite->data[2]++;
if (sprite->data[2] == 52)
{
if (sprite->data[7])
DestroySpriteAndFreeResources(sprite);
else
DestroySprite(sprite);
}
}
void AnimTask_FrozenIceCube(u8 taskId)
{
s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) - 32;
s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) - 36;
u8 spriteId;
if (IsContest())
x -= 6;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
spriteId = CreateSprite(&sFrozenIceCubeSpriteTemplate, x, y, 4);
if (GetSpriteTileStartByTag(ANIM_TAG_ICE_CUBE) == 0xFFFF)
gSprites[spriteId].invisible = TRUE;
SetSubspriteTables(&gSprites[spriteId], sFrozenIceCubeSubspriteTable);
gTasks[taskId].data[15] = spriteId;
gTasks[taskId].func = AnimTask_FrozenIceCube_Step1;
}
static void AnimTask_FrozenIceCube_Step1(u8 taskId)
{
gTasks[taskId].data[1]++;
if (gTasks[taskId].data[1] == 10)
{
gTasks[taskId].func = AnimTask_FrozenIceCube_Step2;
gTasks[taskId].data[1] = 0;
}
else
{
u8 var = gTasks[taskId].data[1];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(var, 16 - var));
}
}
static void AnimTask_FrozenIceCube_Step2(u8 taskId)
{
u8 palIndex = IndexOfSpritePaletteTag(ANIM_TAG_ICE_CUBE);
if (gTasks[taskId].data[1]++ > 13)
{
gTasks[taskId].data[2]++;
if (gTasks[taskId].data[2] == 3)
{
u16 temp;
temp = gPlttBufferFaded[0x100 + palIndex * 16 + 13];
gPlttBufferFaded[0x100 + palIndex * 16 + 13] = gPlttBufferFaded[0x100 + palIndex * 16 + 14];
gPlttBufferFaded[0x100 + palIndex * 16 + 14] = gPlttBufferFaded[0x100 + palIndex * 16 + 15];
gPlttBufferFaded[0x100 + palIndex * 16 + 15] = temp;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3]++;
if (gTasks[taskId].data[3] == 3)
{
gTasks[taskId].data[3] = 0;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[4]++;
if (gTasks[taskId].data[4] == 2)
{
gTasks[taskId].data[1] = 9;
gTasks[taskId].func = AnimTask_FrozenIceCube_Step3;
}
}
}
}
}
static void AnimTask_FrozenIceCube_Step3(u8 taskId)
{
gTasks[taskId].data[1]--;
if (gTasks[taskId].data[1] == -1)
{
gTasks[taskId].func = AnimTask_FrozenIceCube_Step4;
gTasks[taskId].data[1] = 0;
}
else
{
u8 var = gTasks[taskId].data[1];
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(var, 16 - var));
}
}
static void AnimTask_FrozenIceCube_Step4(u8 taskId)
{
gTasks[taskId].data[1]++;
if (gTasks[taskId].data[1] == 37)
{
u8 spriteId = gTasks[taskId].data[15];
FreeSpriteOamMatrix(&gSprites[spriteId]);
DestroySprite(&gSprites[spriteId]);
}
else if (gTasks[taskId].data[1] == 39)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
}
}
#define CASE(by, stat) case (STAT_ANIM_##by + stat - 1)
void AnimTask_StatsChange(u8 taskId)
{
bool16 goesDown = FALSE;
s16 animStatId = 0;
bool16 sharply = FALSE;
switch (gBattleSpritesDataPtr->animationData->animArg)
{
CASE(PLUS1, STAT_ATK): goesDown = FALSE; animStatId = 0; break;
CASE(PLUS1, STAT_DEF): goesDown = FALSE; animStatId = 1; break;
CASE(PLUS1, STAT_SPEED): goesDown = FALSE; animStatId = 3; break;
CASE(PLUS1, STAT_SPATK): goesDown = FALSE; animStatId = 5; break;
CASE(PLUS1, STAT_SPDEF): goesDown = FALSE; animStatId = 6; break;
CASE(PLUS1, STAT_ACC): goesDown = FALSE; animStatId = 2; break;
CASE(PLUS1, STAT_EVASION): goesDown = FALSE; animStatId = 4; break;
CASE(MINUS1, STAT_ATK): goesDown = TRUE; animStatId = 0; break;
CASE(MINUS1, STAT_DEF): goesDown = TRUE; animStatId = 1; break;
CASE(MINUS1, STAT_SPEED): goesDown = TRUE; animStatId = 3; break;
CASE(MINUS1, STAT_SPATK): goesDown = TRUE; animStatId = 5; break;
CASE(MINUS1, STAT_SPDEF): goesDown = TRUE; animStatId = 6; break;
CASE(MINUS1, STAT_ACC): goesDown = TRUE; animStatId = 2; break;
CASE(MINUS1, STAT_EVASION): goesDown = TRUE; animStatId = 4; break;
CASE(PLUS2, STAT_ATK): goesDown = FALSE; animStatId = 0; sharply = TRUE; break;
CASE(PLUS2, STAT_DEF): goesDown = FALSE; animStatId = 1; sharply = TRUE; break;
CASE(PLUS2, STAT_SPEED): goesDown = FALSE; animStatId = 3; sharply = TRUE; break;
CASE(PLUS2, STAT_SPATK): goesDown = FALSE; animStatId = 5; sharply = TRUE; break;
CASE(PLUS2, STAT_SPDEF): goesDown = FALSE; animStatId = 6; sharply = TRUE; break;
CASE(PLUS2, STAT_ACC): goesDown = FALSE; animStatId = 2; sharply = TRUE; break;
CASE(PLUS2, STAT_EVASION): goesDown = FALSE; animStatId = 4; sharply = TRUE; break;
CASE(MINUS2, STAT_ATK): goesDown = TRUE; animStatId = 0; sharply = TRUE; break;
CASE(MINUS2, STAT_DEF): goesDown = TRUE; animStatId = 1; sharply = TRUE; break;
CASE(MINUS2, STAT_SPEED): goesDown = TRUE; animStatId = 3; sharply = TRUE; break;
CASE(MINUS2, STAT_SPATK): goesDown = TRUE; animStatId = 5; sharply = TRUE; break;
CASE(MINUS2, STAT_SPDEF): goesDown = TRUE; animStatId = 6; sharply = TRUE; break;
CASE(MINUS2, STAT_ACC): goesDown = TRUE; animStatId = 2; sharply = TRUE; break;
CASE(MINUS2, STAT_EVASION): goesDown = TRUE; animStatId = 4; sharply = TRUE; break;
case STAT_ANIM_MULTIPLE_PLUS1: goesDown = FALSE; animStatId = 0xFF; sharply = FALSE; break;
case STAT_ANIM_MULTIPLE_PLUS2: goesDown = FALSE; animStatId = 0xFF; sharply = TRUE; break;
case STAT_ANIM_MULTIPLE_MINUS1: goesDown = TRUE; animStatId = 0xFF; sharply = FALSE; break;
case STAT_ANIM_MULTIPLE_MINUS2: goesDown = TRUE; animStatId = 0xFF; sharply = TRUE; break;
default:
DestroyAnimVisualTask(taskId);
return;
}
gBattleAnimArgs[0] = goesDown;
gBattleAnimArgs[1] = animStatId;
gBattleAnimArgs[2] = 0;
gBattleAnimArgs[3] = 0;
gBattleAnimArgs[4] = sharply;
gTasks[taskId].func = InitStatsChangeAnimation;
InitStatsChangeAnimation(taskId);
}
#undef CASE
void LaunchStatusAnimation(u8 battlerId, u8 statusAnimId)
{
u8 taskId;
gBattleAnimAttacker = battlerId;
gBattleAnimTarget = battlerId;
LaunchBattleAnimation(gBattleAnims_StatusConditions, statusAnimId, FALSE);
taskId = CreateTask(Task_DoStatusAnimation, 10);
gTasks[taskId].data[0] = battlerId;
}
static void Task_DoStatusAnimation(u8 taskId)
{
gAnimScriptCallback();
if (!gAnimScriptActive)
{
gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].data[0]].statusAnimActive = FALSE;
DestroyTask(taskId);
}
}
#include "global.h"
#include "battle_anim.h"
#include "gpu_regs.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimMegahornHorn(struct Sprite *);
static void AnimLeechLifeNeedle(struct Sprite *);
static void AnimTranslateWebThread(struct Sprite *);
static void AnimTranslateWebThread_Step(struct Sprite *);
static void AnimStringWrap(struct Sprite *);
static void AnimStringWrap_Step(struct Sprite *);
static void AnimSpiderWeb(struct Sprite *);
static void AnimSpiderWeb_Step(struct Sprite *);
static void AnimSpiderWeb_End(struct Sprite *);
static void AnimTranslateStinger(struct Sprite *);
static void AnimMissileArc(struct Sprite *);
static void AnimMissileArc_Step(struct Sprite *);
static void AnimTailGlowOrb(struct Sprite *);
static const union AffineAnimCmd sAffineAnim_MegahornHorn_0[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 30, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_MegahornHorn_1[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, -99, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_MegahornHorn_2[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 94, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_MegahornHorn[] =
{
sAffineAnim_MegahornHorn_0,
sAffineAnim_MegahornHorn_1,
sAffineAnim_MegahornHorn_2,
};
const struct SpriteTemplate gMegahornHornSpriteTemplate =
{
.tileTag = ANIM_TAG_HORN_HIT_2,
.paletteTag = ANIM_TAG_HORN_HIT_2,
.oam = &gOamData_AffineDouble_ObjNormal_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_MegahornHorn,
.callback = AnimMegahornHorn,
};
static const union AffineAnimCmd sAffineAnim_LeechLifeNeedle_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -33, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_LeechLifeNeedle_1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_LeechLifeNeedle_2[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_LeechLifeNeedle[] =
{
sAffineAnim_LeechLifeNeedle_0,
sAffineAnim_LeechLifeNeedle_1,
sAffineAnim_LeechLifeNeedle_2,
};
const struct SpriteTemplate gLeechLifeNeedleSpriteTemplate =
{
.tileTag = ANIM_TAG_NEEDLE,
.paletteTag = ANIM_TAG_NEEDLE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_LeechLifeNeedle,
.callback = AnimLeechLifeNeedle,
};
const struct SpriteTemplate gWebThreadSpriteTemplate =
{
.tileTag = ANIM_TAG_WEB_THREAD,
.paletteTag = ANIM_TAG_WEB_THREAD,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateWebThread,
};
const struct SpriteTemplate gStringWrapSpriteTemplate =
{
.tileTag = ANIM_TAG_STRING,
.paletteTag = ANIM_TAG_STRING,
.oam = &gOamData_AffineOff_ObjNormal_64x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimStringWrap,
};
static const union AffineAnimCmd sAffineAnim_SpiderWeb[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x6, 0x6, 0, 1),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd *const sAffineAnims_SpiderWeb[] =
{
sAffineAnim_SpiderWeb,
};
const struct SpriteTemplate gSpiderWebSpriteTemplate =
{
.tileTag = ANIM_TAG_SPIDER_WEB,
.paletteTag = ANIM_TAG_SPIDER_WEB,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_SpiderWeb,
.callback = AnimSpiderWeb,
};
const struct SpriteTemplate gLinearStingerSpriteTemplate =
{
.tileTag = ANIM_TAG_NEEDLE,
.paletteTag = ANIM_TAG_NEEDLE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateStinger,
};
const struct SpriteTemplate gPinMissileSpriteTemplate =
{
.tileTag = ANIM_TAG_NEEDLE,
.paletteTag = ANIM_TAG_NEEDLE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMissileArc,
};
const struct SpriteTemplate gIcicleSpearSpriteTemplate =
{
.tileTag = ANIM_TAG_ICICLE_SPEAR,
.paletteTag = ANIM_TAG_ICICLE_SPEAR,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMissileArc,
};
static const union AffineAnimCmd sAffineAnim_TailGlowOrb[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 18),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0xFFFB, 0xFFFB, 0, 8),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 8),
AFFINEANIMCMD_LOOP(5),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_TailGlowOrb[] =
{
sAffineAnim_TailGlowOrb,
};
const struct SpriteTemplate gTailGlowOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_TailGlowOrb,
.callback = AnimTailGlowOrb,
};
static void AnimMegahornHorn(struct Sprite *sprite)
{
if (IsContest())
{
StartSpriteAffineAnim(sprite, 2);
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
}
else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
StartSpriteAffineAnim(sprite, 1);
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
}
sprite->x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimLeechLifeNeedle(struct Sprite *sprite)
{
if (IsContest())
{
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
StartSpriteAffineAnim(sprite, 2);
}
else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
}
sprite->x = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord2(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Creates a single web thread that travels from attacker to target.
// Used by MOVE_STRING_SHOT and MOVE_SPIDER_WEB in their first move phase.
// arg 0: x
// arg 1: y
// arg 2: controls the left-to-right movement
// arg 3: amplitude
// arg 4: if targets both opponents
static void AnimTranslateWebThread(struct Sprite *sprite)
{
if (IsContest())
gBattleAnimArgs[2] /= 2;
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = sprite->x;
sprite->data[3] = sprite->y;
if (!gBattleAnimArgs[4])
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]);
}
InitAnimLinearTranslationWithSpeed(sprite);
sprite->data[5] = gBattleAnimArgs[3];
sprite->callback = AnimTranslateWebThread_Step;
}
static void AnimTranslateWebThread_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
{
DestroyAnimSprite(sprite);
return;
}
sprite->x2 += Sin(sprite->data[6], sprite->data[5]);
sprite->data[6] = (sprite->data[6] + 13) & 0xFF;
}
// Second stage of String Shot
static void AnimStringWrap(struct Sprite *sprite)
{
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y);
if (GetBattlerSide(gBattleAnimAttacker))
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
sprite->y += 8;
sprite->callback = AnimStringWrap_Step;
}
static void AnimStringWrap_Step(struct Sprite *sprite)
{
if (++sprite->data[0] == 3)
{
sprite->data[0] = 0;
sprite->invisible ^= 1;
}
if (++sprite->data[1] == 51)
{
DestroyAnimSprite(sprite);
}
}
static void AnimSpiderWeb(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
sprite->data[0] = 16;
sprite->callback = AnimSpiderWeb_Step;
}
static void AnimSpiderWeb_Step(struct Sprite *sprite)
{
if (sprite->data[2] < 20)
{
sprite->data[2]++;
}
else if (sprite->data[1]++ & 1)
{
sprite->data[0]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0]));
if (sprite->data[0] == 0)
{
sprite->invisible = TRUE;
sprite->callback = AnimSpiderWeb_End;
}
}
}
static void AnimSpiderWeb_End(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
// Translates a stinger sprite linearly to a destination location. The sprite is
// initially rotated so that it appears to be traveling in a straight line.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
static void AnimTranslateStinger(struct Sprite *sprite)
{
s16 lVarX, lVarY;
u16 rot;
if (IsContest())
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
}
else
{
if (GetBattlerSide(gBattleAnimAttacker))
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
}
if (!IsContest() && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
{
if (GetBattlerPosition(gBattleAnimTarget) == B_POSITION_PLAYER_LEFT
|| GetBattlerPosition(gBattleAnimTarget) == B_POSITION_OPPONENT_LEFT)
{
gBattleAnimArgs[2] *= -1;
gBattleAnimArgs[0] *= -1;
}
}
InitSpritePosToAnimAttacker(sprite, TRUE);
lVarX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
lVarY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
rot = ArcTan2Neg(lVarX - sprite->x, lVarY - sprite->y);
rot += 0xC000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rot);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = lVarX;
sprite->data[4] = lVarY;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Rotates sprite and moves it in an arc, so that it appears like a missle or arrow traveling.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
// arg 5: wave amplitude
static void AnimMissileArc(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker))
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
sprite->callback = AnimMissileArc_Step;
sprite->invisible = TRUE;
}
static void AnimMissileArc_Step(struct Sprite *sprite)
{
sprite->invisible = FALSE;
if (TranslateAnimHorizontalArc(sprite))
{
DestroyAnimSprite(sprite);
}
else
{
s16 tempData[8];
u16 *data = sprite->data;
u16 x1 = sprite->x;
s16 x2 = sprite->x2;
u16 y1 = sprite->y;
s16 y2 = sprite->y2;
int i;
for (i = 0; i < 8; i++)
tempData[i] = data[i];
x2 += x1;
y2 += y1;
if (!TranslateAnimHorizontalArc(sprite))
{
u16 rotation = ArcTan2Neg(sprite->x + sprite->x2 - x2,
sprite->y + sprite->y2 - y2);
rotation += 0xC000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation);
for (i = 0; i < 8; i++)
data[i] = tempData[i];
}
}
}
static void AnimTailGlowOrb(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + 18;
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + 18;
}
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
#include "global.h"
#include "battle_anim.h"
#include "contest.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "palette.h"
#include "scanline_effect.h"
#include "trig.h"
#include "util.h"
#include "constants/rgb.h"
static void AnimUnusedBagSteal(struct Sprite *);
static void AnimUnusedBagSteal_Step(struct Sprite *);
static void AnimBite(struct Sprite *);
static void AnimTearDrop(struct Sprite *);
static void AnimClawSlash(struct Sprite *);
static void AnimTask_AttackerFadeToInvisible_Step(u8);
static void AnimTask_AttackerFadeFromInvisible_Step(u8);
static void AnimBite_Step1(struct Sprite *);
static void AnimBite_Step2(struct Sprite *);
static void AnimTearDrop_Step(struct Sprite *);
static void AnimTask_MoveAttackerMementoShadow_Step(u8);
static void AnimTask_MoveTargetMementoShadow_Step(u8);
static void DoMementoShadowEffect(struct Task *);
static void SetAllBattlersSpritePriority(u8);
static void AnimTask_MetallicShine_Step(u8);
// Unused
static const struct SpriteTemplate sUnusedBagStealSpriteTemplate =
{
.tileTag = ANIM_TAG_TIED_BAG,
.paletteTag = ANIM_TAG_TIED_BAG,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedBagSteal,
};
static const union AffineAnimCmd sAffineAnim_Bite_0[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 32, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_2[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 64, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_3[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 96, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_4[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -128, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_5[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -96, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_6[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -64, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_Bite_7[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -32, 1),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gAffineAnims_Bite[] =
{
sAffineAnim_Bite_0,
sAffineAnim_Bite_1,
sAffineAnim_Bite_2,
sAffineAnim_Bite_3,
sAffineAnim_Bite_4,
sAffineAnim_Bite_5,
sAffineAnim_Bite_6,
sAffineAnim_Bite_7,
};
const struct SpriteTemplate gSharpTeethSpriteTemplate =
{
.tileTag = ANIM_TAG_SHARP_TEETH,
.paletteTag = ANIM_TAG_SHARP_TEETH,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_Bite,
.callback = AnimBite,
};
const struct SpriteTemplate gClampJawSpriteTemplate =
{
.tileTag = ANIM_TAG_CLAMP,
.paletteTag = ANIM_TAG_CLAMP,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_Bite,
.callback = AnimBite,
};
static const union AffineAnimCmd sAffineAnim_TearDrop_0[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, 80, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, -2, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_TearDrop_1[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, -80, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 8),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_TearDrop[] =
{
sAffineAnim_TearDrop_0,
sAffineAnim_TearDrop_1,
};
const struct SpriteTemplate gTearDropSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_BUBBLES,
.paletteTag = ANIM_TAG_SMALL_BUBBLES,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_TearDrop,
.callback = AnimTearDrop,
};
static const union AnimCmd sAnim_ClawSlash_0[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_END,
};
static const union AnimCmd sAnim_ClawSlash_1[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_FRAME(48, 4, .hFlip = TRUE),
ANIMCMD_FRAME(64, 4, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ClawSlash[] =
{
sAnim_ClawSlash_0,
sAnim_ClawSlash_1,
};
const struct SpriteTemplate gClawSlashSpriteTemplate =
{
.tileTag = ANIM_TAG_CLAW_SLASH,
.paletteTag = ANIM_TAG_CLAW_SLASH,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_ClawSlash,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimClawSlash,
};
void AnimTask_AttackerFadeToInvisible(u8 taskId)
{
int battler;
gTasks[taskId].data[0] = gBattleAnimArgs[0];
battler = gBattleAnimAttacker;
gTasks[taskId].data[1] = 16;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
if (GetBattlerSpriteBGPriorityRank(battler) == 1)
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
else
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
gTasks[taskId].func = AnimTask_AttackerFadeToInvisible_Step;
}
static void AnimTask_AttackerFadeToInvisible_Step(u8 taskId)
{
u8 blendA = gTasks[taskId].data[1] >> 8;
u8 blendB = gTasks[taskId].data[1];
if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
{
blendA++;
blendB--;
gTasks[taskId].data[1] = BLDALPHA_BLEND(blendB, blendA);
SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
gTasks[taskId].data[2] = 0;
if (blendA == 16)
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = TRUE;
DestroyAnimVisualTask(taskId);
}
}
else
{
gTasks[taskId].data[2]++;
}
}
void AnimTask_AttackerFadeFromInvisible(u8 taskId)
{
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = BLDALPHA_BLEND(0, 16);
gTasks[taskId].func = AnimTask_AttackerFadeFromInvisible_Step;
SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
}
static void AnimTask_AttackerFadeFromInvisible_Step(u8 taskId)
{
u8 blendA = gTasks[taskId].data[1] >> 8;
u8 blendB = gTasks[taskId].data[1];
if (gTasks[taskId].data[2] == (u8)gTasks[taskId].data[0])
{
blendA--;
blendB++;
gTasks[taskId].data[1] = (blendA << 8) | blendB;
SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1]);
gTasks[taskId].data[2] = 0;
if (blendA == 0)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
}
}
else
{
gTasks[taskId].data[2]++;
}
}
void AnimTask_InitAttackerFadeFromInvisible(u8 taskId)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
else
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
DestroyAnimVisualTask(taskId);
}
static void AnimUnusedBagSteal(struct Sprite *sprite)
{
sprite->data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[3] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = 0x7E;
InitSpriteDataForLinearTranslation(sprite);
sprite->data[3] = -sprite->data[1];
sprite->data[4] = -sprite->data[2];
sprite->data[6] = 0xFFD8;
sprite->callback = AnimUnusedBagSteal_Step;
sprite->callback(sprite);
}
static void AnimUnusedBagSteal_Step(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
if (sprite->data[7] == 0)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
sprite->data[0]--;
}
sprite->y2 += Sin(sprite->data[5], sprite->data[6]);
sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
if (sprite->data[5] > 0x7F)
{
sprite->data[5] = 0;
sprite->data[6] += 20;
sprite->data[7]++;
}
if (--sprite->data[0] == 0)
DestroyAnimSprite(sprite);
}
// Move sprite inward for Bite/Crunch and Clamp
static void AnimBite(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
StartSpriteAffineAnim(sprite, gBattleAnimArgs[2]);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = gBattleAnimArgs[4];
sprite->data[2] = gBattleAnimArgs[5];
sprite->callback = AnimBite_Step1;
}
static void AnimBite_Step1(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[0];
sprite->data[5] += sprite->data[1];
sprite->x2 = sprite->data[4] >> 8;
sprite->y2 = sprite->data[5] >> 8;
if (++sprite->data[3] == sprite->data[2])
sprite->callback = AnimBite_Step2;
}
static void AnimBite_Step2(struct Sprite *sprite)
{
sprite->data[4] -= sprite->data[0];
sprite->data[5] -= sprite->data[1];
sprite->x2 = sprite->data[4] >> 8;
sprite->y2 = sprite->data[5] >> 8;
if (--sprite->data[3] == 0)
DestroySpriteAndMatrix(sprite);
}
// Launches a tear drop away from the battler. Used by Fake Tears
static void AnimTearDrop(struct Sprite *sprite)
{
u8 battler;
s8 xOffset;
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
xOffset = 20;
sprite->oam.tileNum += 4;
switch (gBattleAnimArgs[1])
{
case 0:
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 8;
sprite->y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8;
break;
case 1:
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) - 14;
sprite->y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16;
break;
case 2:
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 8;
sprite->y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 8;
StartSpriteAffineAnim(sprite, 1);
xOffset = -20;
break;
case 3:
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) + 14;
sprite->y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP) + 16;
StartSpriteAffineAnim(sprite, 1);
xOffset = -20;
break;
}
sprite->data[0] = 32;
sprite->data[2] = sprite->x + xOffset;
sprite->data[4] = sprite->y + 12;
sprite->data[5] = -12;
InitAnimArcTranslation(sprite);
sprite->callback = AnimTearDrop_Step;
}
static void AnimTearDrop_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroySpriteAndMatrix(sprite);
}
void AnimTask_MoveAttackerMementoShadow(u8 taskId)
{
struct ScanlineEffectParams scanlineParams;
struct BattleAnimBgData animBg;
u16 i;
u8 pos;
int var0;
struct Task *task = &gTasks[taskId];
task->data[7] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 31;
task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP) - 7;
task->data[5] = task->data[7];
task->data[4] = task->data[6];
task->data[13] = (task->data[7] - task->data[6]) << 8;
pos = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
task->data[14] = pos - 32;
task->data[15] = pos + 32;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
task->data[8] = -12;
else
task->data[8] = -64;
task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
if (task->data[3] == 1)
{
GetBattleAnimBg1Data(&animBg);
task->data[10] = gBattle_BG1_Y;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
FillPalette(RGB_BLACK, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
scanlineParams.dmaDest = &REG_BG1VOFS;
var0 = WINOUT_WIN01_BG1;
if (!IsContest())
gBattle_BG2_X += DISPLAY_WIDTH;
}
else
{
task->data[10] = gBattle_BG2_Y;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
FillPalette(RGB_BLACK, BG_PLTT_ID(9), PLTT_SIZE_4BPP);
scanlineParams.dmaDest = &REG_BG2VOFS;
var0 = WINOUT_WIN01_BG2;
if (!IsContest())
gBattle_BG1_X += DISPLAY_WIDTH;
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
task->data[11] = 0;
task->data[12] = 16;
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
SetAllBattlersSpritePriority(3);
for (i = 0; i < 112; i++)
{
gScanlineEffectRegBuffers[0][i] = task->data[10];
gScanlineEffectRegBuffers[1][i] = task->data[10];
}
ScanlineEffect_SetParams(scanlineParams);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | (var0 ^ (WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR)));
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
gBattle_WIN0V = DISPLAY_HEIGHT;
task->func = AnimTask_MoveAttackerMementoShadow_Step;
}
static void AnimTask_MoveAttackerMementoShadow_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] > 1)
{
task->data[1] = 0;
if (++task->data[2] & 1)
{
if (task->data[11] != 12)
task->data[11]++;
}
else
{
if (task->data[12] != 8)
task->data[12]--;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12]));
if (task->data[11] == 12 && task->data[12] == 8)
task->data[0]++;
}
break;
case 1:
task->data[4] -= 8;
DoMementoShadowEffect(task);
if (task->data[4] < task->data[8])
task->data[0]++;
break;
case 2:
task->data[4] -= 8;
DoMementoShadowEffect(task);
task->data[14] += 4;
task->data[15] -= 4;
if (task->data[14] >= task->data[15])
task->data[14] = task->data[15];
gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
if (task->data[14] == task->data[15])
task->data[0]++;
break;
case 3:
gScanlineEffect.state = 3;
task->data[0]++;
break;
case 4:
DestroyAnimVisualTask(taskId);
break;
}
}
void AnimTask_MoveTargetMementoShadow(u8 taskId)
{
struct BattleAnimBgData animBg;
struct ScanlineEffectParams scanlineParams;
u8 x;
u16 i;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (IsContest() == TRUE)
{
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
DestroyAnimVisualTask(taskId);
}
else
{
task->data[3] = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
if (task->data[3] == 1)
{
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
gBattle_BG2_X += DISPLAY_WIDTH;
}
else
{
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
gBattle_BG1_X += DISPLAY_WIDTH;
}
task->data[0]++;
}
break;
case 1:
if (task->data[3] == 1)
{
GetBattleAnimBg1Data(&animBg);
task->data[10] = gBattle_BG1_Y;
FillPalette(RGB_BLACK, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
}
else
{
task->data[10] = gBattle_BG2_Y;
FillPalette(RGB_BLACK, BG_PLTT_ID(9), PLTT_SIZE_4BPP);
}
SetAllBattlersSpritePriority(3);
task->data[0]++;
break;
case 2:
task->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 31;
task->data[6] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP) - 7;
task->data[13] = (task->data[7] - task->data[6]) << 8;
x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
task->data[14] = x - 4;
task->data[15] = x + 4;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
task->data[8] = -12;
else
task->data[8] = -64;
task->data[4] = task->data[8];
task->data[5] = task->data[8];
task->data[11] = 12;
task->data[12] = 8;
task->data[0]++;
break;
case 3:
if (task->data[3] == 1)
scanlineParams.dmaDest = &REG_BG1VOFS;
else
scanlineParams.dmaDest = &REG_BG2VOFS;
for (i = 0; i < 112; i++)
{
gScanlineEffectRegBuffers[0][i] = task->data[10] + (159 - i);
gScanlineEffectRegBuffers[1][i] = task->data[10] + (159 - i);
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
ScanlineEffect_SetParams(scanlineParams);
task->data[0]++;
break;
case 4:
if (task->data[3] == 1)
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
else
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
gBattle_WIN0V = DISPLAY_HEIGHT;
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8));
task->func = AnimTask_MoveTargetMementoShadow_Step;
break;
}
}
static void AnimTask_MoveTargetMementoShadow_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[5] += 8;
if (task->data[5] >= task->data[7])
task->data[5] = task->data[7];
DoMementoShadowEffect(task);
if (task->data[5] == task->data[7])
task->data[0]++;
break;
case 1:
if (task->data[15] - task->data[14] < 0x40)
{
task->data[14] -= 4;
task->data[15] += 4;
}
else
{
task->data[1] = 1;
}
gBattle_WIN0H = (task->data[14] << 8) | task->data[15];
task->data[4] += 8;
if (task->data[4] >= task->data[6])
task->data[4] = task->data[6];
DoMementoShadowEffect(task);
if (task->data[4] == task->data[6] && task->data[1])
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 2:
if (++task->data[1] > 1)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
{
if (task->data[11])
task->data[11]--;
}
else
{
if (task->data[12] < 16)
task->data[12]++;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[11], task->data[12]));
if (task->data[11] == 0 && task->data[12] == 16)
task->data[0]++;
}
break;
case 3:
gScanlineEffect.state = 3;
task->data[0]++;
break;
case 4:
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
DestroyAnimVisualTask(taskId);
break;
}
}
static void DoMementoShadowEffect(struct Task *task)
{
int var0, var1;
s16 var2;
s16 i;
int var4;
var2 = task->data[5] - task->data[4];
if (var2 != 0)
{
var0 = task->data[13] / var2;
var1 = task->data[6] << 8;
for (i = 0; i < task->data[4]; i++)
{
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = task->data[10] - (i - 159);
}
for (i = task->data[4]; i <= task->data[5]; i++)
{
if (i >= 0)
{
s16 var3 = (var1 >> 8) - i;
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var3 + task->data[10];
}
var1 += var0;
}
var4 = task->data[10] - (i - 159);
for (i = i; i < task->data[7]; i++)
{
if (i >= 0)
{
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = var4;
var4--;
}
}
}
else
{
var4 = task->data[10] + 159;
for (i = 0; i < 112; i++)
{
gScanlineEffectRegBuffers[0][i] = var4;
gScanlineEffectRegBuffers[1][i] = var4;
var4--;
}
}
}
static void SetAllBattlersSpritePriority(u8 priority)
{
u16 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
u8 spriteId = GetAnimBattlerSpriteId(i);
if (spriteId != SPRITE_NONE)
gSprites[spriteId].oam.priority = priority;
}
}
void AnimTask_InitMementoShadow(u8 taskId)
{
u8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? 1 : 0;
MoveBattlerSpriteToBG(gBattleAnimAttacker, toBG2, TRUE);
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible = FALSE;
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
{
MoveBattlerSpriteToBG(BATTLE_PARTNER(gBattleAnimAttacker), toBG2 ^ 1, TRUE);
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].invisible = FALSE;
}
DestroyAnimVisualTask(taskId);
}
void AnimTask_MementoHandleBg(u8 taskId)
{
bool8 toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) ^ 1 ? TRUE : FALSE;
ResetBattleAnimBg(toBG2);
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
ResetBattleAnimBg(toBG2 ^ 1);
DestroyAnimVisualTask(taskId);
}
// Animates a deep slash from a claw. Used by Metal Claw, Dragon Claw, and Crush Claw
static void AnimClawSlash(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
StartSpriteAnim(sprite, gBattleAnimArgs[2]);
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Makes the attacker metallic and shining.
// Used by MOVE_HARDEN and MOVE_IRON_DEFENSE.
// arg0: if true won't change battler's palette back
// arg1: if true, use custom color
// arg2: custom color
// Custom color argument is used in MOVE_POISON_TAIL to make the mon turn purplish/pinkish as if became cloaked in poison.
void AnimTask_MetallicShine(u8 taskId)
{
u16 species;
u8 spriteId;
u8 newSpriteId;
u16 paletteNum;
struct BattleAnimBgData animBg;
bool32 priorityChanged = FALSE;
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 0);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
if (IsDoubleBattle() && !IsContest())
{
if (GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_OPPONENT_RIGHT || GetBattlerPosition(gBattleAnimAttacker) == B_POSITION_PLAYER_LEFT)
{
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)) == TRUE)
{
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority--;
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
priorityChanged = TRUE;
}
}
}
if (IsContest())
{
species = gContestResources->moveAnim->species;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
}
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
newSpriteId = CreateInvisibleSpriteCopy(gBattleAnimAttacker, spriteId, species);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgTilemap(animBg.bgId, gMetalShineTilemap);
AnimLoadCompressedBgGfx(animBg.bgId, gMetalShineGfx, animBg.tilesOffset);
LoadCompressedPalette(gMetalShinePalette, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gBattle_BG1_X = -gSprites[spriteId].x + 96;
gBattle_BG1_Y = -gSprites[spriteId].y + 32;
paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
if (gBattleAnimArgs[1] == 0)
SetGrayscaleOrOriginalPalette(paletteNum, FALSE);
else
BlendPalette(BG_PLTT_ID(paletteNum), 16, 11, gBattleAnimArgs[2]);
gTasks[taskId].data[0] = newSpriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[0];
gTasks[taskId].data[2] = gBattleAnimArgs[1];
gTasks[taskId].data[3] = gBattleAnimArgs[2];
gTasks[taskId].data[6] = priorityChanged;
gTasks[taskId].func = AnimTask_MetallicShine_Step;
}
static void AnimTask_MetallicShine_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
u16 paletteNum;
u8 spriteId;
gTasks[taskId].data[10] += 4;
gBattle_BG1_X -= 4;
if (gTasks[taskId].data[10] == 128)
{
gTasks[taskId].data[10] = 0;
gBattle_BG1_X += 128;
gTasks[taskId].data[11]++;
if (gTasks[taskId].data[11] == 2)
{
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
paletteNum = 16 + gSprites[spriteId].oam.paletteNum;
if (gTasks[taskId].data[1] == 0)
SetGrayscaleOrOriginalPalette(paletteNum, TRUE);
DestroySprite(&gSprites[gTasks[taskId].data[0]]);
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
if (gTasks[taskId].data[6] == 1)
gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority++;
}
else if (gTasks[taskId].data[11] == 3)
{
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR | WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
}
}
}
// Changes battler's palette to either grayscale or original.
// arg0: which battler
// arg1: FALSE grayscale, TRUE original
void AnimTask_SetGrayscaleOrOriginalPal(u8 taskId)
{
u8 spriteId;
u8 battler;
bool8 calcSpriteId = FALSE;
u8 position = B_POSITION_PLAYER_LEFT;
switch (gBattleAnimArgs[0])
{
case ANIM_ATTACKER:
case ANIM_TARGET:
case ANIM_ATK_PARTNER:
case ANIM_DEF_PARTNER:
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
break;
case ANIM_PLAYER_LEFT:
position = B_POSITION_PLAYER_LEFT;
calcSpriteId = TRUE;
break;
case ANIM_PLAYER_RIGHT:
position = B_POSITION_PLAYER_RIGHT;
calcSpriteId = TRUE;
break;
case ANIM_OPPONENT_LEFT:
position = B_POSITION_OPPONENT_LEFT;
calcSpriteId = TRUE;
break;
case ANIM_OPPONENT_RIGHT:
position = B_POSITION_OPPONENT_RIGHT;
calcSpriteId = TRUE;
break;
default:
spriteId = SPRITE_NONE;
break;
}
if (calcSpriteId)
{
battler = GetBattlerAtPosition(position);
if (IsBattlerSpriteVisible(battler))
spriteId = gBattlerSpriteIds[battler];
else
spriteId = SPRITE_NONE;
}
if (spriteId != SPRITE_NONE)
SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, gBattleAnimArgs[1]);
DestroyAnimVisualTask(taskId);
}
void GetIsDoomDesireHitTurn(u8 taskId)
{
if (gAnimMoveTurn < 2)
gBattleAnimArgs[ARG_RET_ID] = FALSE;
if (gAnimMoveTurn == 2)
gBattleAnimArgs[ARG_RET_ID] = TRUE;
DestroyAnimVisualTask(taskId);
}
#include "global.h"
#include "battle_anim.h"
#include "scanline_effect.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimOutrageFlame(struct Sprite *);
static void AnimDragonRageFirePlume(struct Sprite *);
static void AnimDragonFireToTarget(struct Sprite *);
static void AnimDragonDanceOrb(struct Sprite *);
static void AnimDragonDanceOrb_Step(struct Sprite *);
static void AnimOverheatFlame(struct Sprite *);
static void AnimOverheatFlame_Step(struct Sprite *);
static void AnimTask_DragonDanceWaver_Step(u8);
static void UpdateDragonDanceScanlineEffect(struct Task *);
EWRAM_DATA static u16 sUnusedOverheatData[7] = {0};
static const union AnimCmd sAnim_OutrageOverheatFire_0[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_OutrageOverheatFire[] =
{
sAnim_OutrageOverheatFire_0,
};
const struct SpriteTemplate gOutrageFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_OutrageOverheatFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimOutrageFlame,
};
static const union AnimCmd sAnim_DragonBreathFire_0[] =
{
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sAnim_DragonBreathFire_1[] =
{
ANIMCMD_FRAME(16, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(32, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(48, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_DragonBreathFire[] =
{
sAnim_DragonBreathFire_0,
sAnim_DragonBreathFire_1,
};
static const union AffineAnimCmd sAffineAnim_DragonBreathFire_0[] =
{
AFFINEANIMCMD_FRAME(0x50, 0x50, 127, 0),
AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_DragonBreathFire_1[] =
{
AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0),
AFFINEANIMCMD_FRAME(0xD, 0xD, 0, 100),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_DragonBreathFire[] =
{
sAffineAnim_DragonBreathFire_0,
sAffineAnim_DragonBreathFire_1,
};
const struct SpriteTemplate gDragonBreathFireSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_DragonBreathFire,
.images = NULL,
.affineAnims = sAffineAnims_DragonBreathFire,
.callback = AnimDragonFireToTarget,
};
static const union AnimCmd sAnim_DragonRageFirePlume[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_FRAME(64, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_DragonRageFirePlume[] =
{
sAnim_DragonRageFirePlume,
};
const struct SpriteTemplate gDragonRageFirePlumeSpriteTemplate =
{
.tileTag = ANIM_TAG_FIRE_PLUME,
.paletteTag = ANIM_TAG_FIRE_PLUME,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_DragonRageFirePlume,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDragonRageFirePlume,
};
static const union AnimCmd sAnim_DragonRageFire[] =
{
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_JUMP(0),
};
static const union AnimCmd *const sAnims_DragonRageFire[] =
{
sAnim_DragonRageFire,
sAnim_DragonRageFire,
};
static const union AffineAnimCmd sAffineAnim_DragonRageFire_0[] =
{
AFFINEANIMCMD_FRAME(0x64, 0x64, 127, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_DragonRageFire_1[] =
{
AFFINEANIMCMD_FRAME(0x64, 0x64, 0, 1),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_DragonRageFire[] =
{
sAffineAnim_DragonRageFire_0,
sAffineAnim_DragonRageFire_1,
};
const struct SpriteTemplate gDragonRageFireSpitSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = sAnims_DragonRageFire,
.images = NULL,
.affineAnims = sAffineAnims_DragonRageFire,
.callback = AnimDragonFireToTarget,
};
const struct SpriteTemplate gDragonDanceOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_HOLLOW_ORB,
.paletteTag = ANIM_TAG_HOLLOW_ORB,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDragonDanceOrb,
};
const struct SpriteTemplate gOverheatFlameSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_EMBER,
.paletteTag = ANIM_TAG_SMALL_EMBER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_OutrageOverheatFire,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimOverheatFlame,
};
static void AnimOutrageFlame(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[0];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
gBattleAnimArgs[4] = -gBattleAnimArgs[4];
}
else
{
sprite->x += gBattleAnimArgs[0];
}
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
sprite->data[5] = gBattleAnimArgs[5];
sprite->invisible = TRUE;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteLinearAndFlicker;
}
static void StartDragonFireTranslation(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[1];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] -= gBattleAnimArgs[2];
sprite->data[4] += gBattleAnimArgs[3];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[2] += gBattleAnimArgs[2];
sprite->data[4] += gBattleAnimArgs[3];
StartSpriteAnim(sprite, 1);
}
sprite->data[0] = gBattleAnimArgs[4];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
static void AnimDragonRageFirePlume(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
}
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[1]);
sprite->y += gBattleAnimArgs[2];
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
// For Dragon Breath and Dragon Rage
static void AnimDragonFireToTarget(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
StartSpriteAffineAnim(sprite, 1);
StartDragonFireTranslation(sprite);
}
static void AnimDragonDanceOrb(struct Sprite *sprite)
{
u16 r5;
u16 r0;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[4] = 0;
sprite->data[5] = 1;
sprite->data[6] = gBattleAnimArgs[0];
r5 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_HEIGHT);
r0 = GetBattlerSpriteCoordAttr(gBattlerAttacker, BATTLER_COORD_ATTR_WIDTH);
if (r5 > r0)
sprite->data[7] = r5 / 2;
else
sprite->data[7] = r0 / 2;
sprite->x2 = Cos(sprite->data[6], sprite->data[7]);
sprite->y2 = Sin(sprite->data[6], sprite->data[7]);
sprite->callback = AnimDragonDanceOrb_Step;
}
static void AnimDragonDanceOrb_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
sprite->x2 = Cos(sprite->data[6], sprite->data[7]);
sprite->y2 = Sin(sprite->data[6], sprite->data[7]);
if (++sprite->data[4] > 5)
{
sprite->data[4] = 0;
if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
sprite->data[5] = 16;
}
if (++sprite->data[3] > 0x3C)
{
sprite->data[3] = 0;
sprite->data[0]++;
}
break;
case 1:
sprite->data[6] = (sprite->data[6] - sprite->data[5]) & 0xFF;
if (sprite->data[7] <= 0x95 && (sprite->data[7] += 8) > 0x95)
sprite->data[7] = 0x96;
sprite->x2 = Cos(sprite->data[6], sprite->data[7]);
sprite->y2 = Sin(sprite->data[6], sprite->data[7]);
if (++sprite->data[4] > 5)
{
sprite->data[4] = 0;
if (sprite->data[5] <= 15 && ++sprite->data[5] > 15)
sprite->data[5] = 16;
}
if (++sprite->data[3] > 20)
DestroyAnimSprite(sprite);
break;
}
}
// Wavers the attacker back and forth. Progressing vertical wave of scanline shifts
// Used by Dragon Dance
void AnimTask_DragonDanceWaver(u8 taskId)
{
struct ScanlineEffectParams scanlineParams;
struct Task *task = &gTasks[taskId];
u16 i;
u8 y;
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
{
scanlineParams.dmaDest = &REG_BG1HOFS;
task->data[2] = gBattle_BG1_X;
}
else
{
scanlineParams.dmaDest = &REG_BG2HOFS;
task->data[2] = gBattle_BG2_X;
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
y = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
task->data[3] = y - 32;
task->data[4] = y + 32;
if (task->data[3] < 0)
task->data[3] = 0;
for (i = task->data[3]; i <= task->data[4]; i++)
{
gScanlineEffectRegBuffers[0][i] = task->data[2];
gScanlineEffectRegBuffers[1][i] = task->data[2];
}
ScanlineEffect_SetParams(scanlineParams);
task->func = AnimTask_DragonDanceWaver_Step;
}
static void AnimTask_DragonDanceWaver_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[7] > 1)
{
task->data[7] = 0;
if (++task->data[6] == 3)
task->data[0]++;
}
UpdateDragonDanceScanlineEffect(task);
break;
case 1:
if (++task->data[1] > 0x3C)
task->data[0]++;
UpdateDragonDanceScanlineEffect(task);
break;
case 2:
if (++task->data[7] > 1)
{
task->data[7] = 0;
if (--task->data[6] == 0)
task->data[0]++;
}
UpdateDragonDanceScanlineEffect(task);
break;
case 3:
gScanlineEffect.state = 3;
task->data[0]++;
break;
case 4:
DestroyAnimVisualTask(taskId);
break;
}
}
static void UpdateDragonDanceScanlineEffect(struct Task *task)
{
u16 sineIndex = task->data[5];
u16 i;
for (i = task->data[3]; i <= task->data[4]; i++)
{
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = ((gSineTable[sineIndex] * task->data[6]) >> 7) + task->data[2];
sineIndex = (sineIndex + 8) & 0xFF;
}
task->data[5] = (task->data[5] + 9) & 0xFF;
}
static void AnimOverheatFlame(struct Sprite *sprite)
{
int i;
int yAmplitude = (gBattleAnimArgs[2] * 3) / 5;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[4];
sprite->data[1] = Cos(gBattleAnimArgs[1], gBattleAnimArgs[2]);
sprite->data[2] = Sin(gBattleAnimArgs[1], yAmplitude);
sprite->x += sprite->data[1] * gBattleAnimArgs[0];
sprite->y += sprite->data[2] * gBattleAnimArgs[0];
sprite->data[3] = gBattleAnimArgs[3];
sprite->callback = AnimOverheatFlame_Step;
for (i = 0; i < 7; i++)
sUnusedOverheatData[i] = sprite->data[i];
}
static void AnimOverheatFlame_Step(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[1];
sprite->data[5] += sprite->data[2];
sprite->x2 = sprite->data[4] / 10;
sprite->y2 = sprite->data[5] / 10;
if (++sprite->data[0] > sprite->data[3])
DestroyAnimSprite(sprite);
}
#include "global.h"
#include "malloc.h"
#include "battle_anim.h"
#include "battle_interface.h"
#include "decompress.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "main.h"
#include "math_util.h"
#include "palette.h"
#include "random.h"
#include "scanline_effect.h"
#include "sound.h"
#include "trig.h"
#include "util.h"
#include "constants/rgb.h"
#include "constants/songs.h"
static void AnimCirclingFinger(struct Sprite *);
static void AnimBouncingMusicNote(struct Sprite *);
static void AnimBouncingMusicNote_Step(struct Sprite *);
static void AnimVibrateBattlerBack(struct Sprite *);
static void AnimMovingClamp(struct Sprite *);
static void AnimMovingClamp_Step(struct Sprite *);
static void AnimMovingClamp_End(struct Sprite *);
static void AnimKinesisZapEnergy(struct Sprite *);
static void AnimSwordsDanceBlade(struct Sprite *);
static void AnimSwordsDanceBlade_Step(struct Sprite *);
static void AnimSonicBoomProjectile(struct Sprite *);
static void AnimAirWaveProjectile(struct Sprite *);
static void AnimAirWaveProjectile_Step1(struct Sprite *sprite);
static void AnimAirWaveProjectile_Step2(struct Sprite *sprite);
static void AnimVoidLines(struct Sprite *);
static void AnimVoidLines_Step(struct Sprite *);
static void AnimCoinThrow(struct Sprite *);
static void AnimFallingCoin(struct Sprite *);
static void AnimFallingCoin_Step(struct Sprite *);
static void AnimBulletSeed(struct Sprite *);
static void AnimBulletSeed_Step1(struct Sprite *);
static void AnimBulletSeed_Step2(struct Sprite *);
static void AnimRazorWindTornado(struct Sprite *);
static void AnimViceGripPincer(struct Sprite *);
static void AnimViceGripPincer_Step(struct Sprite *);
static void AnimGuillotinePincer(struct Sprite *);
static void AnimGuillotinePincer_Step1(struct Sprite *);
static void AnimGuillotinePincer_Step2(struct Sprite *);
static void AnimGuillotinePincer_Step3(struct Sprite *);
static void AnimBreathPuff(struct Sprite *);
static void AnimAngerMark(struct Sprite *);
static void AnimPencil(struct Sprite *);
static void AnimPencil_Step(struct Sprite *);
static void AnimBlendThinRing(struct Sprite *);
static void AnimHyperVoiceRing(struct Sprite *);
static void AnimUproarRing(struct Sprite *);
static void AnimSoftBoiledEgg(struct Sprite *);
static void AnimSoftBoiledEgg_Step1(struct Sprite *);
static void AnimSoftBoiledEgg_Step2(struct Sprite *);
static void AnimSoftBoiledEgg_Step3(struct Sprite *);
static void AnimSoftBoiledEgg_Step3_Callback1(struct Sprite *);
static void AnimSoftBoiledEgg_Step3_Callback2(struct Sprite *);
static void AnimSoftBoiledEgg_Step4(struct Sprite *);
static void AnimSoftBoiledEgg_Step4_Callback(struct Sprite *);
static void AnimSpeedDust(struct Sprite *);
static void AnimHealBellMusicNote(struct Sprite *);
static void AnimMagentaHeart(struct Sprite *);
static void AnimRedHeartProjectile(struct Sprite *);
static void AnimRedHeartProjectile_Step(struct Sprite *);
static void AnimRedHeartRising(struct Sprite *);
static void AnimRedHeartRising_Step(struct Sprite *);
static void AnimOrbitFast(struct Sprite *);
static void AnimOrbitFast_Step(struct Sprite *);
static void AnimOrbitScatter(struct Sprite *);
static void AnimOrbitScatter_Step(struct Sprite *);
static void AnimSpitUpOrb(struct Sprite *);
static void AnimSpitUpOrb_Step(struct Sprite *sprite);
static void AnimEyeSparkle(struct Sprite *);
static void AnimEyeSparkle_Step(struct Sprite *sprite);
static void AnimAngel(struct Sprite *);
static void AnimPinkHeart(struct Sprite *);
static void AnimDevil(struct Sprite *);
static void AnimFurySwipes(struct Sprite *);
static void AnimMovementWaves(struct Sprite *);
static void AnimMovementWaves_Step(struct Sprite *);
static void AnimJaggedMusicNote(struct Sprite *);
static void AnimJaggedMusicNote_Step(struct Sprite *);
static void AnimPerishSongMusicNote2(struct Sprite *);
static void AnimPerishSongMusicNote(struct Sprite *);
static void AnimPerishSongMusicNote_Step1(struct Sprite *);
static void AnimPerishSongMusicNote_Step2(struct Sprite *);
static void AnimGuardRing(struct Sprite *);
static void AnimTask_Withdraw_Step(u8);
static void AnimTask_GrowAndGrayscale_Step(u8);
static void AnimTask_Minimize_Step(u8);
static void CreateMinimizeSprite(struct Task *, u8);
static void ClonedMinizeSprite_Step(struct Sprite *);
static void AnimTask_Splash_Step(u8);
static void AnimTask_GrowAndShrink_Step(u8);
static void AnimTask_ThrashMoveMonHorizontal_Step(u8);
static void AnimTask_ThrashMoveMonVertical_Step(u8);
static void AnimTask_SketchDrawMon_Step(u8);
static void AnimTask_AttackerStretchAndDisappear_Step(u8);
static void AnimTask_ExtremeSpeedImpact_Step(u8);
static void AnimTask_ExtremeSpeedMonReappear_Step(u8);
static void AnimTask_SpeedDust_Step(u8);
static void AnimTask_FakeOut_Step1(u8);
static void AnimTask_FakeOut_Step2(u8);
static void AnimTask_HeartsBackground_Step(u8);
static void AnimTask_ScaryFace_Step(u8);
static void AnimTask_UproarDistortion_Step(u8);
// Unused
static const struct SpriteTemplate sCirclingFingerSpriteTemplate =
{
.tileTag = ANIM_TAG_FINGER,
.paletteTag = ANIM_TAG_FINGER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCirclingFinger,
};
static const union AnimCmd sAnim_BouncingMusicNote[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
// Unused (association assumed)
static const union AnimCmd *const sAnims_BouncingMusicNote[] =
{
sAnim_BouncingMusicNote,
};
// Unused
static const struct SpriteTemplate sBouncingMusicNoteSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBouncingMusicNote,
};
// Unused
static const struct SpriteTemplate sVibrateBattlerBackSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimVibrateBattlerBack,
};
// Unused
static const struct SpriteTemplate sMovingClampSpriteTemplate =
{
.tileTag = ANIM_TAG_CLAMP,
.paletteTag = ANIM_TAG_CLAMP,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_Bite,
.callback = AnimMovingClamp,
};
static const union AnimCmd sAnim_SmallExplosion[] =
{
ANIMCMD_FRAME(0, 9),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_SmallExplosion[] =
{
sAnim_SmallExplosion,
};
static const union AffineAnimCmd sAffineAnim_SmallExplosion[] =
{
AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0),
AFFINEANIMCMD_FRAME(0x9, 0x9, 0, 18),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_SmallExplosion[] =
{
sAffineAnim_SmallExplosion,
};
// Unused
static const struct SpriteTemplate sSmallExplosionSpriteTemplate =
{
.tileTag = ANIM_TAG_EXPLOSION_6,
.paletteTag = ANIM_TAG_EXPLOSION_6,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = sAnims_SmallExplosion,
.images = NULL,
.affineAnims = sAffineAnims_SmallExplosion,
.callback = AnimSpriteOnMonPos,
};
const union AnimCmd gKinesisZapEnergyAnimCmds[] =
{
ANIMCMD_FRAME(0, 3, .hFlip = TRUE),
ANIMCMD_FRAME(8, 3, .hFlip = TRUE),
ANIMCMD_FRAME(16, 3, .hFlip = TRUE),
ANIMCMD_FRAME(24, 3, .hFlip = TRUE),
ANIMCMD_FRAME(32, 3, .hFlip = TRUE),
ANIMCMD_FRAME(40, 3, .hFlip = TRUE),
ANIMCMD_FRAME(48, 3, .hFlip = TRUE),
ANIMCMD_LOOP(1),
ANIMCMD_END,
};
const union AnimCmd *const gKinesisZapEnergyAnimTable[] =
{
gKinesisZapEnergyAnimCmds,
};
const struct SpriteTemplate gKinesisZapEnergySpriteTemplate =
{
.tileTag = ANIM_TAG_ALERT,
.paletteTag = ANIM_TAG_ALERT,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gKinesisZapEnergyAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimKinesisZapEnergy,
};
const union AffineAnimCmd gSwordsDanceBladeAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x14, 0x0, 0, 12),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gSwordsDanceBladeAffineAnimTable[] =
{
gSwordsDanceBladeAffineAnimCmds,
};
const struct SpriteTemplate gSwordsDanceBladeSpriteTemplate =
{
.tileTag = ANIM_TAG_SWORD,
.paletteTag = ANIM_TAG_SWORD,
.oam = &gOamData_AffineNormal_ObjBlend_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSwordsDanceBladeAffineAnimTable,
.callback = AnimSwordsDanceBlade,
};
const struct SpriteTemplate gSonicBoomSpriteTemplate =
{
.tileTag = ANIM_TAG_AIR_WAVE,
.paletteTag = ANIM_TAG_AIR_WAVE,
.oam = &gOamData_AffineDouble_ObjBlend_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSonicBoomProjectile,
};
const struct SpriteTemplate gAirWaveProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_AIR_WAVE,
.paletteTag = ANIM_TAG_AIR_WAVE,
.oam = &gOamData_AffineOff_ObjBlend_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimAirWaveProjectile,
};
const union AffineAnimCmd gGrowingRingAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
AFFINEANIMCMD_FRAME(0x7, 0x7, 0, -56),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gWaterPulseRingAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10),
AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10),
AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10),
AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10),
AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10),
AFFINEANIMCMD_FRAME(0xFFF6, 0xFFF6, 0, 10),
AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gGrowingRingAffineAnimTable[] =
{
gGrowingRingAffineAnimCmds,
};
const union AffineAnimCmd *const gWaterPulseRingAffineAnimTable[] =
{
gWaterPulseRingAffineAnimCmds,
};
const struct SpriteTemplate gSupersonicRingSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_RING,
.paletteTag = ANIM_TAG_GOLD_RING,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gGrowingRingAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
const struct SpriteTemplate gScreechRingSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_RING,
.paletteTag = ANIM_TAG_PURPLE_RING,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gGrowingRingAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
const struct SpriteTemplate gMetalSoundSpriteTemplate =
{
.tileTag = ANIM_TAG_METAL_SOUND_WAVES,
.paletteTag = ANIM_TAG_METAL_SOUND_WAVES,
.oam = &gOamData_AffineDouble_ObjNormal_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gGrowingRingAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
const struct SpriteTemplate gWaterPulseRingSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_RING_2,
.paletteTag = ANIM_TAG_BLUE_RING_2,
.oam = &gOamData_AffineDouble_ObjNormal_16x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gWaterPulseRingAffineAnimTable,
.callback = AnimWaterPulseRing,
};
const struct SpriteTemplate gEggThrowSpriteTemplate =
{
.tileTag = ANIM_TAG_LARGE_FRESH_EGG,
.paletteTag = ANIM_TAG_LARGE_FRESH_EGG,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThrowProjectile,
};
// Unused
static const struct SpriteTemplate sVoidLinesSpriteTemplate =
{
.tileTag = ANIM_TAG_VOID_LINES,
.paletteTag = ANIM_TAG_VOID_LINES,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimVoidLines,
};
const union AnimCmd gCoinAnimCmds[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
const union AnimCmd *const gCoinAnimTable[] =
{
gCoinAnimCmds,
};
const union AffineAnimCmd gFallingCoinAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gFallingCoinAffineAnimTable[] =
{
gFallingCoinAffineAnimCmds,
};
const struct SpriteTemplate gCoinThrowSpriteTemplate =
{
.tileTag = ANIM_TAG_COIN,
.paletteTag = ANIM_TAG_COIN,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gCoinAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCoinThrow,
};
const struct SpriteTemplate gFallingCoinSpriteTemplate =
{
.tileTag = ANIM_TAG_COIN,
.paletteTag = ANIM_TAG_COIN,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gCoinAnimTable,
.images = NULL,
.affineAnims = gFallingCoinAffineAnimTable,
.callback = AnimFallingCoin,
};
const union AffineAnimCmd gBulletSeedAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gBulletSeedAffineAnimTable[] =
{
gBulletSeedAffineAnimCmds,
};
const struct SpriteTemplate gBulletSeedSpriteTemplate =
{
.tileTag = ANIM_TAG_SEED,
.paletteTag = ANIM_TAG_SEED,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gBulletSeedAffineAnimTable,
.callback = AnimBulletSeed,
};
const union AffineAnimCmd gRazorWindTornadoAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x4, 0x0, 0, 40),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gRazorWindTornadoAffineAnimTable[] =
{
gRazorWindTornadoAffineAnimCmds,
};
const struct SpriteTemplate gRazorWindTornadoSpriteTemplate =
{
.tileTag = ANIM_TAG_GUST,
.paletteTag = ANIM_TAG_GUST,
.oam = &gOamData_AffineNormal_ObjNormal_32x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gRazorWindTornadoAffineAnimTable,
.callback = AnimRazorWindTornado,
};
const union AnimCmd gViceGripAnimCmds1[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 20),
ANIMCMD_END,
};
const union AnimCmd gViceGripAnimCmds2[] =
{
ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(16, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(32, 20, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gViceGripAnimTable[] =
{
gViceGripAnimCmds1,
gViceGripAnimCmds2,
};
const struct SpriteTemplate gViceGripSpriteTemplate =
{
.tileTag = ANIM_TAG_CUT,
.paletteTag = ANIM_TAG_CUT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gViceGripAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimViceGripPincer,
};
const union AnimCmd gGuillotineAnimCmds1[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
const union AnimCmd gGuillotineAnimCmds2[] =
{
ANIMCMD_FRAME(0, 2, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(16, 2, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(32, 1, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gGuillotineAnimTable[] =
{
gGuillotineAnimCmds1,
gGuillotineAnimCmds2,
};
const struct SpriteTemplate gGuillotineSpriteTemplate =
{
.tileTag = ANIM_TAG_CUT,
.paletteTag = ANIM_TAG_CUT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gGuillotineAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGuillotinePincer,
};
const union AffineAnimCmd gSplashEffectAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-6, 4, 0, 8),
AFFINEANIMCMD_FRAME(10, -10, 0, 8),
AFFINEANIMCMD_FRAME(-4, 6, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gGrowAndShrinkAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-4, -5, 0, 12),
AFFINEANIMCMD_FRAME(0, 0, 0, 24),
AFFINEANIMCMD_FRAME(4, 5, 0, 12),
AFFINEANIMCMD_END,
};
const union AnimCmd gBreathPuffAnimCmds1[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(4, 40, .hFlip = TRUE),
ANIMCMD_FRAME(8, 4, .hFlip = TRUE),
ANIMCMD_FRAME(12, 4, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gBreathPuffAnimCmds2[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(4, 40),
ANIMCMD_FRAME(8, 4),
ANIMCMD_FRAME(12, 4),
ANIMCMD_END,
};
const union AnimCmd *const gBreathPuffAnimTable[] =
{
gBreathPuffAnimCmds1,
gBreathPuffAnimCmds2,
};
const struct SpriteTemplate gBreathPuffSpriteTemplate =
{
.tileTag = ANIM_TAG_BREATH,
.paletteTag = ANIM_TAG_BREATH,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gBreathPuffAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBreathPuff,
};
const union AffineAnimCmd gAngerMarkAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0xB, 0xB, 0, 8),
AFFINEANIMCMD_FRAME(0xFFF5, 0xFFF5, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gAngerMarkAffineAnimTable[] =
{
gAngerMarkAffineAnimCmds,
};
const struct SpriteTemplate gAngerMarkSpriteTemplate =
{
.tileTag = ANIM_TAG_ANGER,
.paletteTag = ANIM_TAG_ANGER,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAngerMarkAffineAnimTable,
.callback = AnimAngerMark,
};
const union AffineAnimCmd gThrashMoveMonAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-10, 9, 0, 7),
AFFINEANIMCMD_FRAME(20, -20, 0, 7),
AFFINEANIMCMD_FRAME(-20, 20, 0, 7),
AFFINEANIMCMD_FRAME(10, -9, 0, 7),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gPencilSpriteTemplate =
{
.tileTag = ANIM_TAG_PENCIL,
.paletteTag = ANIM_TAG_PENCIL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPencil,
};
const struct SpriteTemplate gSnoreZSpriteTemplate =
{
.tileTag = ANIM_TAG_SNORE_Z,
.paletteTag = ANIM_TAG_SNORE_Z,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTravelDiagonally,
};
const union AnimCmd gExplosionAnimCmds[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_END,
};
const union AnimCmd *const gExplosionAnimTable[] =
{
gExplosionAnimCmds,
};
const struct SpriteTemplate gExplosionSpriteTemplate =
{
.tileTag = ANIM_TAG_EXPLOSION,
.paletteTag = ANIM_TAG_EXPLOSION,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gExplosionAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 2),
AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 4),
AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 2),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gSoftBoiledEggAffineAnimCmds3[] =
{
AFFINEANIMCMD_FRAME(0xFFF8, 0x4, 0, 8),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0x10, 0xFFF8, 0, 8),
AFFINEANIMCMD_FRAME(0xFFF0, 0x8, 0, 8),
AFFINEANIMCMD_LOOP(1),
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 15),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gSoftBoiledEggAffineAnimTable[] =
{
gSoftBoiledEggAffineAnimCmds1,
gSoftBoiledEggAffineAnimCmds2,
gSoftBoiledEggAffineAnimCmds3,
};
const struct SpriteTemplate gSoftBoiledEggSpriteTemplate =
{
.tileTag = ANIM_TAG_BREAKING_EGG,
.paletteTag = ANIM_TAG_BREAKING_EGG,
.oam = &gOamData_AffineDouble_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSoftBoiledEggAffineAnimTable,
.callback = AnimSoftBoiledEgg,
};
const union AffineAnimCmd gThinRingExpandingAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 30),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd gThinRingExpandingAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 15),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd gHyperVoiceRingAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0xB, 0xB, 0, 45),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd *const gThinRingExpandingAffineAnimTable[] =
{
gThinRingExpandingAffineAnimCmds1,
gThinRingExpandingAffineAnimCmds2,
};
const union AffineAnimCmd *const gHyperVoiceRingAffineAnimTable[] =
{
gHyperVoiceRingAffineAnimCmds,
};
const struct SpriteTemplate gThinRingExpandingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_THIN_RING,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gThinRingExpandingAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const union AffineAnimCmd gThinRingShrinkingAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 30),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd *const gThinRingShrinkingAffineAnimTable[] =
{
gThinRingShrinkingAffineAnimCmds,
};
const struct SpriteTemplate gThinRingShrinkingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_THIN_RING,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gThinRingShrinkingAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gBlendThinRingExpandingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_THIN_RING,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gThinRingExpandingAffineAnimTable,
.callback = AnimBlendThinRing,
};
const struct SpriteTemplate gHyperVoiceRingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_THIN_RING,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gHyperVoiceRingAffineAnimTable,
.callback = AnimHyperVoiceRing,
};
const struct SpriteTemplate gUproarRingSpriteTemplate =
{
.tileTag = ANIM_TAG_THIN_RING,
.paletteTag = ANIM_TAG_THIN_RING,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gThinRingExpandingAffineAnimTable,
.callback = AnimUproarRing,
};
const union AffineAnimCmd gStretchAttackerAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(96, -13, 0, 8),
AFFINEANIMCMD_END,
};
const union AnimCmd gSpeedDustAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(4, 3),
ANIMCMD_FRAME(8, 3),
ANIMCMD_FRAME(4, 3),
ANIMCMD_FRAME(0, 3),
ANIMCMD_END,
};
const union AnimCmd *const gSpeedDustAnimTable[] =
{
gSpeedDustAnimCmds,
};
const struct SpriteTemplate gSpeedDustSpriteTemplate =
{
.tileTag = ANIM_TAG_SPEED_DUST,
.paletteTag = ANIM_TAG_SPEED_DUST,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gSpeedDustAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpeedDust,
};
const s8 gSpeedDustPosTable[][2] =
{
{30, 28},
{-20, 24},
{16, 26},
{-10, 28},
};
const union AnimCmd gBellAnimCmds[] =
{
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 15),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6, .hFlip = TRUE),
ANIMCMD_FRAME(32, 15, .hFlip = TRUE),
ANIMCMD_FRAME(16, 6, .hFlip = TRUE),
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 15),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(0, 6),
ANIMCMD_END,
};
const union AnimCmd *const gBellAnimTable[] =
{
gBellAnimCmds,
};
const struct SpriteTemplate gBellSpriteTemplate =
{
.tileTag = ANIM_TAG_BELL,
.paletteTag = ANIM_TAG_BELL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gBellAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
#define NUM_MUSIC_NOTE_PAL_TAGS 3
static const u16 sMusicNotePaletteTagsTable[NUM_MUSIC_NOTE_PAL_TAGS] =
{
ANIM_TAG_MUSIC_NOTES_2,
ANIM_SPRITES_START - 1,
ANIM_SPRITES_START - 2,
};
const struct SpriteTemplate gHealBellMusicNoteSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES_2,
.paletteTag = ANIM_TAG_MUSIC_NOTES_2,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimHealBellMusicNote,
};
const struct SpriteTemplate gMagentaHeartSpriteTemplate =
{
.tileTag = ANIM_TAG_MAGENTA_HEART,
.paletteTag = ANIM_TAG_MAGENTA_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMagentaHeart,
};
static const union AffineAnimCmd sAffineAnims_StretchBattlerUp[] =
{
AFFINEANIMCMD_FRAME(0x000A, 0xFFF3, 0x00, 0x0A),
AFFINEANIMCMD_FRAME(0xFFF6, 0x000D, 0x00, 0x0A),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gRedHeartProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_HEART,
.paletteTag = ANIM_TAG_RED_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRedHeartProjectile,
};
const struct SpriteTemplate gRedHeartBurstSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_HEART,
.paletteTag = ANIM_TAG_RED_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimParticleBurst,
};
const struct SpriteTemplate gRedHeartRisingSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_HEART,
.paletteTag = ANIM_TAG_RED_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRedHeartRising,
};
const union AffineAnimCmd gHiddenPowerOrbAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gHiddenPowerOrbAffineAnimTable[] =
{
gHiddenPowerOrbAffineAnimCmds,
};
const struct SpriteTemplate gHiddenPowerOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_ORB,
.paletteTag = ANIM_TAG_RED_ORB,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gHiddenPowerOrbAffineAnimTable,
.callback = AnimOrbitFast,
};
const struct SpriteTemplate gHiddenPowerOrbScatterSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_ORB,
.paletteTag = ANIM_TAG_RED_ORB,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gHiddenPowerOrbAffineAnimTable,
.callback = AnimOrbitScatter,
};
const union AffineAnimCmd gSpitUpOrbAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gSpitUpOrbAffineAnimTable[] =
{
gSpitUpOrbAffineAnimCmds,
};
const struct SpriteTemplate gSpitUpOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_ORB_2,
.paletteTag = ANIM_TAG_RED_ORB_2,
.oam = &gOamData_AffineDouble_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSpitUpOrbAffineAnimTable,
.callback = AnimSpitUpOrb,
};
const union AnimCmd gEyeSparkleAnimCmds[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(4, 4),
ANIMCMD_FRAME(8, 4),
ANIMCMD_FRAME(4, 4),
ANIMCMD_FRAME(0, 4),
ANIMCMD_END,
};
const union AnimCmd *const gEyeSparkleAnimTable[] =
{
gEyeSparkleAnimCmds,
};
const struct SpriteTemplate gEyeSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_EYE_SPARKLE,
.paletteTag = ANIM_TAG_EYE_SPARKLE,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gEyeSparkleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEyeSparkle,
};
const union AnimCmd gAngelSpriteAnimCmds[] =
{
ANIMCMD_FRAME(0, 24),
ANIMCMD_END,
};
const union AnimCmd *const gAngelSpriteAnimTable[] =
{
gAngelSpriteAnimCmds,
};
const struct SpriteTemplate gAngelSpriteTemplate =
{
.tileTag = ANIM_TAG_ANGEL,
.paletteTag = ANIM_TAG_ANGEL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gAngelSpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimAngel,
};
const struct SpriteTemplate gPinkHeartSpriteTemplate =
{
.tileTag = ANIM_TAG_PINK_HEART,
.paletteTag = ANIM_TAG_PINK_HEART,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPinkHeart,
};
const union AnimCmd gDevilAnimCmds1[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_JUMP(0),
};
const union AnimCmd gDevilAnimCmds2[] =
{
ANIMCMD_FRAME(16, 3),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gDevilAnimTable[] =
{
gDevilAnimCmds1,
gDevilAnimCmds2,
};
const struct SpriteTemplate gDevilSpriteTemplate =
{
.tileTag = ANIM_TAG_DEVIL,
.paletteTag = ANIM_TAG_DEVIL,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDevilAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimDevil,
};
static const union AnimCmd sAnim_FurySwipes[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_END,
};
static const union AnimCmd sAnim_FurySwipes_Flipped[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_FRAME(48, 4, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_FurySwipes[] =
{
sAnim_FurySwipes,
sAnim_FurySwipes_Flipped,
};
const struct SpriteTemplate gFurySwipesSpriteTemplate =
{
.tileTag = ANIM_TAG_SWIPE,
.paletteTag = ANIM_TAG_SWIPE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_FurySwipes,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFurySwipes,
};
const union AnimCmd gMovementWavesAnimCmds1[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(16, 8),
ANIMCMD_FRAME(32, 8),
ANIMCMD_FRAME(16, 8),
ANIMCMD_END,
};
const union AnimCmd gMovementWavesAnimCmds2[] =
{
ANIMCMD_FRAME(16, 8, .hFlip = TRUE),
ANIMCMD_FRAME(32, 8, .hFlip = TRUE),
ANIMCMD_FRAME(16, 8, .hFlip = TRUE),
ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gMovementWavesAnimTable[] =
{
gMovementWavesAnimCmds1,
gMovementWavesAnimCmds2,
};
const struct SpriteTemplate gMovementWavesSpriteTemplate =
{
.tileTag = ANIM_TAG_MOVEMENT_WAVES,
.paletteTag = ANIM_TAG_MOVEMENT_WAVES,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gMovementWavesAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMovementWaves,
};
static const union AffineAnimCmd sAffineAnims_UproarDistortion[] =
{
AFFINEANIMCMD_FRAME(-12, 8, 0, 4),
AFFINEANIMCMD_FRAME(20, -20, 0, 4),
AFFINEANIMCMD_FRAME(-8, 12, 0, 4),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gJaggedMusicNoteSpriteTemplate =
{
.tileTag = ANIM_TAG_JAGGED_MUSIC_NOTE,
.paletteTag = ANIM_TAG_JAGGED_MUSIC_NOTE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimJaggedMusicNote,
};
const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 5),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 16),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd gPerishSongMusicNoteAffineAnimCmds3[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 16),
AFFINEANIMCMD_END_ALT(1),
};
const union AffineAnimCmd *const gPerishSongMusicNoteAffineAnimTable[] =
{
gPerishSongMusicNoteAffineAnimCmds1,
gPerishSongMusicNoteAffineAnimCmds2,
gPerishSongMusicNoteAffineAnimCmds3,
};
extern const union AnimCmd *const gMusicNotesAnimTable[];
const struct SpriteTemplate gPerishSongMusicNoteSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES_2,
.paletteTag = ANIM_TAG_MUSIC_NOTES_2,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
.affineAnims = gPerishSongMusicNoteAffineAnimTable,
.callback = AnimPerishSongMusicNote,
};
const struct SpriteTemplate gPerishSongMusicNote2SpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES_2,
.paletteTag = ANIM_TAG_MUSIC_NOTES_2,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
.affineAnims = gPerishSongMusicNoteAffineAnimTable,
.callback = AnimPerishSongMusicNote2,
};
const union AffineAnimCmd gGuardRingAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gGuardRingAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gGuardRingAffineAnimTable[] =
{
gGuardRingAffineAnimCmds1,
gGuardRingAffineAnimCmds2,
};
const struct SpriteTemplate gGuardRingSpriteTemplate =
{
.tileTag = ANIM_TAG_GUARD_RING,
.paletteTag = ANIM_TAG_GUARD_RING,
.oam = &gOamData_AffineDouble_ObjBlend_64x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gGuardRingAffineAnimTable,
.callback = AnimGuardRing,
};
#define sAmplitudeX data[1]
#define sCircleSpeed data[2]
#define sMoveSteps data[3]
#define sAmplitudeY data[4]
static void AnimCirclingFinger(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
sprite->sAmplitudeX = gBattleAnimArgs[2];
sprite->sCircleSpeed = gBattleAnimArgs[4];
sprite->sMoveSteps = gBattleAnimArgs[5];
sprite->sAmplitudeY = gBattleAnimArgs[3];
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteInEllipse;
sprite->callback(sprite);
}
#undef sAmplitudeX
#undef sCircleSpeed
#undef sMoveSteps
#undef sAmplitudeY
static void AnimBouncingMusicNote(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
SetSpriteNextToMonHead(battler, sprite);
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->callback = AnimBouncingMusicNote_Step;
}
static void AnimBouncingMusicNote_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->y2 -= 3;
if (++sprite->data[1] == 6)
sprite->data[0]++;
break;
case 1:
sprite->y2 += 3;
if (--sprite->data[1] == 0)
sprite->data[0]++;
break;
case 2:
if (++sprite->data[1] == 64)
DestroyAnimSprite(sprite);
break;
}
}
static void AnimVibrateBattlerBack_Step(struct Sprite *sprite)
{
s16 temp;
gSprites[sprite->data[2]].x2 += sprite->data[1];
temp = sprite->data[1];
sprite->data[1] = -temp;
if (sprite->data[0] == 0)
{
gSprites[sprite->data[2]].x2 = 0;
DestroySpriteAndMatrix(sprite);
}
sprite->data[0]--;
}
static void AnimVibrateBattlerBack(struct Sprite *sprite)
{
u8 spriteId;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
spriteId = gBattlerSpriteIds[gBattleAnimTarget];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = spriteId;
sprite->callback = AnimVibrateBattlerBack_Step;
sprite->invisible = TRUE;
}
static void AnimMovingClamp(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[4];
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimMovingClamp_Step);
}
static void AnimMovingClamp_Step(struct Sprite *sprite)
{
sprite->data[0] = sprite->data[1];
sprite->data[2] = sprite->x;
sprite->data[4] = sprite->y + 15;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimMovingClamp_End);
}
static void AnimMovingClamp_End(struct Sprite *sprite)
{
if (sprite->data[5] == 0)
DestroyAnimSprite(sprite);
else
sprite->data[5]--;
}
// Rotates the attacking mon sprite downwards and then back upwards to its original position.
// No args.
void AnimTask_Withdraw(u8 taskId)
{
PrepareBattlerSpriteForRotScale(gBattlerSpriteIds[gBattleAnimAttacker], ST_OAM_OBJ_NORMAL);
gTasks[taskId].func = AnimTask_Withdraw_Step;
}
static void AnimTask_Withdraw_Step(u8 taskId)
{
u8 spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
s16 rotation;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
rotation = -gTasks[taskId].data[0];
else
rotation = gTasks[taskId].data[0];
SetSpriteRotScale(spriteId, 0x100, 0x100, rotation);
if (gTasks[taskId].data[1] == 0)
{
gTasks[taskId].data[0] += 0xB0;
// this y position update gets overwritten by SetBattlerSpriteYOffsetFromRotation()
gSprites[spriteId].y2++;
}
else if (gTasks[taskId].data[1] == 1)
{
if (++gTasks[taskId].data[3] == 30)
gTasks[taskId].data[1] = 2;
return;
}
else
{
gTasks[taskId].data[0] -= 0xB0;
// this y position update gets overwritten by SetBattlerSpriteYOffsetFromRotation()
gSprites[spriteId].y2--;
}
SetBattlerSpriteYOffsetFromRotation(spriteId);
if (gTasks[taskId].data[0] == 0xF20 || gTasks[taskId].data[0] == 0)
{
if (gTasks[taskId].data[1] == 2)
{
ResetSpriteRotScale(spriteId);
DestroyAnimVisualTask(taskId);
}
else
{
gTasks[taskId].data[1]++;
}
}
}
// Animates a "zap of energy" used in KINESIS.
// arg 0: x pixel offset
// arg 1: y pixel offset
// arg 2: vertical flip
static void AnimKinesisZapEnergy(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->hFlip = 1;
if (gBattleAnimArgs[2])
sprite->vFlip = 1;
}
else
{
if (gBattleAnimArgs[2])
sprite->vFlip = 1;
}
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Animates a sword that rises into the air after a brief pause.
// arg 0: x pixel offset
// arg 1: y pixel offset
static void AnimSwordsDanceBlade(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, AnimSwordsDanceBlade_Step);
}
static void AnimSwordsDanceBlade_Step(struct Sprite *sprite)
{
sprite->data[0] = 6;
sprite->data[2] = sprite->x;
sprite->data[4] = sprite->y - 32;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Moves a projectile towards the target mon. The sprite is rotated to be pointing
// in the same direction it's moving.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
static void AnimSonicBoomProjectile(struct Sprite *sprite)
{
s16 targetXPos;
s16 targetYPos;
u16 rotation;
if (IsContest())
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
}
else if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
}
InitSpritePosToAnimAttacker(sprite, TRUE);
targetXPos = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
targetYPos = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
rotation = ArcTan2Neg(targetXPos - sprite->x, targetYPos - sprite->y);
rotation += 0xF000;
if (IsContest())
rotation -= 0x6000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = targetXPos;
sprite->data[4] = targetYPos;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimAirWaveProjectile_Step2(struct Sprite *sprite)
{
if (sprite->data[0]-- <= 0)
{
gTasks[sprite->data[7]].data[1]--;
DestroySprite(sprite);
}
}
static void AnimAirWaveProjectile_Step1(struct Sprite *sprite)
{
struct Task *task = &gTasks[sprite->data[7]];
if (sprite->data[0] > task->data[5])
{
sprite->data[5] += sprite->data[3];
sprite->data[6] += sprite->data[4];
}
else
{
sprite->data[5] -= sprite->data[3];
sprite->data[6] -= sprite->data[4];
}
sprite->data[1] += sprite->data[5];
sprite->data[2] += sprite->data[6];
if (1 & task->data[7])
sprite->x2 = ((u16)sprite->data[1] >> 8) * -1;
else
sprite->x2 = (u16)sprite->data[1] >> 8;
if (1 & task->data[8])
sprite->y2 = ((u16)sprite->data[2] / 256u) * -1;
else
sprite->y2 = (u16)sprite->data[2] / 256u;
if (sprite->data[0]-- <= 0)
{
sprite->data[0] = 30;
sprite->callback = AnimAirWaveProjectile_Step2;
}
}
static void AnimAirWaveProjectile(struct Sprite *sprite)
{
s16 a;
s16 b;
s16 c;
struct Task *task = &gTasks[sprite->data[7]];
sprite->data[1] += (-2 & task->data[7]);
sprite->data[2] += (-2 & task->data[8]);
if (1 & task->data[7])
sprite->x2 = ((u16)sprite->data[1] >> 8) * -1;
else
sprite->x2 = (u16)sprite->data[1] >> 8;
if (1 & task->data[8])
sprite->y2 = ((u16)sprite->data[2] / 256u) * -1;
else
sprite->y2 = (u16)sprite->data[2] / 256u;
if (sprite->data[0]-- <= 0)
{
sprite->data[0] = 8;
task->data[5] = 4;
a = MathUtil_Inv16(Q_8_8(16));
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
if (task->data[11] >= sprite->x)
b = (task->data[11] - sprite->x) << 8;
else
b = (sprite->x - task->data[11]) << 8;
if (task->data[12] >= sprite->y)
c = (task->data[12] - sprite->y) << 8;
else
c = (sprite->y - task->data[12]) << 8;
sprite->data[2] = 0;
sprite->data[1] = 0;
sprite->data[6] = 0;
sprite->data[5] = 0;
sprite->data[3] = MathUtil_Mul16(MathUtil_Mul16(b, a), MathUtil_Inv16(Q_8_8(1.75)));
sprite->data[4] = MathUtil_Mul16(MathUtil_Mul16(c, a), MathUtil_Inv16(Q_8_8(1.75)));
sprite->callback = AnimAirWaveProjectile_Step1;
}
}
static void AirCutterProjectileStep2(u8 taskId)
{
if (gTasks[taskId].data[1] == 0)
DestroyAnimVisualTask(taskId);
}
static void AirCutterProjectileStep1(u8 taskId)
{
if (gTasks[taskId].data[0]-- <= 0)
{
u8 spriteId;
struct Sprite *sprite;
spriteId = CreateSprite(&gAirWaveProjectileSpriteTemplate, gTasks[taskId].data[9], gTasks[taskId].data[10], gTasks[taskId].data[2] - gTasks[taskId].data[1]);
sprite = &gSprites[spriteId];
switch (gTasks[taskId].data[4])
{
case 1:
sprite->oam.matrixNum |= (ST_OAM_HFLIP | ST_OAM_VFLIP);
break;
case 2:
sprite->oam.matrixNum = ST_OAM_HFLIP;
break;
}
sprite->data[0] = gTasks[taskId].data[5] - gTasks[taskId].data[6];
sprite->data[7] = taskId;
gTasks[taskId].data[gTasks[taskId].data[1] + 13] = spriteId;
gTasks[taskId].data[0] = gTasks[taskId].data[3];
gTasks[taskId].data[1]++;
PlaySE12WithPanning(SE_M_BLIZZARD2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER + 1));
if (gTasks[taskId].data[1] > 2)
gTasks[taskId].func = AirCutterProjectileStep2;
}
}
void AnimTask_AirCutterProjectile(u8 taskId)
{
s16 attackerY = 0;
s16 attackerX = 0;
s16 targetX = 0;
s16 targetY = 0;
s16 xDiff, yDiff;
if (IsContest())
{
gTasks[taskId].data[4] = 2;
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
if (gBattleAnimArgs[2] & 1)
gBattleAnimArgs[2] &= ~1;
else
gBattleAnimArgs[2] |= 1;
}
else
{
if (GET_BATTLER_SIDE2(gBattleAnimTarget) == B_SIDE_PLAYER)
{
gTasks[taskId].data[4] = 1;
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
if (gBattleAnimArgs[2] & 1)
gBattleAnimArgs[2] &= ~1;
else
gBattleAnimArgs[2] |= 1;
}
}
attackerX = gTasks[taskId].data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
attackerY = gTasks[taskId].data[10] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
&& IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
{
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &targetX, &targetY);
}
else
{
targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
}
targetX = gTasks[taskId].data[11] = targetX + gBattleAnimArgs[0];
targetY = gTasks[taskId].data[12] = targetY + gBattleAnimArgs[1];
if (targetX >= attackerX)
xDiff = targetX - attackerX;
else
xDiff = attackerX - targetX;
gTasks[taskId].data[5] = MathUtil_Mul16(xDiff, MathUtil_Inv16(gBattleAnimArgs[2] & ~1));
gTasks[taskId].data[6] = MathUtil_Mul16(gTasks[taskId].data[5], Q_8_8(0.5));
gTasks[taskId].data[7] = gBattleAnimArgs[2];
if (targetY >= attackerY)
{
yDiff = targetY - attackerY;
gTasks[taskId].data[8] = MathUtil_Mul16(yDiff, MathUtil_Inv16(gTasks[taskId].data[5])) & ~1;
}
else
{
yDiff = attackerY - targetY;
gTasks[taskId].data[8] = MathUtil_Mul16(yDiff, MathUtil_Inv16(gTasks[taskId].data[5])) | 1;
}
gTasks[taskId].data[3] = gBattleAnimArgs[3];
if (gBattleAnimArgs[4] & 0x80)
{
gBattleAnimArgs[4] ^= 0x80;
if (gBattleAnimArgs[4] >= 64)
{
u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (gBattleAnimArgs[4] - 64);
gTasks[taskId].data[2] = var;
}
else
{
u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) - gBattleAnimArgs[4];
gTasks[taskId].data[2] = var;
}
}
else
{
if (gBattleAnimArgs[4] >= 64)
{
u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (gBattleAnimArgs[4] - 64);
gTasks[taskId].data[2] = var;
}
else
{
u16 var = GetBattlerSpriteSubpriority(gBattleAnimTarget) - gBattleAnimArgs[4];
gTasks[taskId].data[2] = var;
}
}
if (gTasks[taskId].data[2] < 3)
gTasks[taskId].data[2] = 3;
gTasks[taskId].func = AirCutterProjectileStep1;
}
static void AnimVoidLines(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[0] = 0x100 + (IndexOfSpritePaletteTag(sVoidLinesSpriteTemplate.paletteTag) << 4);
sprite->callback = AnimVoidLines_Step;
}
static void AnimVoidLines_Step(struct Sprite *sprite)
{
u16 id, val;
int i;
if (++sprite->data[1] == 2)
{
sprite->data[1] = 0;
id = sprite->data[0];
val = gPlttBufferFaded[8 + id];
for (i = 8; i < 16; i++)
gPlttBufferFaded[i + id] = gPlttBufferFaded[i + id + 1];
gPlttBufferFaded[id + 15] = val;
if (++sprite->data[2] == 24)
DestroyAnimSprite(sprite);
}
}
static void AnimCoinThrow(struct Sprite *sprite)
{
s16 r6;
s16 r7;
u16 var;
InitSpritePosToAnimAttacker(sprite, TRUE);
r6 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
r7 = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
r6 += gBattleAnimArgs[2];
var = ArcTan2Neg(r6 - sprite->x, r7 - sprite->y);
var += 0xC000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, var);
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = r6;
sprite->data[4] = r7;
sprite->callback = InitAnimLinearTranslationWithSpeedAndPos;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimFallingCoin(struct Sprite *sprite)
{
sprite->data[2] = -16;
sprite->y += 8;
sprite->callback = AnimFallingCoin_Step;
}
static void AnimFallingCoin_Step(struct Sprite *sprite)
{
sprite->data[0] += 0x80;
sprite->x2 = sprite->data[0] >> 8;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->x2 = -sprite->x2;
sprite->y2 = Sin(sprite->data[1], sprite->data[2]);
sprite->data[1] += 5;
if (sprite->data[1] > 126)
{
sprite->data[1] = 0;
sprite->data[2] /= 2;
if (++sprite->data[3] == 2)
DestroyAnimSprite(sprite);
}
}
static void AnimBulletSeed(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = 20;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
sprite->affineAnimPaused = 1;
StoreSpriteCallbackInData6(sprite, AnimBulletSeed_Step1);
}
static void AnimBulletSeed_Step1(struct Sprite *sprite)
{
int i;
u16 rand;
s16 *ptr;
PlaySE12WithPanning(SE_M_HORN_ATTACK, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
ptr = &sprite->data[7];
for (i = 0; i < 8; i++)
ptr[i - 7] = 0;
rand = Random2();
sprite->data[6] = 0xFFF4 - (rand & 7);
rand = Random2();
sprite->data[7] = (rand % 0xA0) + 0xA0;
sprite->callback = AnimBulletSeed_Step2;
sprite->affineAnimPaused = 0;
}
static void AnimBulletSeed_Step2(struct Sprite *sprite)
{
sprite->data[0] += sprite->data[7];
sprite->x2 = sprite->data[0] >> 8;
if (sprite->data[7] & 1)
sprite->x2 = -sprite->x2;
sprite->y2 = Sin(sprite->data[1], sprite->data[6]);
sprite->data[1] += 8;
if (sprite->data[1] > 126)
{
sprite->data[1] = 0;
sprite->data[2] /= 2;
if (++sprite->data[3] == 1)
DestroyAnimSprite(sprite);
}
}
// Moves a tornado in a circlular motion.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: wave amplitude
// arg 3: unused
// arg 4: initial wave offset
// arg 5: wave period (higher means faster wave)
// arg 6: duration
static void AnimRazorWindTornado(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->y += 16;
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[5];
sprite->data[3] = gBattleAnimArgs[6];
sprite->data[4] = gBattleAnimArgs[3];
sprite->callback = TranslateSpriteInCircle;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback(sprite);
}
// Animates a single pincer line that extends towards the center of the target mon.
// arg 0: invert
static void AnimViceGripPincer(struct Sprite *sprite)
{
s16 startXOffset = 32;
s16 startYOffset = -32;
s16 endXOffset = 16;
s16 endYOffset = -16;
if (gBattleAnimArgs[0])
{
startXOffset = -32;
startYOffset = 32;
endXOffset = -16;
endYOffset = 16;
StartSpriteAnim(sprite, 1);
}
sprite->x += startXOffset;
sprite->y += startYOffset;
sprite->data[0] = 6;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + endXOffset;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + endYOffset;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimViceGripPincer_Step);
}
static void AnimViceGripPincer_Step(struct Sprite *sprite)
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
// Animates a single pincer line that extends towards the center of the target mon, and then back out.
// arg 0: animation id
static void AnimGuillotinePincer(struct Sprite *sprite)
{
s16 startXOffset = 32;
s16 startYOffset = -32;
s16 endXOffset = 16;
s16 endYOffset = -16;
if (gBattleAnimArgs[0])
{
startXOffset = -32;
startYOffset = 32;
endXOffset = -16;
endYOffset = 16;
StartSpriteAnim(sprite, gBattleAnimArgs[0]);
}
sprite->x += startXOffset;
sprite->y += startYOffset;
sprite->data[0] = 6;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + endXOffset;
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + endYOffset;
InitAnimLinearTranslation(sprite);
sprite->data[5] = gBattleAnimArgs[0];
sprite->data[6] = sprite->data[0];
sprite->callback = AnimGuillotinePincer_Step1;
}
static void AnimGuillotinePincer_Step1(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite) && sprite->animEnded)
{
SeekSpriteAnim(sprite, 0);
sprite->animPaused = 1;
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 2;
sprite->y2 = -2;
sprite->data[0] = sprite->data[6];
sprite->data[1] ^= 1;
sprite->data[2] ^= 1;
sprite->data[4] = 0;
sprite->data[3] = 0;
sprite->callback = AnimGuillotinePincer_Step2;
}
}
static void AnimGuillotinePincer_Step2(struct Sprite *sprite)
{
if (sprite->data[3])
{
sprite->x2 = -sprite->x2;
sprite->y2 = -sprite->y2;
}
sprite->data[3] ^= 1;
if (++sprite->data[4] == 51)
{
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[4] = 0;
sprite->data[3] = 0;
sprite->animPaused = 0;
StartSpriteAnim(sprite, sprite->data[5] ^ 1);
sprite->callback = AnimGuillotinePincer_Step3;
}
}
static void AnimGuillotinePincer_Step3(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
DestroyAnimSprite(sprite);
}
// Scales up the target mon sprite, and sets the palette to grayscale.
// Used in MOVE_DISABLE.
// No args.
void AnimTask_GrowAndGrayscale(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
SetSpriteRotScale(spriteId, 0xD0, 0xD0, 0);
SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, FALSE);
gTasks[taskId].data[0] = 80;
gTasks[taskId].func = AnimTask_GrowAndGrayscale_Step;
}
static void AnimTask_GrowAndGrayscale_Step(u8 taskId)
{
if (--gTasks[taskId].data[0] == -1)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
ResetSpriteRotScale(spriteId);
SetGrayscaleOrOriginalPalette(gSprites[spriteId].oam.paletteNum + 16, TRUE);
DestroyAnimVisualTask(taskId);
}
}
// Shrinks and grows the attacking mon several times. Also creates transparent versions of the
// mon's sprite while it is shrinking.
// No args.
void AnimTask_Minimize(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[0] = spriteId;
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
task->data[4] = 0x100;
task->data[5] = 0;
task->data[6] = 0;
task->data[7] = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
task->func = AnimTask_Minimize_Step;
}
static void AnimTask_Minimize_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[1])
{
case 0:
if (task->data[2] == 0 || task->data[2] == 3 || task->data[2] == 6)
CreateMinimizeSprite(task, taskId);
task->data[2]++;
task->data[4] += 0x28;
SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0);
SetBattlerSpriteYOffsetFromYScale(task->data[0]);
if (task->data[2] == 32)
{
task->data[5]++;
task->data[1]++;
}
break;
case 1:
if (task->data[6] == 0)
{
if (task->data[5] == 3)
{
task->data[2] = 0;
task->data[1] = 3;
}
else
{
task->data[2] = 0;
task->data[3] = 0;
task->data[4] = 0x100;
SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0);
SetBattlerSpriteYOffsetFromYScale(task->data[0]);
task->data[1] = 2;
}
}
break;
case 2:
task->data[1] = 0;
break;
case 3:
if (++task->data[2] > 32)
{
task->data[2] = 0;
task->data[1]++;
}
break;
case 4:
task->data[2] += 2;
task->data[4] -= 0x50;
SetSpriteRotScale(task->data[0], task->data[4], task->data[4], 0);
SetBattlerSpriteYOffsetFromYScale(task->data[0]);
if (task->data[2] == 32)
{
task->data[2] = 0;
task->data[1]++;
}
break;
case 5:
ResetSpriteRotScale(task->data[0]);
gSprites[task->data[15]].y2 = 0;
DestroyAnimVisualTask(taskId);
break;
}
}
static void CreateMinimizeSprite(struct Task *task, u8 taskId)
{
u16 matrixNum;
s16 spriteId = CloneBattlerSpriteWithBlend(ANIM_ATTACKER);
if (spriteId >= 0)
{
if ((matrixNum = AllocOamMatrix()) == 0xFF)
{
DestroySpriteWithActiveSheet(&gSprites[spriteId]);
}
else
{
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
gSprites[spriteId].affineAnimPaused = TRUE;
gSprites[spriteId].oam.matrixNum = matrixNum;
gSprites[spriteId].subpriority = task->data[7] - task->data[3];
task->data[3]++;
task->data[6]++;
gSprites[spriteId].data[0] = 16;
gSprites[spriteId].data[1] = taskId;
gSprites[spriteId].data[2] = 6;
gSprites[spriteId].callback = ClonedMinizeSprite_Step;
SetSpriteRotScale(spriteId, task->data[4], task->data[4], 0);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
}
}
}
static void ClonedMinizeSprite_Step(struct Sprite *sprite)
{
if (--sprite->data[0] == 0)
{
gTasks[sprite->data[1]].data[sprite->data[2]]--;
FreeOamMatrix(sprite->oam.matrixNum);
DestroySpriteWithActiveSheet(sprite);
}
}
// Task to facilitate expanding and hopping effect seen in Splash.
// arg 0: anim battler
// arg 1: num hops
void AnimTask_Splash(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[1] == 0)
{
DestroyAnimVisualTask(taskId);
}
else
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
task->data[0] = spriteId;
task->data[1] = 0;
task->data[2] = gBattleAnimArgs[1];
task->data[3] = 0;
task->data[4] = 0;
PrepareAffineAnimInTaskData(task, spriteId, gSplashEffectAffineAnimCmds);
task->func = AnimTask_Splash_Step;
}
}
static void AnimTask_Splash_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[1])
{
case 0:
RunAffineAnimFromTaskData(task);
task->data[4] += 3;
gSprites[task->data[0]].y2 += task->data[4];
if (++task->data[3] > 7)
{
task->data[3] = 0;
task->data[1]++;
}
break;
case 1:
RunAffineAnimFromTaskData(task);
gSprites[task->data[0]].y2 += task->data[4];
if (++task->data[3] > 7)
{
task->data[3] = 0;
task->data[1]++;
}
break;
case 2:
if (task->data[4] != 0)
{
gSprites[task->data[0]].y2 -= 2;
task->data[4] -= 2;
}
else
task->data[1]++;
break;
case 3:
if (!RunAffineAnimFromTaskData(task))
{
if (--task->data[2] == 0)
{
gSprites[task->data[0]].y2 = 0;
DestroyAnimVisualTask(taskId);
}
else
{
PrepareAffineAnimInTaskData(task, task->data[0], gSplashEffectAffineAnimCmds);
task->data[1] = 0;
}
}
break;
}
}
// Grows, pauses, then shrinks the attacking mon.
// Used by MOVE_SWAGGER and MOVE_BULK_UP
// No args.
void AnimTask_GrowAndShrink(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
PrepareAffineAnimInTaskData(task, spriteId, gGrowAndShrinkAffineAnimCmds);
task->func = AnimTask_GrowAndShrink_Step;
}
static void AnimTask_GrowAndShrink_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (!RunAffineAnimFromTaskData(task))
DestroyAnimVisualTask(taskId);
}
// Animates a little puff of the mon's breath.
// Used by MOVE_SWAGGER and MOVE_BULK_UP
// No args.
static void AnimBreathPuff(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
StartSpriteAnim(sprite, 0);
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + 32;
sprite->data[1] = 64;
}
else
{
StartSpriteAnim(sprite, 1);
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - 32;
sprite->data[1] = -64;
}
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = 52;
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = 0;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteLinearFixedPoint;
}
// Animates an "angry" mark above a mon's head.
// arg 0: target mon (0 = attacker, 1 = target)
// arg 1: x pixel offset
// arg 2: y pixel offset
static void AnimAngerMark(struct Sprite *sprite)
{
u8 battler;
if (!gBattleAnimArgs[0])
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
gBattleAnimArgs[1] *= -1;
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
if (sprite->y < 8)
sprite->y = 8;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
// left/right movements
void AnimTask_ThrashMoveMonHorizontal(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[0] = spriteId;
task->data[1] = 0;
PrepareAffineAnimInTaskData(task, spriteId, gThrashMoveMonAffineAnimCmds);
task->func = AnimTask_ThrashMoveMonHorizontal_Step;
}
static void AnimTask_ThrashMoveMonHorizontal_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (!RunAffineAnimFromTaskData(task))
DestroyAnimVisualTask(taskId);
}
// up/down movements
void AnimTask_ThrashMoveMonVertical(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[1] = 0;
task->data[2] = 4;
task->data[3] = 7;
task->data[4] = 3;
task->data[5] = gSprites[task->data[0]].x;
task->data[6] = gSprites[task->data[0]].y;
task->data[7] = 0;
task->data[8] = 0;
task->data[9] = 2;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
task->data[2] *= -1;
task->func = AnimTask_ThrashMoveMonVertical_Step;
}
static void AnimTask_ThrashMoveMonVertical_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (++task->data[7] > 2)
{
task->data[7] = 0;
task->data[8]++;
if (task->data[8] & 1)
gSprites[task->data[0]].y += task->data[9];
else
gSprites[task->data[0]].y -= task->data[9];
}
switch (task->data[1])
{
case 0:
gSprites[task->data[0]].x += task->data[2];
if (--task->data[3] == 0)
{
task->data[3] = 14;
task->data[1] = 1;
}
break;
case 1:
gSprites[task->data[0]].x -= task->data[2];
if (--task->data[3] == 0)
{
task->data[3] = 7;
task->data[1] = 2;
}
break;
case 2:
gSprites[task->data[0]].x += task->data[2];
if (--task->data[3] == 0)
{
if (--task->data[4] != 0)
{
task->data[3] = 7;
task->data[1] = 0;
}
else
{
if ((task->data[8] & 1) != 0)
gSprites[task->data[0]].y -= task->data[9];
DestroyAnimVisualTask(taskId);
}
}
break;
}
}
void AnimTask_SketchDrawMon(u8 taskId)
{
struct Task *task = &gTasks[taskId];
struct ScanlineEffectParams params;
s16 i;
task->data[0] = GetBattlerYCoordWithElevation(gBattleAnimTarget) + 32;
task->data[1] = 4;
task->data[2] = 0;
task->data[3] = 0;
task->data[4] = 0;
task->data[5] = 0;
task->data[15] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT);
if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1)
{
task->data[6] = gBattle_BG1_X;
params.dmaDest = &REG_BG1HOFS;
}
else
{
task->data[6] = gBattle_BG2_X;
params.dmaDest = &REG_BG2HOFS;
}
for (i = task->data[0] - 0x40; i <= task->data[0]; i++)
{
if (i >= 0)
{
gScanlineEffectRegBuffers[0][i] = task->data[6] + 0xF0;
gScanlineEffectRegBuffers[1][i] = task->data[6] + 0xF0;
}
}
params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
params.initState = 1;
params.unused9 = 0;
ScanlineEffect_SetParams(params);
task->func = AnimTask_SketchDrawMon_Step;
}
static void AnimTask_SketchDrawMon_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[4])
{
case 0:
if (++task->data[5] > 20)
task->data[4]++;
break;
case 1:
if (++task->data[1] > 3)
{
task->data[1] = 0;
task->data[2] = task->data[3] & 3;
task->data[5] = task->data[0] - task->data[3];
switch (task->data[2])
{
case 0:
break;
case 1:
task->data[5] -= 2;
break;
case 2:
task->data[5] += 1;
break;
case 3:
task->data[5] += 1;
break;
}
if (task->data[5] >= 0)
{
gScanlineEffectRegBuffers[0][task->data[5]] = task->data[6];
gScanlineEffectRegBuffers[1][task->data[5]] = task->data[6];
}
if (++task->data[3] >= task->data[15])
{
gScanlineEffect.state = 3;
DestroyAnimVisualTask(taskId);
}
}
break;
}
}
static void AnimPencil(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) - 16;
sprite->y = GetBattlerYCoordWithElevation(gBattleAnimTarget) + 16;
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->data[3] = 16;
sprite->data[4] = 0;
sprite->data[5] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) + 2;
sprite->data[6] = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
sprite->callback = AnimPencil_Step;
}
static void AnimPencil_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (++sprite->data[2] > 1)
{
sprite->data[2] = 0;
sprite->invisible = !sprite->invisible;
}
if (++sprite->data[1] > 16)
{
sprite->invisible = FALSE;
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[1] > 3 && sprite->data[2] < sprite->data[5])
{
sprite->data[1] = 0;
sprite->y -= 1;
sprite->data[2]++;
if (sprite->data[2] % 10 == 0)
PlaySE12WithPanning(SE_M_SKETCH, sprite->data[6]);
}
sprite->data[4] += sprite->data[3];
if (sprite->data[4] > 31)
{
sprite->data[4] = 0x40 - sprite->data[4];
sprite->data[3] *= -1;
}
else if (sprite->data[4] <= -32)
{
sprite->data[4] = -0x40 - sprite->data[4];
sprite->data[3] *= -1;
}
sprite->x2 = sprite->data[4];
if (sprite->data[5] == sprite->data[2])
{
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->data[0]++;
}
break;
case 2:
if (++sprite->data[2] > 1)
{
sprite->data[2] = 0;
sprite->invisible = !sprite->invisible;
}
if (++sprite->data[1] > 16)
{
sprite->invisible = FALSE;
DestroyAnimSprite(sprite);
}
break;
}
}
static void AnimBlendThinRing(struct Sprite *sprite)
{
u8 battler = 0;
u16 sp0 = 0;
u16 sp1 = 0;
u8 r4;
if (gBattleAnimArgs[2] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
r4 = gBattleAnimArgs[3] ^ 1;
if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler)))
{
SetAverageBattlerPositions(battler, r4, &sp0, &sp1);
if (r4 == 0)
r4 = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
else
r4 = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
gBattleAnimArgs[0] -= (sp0 - r4) - gBattleAnimArgs[0]; // This is weird.
else
gBattleAnimArgs[0] = sp0 - r4;
}
sprite->callback = AnimSpriteOnMonPos;
sprite->callback(sprite);
}
static void AnimHyperVoiceRing_WaitEnd(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
{
FreeSpriteOamMatrix(sprite);
DestroyAnimSprite(sprite);
}
}
static void AnimHyperVoiceRing(struct Sprite *sprite)
{
u16 startX = 0;
u16 startY = 0;
s16 x = 0;
s16 y = 0;
u8 yCoordType;
u8 battler1;
u8 battler2;
u8 xCoordType;
if (gBattleAnimArgs[5] == 0)
{
battler1 = gBattleAnimAttacker;
battler2 = gBattleAnimTarget;
}
else
{
battler1 = gBattleAnimTarget;
battler2 = gBattleAnimAttacker;
}
if (!gBattleAnimArgs[6])
{
xCoordType = BATTLER_COORD_X;
yCoordType = BATTLER_COORD_Y;
}
else
{
xCoordType = BATTLER_COORD_X_2;
yCoordType = BATTLER_COORD_Y_PIC_OFFSET;
}
if (GetBattlerSide(battler1) != B_SIDE_PLAYER)
{
startX = GetBattlerSpriteCoord(battler1, xCoordType) + gBattleAnimArgs[0];
if (IsBattlerSpriteVisible(BATTLE_PARTNER(battler2)))
sprite->subpriority = gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler2)]].subpriority - 1;
else
sprite->subpriority = gSprites[gBattlerSpriteIds[battler2]].subpriority - 1;
}
else
{
startX = GetBattlerSpriteCoord(battler1, xCoordType) - gBattleAnimArgs[0];
if (!IsContest() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler1)))
{
if (gSprites[gBattlerSpriteIds[battler1]].x < gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler1)]].x)
sprite->subpriority = gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler1)]].subpriority + 1;
else
sprite->subpriority = gSprites[gBattlerSpriteIds[battler1]].subpriority - 1;
}
else
{
sprite->subpriority = gSprites[gBattlerSpriteIds[battler1]].subpriority - 1;
}
}
startY = GetBattlerSpriteCoord(battler1, yCoordType) + gBattleAnimArgs[1];
if (!IsContest() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler2)))
{
SetAverageBattlerPositions(battler2, gBattleAnimArgs[6], &x, &y);
}
else
{
x = GetBattlerSpriteCoord(battler2, xCoordType);
y = GetBattlerSpriteCoord(battler2, yCoordType);
}
if (GetBattlerSide(battler2))
x += gBattleAnimArgs[3];
else
x -= gBattleAnimArgs[3];
y += gBattleAnimArgs[4];
sprite->x = sprite->data[1] = startX;
sprite->y = sprite->data[3] = startY;
sprite->data[2] = x;
sprite->data[4] = y;
sprite->data[0] = gBattleAnimArgs[0];
InitAnimLinearTranslation(sprite);
sprite->callback = AnimHyperVoiceRing_WaitEnd;
sprite->callback(sprite);
}
static void AnimUproarRing(struct Sprite *sprite)
{
u8 index = IndexOfSpritePaletteTag(ANIM_TAG_THIN_RING);
if (index != 0xFF)
{
BlendPalette((OBJ_PLTT_ID(index) + 1), 15, gBattleAnimArgs[5], gBattleAnimArgs[4]);
}
StartSpriteAffineAnim(sprite, 1);
sprite->callback = AnimSpriteOnMonPos;
sprite->callback(sprite);
}
static void AnimSoftBoiledEgg(struct Sprite *sprite)
{
s16 r1;
InitSpritePosToAnimAttacker(sprite, FALSE);
r1 = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? -160 : 160;
sprite->data[0] = 0x380;
sprite->data[1] = r1;
sprite->data[7] = gBattleAnimArgs[2];
sprite->callback = AnimSoftBoiledEgg_Step1;
}
static void AnimSoftBoiledEgg_Step1(struct Sprite *sprite)
{
s16 add;
sprite->y2 -= (sprite->data[0] >> 8);
sprite->x2 = sprite->data[1] >> 8;
sprite->data[0] -= 32;
add = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? -160 : 160;
sprite->data[1] += add;
if (sprite->y2 > 0)
{
sprite->y += sprite->y2;
sprite->x += sprite->x2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 0;
StartSpriteAffineAnim(sprite, 1);
sprite->callback = AnimSoftBoiledEgg_Step2;
}
}
static void AnimSoftBoiledEgg_Step2(struct Sprite *sprite)
{
if (sprite->data[0]++ > 19)
{
StartSpriteAffineAnim(sprite, 2);
sprite->callback = AnimSoftBoiledEgg_Step3;
}
}
static void AnimSoftBoiledEgg_Step3(struct Sprite *sprite)
{
if (sprite->affineAnimEnded)
{
StartSpriteAffineAnim(sprite, 1);
sprite->data[0] = 0;
if (sprite->data[7] == 0)
{
sprite->oam.tileNum += 16;
sprite->callback = AnimSoftBoiledEgg_Step3_Callback1;
}
else
{
sprite->oam.tileNum += 32;
sprite->callback = AnimSoftBoiledEgg_Step4;
}
}
}
static void AnimSoftBoiledEgg_Step3_Callback1(struct Sprite *sprite)
{
sprite->y2 -= 2;
if (++sprite->data[0] == 9)
{
sprite->data[0] = 16;
sprite->data[1] = 0;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND((u16)sprite->data[0], 0));
sprite->callback = AnimSoftBoiledEgg_Step3_Callback2;
}
}
static void AnimSoftBoiledEgg_Step3_Callback2(struct Sprite *sprite)
{
if (sprite->data[1]++ % 3 == 0)
{
sprite->data[0]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0]));
if (sprite->data[0] == 0)
sprite->callback = AnimSoftBoiledEgg_Step4;
}
}
static void AnimSoftBoiledEgg_Step4(struct Sprite *sprite)
{
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
{
sprite->invisible = TRUE;
if (sprite->data[7] == 0)
sprite->callback = AnimSoftBoiledEgg_Step4_Callback;
else
sprite->callback = DestroyAnimSprite;
}
}
static void AnimSoftBoiledEgg_Step4_Callback(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
// Used by Extremespeed
void AnimTask_AttackerStretchAndDisappear(u8 taskId)
{
struct Task *task = &gTasks[taskId];
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[0] = spriteId;
PrepareAffineAnimInTaskData(task, spriteId, gStretchAttackerAffineAnimCmds);
task->func = AnimTask_AttackerStretchAndDisappear_Step;
}
static void AnimTask_AttackerStretchAndDisappear_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (!RunAffineAnimFromTaskData(task))
{
gSprites[task->data[0]].y2 = 0;
gSprites[task->data[0]].invisible = TRUE;
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_ExtremeSpeedImpact(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
task->data[12] = 3;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
task->data[13] = 0xFFFF;
task->data[14] = 8;
}
else
{
task->data[13] = 1;
task->data[14] = -8;
}
task->data[15] = GetAnimBattlerSpriteId(ANIM_TARGET);
task->func = AnimTask_ExtremeSpeedImpact_Step;
}
static void AnimTask_ExtremeSpeedImpact_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
gSprites[task->data[15]].x2 += task->data[14];
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
task->data[0]++;
break;
case 1:
if (++task->data[1] > 1)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
gSprites[task->data[15]].x2 += 6;
else
gSprites[task->data[15]].x2 -= 6;
if (++task->data[3] > 4)
{
if (task->data[2] & 1)
gSprites[task->data[15]].x2 -= 6;
task->data[0]++;
}
}
break;
case 2:
if (--task->data[12] != 0)
task->data[0] = 0;
else
task->data[0]++;
break;
case 3:
gSprites[task->data[15]].x2 += task->data[13];
if (gSprites[task->data[15]].x2 == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
void AnimTask_ExtremeSpeedMonReappear(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
task->data[4] = 1;
task->data[13] = 14;
task->data[14] = 2;
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->func = AnimTask_ExtremeSpeedMonReappear_Step;
}
static void AnimTask_ExtremeSpeedMonReappear_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (task->data[0] == 0 && ++task->data[1] > task->data[4])
{
task->data[1] = 0;
if (++task->data[2] & 1)
gSprites[task->data[15]].invisible = FALSE;
else
gSprites[task->data[15]].invisible = TRUE;
if (++task->data[3] >= task->data[13])
{
if (++task->data[4] < task->data[14])
{
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
}
else
{
gSprites[task->data[15]].invisible = FALSE;
DestroyAnimVisualTask(taskId);
}
}
}
}
void AnimTask_SpeedDust(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 4;
task->data[2] = 0;
task->data[3] = 0;
task->data[4] = 0;
task->data[5] = 0;
task->data[6] = 0;
task->data[7] = 0;
task->data[8] = 0;
task->data[13] = 0;
task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
task->data[15] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
task->func = AnimTask_SpeedDust_Step;
}
static void AnimTask_SpeedDust_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[8])
{
case 0:
if (++task->data[4] > 1)
{
task->data[4] = 0;
task->data[5] = (task->data[5] + 1) & 1;
if (++task->data[6] > 20)
{
if (task->data[7] == 0)
{
task->data[6] = 0;
task->data[8] = 1;
}
else
task->data[8] = 2;
}
}
break;
case 1:
task->data[5] = 0;
if (++task->data[4] > 20)
{
task->data[7] = 1;
task->data[8] = 0;
}
break;
case 2:
task->data[5] = 1;
break;
}
switch (task->data[0])
{
case 0:
if (++task->data[1] > 4)
{
u8 spriteId;
task->data[1] = 0;
spriteId = CreateSprite(&gSpeedDustSpriteTemplate, task->data[14], task->data[15], 0);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[0] = taskId;
gSprites[spriteId].data[1] = 13;
gSprites[spriteId].x2 = gSpeedDustPosTable[task->data[2]][0];
gSprites[spriteId].y2 = gSpeedDustPosTable[task->data[2]][1];
task->data[13]++;
if (++task->data[2] > 3)
{
task->data[2] = 0;
if (++task->data[3] > 5)
task->data[0]++;
}
}
}
break;
case 1:
if (task->data[13] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimSpeedDust(struct Sprite *sprite)
{
sprite->invisible = gTasks[sprite->data[0]].data[5];
if (sprite->animEnded)
{
gTasks[sprite->data[0]].data[sprite->data[1]]--;
DestroySprite(sprite);
}
}
void AnimTask_LoadMusicNotesPals(u8 taskId)
{
int i;
u8 paletteNums[NUM_MUSIC_NOTE_PAL_TAGS];
paletteNums[0] = IndexOfSpritePaletteTag(ANIM_TAG_MUSIC_NOTES_2);
for (i = 1; i < NUM_MUSIC_NOTE_PAL_TAGS; i++)
paletteNums[i] = AllocSpritePalette(ANIM_SPRITES_START - i);
gMonSpritesGfxPtr->buffer = AllocZeroed(MON_PIC_SIZE * MAX_MON_PIC_FRAMES);
LZDecompressWram(gBattleAnimSpritePal_MusicNotes2, gMonSpritesGfxPtr->buffer);
for (i = 0; i < NUM_MUSIC_NOTE_PAL_TAGS; i++)
LoadPalette(&gMonSpritesGfxPtr->buffer[i * 32], (u16)(OBJ_PLTT_ID(paletteNums[i])), PLTT_SIZE_4BPP);
FREE_AND_SET_NULL(gMonSpritesGfxPtr->buffer);
DestroyAnimVisualTask(taskId);
}
void AnimTask_FreeMusicNotesPals(u8 taskId)
{
int i;
for (i = 0; i < NUM_MUSIC_NOTE_PAL_TAGS; i++)
FreeSpritePaletteByTag(sMusicNotePaletteTagsTable[i]);
DestroyAnimVisualTask(taskId);
}
static void SetMusicNotePalette(struct Sprite *sprite, u8 a, u8 b)
{
u8 tile = (b & 1) ? 32 : 0;
sprite->oam.tileNum += tile + (a << 2);
sprite->oam.paletteNum = IndexOfSpritePaletteTag(sMusicNotePaletteTagsTable[b >> 1]);
}
static void AnimHealBellMusicNote(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[3];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
SetMusicNotePalette(sprite, gBattleAnimArgs[5], gBattleAnimArgs[6]);
}
static void AnimMagentaHeart(struct Sprite *sprite)
{
if (++sprite->data[0] == 1)
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->x2 = Sin(sprite->data[1], 8);
sprite->y2 = sprite->data[2] >> 8;
sprite->data[1] = (sprite->data[1] + 7) & 0xFF;
sprite->data[2] -= 0x80;
if (sprite->data[0] == 60)
DestroyAnimSprite(sprite);
}
void AnimTask_FakeOut(u8 taskId)
{
u16 win0h = IsContest() ? 152 : DISPLAY_WIDTH;
u16 win0v = 0;
gBattle_WIN0H = win0h;
gBattle_WIN0V = DISPLAY_HEIGHT;
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_ALL);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_ALL | WINOUT_WINOBJ_ALL);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_DARKEN);
SetGpuReg(REG_OFFSET_BLDY, 16);
gTasks[taskId].data[0] = win0v;
gTasks[taskId].data[1] = win0h;
gTasks[taskId].func = AnimTask_FakeOut_Step1;
}
static void AnimTask_FakeOut_Step1(u8 taskId)
{
gTasks[taskId].data[0] += 13;
gTasks[taskId].data[1] -= 13;
if (gTasks[taskId].data[0] >= gTasks[taskId].data[1])
{
gBattle_WIN0H = 0;
gTasks[taskId].func = AnimTask_FakeOut_Step2;
}
else
{
gBattle_WIN0H = WIN_RANGE(gTasks[taskId].data[0], gTasks[taskId].data[1]);
}
}
static void AnimTask_FakeOut_Step2(u8 taskId)
{
if (++gTasks[taskId].data[10] == 5)
{
gTasks[taskId].data[11] = 0x88;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_LIGHTEN);
BlendPalettes(GetBattlePalettesMask(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), 16, RGB(31, 31, 31));
}
else if (gTasks[taskId].data[10] > 4)
{
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_StretchTargetUp(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
if (++gTasks[taskId].data[0] == 1)
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_TARGET), sAffineAnims_StretchBattlerUp);
gSprites[spriteId].x2 = 4;
}
else
{
gSprites[spriteId].x2 = -gSprites[spriteId].x2;
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
{
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
}
}
}
void AnimTask_StretchAttackerUp(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
if (++gTasks[taskId].data[0] == 1)
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), sAffineAnims_StretchBattlerUp);
gSprites[spriteId].x2 = 4;
}
else
{
gSprites[spriteId].x2 = -gSprites[spriteId].x2;
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
{
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
}
}
}
static void AnimRedHeartProjectile(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = 95;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->callback = AnimRedHeartProjectile_Step;
}
static void AnimRedHeartProjectile_Step(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->y2 += Sin(sprite->data[5], 14);
sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
void AnimParticleBurst(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[0]++;
}
else
{
sprite->data[4] += sprite->data[1];
sprite->x2 = sprite->data[4] >> 8;
sprite->y2 = Sin(sprite->data[3], sprite->data[2]);
sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
if (sprite->data[3] > 100)
sprite->invisible = sprite->data[3] % 2;
if (sprite->data[3] > 120)
DestroyAnimSprite(sprite);
}
}
static void AnimRedHeartRising(struct Sprite *sprite)
{
sprite->x = gBattleAnimArgs[0];
sprite->y = DISPLAY_HEIGHT;
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[1];
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimRedHeartRising_Step);
}
static void AnimRedHeartRising_Step(struct Sprite *sprite)
{
s16 y;
sprite->data[2] += sprite->data[1];
sprite->y2 = -((u16)sprite->data[2] >> 8);
sprite->x2 = Sin(sprite->data[3], 4);
sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
y = sprite->y + sprite->y2;
if (y <= 72)
{
sprite->invisible = sprite->data[3] % 2;
if (y <= 64)
DestroyAnimSprite(sprite);
}
}
void AnimTask_HeartsBackground(u8 taskId)
{
struct BattleAnimBgData animBg;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 3);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_Attract, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimBgTilemap_Attract, FALSE);
LoadCompressedPalette(gBattleAnimBgPalette_Attract, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].func = AnimTask_HeartsBackground_Step;
}
static void AnimTask_HeartsBackground_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 16)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 141)
{
gTasks[taskId].data[11] = 16;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
gTasks[taskId].data[12]++;
break;
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}
void AnimTask_ScaryFace(u8 taskId)
{
struct BattleAnimBgData animBg;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
if (IsContest())
AnimLoadCompressedBgTilemapHandleContest(&animBg, &gBattleAnimBgTilemap_ScaryFaceContest, FALSE);
else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT)
AnimLoadCompressedBgTilemapHandleContest(&animBg, &gBattleAnimBgTilemap_ScaryFacePlayer, FALSE);
else
AnimLoadCompressedBgTilemapHandleContest(&animBg, &gBattleAnimBgTilemap_ScaryFaceOpponent, FALSE);
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_ScaryFace, animBg.tilesOffset);
LoadCompressedPalette(gBattleAnimBgPalette_ScaryFace, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].func = AnimTask_ScaryFace_Step;
}
static void AnimTask_ScaryFace_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 2)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 14)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 21)
{
gTasks[taskId].data[11] = 14;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 2)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(1);
ClearBattleAnimBg(2);
gTasks[taskId].data[12]++;
// fall through
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}
// Orbits a sphere in an ellipse around the mon.
// Used by MOVE_HIDDEN_POWER
// arg 0: duration
// arg 1: initial wave offset
static void AnimOrbitFast(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->affineAnimPaused = 1;
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[7] = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
sprite->callback = AnimOrbitFast_Step;
sprite->callback(sprite);
}
static void AnimOrbitFast_Step(struct Sprite *sprite)
{
if (sprite->data[1] >= 64 && sprite->data[1] <= 191)
sprite->subpriority = sprite->data[7] + 1;
else
sprite->subpriority = sprite->data[7] - 1;
sprite->x2 = Sin(sprite->data[1], sprite->data[2] >> 8);
sprite->y2 = Cos(sprite->data[1], sprite->data[3] >> 8);
sprite->data[1] = (sprite->data[1] + 9) & 0xFF;
switch (sprite->data[5])
{
case 1:
sprite->data[2] -= 0x400;
sprite->data[3] -= 0x100;
if (++sprite->data[4] == sprite->data[0])
{
sprite->data[5] = 2;
return;
}
break;
case 0:
sprite->data[2] += 0x400;
sprite->data[3] += 0x100;
if (++sprite->data[4] == sprite->data[0])
{
sprite->data[4] = 0;
sprite->data[5] = 1;
}
break;
}
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
DestroyAnimSprite(sprite);
}
// Moves orbs away from the mon, based on where they are in their orbit.
// Used in MOVE_HIDDEN_POWER.
// arg 0: initial wave offset
static void AnimOrbitScatter(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = Sin(gBattleAnimArgs[0], 10);
sprite->data[1] = Cos(gBattleAnimArgs[0], 7);
sprite->callback = AnimOrbitScatter_Step;
}
static void AnimOrbitScatter_Step(struct Sprite *sprite)
{
sprite->x2 += sprite->data[0];
sprite->y2 += sprite->data[1];
if (sprite->x + sprite->x2 + 16 > ((u32)DISPLAY_WIDTH + 32)
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT || sprite->y + sprite->y2 < -16)
DestroyAnimSprite(sprite);
}
static void AnimSpitUpOrb_Step(struct Sprite *sprite)
{
sprite->x2 += sprite->data[0];
sprite->y2 += sprite->data[1];
if (sprite->data[3]++ >= sprite->data[2])
DestroyAnimSprite(sprite);
}
static void AnimSpitUpOrb(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = Sin(gBattleAnimArgs[0], 10);
sprite->data[1] = Cos(gBattleAnimArgs[0], 7);
sprite->data[2] = gBattleAnimArgs[1];
sprite->callback = AnimSpitUpOrb_Step;
}
static void AnimEyeSparkle_Step(struct Sprite *sprite)
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimEyeSparkle(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->callback = AnimEyeSparkle_Step;
}
static void AnimAngel(struct Sprite *sprite)
{
s16 var0;
if (!sprite->data[0])
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->data[0]++;
var0 = (sprite->data[0] * 10) & 0xFF;
sprite->x2 = Sin(var0, 80) >> 8;
if (sprite->data[0] < 80)
sprite->y2 = (sprite->data[0] / 2) + (Cos(var0, 80) >> 8);
if (sprite->data[0] > 90)
{
sprite->data[2]++;
sprite->x2 -= sprite->data[2] / 2;
}
if (sprite->data[0] > 100)
DestroyAnimSprite(sprite);
}
static void AnimPinkHeart_Step(struct Sprite *sprite)
{
sprite->data[5]++;
sprite->x2 = Sin(sprite->data[3], 5);
sprite->y2 = sprite->data[5] / 2;
sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
if (sprite->data[5] > 20)
sprite->invisible = sprite->data[5] % 2;
if (sprite->data[5] > 30)
DestroyAnimSprite(sprite);
}
static void AnimPinkHeart(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
sprite->data[0]++;
}
else
{
sprite->data[4] += sprite->data[1];
sprite->x2 = sprite->data[4] >> 8;
sprite->y2 = Sin(sprite->data[3], sprite->data[2]);
sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
if (sprite->data[3] > 70)
{
sprite->callback = AnimPinkHeart_Step;
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[3] = Random2() % 180;
}
}
}
static void AnimDevil(struct Sprite *sprite)
{
if (sprite->data[3] == 0)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
StartSpriteAnim(sprite, 0);
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 1;
sprite->data[2] = 1;
}
sprite->data[0] += sprite->data[2];
sprite->data[1] = (sprite->data[0] * 4) % 256;
if (sprite->data[1] < 0)
sprite->data[1] = 0;
sprite->x2 = Cos(sprite->data[1], 30 - sprite->data[0] / 4);
sprite->y2 = Sin(sprite->data[1], 10 - sprite->data[0] / 8);
if (sprite->data[1] > 128 && sprite->data[2] > 0)
sprite->data[2] = -1;
if (sprite->data[1] == 0 && sprite->data[2] < 0)
sprite->data[2] = 1;
sprite->data[3]++;
if (sprite->data[3] < 10 || sprite->data[3] > 80)
sprite->invisible = sprite->data[0] % 2;
else
sprite->invisible = FALSE;
if (sprite->data[3] > 90)
DestroyAnimSprite(sprite);
}
static void AnimFurySwipes(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
StartSpriteAnim(sprite, gBattleAnimArgs[2]);
sprite->data[0]++;
}
else if (sprite->animEnded)
{
DestroyAnimSprite(sprite);
}
}
static void AnimMovementWaves(struct Sprite *sprite)
{
if (!gBattleAnimArgs[2])
{
DestroyAnimSprite(sprite);
}
else
{
if (!gBattleAnimArgs[0])
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
if (!gBattleAnimArgs[1])
sprite->x += 32;
else
sprite->x -= 32;
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[1];
StartSpriteAnim(sprite, sprite->data[1]);
sprite->callback = AnimMovementWaves_Step;
}
}
static void AnimMovementWaves_Step(struct Sprite *sprite)
{
if (sprite->animEnded)
{
if (--sprite->data[0])
StartSpriteAnim(sprite, sprite->data[1]);
else
DestroyAnimSprite(sprite);
}
}
void AnimTask_UproarDistortion(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareAffineAnimInTaskData(&gTasks[taskId], spriteId, sAffineAnims_UproarDistortion);
gTasks[taskId].func = AnimTask_UproarDistortion_Step;
}
static void AnimTask_UproarDistortion_Step(u8 taskId)
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
static void AnimJaggedMusicNote(struct Sprite *sprite)
{
int var1;
u8 battler = !gBattleAnimArgs[0] ? gBattleAnimAttacker : gBattleAnimTarget;
if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
gBattleAnimArgs[1] *= -1;
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
sprite->data[0] = 0;
sprite->data[1] = (u16)sprite->x << 3;
sprite->data[2] = (u16)sprite->y << 3;
var1 = gBattleAnimArgs[1] << 3;
if (var1 < 0)
var1 += 7;
sprite->data[3] = var1 >> 3;
var1 = gBattleAnimArgs[2] << 3;
if (var1 < 0)
var1 += 7;
sprite->data[4] = var1 >> 3;
sprite->oam.tileNum += gBattleAnimArgs[3] * 16;
sprite->callback = AnimJaggedMusicNote_Step;
}
static void AnimJaggedMusicNote_Step(struct Sprite *sprite)
{
sprite->data[1] += sprite->data[3];
sprite->data[2] += sprite->data[4];
sprite->x = sprite->data[1] >> 3;
sprite->y = sprite->data[2] >> 3;
if (++sprite->data[0] > 16)
DestroyAnimSprite(sprite);
}
static void AnimPerishSongMusicNote2(struct Sprite *sprite)
{
if (!sprite->data[0])
{
sprite->data[1] = 120 - gBattleAnimArgs[0];
sprite->invisible = TRUE;
}
if (++sprite->data[0] == sprite->data[1])
SetGrayscaleOrOriginalPalette(sprite->oam.paletteNum + 16, FALSE);
if (sprite->data[0] == sprite->data[1] + 80)
DestroyAnimSprite(sprite);
}
static void AnimPerishSongMusicNote(struct Sprite *sprite)
{
int index;
int var2;
if (!sprite->data[0])
{
sprite->x = 120;
sprite->y = (gBattleAnimArgs[0] + (((u16)gBattleAnimArgs[0]) >> 31)) / 2 - 15;
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
sprite->data[5] = 120;
sprite->data[3] = gBattleAnimArgs[2];
}
sprite->data[0]++;
sprite->data[1] = (sprite->data[0] + ((u16)sprite->data[0] >> 31)) / 2;
index = ((sprite->data[0] * 3) + (u16)sprite->data[3]);
var2 = 0xFF;
sprite->data[6] = (sprite->data[6] + 10) & 0xFF;
index &= var2;
sprite->x2 = Cos(index, 100);
sprite->y2 = sprite->data[1] + Sin(index, 10) + Cos(sprite->data[6], 4);
if (sprite->data[0] > sprite->data[5])
{
sprite->callback = AnimPerishSongMusicNote_Step1;
sprite->data[0] = 0;
SetSpritePrimaryCoordsFromSecondaryCoords(sprite);
sprite->data[2] = 5;
sprite->data[4] = 0;
sprite->data[3] = 0;
StartSpriteAffineAnim(sprite, 1);
}
}
static void AnimPerishSongMusicNote_Step1(struct Sprite *sprite)
{
if (++sprite->data[0] > 10)
{
sprite->data[0] = 0;
sprite->callback = AnimPerishSongMusicNote_Step2;
}
}
static void AnimPerishSongMusicNote_Step2(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[2];
sprite->y2 = sprite->data[3];
sprite->data[2]++;
if (sprite->data[3] > 48 && sprite->data[2] > 0)
{
sprite->data[2] = sprite->data[4] - 5;
sprite->data[4]++;
}
if (sprite->data[4] > 3)
{
sprite->invisible = sprite->data[2] % 2;
DestroyAnimSprite(sprite);
}
if (sprite->data[4] == 4)
{
DestroyAnimSprite(sprite);
}
}
static void AnimGuardRing(struct Sprite *sprite)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
{
SetAverageBattlerPositions(gBattleAnimAttacker, FALSE, &sprite->x, &sprite->y);
sprite->y += 40;
StartSpriteAffineAnim(sprite, 1);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 40;
}
sprite->data[0] = 13;
sprite->data[2] = sprite->x;
sprite->data[4] = sprite->y - 72;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
void AnimTask_IsFuryCutterHitRight(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = gAnimDisableStructPtr->furyCutterCounter & 1;
DestroyAnimVisualTask(taskId);
}
void AnimTask_GetFuryCutterHitCount(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = gAnimDisableStructPtr->furyCutterCounter;
DestroyAnimVisualTask(taskId);
}
#include "global.h"
#include "malloc.h"
#include "battle_anim.h"
#include "battle_interface.h"
#include "decompress.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "main.h"
#include "math_util.h"
#include "palette.h"
#include "random.h"
#include "scanline_effect.h"
#include "sound.h"
#include "trig.h"
#include "util.h"
#include "constants/rgb.h"
#include "constants/songs.h"
struct {
s16 startX;
s16 startY;
s16 targetX;
s16 targetY;
} static EWRAM_DATA sFrenzyPlantRootData = {0}; // Debug? Written to but never read.
static void AnimMovePowderParticle(struct Sprite *);
static void AnimMovePowderParticle_Step(struct Sprite *);
static void AnimPowerAbsorptionOrb(struct Sprite *);
static void AnimSolarBeamBigOrb(struct Sprite *);
static void AnimSolarBeamSmallOrb(struct Sprite *);
static void AnimSolarBeamSmallOrb_Step(struct Sprite *);
static void AnimAbsorptionOrb(struct Sprite *);
static void AnimAbsorptionOrb_Step(struct Sprite *);
static void AnimHyperBeamOrb(struct Sprite *);
static void AnimHyperBeamOrb_Step(struct Sprite *);
static void AnimSporeParticle(struct Sprite *);
static void AnimSporeParticle_Step(struct Sprite *);
static void AnimPetalDanceBigFlower(struct Sprite *);
static void AnimPetalDanceBigFlower_Step(struct Sprite *);
static void AnimPetalDanceSmallFlower(struct Sprite *);
static void AnimPetalDanceSmallFlower_Step(struct Sprite *);
static void AnimRazorLeafParticle(struct Sprite *);
static void AnimRazorLeafParticle_Step1(struct Sprite *);
static void AnimRazorLeafParticle_Step2(struct Sprite *);
static void AnimLeechSeed(struct Sprite *);
static void AnimLeechSeed_Step(struct Sprite *);
static void AnimLeechSeedSprouts(struct Sprite *);
static void AnimTranslateLinearSingleSineWave(struct Sprite *);
static void AnimTranslateLinearSingleSineWave_Step(struct Sprite *);
static void AnimConstrictBinding(struct Sprite *);
static void AnimConstrictBinding_Step1(struct Sprite *);
static void AnimConstrictBinding_Step2(struct Sprite *);
static void AnimMimicOrb(struct Sprite *);
static void AnimIngrainRoot(struct Sprite *);
static void AnimFrenzyPlantRoot(struct Sprite *);
static void AnimRootFlickerOut(struct Sprite *);
static void AnimIngrainOrb(struct Sprite *);
static void AnimPresent(struct Sprite *);
static void AnimKnockOffItem(struct Sprite *);
static void AnimPresentHealParticle(struct Sprite *);
static void AnimItemSteal(struct Sprite *);
static void AnimItemSteal_Step1(struct Sprite *);
static void AnimItemSteal_Step2(struct Sprite *);
static void AnimItemSteal_Step3(struct Sprite *);
static void AnimTrickBag(struct Sprite *);
static void AnimTrickBag_Step1(struct Sprite *);
static void AnimTrickBag_Step2(struct Sprite *);
static void AnimTrickBag_Step3(struct Sprite *);
static void AnimFlyingParticle(struct Sprite *);
static void AnimFlyingParticle_Step(struct Sprite *);
static void AnimNeedleArmSpike(struct Sprite *);
static void AnimNeedleArmSpike_Step(struct Sprite *);
static void AnimSlidingHit(struct Sprite *);
static void AnimWhipHit(struct Sprite *);
static void AnimFlickeringPunch(struct Sprite *);
static void AnimCuttingSlice(struct Sprite *);
static void AnimAirCutterSlice(struct Sprite *);
static void AnimSlice_Step(struct Sprite *);
static void AnimCirclingMusicNote(struct Sprite *);
static void AnimCirclingMusicNote_Step(struct Sprite *);
static void AnimProtect(struct Sprite *);
static void AnimProtect_Step(struct Sprite *);
static void AnimMilkBottle(struct Sprite *);
static void AnimMilkBottle_Step1(struct Sprite *);
static void AnimMilkBottle_Step2(struct Sprite *, int, int);
static void AnimGrantingStars(struct Sprite *);
static void AnimSparklingStars(struct Sprite *);
static void AnimBubbleBurst(struct Sprite *);
static void AnimBubbleBurst_Step(struct Sprite *);
static void AnimSleepLetterZ(struct Sprite *);
static void AnimSleepLetterZ_Step(struct Sprite *);
static void AnimLockOnTarget(struct Sprite *);
static void AnimLockOnTarget_Step1(struct Sprite *);
static void AnimLockOnTarget_Step2(struct Sprite *);
static void AnimLockOnTarget_Step3(struct Sprite *);
static void AnimLockOnTarget_Step4(struct Sprite *);
static void AnimLockOnTarget_Step5(struct Sprite *);
static void AnimLockOnTarget_Step6(struct Sprite *);
static void AnimLockOnMoveTarget(struct Sprite *);
static void AnimBowMon(struct Sprite *);
static void AnimBowMon_Step1(struct Sprite *);
static void AnimBowMon_Step1_Callback(struct Sprite *);
static void AnimBowMon_Step2(struct Sprite *);
static void AnimBowMon_Step3(struct Sprite *);
static void AnimBowMon_Step4(struct Sprite *);
static void AnimBowMon_Step3_Callback(struct Sprite *);
static void AnimTipMon(struct Sprite *);
static void AnimTipMon_Step(struct Sprite *);
static void AnimSlashSlice(struct Sprite *);
static void AnimFalseSwipeSlice(struct Sprite *);
static void AnimFalseSwipeSlice_Step1(struct Sprite *);
static void AnimFalseSwipeSlice_Step2(struct Sprite *);
static void AnimFalseSwipeSlice_Step3(struct Sprite *);
static void AnimFalseSwipePositionedSlice(struct Sprite *);
static void AnimEndureEnergy(struct Sprite *);
static void AnimEndureEnergy_Step(struct Sprite *);
static void AnimSharpenSphere(struct Sprite *);
static void AnimSharpenSphere_Step(struct Sprite *);
static void AnimConversion(struct Sprite *);
static void AnimConversion2(struct Sprite *);
static void AnimConversion2_Step(struct Sprite *);
static void AnimMoon(struct Sprite *);
static void AnimMoon_Step(struct Sprite *);
static void AnimMoonlightSparkle(struct Sprite *);
static void AnimMoonlightSparkle_Step(struct Sprite *);
static void AnimHornHit(struct Sprite *);
static void AnimHornHit_Step(struct Sprite *);
static void AnimSuperFang(struct Sprite *);
static void AnimWavyMusicNotes(struct Sprite *);
static void AnimWavyMusicNotes_Step(struct Sprite *);
static void AnimWavyMusicNotes_CalcVelocity(s16, s16, s16 *, s16 *, s8);
static void AnimFlyingMusicNotes(struct Sprite *);
static void AnimFlyingMusicNotes_Step(struct Sprite *);
static void AnimBellyDrumHand(struct Sprite *);
static void AnimSlowFlyingMusicNotes(struct Sprite *);
static void AnimSlowFlyingMusicNotes_Step(struct Sprite *);
static void AnimThoughtBubble(struct Sprite *);
static void AnimThoughtBubble_Step(struct Sprite *);
static void AnimMetronomeFinger(struct Sprite *);
static void AnimMetronomeFinger_Step(struct Sprite *);
static void AnimFollowMeFinger(struct Sprite *);
static void AnimFollowMeFinger_Step1(struct Sprite *);
static void AnimFollowMeFinger_Step2(struct Sprite *);
static void AnimTauntFinger(struct Sprite *);
static void AnimTauntFinger_Step1(struct Sprite *);
static void AnimTauntFinger_Step2(struct Sprite *);
static void AnimMoveTwisterParticle_Step(struct Sprite *);
static void AnimTask_MoonlightEndFade_Step(u8 taskId);
static void AnimTask_LeafBlade_Step(u8);
static void AnimTask_DuplicateAndShrinkToPos_Step1(u8);
static void AnimTask_DuplicateAndShrinkToPos_Step2(u8);
static s16 LeafBladeGetPosFactor(struct Sprite *);
static void AnimTask_LeafBlade_Step2(struct Task *, u8);
static void AnimTask_LeafBlade_Step2_Callback(struct Sprite *);
static void AnimTask_SkullBashPositionSet(u8);
static void AnimTask_SkullBashPositionReset(u8);
static void AnimTask_DoubleTeam_Step(u8);
static void AnimDoubleTeam(struct Sprite *);
const union AnimCmd gPowderParticlesAnimCmds[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(6, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(10, 5),
ANIMCMD_FRAME(12, 5),
ANIMCMD_FRAME(14, 5),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gPowderParticlesAnimTable[] =
{
gPowderParticlesAnimCmds,
};
const struct SpriteTemplate gSleepPowderParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_SLEEP_POWDER,
.paletteTag = ANIM_TAG_SLEEP_POWDER,
.oam = &gOamData_AffineOff_ObjNormal_8x16,
.anims = gPowderParticlesAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMovePowderParticle,
};
const struct SpriteTemplate gStunSporeParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_STUN_SPORE,
.paletteTag = ANIM_TAG_STUN_SPORE,
.oam = &gOamData_AffineOff_ObjNormal_8x16,
.anims = gPowderParticlesAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMovePowderParticle,
};
const struct SpriteTemplate gPoisonPowderParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_POISON_POWDER,
.paletteTag = ANIM_TAG_POISON_POWDER,
.oam = &gOamData_AffineOff_ObjNormal_8x16,
.anims = gPowderParticlesAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMovePowderParticle,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds1[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds2[] =
{
ANIMCMD_FRAME(1, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds3[] =
{
ANIMCMD_FRAME(2, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds4[] =
{
ANIMCMD_FRAME(3, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds5[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds6[] =
{
ANIMCMD_FRAME(5, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamBigOrbAnimCmds7[] =
{
ANIMCMD_FRAME(6, 1),
ANIMCMD_END,
};
const union AnimCmd gSolarBeamSmallOrbAnimCms[] =
{
ANIMCMD_FRAME(7, 1),
ANIMCMD_END,
};
const union AnimCmd gPowerAbsorptionOrbAnimCmds[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
const union AnimCmd *const gSolarBeamBigOrbAnimTable[] =
{
gSolarBeamBigOrbAnimCmds1,
gSolarBeamBigOrbAnimCmds2,
gSolarBeamBigOrbAnimCmds3,
gSolarBeamBigOrbAnimCmds4,
gSolarBeamBigOrbAnimCmds5,
gSolarBeamBigOrbAnimCmds6,
gSolarBeamBigOrbAnimCmds7,
};
const union AnimCmd *const gSolarBeamSmallOrbAnimTable[] =
{
gSolarBeamSmallOrbAnimCms,
};
const union AnimCmd *const gPowerAbsorptionOrbAnimTable[] =
{
gPowerAbsorptionOrbAnimCmds,
};
const union AffineAnimCmd gPowerAbsorptionOrbAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(-5, -5, 0, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gPowerAbsorptionOrbAffineAnimTable[] = {
gPowerAbsorptionOrbAffineAnimCmds,
};
const struct SpriteTemplate gPowerAbsorptionOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = gPowerAbsorptionOrbAnimTable,
.images = NULL,
.affineAnims = gPowerAbsorptionOrbAffineAnimTable,
.callback = AnimPowerAbsorptionOrb,
};
const struct SpriteTemplate gSolarBeamBigOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSolarBeamBigOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSolarBeamBigOrb,
};
const struct SpriteTemplate gSolarBeamSmallOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSolarBeamSmallOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSolarBeamSmallOrb,
};
const union AffineAnimCmd gStockpileAbsorptionOrbAffineCmds[] = {
AFFINEANIMCMD_FRAME(320, 320, 0, 0),
AFFINEANIMCMD_FRAME(-14, -14, 0, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gStockpileAbsorptionOrbAffineAnimTable[] = {
gStockpileAbsorptionOrbAffineCmds,
};
const struct SpriteTemplate gStockpileAbsorptionOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_GRAY_ORB,
.paletteTag = ANIM_TAG_GRAY_ORB,
.oam = &gOamData_AffineDouble_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gStockpileAbsorptionOrbAffineAnimTable,
.callback = AnimPowerAbsorptionOrb,
};
const union AffineAnimCmd gAbsorptionOrbAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(-5, -5, 0, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gAbsorptionOrbAffineAnimTable[] = {
gAbsorptionOrbAffineAnimCmds,
};
const struct SpriteTemplate gAbsorptionOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
.anims = gPowerAbsorptionOrbAnimTable,
.images = NULL,
.affineAnims = gAbsorptionOrbAffineAnimTable,
.callback = AnimAbsorptionOrb,
};
const struct SpriteTemplate gHyperBeamOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSolarBeamBigOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimHyperBeamOrb,
};
const union AnimCmd gLeechSeedAnimCmds1[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
const union AnimCmd gLeechSeedAnimCmds2[] =
{
ANIMCMD_FRAME(4, 7),
ANIMCMD_FRAME(8, 7),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gLeechSeedAnimTable[] =
{
gLeechSeedAnimCmds1,
gLeechSeedAnimCmds2,
};
const struct SpriteTemplate gLeechSeedSpriteTemplate =
{
.tileTag = ANIM_TAG_SEED,
.paletteTag = ANIM_TAG_SEED,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gLeechSeedAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLeechSeed,
};
const union AnimCmd gSporeParticleAnimCmds1[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
const union AnimCmd gSporeParticleAnimCmds2[] =
{
ANIMCMD_FRAME(4, 7),
ANIMCMD_END,
};
const union AnimCmd *const gSporeParticleAnimTable[] =
{
gSporeParticleAnimCmds1,
gSporeParticleAnimCmds2,
};
const struct SpriteTemplate gSporeParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_SPORE,
.paletteTag = ANIM_TAG_SPORE,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gSporeParticleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSporeParticle,
};
const union AnimCmd gPetalDanceBigFlowerAnimCmds[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
const union AnimCmd gPetalDanceSmallFlowerAnimCmds[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
const union AnimCmd *const gPetalDanceBigFlowerAnimTable[] =
{
gPetalDanceBigFlowerAnimCmds,
};
const union AnimCmd *const gPetalDanceSmallFlowerAnimTable[] =
{
gPetalDanceSmallFlowerAnimCmds,
};
const struct SpriteTemplate gPetalDanceBigFlowerSpriteTemplate =
{
.tileTag = ANIM_TAG_FLOWER,
.paletteTag = ANIM_TAG_FLOWER,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gPetalDanceBigFlowerAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPetalDanceBigFlower,
};
const struct SpriteTemplate gPetalDanceSmallFlowerSpriteTemplate =
{
.tileTag = ANIM_TAG_FLOWER,
.paletteTag = ANIM_TAG_FLOWER,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gPetalDanceSmallFlowerAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPetalDanceSmallFlower,
};
const union AnimCmd gRazorLeafParticleAnimCmds1[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(12, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(20, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(12, 5),
ANIMCMD_FRAME(8, 5),
ANIMCMD_FRAME(4, 5),
ANIMCMD_JUMP(0),
};
const union AnimCmd gRazorLeafParticleAnimCmds2[] =
{
ANIMCMD_FRAME(24, 5),
ANIMCMD_FRAME(28, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_END,
};
const union AnimCmd *const gRazorLeafParticleAnimTable[] =
{
gRazorLeafParticleAnimCmds1,
gRazorLeafParticleAnimCmds2,
};
const struct SpriteTemplate gRazorLeafParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_LEAF,
.paletteTag = ANIM_TAG_LEAF,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gRazorLeafParticleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRazorLeafParticle,
};
const struct SpriteTemplate gTwisterLeafSpriteTemplate =
{
.tileTag = ANIM_TAG_LEAF,
.paletteTag = ANIM_TAG_LEAF,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gRazorLeafParticleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMoveTwisterParticle,
};
const union AnimCmd gRazorLeafCutterAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(0, 3, .hFlip = TRUE),
ANIMCMD_FRAME(0, 3, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(0, 3, .vFlip = TRUE),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gRazorLeafCutterAnimTable[] =
{
gRazorLeafCutterAnimCmds,
};
const struct SpriteTemplate gRazorLeafCutterSpriteTemplate =
{
.tileTag = ANIM_TAG_RAZOR_LEAF,
.paletteTag = ANIM_TAG_RAZOR_LEAF,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gRazorLeafCutterAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTranslateLinearSingleSineWave,
};
const union AffineAnimCmd gSwiftStarAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(0, 0, 0, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gSwiftStarAffineAnimTable[] = {
gSwiftStarAffineAnimCmds,
};
const struct SpriteTemplate gSwiftStarSpriteTemplate =
{
.tileTag = ANIM_TAG_YELLOW_STAR,
.paletteTag = ANIM_TAG_YELLOW_STAR,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSwiftStarAffineAnimTable,
.callback = AnimTranslateLinearSingleSineWave,
};
static const union AnimCmd sAnim_ConstrictBinding[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_FRAME(96, 4),
ANIMCMD_END,
};
static const union AnimCmd sAnim_ConstrictBinding_Flipped[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_FRAME(64, 4, .hFlip = TRUE),
ANIMCMD_FRAME(96, 4, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_ConstrictBinding[] =
{
sAnim_ConstrictBinding,
sAnim_ConstrictBinding_Flipped,
};
static const union AffineAnimCmd sAffineAnim_ConstrictBinding[] = {
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(-11, 0, 0, 6),
AFFINEANIMCMD_FRAME(11, 0, 0, 6),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_ConstrictBinding_Flipped[] = {
AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(11, 0, 0, 6),
AFFINEANIMCMD_FRAME(-11, 0, 0, 6),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_ConstrictBinding[] = {
sAffineAnim_ConstrictBinding,
sAffineAnim_ConstrictBinding_Flipped,
};
const struct SpriteTemplate gConstrictBindingSpriteTemplate =
{
.tileTag = ANIM_TAG_TENDRILS,
.paletteTag = ANIM_TAG_TENDRILS,
.oam = &gOamData_AffineNormal_ObjNormal_64x32,
.anims = sAnims_ConstrictBinding,
.images = NULL,
.affineAnims = sAffineAnims_ConstrictBinding,
.callback = AnimConstrictBinding,
};
const union AffineAnimCmd gMimicOrbAffineAnimCmds1[] = {
AFFINEANIMCMD_FRAME(0, 0, 0, 0),
AFFINEANIMCMD_FRAME(48, 48, 0, 14),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gMimicOrbAffineAnimCmds2[] = {
AFFINEANIMCMD_FRAME(-16, -16, 0, 1),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gMimicOrbAffineAnimTable[] = {
gMimicOrbAffineAnimCmds1,
gMimicOrbAffineAnimCmds2,
};
const struct SpriteTemplate gMimicOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gPowerAbsorptionOrbAnimTable,
.images = NULL,
.affineAnims = gMimicOrbAffineAnimTable,
.callback = AnimMimicOrb,
};
const union AnimCmd gIngrainRootAnimCmds1[] =
{
ANIMCMD_FRAME(0, 7),
ANIMCMD_FRAME(16, 7),
ANIMCMD_FRAME(32, 7),
ANIMCMD_FRAME(48, 7),
ANIMCMD_END,
};
const union AnimCmd gIngrainRootAnimCmds2[] =
{
ANIMCMD_FRAME(0, 7, .hFlip = TRUE),
ANIMCMD_FRAME(16, 7, .hFlip = TRUE),
ANIMCMD_FRAME(32, 7, .hFlip = TRUE),
ANIMCMD_FRAME(48, 7, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gIngrainRootAnimCmds3[] =
{
ANIMCMD_FRAME(0, 7),
ANIMCMD_FRAME(16, 7),
ANIMCMD_FRAME(32, 7),
ANIMCMD_END,
};
const union AnimCmd gIngrainRootAnimCmds4[] =
{
ANIMCMD_FRAME(0, 7, .hFlip = TRUE),
ANIMCMD_FRAME(16, 7, .hFlip = TRUE),
ANIMCMD_FRAME(32, 7, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gIngrainRootAnimTable[] =
{
gIngrainRootAnimCmds1,
gIngrainRootAnimCmds2,
gIngrainRootAnimCmds3,
gIngrainRootAnimCmds4,
};
const struct SpriteTemplate gIngrainRootSpriteTemplate =
{
.tileTag = ANIM_TAG_ROOTS,
.paletteTag = ANIM_TAG_ROOTS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gIngrainRootAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimIngrainRoot,
};
const struct SpriteTemplate gFrenzyPlantRootSpriteTemplate =
{
.tileTag = ANIM_TAG_ROOTS,
.paletteTag = ANIM_TAG_ROOTS,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gIngrainRootAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFrenzyPlantRoot,
};
const union AnimCmd gIngrainOrbAnimCmds[] =
{
ANIMCMD_FRAME(3, 3),
ANIMCMD_FRAME(0, 5),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gIngrainOrbAnimTable[] =
{
gIngrainOrbAnimCmds,
};
const struct SpriteTemplate gIngrainOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ORBS,
.paletteTag = ANIM_TAG_ORBS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gIngrainOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimIngrainOrb,
};
const union AnimCmd gFallingBagAnimCmds[] =
{
ANIMCMD_FRAME(0, 30),
ANIMCMD_END,
};
const union AnimCmd *const gFallingBagAnimTable[] =
{
gFallingBagAnimCmds,
};
const union AffineAnimCmd gFallingBagAffineAnimCmds1[] = {
AFFINEANIMCMD_FRAME(0, 0, -4, 10),
AFFINEANIMCMD_FRAME(0, 0, 4, 20),
AFFINEANIMCMD_FRAME(0, 0, -4, 10),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gFallingBagAffineAnimCmds2[] = {
AFFINEANIMCMD_FRAME(0, 0, -1, 2),
AFFINEANIMCMD_FRAME(0, 0, 1, 4),
AFFINEANIMCMD_FRAME(0, 0, -1, 4),
AFFINEANIMCMD_FRAME(0, 0, 1, 4),
AFFINEANIMCMD_FRAME(0, 0, -1, 4),
AFFINEANIMCMD_FRAME(0, 0, 1, 2),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gFallingBagAffineAnimTable[] = {
gFallingBagAffineAnimCmds1,
gFallingBagAffineAnimCmds2,
};
const struct SpriteTemplate gPresentSpriteTemplate =
{
.tileTag = ANIM_TAG_ITEM_BAG,
.paletteTag = ANIM_TAG_ITEM_BAG,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gFallingBagAnimTable,
.images = NULL,
.affineAnims = gFallingBagAffineAnimTable,
.callback = AnimPresent,
};
const struct SpriteTemplate gKnockOffItemSpriteTemplate =
{
.tileTag = ANIM_TAG_ITEM_BAG,
.paletteTag = ANIM_TAG_ITEM_BAG,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gFallingBagAnimTable,
.images = NULL,
.affineAnims = gFallingBagAffineAnimTable,
.callback = AnimKnockOffItem,
};
const union AnimCmd gPresentHealParticleAnimCmds[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(4, 4),
ANIMCMD_FRAME(8, 4),
ANIMCMD_FRAME(12, 4),
ANIMCMD_END,
};
const union AnimCmd *const gPresentHealParticleAnimTable[] =
{
gPresentHealParticleAnimCmds,
};
const struct SpriteTemplate gPresentHealParticleSpriteTemplate =
{
.tileTag = ANIM_TAG_GREEN_SPARKLE,
.paletteTag = ANIM_TAG_GREEN_SPARKLE,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gPresentHealParticleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPresentHealParticle,
};
const struct SpriteTemplate gItemStealSpriteTemplate =
{
.tileTag = ANIM_TAG_ITEM_BAG,
.paletteTag = ANIM_TAG_ITEM_BAG,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gFallingBagAnimTable,
.images = NULL,
.affineAnims = gFallingBagAffineAnimTable,
.callback = AnimItemSteal,
};
const union AffineAnimCmd gTrickBagAffineAnimCmds1[] = {
AFFINEANIMCMD_FRAME(0, 0, 0, 3),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gTrickBagAffineAnimCmds2[] = {
AFFINEANIMCMD_FRAME(0, -10, 0, 3),
AFFINEANIMCMD_FRAME(0, -6, 0, 3),
AFFINEANIMCMD_FRAME(0, -2, 0, 3),
AFFINEANIMCMD_FRAME(0, 0, 0, 3),
AFFINEANIMCMD_FRAME(0, 2, 0, 3),
AFFINEANIMCMD_FRAME(0, 6, 0, 3),
AFFINEANIMCMD_FRAME(0, 10, 0, 3),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gTrickBagAffineAnimTable[] = {
gTrickBagAffineAnimCmds1,
gTrickBagAffineAnimCmds2,
gFallingBagAffineAnimCmds1,
gFallingBagAffineAnimCmds2,
};
const struct SpriteTemplate gTrickBagSpriteTemplate =
{
.tileTag = ANIM_TAG_ITEM_BAG,
.paletteTag = ANIM_TAG_ITEM_BAG,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gFallingBagAnimTable,
.images = NULL,
.affineAnims = gTrickBagAffineAnimTable,
.callback = AnimTrickBag,
};
const s8 gTrickBagCoordinates[][3] =
{
{5, 24, 1},
{0, 4, 0},
{8, 16, -1},
{0, 2, 0},
{8, 16, 1},
{0, 2, 0},
{8, 16, 1},
{0, 2, 0},
{8, 16, 1},
{0, 16, 0},
{0, 0, 127},
};
const union AnimCmd gLeafBladeAnimCmds1[] =
{
ANIMCMD_FRAME(28, 1),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds2[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds3[] =
{
ANIMCMD_FRAME(20, 1),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds4[] =
{
ANIMCMD_FRAME(28, 1, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds5[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds6[] =
{
ANIMCMD_FRAME(16, 1, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gLeafBladeAnimCmds7[] =
{
ANIMCMD_FRAME(28, 1),
ANIMCMD_END,
};
const union AnimCmd *const gLeafBladeAnimTable[] =
{
gLeafBladeAnimCmds1,
gLeafBladeAnimCmds2,
gLeafBladeAnimCmds3,
gLeafBladeAnimCmds4,
gLeafBladeAnimCmds5,
gLeafBladeAnimCmds6,
gLeafBladeAnimCmds7,
};
const struct SpriteTemplate gLeafBladeSpriteTemplate =
{
.tileTag = ANIM_TAG_LEAF,
.paletteTag = ANIM_TAG_LEAF,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gLeafBladeAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
const union AffineAnimCmd gAromatherapyBigFlowerAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, 4, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gAromatherapyBigFlowerAffineAnimTable[] = {
gAromatherapyBigFlowerAffineAnimCmds,
};
const struct SpriteTemplate gAromatherapySmallFlowerSpriteTemplate =
{
.tileTag = ANIM_TAG_FLOWER,
.paletteTag = ANIM_TAG_FLOWER,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gPetalDanceSmallFlowerAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFlyingParticle,
};
const struct SpriteTemplate gAromatherapyBigFlowerSpriteTemplate =
{
.tileTag = ANIM_TAG_FLOWER,
.paletteTag = ANIM_TAG_FLOWER,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gPetalDanceBigFlowerAnimTable,
.images = NULL,
.affineAnims = gAromatherapyBigFlowerAffineAnimTable,
.callback = AnimFlyingParticle,
};
const union AffineAnimCmd gSilverWindBigSparkAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, -10, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd gSilverWindMediumSparkAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(192, 192, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, -12, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd gSilverWindSmallSparkAffineAnimCmds[] = {
AFFINEANIMCMD_FRAME(143, 143, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, -15, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gSilverWindBigSparkAffineAnimTable[] = {
gSilverWindBigSparkAffineAnimCmds,
};
const union AffineAnimCmd *const gSilverWindMediumSparkAffineAnimTable[] = {
gSilverWindMediumSparkAffineAnimCmds,
};
const union AffineAnimCmd *const gSilverWindSmallSparkAffineAnimTable[] = {
gSilverWindSmallSparkAffineAnimCmds,
};
const struct SpriteTemplate gSilverWindBigSparkSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_6,
.paletteTag = ANIM_TAG_SPARKLE_6,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSilverWindBigSparkAffineAnimTable,
.callback = AnimFlyingParticle,
};
const struct SpriteTemplate gSilverWindMediumSparkSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_6,
.paletteTag = ANIM_TAG_SPARKLE_6,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSilverWindMediumSparkAffineAnimTable,
.callback = AnimFlyingParticle,
};
const struct SpriteTemplate gSilverWindSmallSparkSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_6,
.paletteTag = ANIM_TAG_SPARKLE_6,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSilverWindSmallSparkAffineAnimTable,
.callback = AnimFlyingParticle,
};
const u16 gMagicalLeafBlendColors[] =
{
RGB(31, 0, 0),
RGB(31, 19, 0),
RGB(31, 31, 0),
RGB(0, 31, 0),
RGB(5, 14, 31),
RGB(22, 10, 31),
RGB(22, 21, 31),
};
const struct SpriteTemplate gNeedleArmSpikeSpriteTemplate =
{
.tileTag = ANIM_TAG_GREEN_SPIKE,
.paletteTag = ANIM_TAG_GREEN_SPIKE,
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimNeedleArmSpike,
};
static const union AnimCmd sAnim_Whip[] =
{
ANIMCMD_FRAME(64, 3),
ANIMCMD_FRAME(80, 3),
ANIMCMD_FRAME(96, 3),
ANIMCMD_FRAME(112, 6),
ANIMCMD_END,
};
static const union AnimCmd sAnim_Whip_Flipped[] =
{
ANIMCMD_FRAME(64, 3, .hFlip = TRUE),
ANIMCMD_FRAME(80, 3, .hFlip = TRUE),
ANIMCMD_FRAME(96, 3, .hFlip = TRUE),
ANIMCMD_FRAME(112, 6, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_Whip[] =
{
sAnim_Whip,
sAnim_Whip_Flipped,
};
const struct SpriteTemplate gSlamHitSpriteTemplate =
{
.tileTag = ANIM_TAG_SLAM_HIT,
.paletteTag = ANIM_TAG_SLAM_HIT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_Whip,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWhipHit,
};
const struct SpriteTemplate gVineWhipSpriteTemplate =
{
.tileTag = ANIM_TAG_WHIP_HIT,
.paletteTag = ANIM_TAG_WHIP_HIT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_Whip,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWhipHit,
};
static const union AnimCmd sAnim_SlidingHit[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 5),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_SlidingHit[] =
{
sAnim_SlidingHit,
};
// Unused
static const struct SpriteTemplate sSlidingHit1SpriteTemplate =
{
.tileTag = ANIM_TAG_HIT,
.paletteTag = ANIM_TAG_HIT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_SlidingHit,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSlidingHit,
};
// Unused
static const struct SpriteTemplate sSlidingHit2SpriteTemplate =
{
.tileTag = ANIM_TAG_HIT_2,
.paletteTag = ANIM_TAG_HIT_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = sAnims_SlidingHit,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSlidingHit,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_Normal[] = {
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedTopLeft[] = {
AFFINEANIMCMD_FRAME(256, 256, 32, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedLeft[] = {
AFFINEANIMCMD_FRAME(256, 256, 64, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedBottomLeft[] = {
AFFINEANIMCMD_FRAME(256, 256, 96, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_UpsideDown[] = {
AFFINEANIMCMD_FRAME(256, 256, -128, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedBottomRight[] = {
AFFINEANIMCMD_FRAME(256, 256, -96, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedRight[] = {
AFFINEANIMCMD_FRAME(256, 256, -64, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd sAffineAnim_FlickeringPunch_TurnedTopRight[] = {
AFFINEANIMCMD_FRAME(256, 256, -32, 0),
AFFINEANIMCMD_END,
};
static const union AffineAnimCmd *const sAffineAnims_FlickeringPunch[] = {
sAffineAnim_FlickeringPunch_Normal,
sAffineAnim_FlickeringPunch_TurnedTopLeft,
sAffineAnim_FlickeringPunch_TurnedLeft,
sAffineAnim_FlickeringPunch_TurnedBottomLeft,
sAffineAnim_FlickeringPunch_UpsideDown,
sAffineAnim_FlickeringPunch_TurnedBottomRight,
sAffineAnim_FlickeringPunch_TurnedRight,
sAffineAnim_FlickeringPunch_TurnedTopRight,
};
// Unused
static const struct SpriteTemplate sFlickeringPunchSpriteTemplate =
{
.tileTag = ANIM_TAG_HANDS_AND_FEET,
.paletteTag = ANIM_TAG_HANDS_AND_FEET,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_FlickeringPunch,
.callback = AnimFlickeringPunch,
};
const union AnimCmd gCuttingSliceAnimCmds[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(32, 5),
ANIMCMD_FRAME(48, 5),
ANIMCMD_END,
};
const union AnimCmd *const gCuttingSliceAnimTable[] =
{
gCuttingSliceAnimCmds,
};
const struct SpriteTemplate gCuttingSliceSpriteTemplate =
{
.tileTag = ANIM_TAG_CUT,
.paletteTag = ANIM_TAG_CUT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gCuttingSliceAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCuttingSlice,
};
const struct SpriteTemplate gAirCutterSliceSpriteTemplate =
{
.tileTag = ANIM_TAG_CUT,
.paletteTag = ANIM_TAG_CUT,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gCuttingSliceAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimAirCutterSlice,
};
static const union AnimCmd sAnim_CirclingMusicNote_Eighth[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_BeamedEighth[] =
{
ANIMCMD_FRAME(4, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_SlantedBeamedEighth[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_Quarter[] =
{
ANIMCMD_FRAME(12, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_QuarterRest[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_EighthRest[] =
{
ANIMCMD_FRAME(20, 1),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_Eighth_Flipped[] =
{
ANIMCMD_FRAME(0, 1, .vFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_BeamedEighth_Flipped[] =
{
ANIMCMD_FRAME(4, 1, .vFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_SlantedBeamedEighth_Flipped[] =
{
ANIMCMD_FRAME(8, 1, .vFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd sAnim_CirclingMusicNote_Quarter_Flipped[] =
{
ANIMCMD_FRAME(12, 1, .vFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_CirclingMusicNote[] =
{
sAnim_CirclingMusicNote_Eighth,
sAnim_CirclingMusicNote_BeamedEighth,
sAnim_CirclingMusicNote_SlantedBeamedEighth,
sAnim_CirclingMusicNote_Quarter,
sAnim_CirclingMusicNote_QuarterRest,
sAnim_CirclingMusicNote_EighthRest,
sAnim_CirclingMusicNote_Eighth_Flipped,
sAnim_CirclingMusicNote_BeamedEighth_Flipped,
sAnim_CirclingMusicNote_SlantedBeamedEighth_Flipped,
sAnim_CirclingMusicNote_Quarter_Flipped,
};
// Unused
static const struct SpriteTemplate sCirclingMusicNoteSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_CirclingMusicNote,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimCirclingMusicNote,
};
const struct SpriteTemplate gProtectSpriteTemplate =
{
.tileTag = ANIM_TAG_PROTECT,
.paletteTag = ANIM_TAG_PROTECT,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimProtect,
};
const union AffineAnimCmd gMilkBottleAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gMilkBottleAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 12),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6),
AFFINEANIMCMD_FRAME(0x0, 0x0, -2, 24),
AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6),
AFFINEANIMCMD_FRAME(0x0, 0x0, 2, 12),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gMilkBottleAffineAnimTable[] =
{
gMilkBottleAffineAnimCmds1,
gMilkBottleAffineAnimCmds2,
};
const struct SpriteTemplate gMilkBottleSpriteTemplate =
{
.tileTag = ANIM_TAG_MILK_BOTTLE,
.paletteTag = ANIM_TAG_MILK_BOTTLE,
.oam = &gOamData_AffineNormal_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gMilkBottleAffineAnimTable,
.callback = AnimMilkBottle,
};
const union AnimCmd gGrantingStarsAnimCmds[] =
{
ANIMCMD_FRAME(0, 7),
ANIMCMD_FRAME(16, 7),
ANIMCMD_FRAME(32, 7),
ANIMCMD_FRAME(48, 7),
ANIMCMD_FRAME(64, 7),
ANIMCMD_FRAME(80, 7),
ANIMCMD_FRAME(96, 7),
ANIMCMD_FRAME(112, 7),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gGrantingStarsAnimTable[] =
{
gGrantingStarsAnimCmds,
};
const struct SpriteTemplate gGrantingStarsSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_2,
.paletteTag = ANIM_TAG_SPARKLE_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gGrantingStarsAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGrantingStars,
};
const struct SpriteTemplate gSparklingStarsSpriteTemplate =
{
.tileTag = ANIM_TAG_SPARKLE_2,
.paletteTag = ANIM_TAG_SPARKLE_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gGrantingStarsAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSparklingStars,
};
static const union AnimCmd sAnim_BubbleBurst[] =
{
ANIMCMD_FRAME(0, 10),
ANIMCMD_FRAME(4, 10),
ANIMCMD_FRAME(8, 10),
ANIMCMD_FRAME(12, 10),
ANIMCMD_FRAME(16, 26),
ANIMCMD_FRAME(16, 5),
ANIMCMD_FRAME(20, 5),
ANIMCMD_FRAME(24, 15),
ANIMCMD_END,
};
static const union AnimCmd sAnim_BubbleBurst_Flipped[] =
{
ANIMCMD_FRAME(0, 10, .hFlip = TRUE),
ANIMCMD_FRAME(4, 10, .hFlip = TRUE),
ANIMCMD_FRAME(8, 10, .hFlip = TRUE),
ANIMCMD_FRAME(12, 10, .hFlip = TRUE),
ANIMCMD_FRAME(16, 26, .hFlip = TRUE),
ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
ANIMCMD_FRAME(20, 5, .hFlip = TRUE),
ANIMCMD_FRAME(24, 15, .hFlip = TRUE),
ANIMCMD_END,
};
static const union AnimCmd *const sAnims_BubbleBurst[] =
{
sAnim_BubbleBurst,
sAnim_BubbleBurst_Flipped,
};
// Unused
static const struct SpriteTemplate sBubbleBurstSpriteTemplate =
{
.tileTag = ANIM_TAG_BUBBLE_BURST,
.paletteTag = ANIM_TAG_BUBBLE_BURST,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = sAnims_BubbleBurst,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBubbleBurst,
};
const union AnimCmd gSleepLetterZAnimCmds[] =
{
ANIMCMD_FRAME(0, 40),
ANIMCMD_END,
};
const union AnimCmd *const gSleepLetterZAnimTable[] =
{
gSleepLetterZAnimCmds,
};
const union AffineAnimCmd gSleepLetterZAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x14, 0x14, -30, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 1, 24),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gSleepLetterZAffineAnimCmds1_2[] =
{
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24),
AFFINEANIMCMD_LOOP(10),
};
const union AffineAnimCmd gSleepLetterZAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x14, 0x14, 30, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, -1, 24),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gSleepLetterZAffineAnimCmds2_2[] =
{
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 24),
AFFINEANIMCMD_LOOP(10),
};
const union AffineAnimCmd *const gSleepLetterZAffineAnimTable[] =
{
gSleepLetterZAffineAnimCmds1,
gSleepLetterZAffineAnimCmds2,
};
const struct SpriteTemplate gSleepLetterZSpriteTemplate =
{
.tileTag = ANIM_TAG_LETTER_Z,
.paletteTag = ANIM_TAG_LETTER_Z,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gSleepLetterZAnimTable,
.images = NULL,
.affineAnims = gSleepLetterZAffineAnimTable,
.callback = AnimSleepLetterZ,
};
const struct SpriteTemplate gLockOnTargetSpriteTemplate =
{
.tileTag = ANIM_TAG_LOCK_ON,
.paletteTag = ANIM_TAG_LOCK_ON,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLockOnTarget,
};
const struct SpriteTemplate gLockOnMoveTargetSpriteTemplate =
{
.tileTag = ANIM_TAG_LOCK_ON,
.paletteTag = ANIM_TAG_LOCK_ON,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLockOnMoveTarget,
};
const s8 gInclineMonCoordTable[][2] =
{
{ 64, 64},
{ 0, -64},
{-64, 64},
{ 32, -32},
};
const struct SpriteTemplate gBowMonSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBowMon,
};
// Unused
// Same as BowMon above but without backing up
static const struct SpriteTemplate sTipMonSpriteTemplate =
{
.tileTag = 0,
.paletteTag = 0,
.oam = &gDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTipMon,
};
const union AnimCmd gSlashSliceAnimCmds1[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_END,
};
const union AnimCmd gSlashSliceAnimCmds2[] =
{
ANIMCMD_FRAME(48, 4),
ANIMCMD_END,
};
const union AnimCmd *const gSlashSliceAnimTable[] =
{
gSlashSliceAnimCmds1,
gSlashSliceAnimCmds2,
};
const struct SpriteTemplate gSlashSliceSpriteTemplate =
{
.tileTag = ANIM_TAG_SLASH,
.paletteTag = ANIM_TAG_SLASH,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gSlashSliceAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSlashSlice,
};
const struct SpriteTemplate gFalseSwipeSliceSpriteTemplate =
{
.tileTag = ANIM_TAG_SLASH_2,
.paletteTag = ANIM_TAG_SLASH_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gSlashSliceAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFalseSwipeSlice,
};
const struct SpriteTemplate gFalseSwipePositionedSliceSpriteTemplate =
{
.tileTag = ANIM_TAG_SLASH_2,
.paletteTag = ANIM_TAG_SLASH_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gSlashSliceAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFalseSwipePositionedSlice,
};
const union AnimCmd gEndureEnergyAnimCmds[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(8, 12),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(24, 4),
ANIMCMD_END,
};
const union AnimCmd *const gEndureEnergyAnimTable[] =
{
gEndureEnergyAnimCmds,
};
const struct SpriteTemplate gEndureEnergySpriteTemplate =
{
.tileTag = ANIM_TAG_FOCUS_ENERGY,
.paletteTag = ANIM_TAG_FOCUS_ENERGY,
.oam = &gOamData_AffineOff_ObjNormal_16x32,
.anims = gEndureEnergyAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimEndureEnergy,
};
const union AnimCmd gSharpenSphereAnimCmds[] =
{
ANIMCMD_FRAME(0, 18),
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 18),
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 18),
ANIMCMD_FRAME(16, 6),
ANIMCMD_FRAME(32, 6),
ANIMCMD_FRAME(48, 18),
ANIMCMD_FRAME(32, 6),
ANIMCMD_FRAME(48, 6),
ANIMCMD_FRAME(64, 18),
ANIMCMD_FRAME(48, 6),
ANIMCMD_FRAME(64, 54),
ANIMCMD_END,
};
const union AnimCmd *const gSharpenSphereAnimTable[] =
{
gSharpenSphereAnimCmds,
};
const struct SpriteTemplate gSharpenSphereSpriteTemplate =
{
.tileTag = ANIM_TAG_SPHERE_TO_CUBE,
.paletteTag = ANIM_TAG_SPHERE_TO_CUBE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gSharpenSphereAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSharpenSphere,
};
const struct SpriteTemplate gOctazookaBallSpriteTemplate =
{
.tileTag = ANIM_TAG_BLACK_BALL,
.paletteTag = ANIM_TAG_BLACK_BALL,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = TranslateAnimSpriteToTargetMonLocation,
};
const union AnimCmd gOctazookaAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_END,
};
const union AnimCmd *const gOctazookaAnimTable[] =
{
gOctazookaAnimCmds,
};
const struct SpriteTemplate gOctazookaSmokeSpriteTemplate =
{
.tileTag = ANIM_TAG_GRAY_SMOKE,
.paletteTag = ANIM_TAG_GRAY_SMOKE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gOctazookaAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const union AnimCmd gConversionAnimCmds[] =
{
ANIMCMD_FRAME(3, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(1, 5),
ANIMCMD_FRAME(0, 5),
ANIMCMD_END,
};
const union AnimCmd *const gConversionAnimTable[] =
{
gConversionAnimCmds,
};
const union AffineAnimCmd gConversionAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gConversionAffineAnimTable[] =
{
gConversionAffineAnimCmds,
};
const struct SpriteTemplate gConversionSpriteTemplate =
{
.tileTag = ANIM_TAG_CONVERSION,
.paletteTag = ANIM_TAG_CONVERSION,
.oam = &gOamData_AffineDouble_ObjBlend_8x8,
.anims = gConversionAnimTable,
.images = NULL,
.affineAnims = gConversionAffineAnimTable,
.callback = AnimConversion,
};
const union AnimCmd gConversion2AnimCmds[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(1, 5),
ANIMCMD_FRAME(2, 5),
ANIMCMD_FRAME(3, 5),
ANIMCMD_END,
};
const union AnimCmd *const gConversion2AnimTable[] =
{
gConversion2AnimCmds,
};
const struct SpriteTemplate gConversion2SpriteTemplate =
{
.tileTag = ANIM_TAG_CONVERSION,
.paletteTag = ANIM_TAG_CONVERSION,
.oam = &gOamData_AffineDouble_ObjBlend_8x8,
.anims = gConversion2AnimTable,
.images = NULL,
.affineAnims = gConversionAffineAnimTable,
.callback = AnimConversion2,
};
const struct SpriteTemplate gMoonSpriteTemplate =
{
.tileTag = ANIM_TAG_MOON,
.paletteTag = ANIM_TAG_MOON,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMoon,
};
const union AnimCmd gMoonlightSparkleAnimCmds[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(4, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_FRAME(12, 8),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gMoonlightSparkleAnimTable[] =
{
gMoonlightSparkleAnimCmds,
};
const struct SpriteTemplate gMoonlightSparkleSpriteTemplate =
{
.tileTag = ANIM_TAG_GREEN_SPARKLE,
.paletteTag = ANIM_TAG_GREEN_SPARKLE,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gMoonlightSparkleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMoonlightSparkle,
};
const union AnimCmd gHealingBlueStarAnimCmds[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 5),
ANIMCMD_FRAME(80, 3),
ANIMCMD_FRAME(96, 2),
ANIMCMD_FRAME(0, 2),
ANIMCMD_END,
};
const union AnimCmd *const gHealingBlueStarAnimTable[] =
{
gHealingBlueStarAnimCmds,
};
const struct SpriteTemplate gHealingBlueStarSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_STAR,
.paletteTag = ANIM_TAG_BLUE_STAR,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gHealingBlueStarAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gHornHitSpriteTemplate =
{
.tileTag = ANIM_TAG_HORN_HIT,
.paletteTag = ANIM_TAG_HORN_HIT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimHornHit,
};
const union AnimCmd gSuperFangAnimCmds[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(48, 2),
ANIMCMD_END,
};
const union AnimCmd *const gSuperFangAnimTable[] =
{
gSuperFangAnimCmds,
};
const struct SpriteTemplate gSuperFangSpriteTemplate =
{
.tileTag = ANIM_TAG_FANG_ATTACK,
.paletteTag = ANIM_TAG_FANG_ATTACK,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gSuperFangAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSuperFang,
};
const union AnimCmd gWavyMusicNotesAnimCmds1[] =
{
ANIMCMD_FRAME(0, 10),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds2[] =
{
ANIMCMD_FRAME(4, 10),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds3[] =
{
ANIMCMD_FRAME(8, 41),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds4[] =
{
ANIMCMD_FRAME(12, 10),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds5[] =
{
ANIMCMD_FRAME(16, 10),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds6[] =
{
ANIMCMD_FRAME(20, 10),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds7[] =
{
ANIMCMD_FRAME(0, 10, .vFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gWavyMusicNotesAnimCmds8[] =
{
ANIMCMD_FRAME(4, 10, .vFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gMusicNotesAnimTable[] =
{
gWavyMusicNotesAnimCmds1,
gWavyMusicNotesAnimCmds2,
gWavyMusicNotesAnimCmds3,
gWavyMusicNotesAnimCmds4,
gWavyMusicNotesAnimCmds5,
gWavyMusicNotesAnimCmds6,
gWavyMusicNotesAnimCmds7,
gWavyMusicNotesAnimCmds8,
};
const union AffineAnimCmd gWavyMusicNotesAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0xC, 0xC, 0, 16),
AFFINEANIMCMD_FRAME(0xFFF4, 0xFFF4, 0, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gMusicNotesAffineAnimTable[] =
{
gWavyMusicNotesAffineAnimCmds,
};
const struct SpriteTemplate gWavyMusicNotesSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
.affineAnims = gMusicNotesAffineAnimTable,
.callback = AnimWavyMusicNotes,
};
const u16 gParticlesColorBlendTable[][6] =
{
{ANIM_TAG_MUSIC_NOTES, RGB(31, 31, 31), RGB(31, 26, 28), RGB(31, 22, 26), RGB(31, 17, 24), RGB(31, 13, 22)},
{ANIM_TAG_BENT_SPOON, RGB(31, 31, 31), RGB(25, 31, 26), RGB(20, 31, 21), RGB(15, 31, 16), RGB(10, 31, 12)},
{ANIM_TAG_SPHERE_TO_CUBE, RGB(31, 31, 31), RGB(31, 31, 24), RGB(31, 31, 17), RGB(31, 31, 10), RGB(31, 31, 3)},
{ANIM_TAG_LARGE_FRESH_EGG, RGB(31, 31, 31), RGB(26, 28, 31), RGB(21, 26, 31), RGB(16, 24, 31), RGB(12, 22, 31)},
};
const struct SpriteTemplate gFastFlyingMusicNotesSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
.affineAnims = gMusicNotesAffineAnimTable,
.callback = AnimFlyingMusicNotes,
};
const struct SpriteTemplate gBellyDrumHandSpriteTemplate =
{
.tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
.paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBellyDrumHand,
};
const union AffineAnimCmd gSlowFlyingMusicNotesAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0xA0, 0xA0, 0, 0),
AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 1),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd *const gSlowFlyingMusicNotesAffineAnimTable[] =
{
gSlowFlyingMusicNotesAffineAnimCmds,
};
const struct SpriteTemplate gSlowFlyingMusicNotesSpriteTemplate =
{
.tileTag = ANIM_TAG_MUSIC_NOTES,
.paletteTag = ANIM_TAG_MUSIC_NOTES,
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
.anims = gMusicNotesAnimTable,
.images = NULL,
.affineAnims = gSlowFlyingMusicNotesAffineAnimTable,
.callback = AnimSlowFlyingMusicNotes,
};
const union AnimCmd gMetronomeThroughtBubbleAnimCmds1[] =
{
ANIMCMD_FRAME(0, 2, .hFlip = TRUE),
ANIMCMD_FRAME(16, 2, .hFlip = TRUE),
ANIMCMD_FRAME(32, 2, .hFlip = TRUE),
ANIMCMD_FRAME(48, 2, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gMetronomeThroughtBubbleAnimCmds3[] =
{
ANIMCMD_FRAME(48, 2, .hFlip = TRUE),
ANIMCMD_FRAME(32, 2, .hFlip = TRUE),
ANIMCMD_FRAME(16, 2, .hFlip = TRUE),
ANIMCMD_FRAME(0, 2, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gMetronomeThroughtBubbleAnimCmds2[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(48, 2),
ANIMCMD_END,
};
const union AnimCmd gMetronomeThroughtBubbleAnimCmds4[] =
{
ANIMCMD_FRAME(48, 2),
ANIMCMD_FRAME(32, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_FRAME(0, 2),
ANIMCMD_END,
};
const union AnimCmd *const gMetronomeThroughtBubbleAnimTable[] =
{
gMetronomeThroughtBubbleAnimCmds1,
gMetronomeThroughtBubbleAnimCmds2,
gMetronomeThroughtBubbleAnimCmds3,
gMetronomeThroughtBubbleAnimCmds4,
};
const struct SpriteTemplate gThoughtBubbleSpriteTemplate =
{
.tileTag = ANIM_TAG_THOUGHT_BUBBLE,
.paletteTag = ANIM_TAG_THOUGHT_BUBBLE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gMetronomeThroughtBubbleAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThoughtBubble,
};
const union AffineAnimCmd gMetronomeFingerAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x1E, 0x1E, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gMetronomeFingerAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 11),
AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 11),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gMetronomeFingerAffineAnimCmds2_2[] =
{
AFFINEANIMCMD_FRAME(16, 16, 0, 0),
AFFINEANIMCMD_FRAME(30, 30, 0, 8),
AFFINEANIMCMD_FRAME(0, 0, 0, 16),
AFFINEANIMCMD_LOOP(0),
AFFINEANIMCMD_FRAME(0, 0, 4, 11),
AFFINEANIMCMD_FRAME(0, 0, -4, 11),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_FRAME(-30, -30, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gMetronomeFingerAffineAnimTable[] =
{
gMetronomeFingerAffineAnimCmds1,
gMetronomeFingerAffineAnimCmds2,
};
const struct SpriteTemplate gMetronomeFingerSpriteTemplate =
{
.tileTag = ANIM_TAG_FINGER,
.paletteTag = ANIM_TAG_FINGER,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gMetronomeFingerAffineAnimTable,
.callback = AnimMetronomeFinger,
};
const struct SpriteTemplate gFollowMeFingerSpriteTemplate =
{
.tileTag = ANIM_TAG_FINGER,
.paletteTag = ANIM_TAG_FINGER,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gMetronomeFingerAffineAnimTable,
.callback = AnimFollowMeFinger,
};
const union AnimCmd gTauntFingerAnimCmds1[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END,
};
const union AnimCmd gTauntFingerAnimCmds2[] =
{
ANIMCMD_FRAME(0, 1, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd gTauntFingerAnimCmds3[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_END,
};
const union AnimCmd gTauntFingerAnimCmds4[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
ANIMCMD_END,
};
const union AnimCmd *const gTauntFingerAnimTable[] =
{
gTauntFingerAnimCmds1,
gTauntFingerAnimCmds2,
gTauntFingerAnimCmds3,
gTauntFingerAnimCmds4,
};
const struct SpriteTemplate gTauntFingerSpriteTemplate =
{
.tileTag = ANIM_TAG_FINGER_2,
.paletteTag = ANIM_TAG_FINGER_2,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gTauntFingerAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTauntFinger,
};
// Animates the falling particles that horizontally wave back and forth.
// Used by Sleep Powder, Stun Spore, and Poison Powder.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: total duration in frames
// arg 3: vertical movement speed (sub-pixel value)
// arg 4: wave amplitude
// arg 5: wave speed
static void AnimMovePowderParticle(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
if (GetBattlerSide(gBattleAnimAttacker))
{
sprite->data[3] = -gBattleAnimArgs[4];
}
else
{
sprite->data[3] = gBattleAnimArgs[4];
}
sprite->data[4] = gBattleAnimArgs[5];
sprite->callback = AnimMovePowderParticle_Step;
}
static void AnimMovePowderParticle_Step(struct Sprite *sprite)
{
if (sprite->data[0] > 0)
{
sprite->data[0]--;
sprite->y2 = sprite->data[2] >> 8;
sprite->data[2] += sprite->data[1];
sprite->x2 = Sin(sprite->data[5], sprite->data[3]);
sprite->data[5] = (sprite->data[5] + sprite->data[4]) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
// Moves an energy orb towards the center of the mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
static void AnimPowerAbsorptionOrb(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
}
// Moves an orb in a straight line towards the target mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
// arg 3: sprite anim number
static void AnimSolarBeamBigOrb(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
StartSpriteAnim(sprite, gBattleAnimArgs[3]);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Moves a small orb in a wavy pattern towards the target mon.
// The small orb "circles" the big orbs in AnimSolarBeamBigOrb.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration
// arg 3: initial wave offset
static void AnimSolarBeamSmallOrb(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimLinearTranslation(sprite);
sprite->data[5] = gBattleAnimArgs[3];
sprite->callback = AnimSolarBeamSmallOrb_Step;
sprite->callback(sprite);
}
static void AnimSolarBeamSmallOrb_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite))
{
DestroySprite(sprite);
}
else
{
if (sprite->data[5] > 0x7F)
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 1;
else
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 6;
sprite->x2 += Sin(sprite->data[5], 5);
sprite->y2 += Cos(sprite->data[5], 14);
sprite->data[5] = (sprite->data[5] + 15) & 0xFF;
}
}
// Creates 15 small secondary orbs used in the SolarBeam anim effect.
// There is a 7-frame delay between each of them.
// No args.
void AnimTask_CreateSmallSolarBeamOrbs(u8 taskId)
{
if (--gTasks[taskId].data[0] == -1)
{
gTasks[taskId].data[1]++;
gTasks[taskId].data[0] = 6;
gBattleAnimArgs[0] = 15;
gBattleAnimArgs[1] = 0;
gBattleAnimArgs[2] = 80;
gBattleAnimArgs[3] = 0;
CreateSpriteAndAnimate(&gSolarBeamSmallOrbSpriteTemplate, 0, 0, GetBattlerSpriteSubpriority(gBattleAnimTarget) + 1);
}
if (gTasks[taskId].data[1] == 15)
DestroyAnimVisualTask(taskId);
}
// Moves an orb from the target mon to the attacking mon in an arc-like fashion.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: wave amplitude
// arg 3: wave period (lower means faster wave)
static void AnimAbsorptionOrb(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[5] = gBattleAnimArgs[2];
InitAnimArcTranslation(sprite);
sprite->callback = AnimAbsorptionOrb_Step;
}
static void AnimAbsorptionOrb_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
DestroyAnimSprite(sprite);
}
// Moves an orb in a wave-like fashion towards the target mon. The wave's
// properties and the sprite anim are randomly determined.
static void AnimHyperBeamOrb(struct Sprite *sprite)
{
u16 speed;
u16 animNum = Random2();
StartSpriteAnim(sprite, animNum % 8);
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= 20;
else
sprite->x += 20;
speed = Random2();
sprite->data[0] = (speed & 31) + 64;
sprite->data[1] = sprite->x;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitAnimFastLinearTranslationWithSpeed(sprite);
sprite->data[5] = Random2() & 0xFF;
sprite->data[6] = sprite->subpriority;
sprite->callback = AnimHyperBeamOrb_Step;
sprite->callback(sprite);
}
static void AnimHyperBeamOrb_Step(struct Sprite *sprite)
{
if (AnimFastTranslateLinear(sprite))
{
DestroyAnimSprite(sprite);
}
else
{
sprite->y2 += Cos(sprite->data[5], 12);
if (sprite->data[5] < 0x7F)
sprite->subpriority = sprite->data[6];
else
sprite->subpriority = sprite->data[6] + 1;
sprite->data[5] += 24;
sprite->data[5] &= 0xFF;
}
}
// seed (sprouts a sapling from a seed.)
// Used by Leech Seed.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target x pixel offset
// arg 3: target y pixel offset
// arg 4: duration
// arg 5: wave amplitude
static void AnimLeechSeed(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[3];
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
sprite->callback = AnimLeechSeed_Step;
}
static void AnimLeechSeed_Step(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
sprite->invisible = TRUE;
sprite->data[0] = 10;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimLeechSeedSprouts);
}
}
static void AnimLeechSeedSprouts(struct Sprite *sprite)
{
sprite->invisible = FALSE;
StartSpriteAnim(sprite, 1);
sprite->data[0] = 60;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
// Moves a spore particle in a halo around the target mon.
// The sprite's priority is updated to give the effect of going
// behind the mon's sprite.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: initial wave offset
// arg 3: duration
// arg 4: blend (0 = off, 1 = on)
static void AnimSporeParticle(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, TRUE);
StartSpriteAnim(sprite, gBattleAnimArgs[4]);
if (gBattleAnimArgs[4] == 1)
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = gBattleAnimArgs[2];
sprite->callback = AnimSporeParticle_Step;
sprite->callback(sprite);
}
static void AnimSporeParticle_Step(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[1], 32);
sprite->y2 = Cos(sprite->data[1], -3) + ((sprite->data[2] += 24) >> 8);
if ((u16)(sprite->data[1] - 0x40) < 0x80)
{
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
}
else
{
u8 priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1;
if (priority > 3)
priority = 3;
sprite->oam.priority = priority;
}
sprite->data[1] += 2;
sprite->data[1] &= 0xFF;
if (--sprite->data[0] == -1)
DestroyAnimSprite(sprite);
}
// In a double battle, Updates the mon sprite background priorities to allow
// the circling effect controlled by AnimSporeParticle.
// No args.
void AnimTask_SporeDoubleBattle(u8 taskId)
{
if (IsContest() || !IsDoubleBattle())
{
DestroyAnimVisualTask(taskId);
}
else
{
if (GetBattlerSpriteBGPriorityRank(gBattleAnimTarget) == 1)
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 3);
else
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
}
}
// Rotates a big flower around the attacking mon, and slowly floats
// downward.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target y pixel offset
// arg 3: duration
static void AnimPetalDanceBigFlower(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
InitAnimLinearTranslation(sprite);
sprite->data[5] = 0x40;
sprite->callback = AnimPetalDanceBigFlower_Step;
sprite->callback(sprite);
}
static void AnimPetalDanceBigFlower_Step(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->x2 += Sin(sprite->data[5], 32);
sprite->y2 += Cos(sprite->data[5], -5);
if ((u16)(sprite->data[5] - 0x40) < 0x80)
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1;
else
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + 1;
sprite->data[5] = (sprite->data[5] + 5) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
// Slowly floats a small flower downard, while swaying from right to left.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: target y pixel offset
// arg 3: duration
static void AnimPetalDanceSmallFlower(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = sprite->x;
sprite->data[2] = sprite->x;
sprite->data[3] = sprite->y;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
InitAnimLinearTranslation(sprite);
sprite->data[5] = 0x40;
sprite->callback = AnimPetalDanceSmallFlower_Step;
sprite->callback(sprite);
}
static void AnimPetalDanceSmallFlower_Step(struct Sprite *sprite)
{
if (!AnimTranslateLinear(sprite))
{
sprite->x2 += Sin(sprite->data[5], 8);
if ((u16)(sprite->data[5] - 59) < 5 || (u16)(sprite->data[5] - 187) < 5)
sprite->oam.matrixNum ^= ST_OAM_HFLIP;
sprite->data[5] += 5;
sprite->data[5] &= 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
// Shoots a leaf upward, then floats it downward while swaying back and forth.
// arg 0: upward x delta per frame
// arg 1: upward y delta per frame
// arg 2: upward duration
static void AnimRazorLeafParticle(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[2];
sprite->callback = AnimRazorLeafParticle_Step1;
}
static void AnimRazorLeafParticle_Step1(struct Sprite *sprite)
{
if (!sprite->data[2])
{
if (sprite->data[1] & 1)
{
sprite->data[0] = 0x80;
sprite->data[1] = 0;
sprite->data[2] = 0;
}
else
{
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 0;
}
sprite->callback = AnimRazorLeafParticle_Step2;
}
else
{
sprite->data[2]--;
sprite->x += sprite->data[0];
sprite->y += sprite->data[1];
}
}
static void AnimRazorLeafParticle_Step2(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker))
sprite->x2 = -Sin(sprite->data[0], 25);
else
sprite->x2 = Sin(sprite->data[0], 25);
sprite->data[0] += 2;
sprite->data[0] &= 0xFF;
sprite->data[1]++;
if (!(sprite->data[1] & 1))
sprite->y2++;
if (sprite->data[1] > 80)
DestroyAnimSprite(sprite);
}
// Animates a sprite that moves linearly from one location to another, with a
// single-cycle sine wave added to the y position along the way.
// Used by Razor Leaf and Magical Leaf.
// arg 0: initial x offset
// arg 1: initial y offset
// arg 2: target x offset
// arg 3: target y offset
// arg 4: translation duration
// arg 5: wave amplitude
// arg 6: target between double battle opponents (boolean)
static void AnimTranslateLinearSingleSineWave(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
if (!gBattleAnimArgs[6])
{
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
}
else
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->data[2], &sprite->data[4]);
sprite->data[2] += gBattleAnimArgs[2];
sprite->data[4] += gBattleAnimArgs[3];
}
sprite->data[5] = gBattleAnimArgs[5];
InitAnimArcTranslation(sprite);
if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
sprite->data[0] = 1;
else
sprite->data[0] = 0;
sprite->callback = AnimTranslateLinearSingleSineWave_Step;
}
static void AnimTranslateLinearSingleSineWave_Step(struct Sprite *sprite)
{
bool8 destroy = FALSE;
s16 a = sprite->data[0];
s16 b = sprite->data[7];
s16 r0;
sprite->data[0] = 1;
TranslateAnimHorizontalArc(sprite);
r0 = sprite->data[7];
sprite->data[0] = a;
if (b > 200 && r0 < 56 && sprite->oam.affineParam == 0)
sprite->oam.affineParam++;
if (sprite->oam.affineParam && sprite->data[0])
{
sprite->invisible ^= 1;
sprite->oam.affineParam++;
if (sprite->oam.affineParam == 30)
destroy = TRUE;
}
if (sprite->x + sprite->x2 > DISPLAY_WIDTH + 16
|| sprite->x + sprite->x2 < -16
|| sprite->y + sprite->y2 > DISPLAY_HEIGHT
|| sprite->y + sprite->y2 < -16)
destroy = TRUE;
if (destroy)
DestroyAnimSprite(sprite);
}
// Animates particles in the Twister move animation.
// arg 0: duration
// arg 1: total y delta (the particles rise upward)
// arg 2: wave period (higher means faster wave)
// arg 3: wave amplitude
// arg 4: speedup frame (particles move faster at the end of the animation)
void AnimMoveTwisterParticle(struct Sprite *sprite)
{
if (IsDoubleBattle() == TRUE)
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->x, &sprite->y);
sprite->y += 32;
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[2];
sprite->data[3] = gBattleAnimArgs[3];
sprite->data[4] = gBattleAnimArgs[4];
sprite->callback = AnimMoveTwisterParticle_Step;
}
static void AnimMoveTwisterParticle_Step(struct Sprite *sprite)
{
if (sprite->data[1] == 0xFF)
{
sprite->y -= 2;
}
else if (sprite->data[1] > 0)
{
sprite->y -= 2;
sprite->data[1] -= 2;
}
sprite->data[5] += sprite->data[2];
if (sprite->data[0] < sprite->data[4])
sprite->data[5] += sprite->data[2];
sprite->data[5] &= 0xFF;
sprite->x2 = Cos(sprite->data[5], sprite->data[3]);
sprite->y2 = Sin(sprite->data[5], 5);
if (sprite->data[5] < 0x80)
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) - 1;
else
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1;
if (--sprite->data[0] == 0)
DestroyAnimSprite(sprite);
}
// Squeezes a constricting "rope" several times via affine animations.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: affine anim num
// arg 3: num squeezes
static void AnimConstrictBinding(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->affineAnimPaused = 1;
StartSpriteAffineAnim(sprite, gBattleAnimArgs[2]);
sprite->data[6] = gBattleAnimArgs[2];
sprite->data[7] = gBattleAnimArgs[3];
sprite->callback = AnimConstrictBinding_Step1;
}
static void AnimConstrictBinding_Step1(struct Sprite *sprite)
{
u8 spriteId;
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
{
sprite->affineAnimPaused = 0;
spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
sprite->data[0] = 0x100;
sprite->callback = AnimConstrictBinding_Step2;
}
}
static void AnimConstrictBinding_Step2(struct Sprite *sprite)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
if (!sprite->data[2])
sprite->data[0] += 11;
else
sprite->data[0] -= 11;
if (++sprite->data[1] == 6)
{
sprite->data[1] = 0;
sprite->data[2] ^= 1;
}
if (sprite->affineAnimEnded)
{
if (--sprite->data[7] > 0)
StartSpriteAffineAnim(sprite, sprite->data[6]);
else
DestroyAnimSprite(sprite);
}
}
void AnimTask_ShrinkTargetCopy(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
if (gSprites[spriteId].invisible)
{
DestroyAnimVisualTask(taskId);
}
else
{
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
gTasks[taskId].data[14] = gSprites[spriteId].oam.priority;
gSprites[spriteId].oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
spriteId = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER);
gTasks[taskId].data[15] = gSprites[spriteId].oam.priority;
gSprites[spriteId].oam.priority = GetBattlerSpriteBGPriority(BATTLE_PARTNER(gBattleAnimTarget));
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[1] = gBattleAnimArgs[1];
gTasks[taskId].data[11] = 0x100;
gTasks[taskId].func = AnimTask_DuplicateAndShrinkToPos_Step1;
}
}
static void AnimTask_DuplicateAndShrinkToPos_Step1(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
gTasks[taskId].data[10] += gTasks[taskId].data[0];
gSprites[spriteId].x2 = gTasks[taskId].data[10] >> 8;
if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
gSprites[spriteId].x2 = -gSprites[spriteId].x2;
gTasks[taskId].data[11] += 16;
SetSpriteRotScale(spriteId, gTasks[taskId].data[11], gTasks[taskId].data[11], 0);
SetBattlerSpriteYOffsetFromYScale(spriteId);
if (--gTasks[taskId].data[1] == 0)
{
gTasks[taskId].data[0] = 0;
gTasks[taskId].func = AnimTask_DuplicateAndShrinkToPos_Step2;
}
}
static void AnimTask_DuplicateAndShrinkToPos_Step2(u8 taskId)
{
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
{
if (gTasks[taskId].data[0] == 0)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
ResetSpriteRotScale(spriteId);
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
gSprites[spriteId].oam.priority = gTasks[taskId].data[14];
spriteId = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER);
gSprites[spriteId].oam.priority = gTasks[taskId].data[15];
gTasks[taskId].data[0]++;
return;
}
}
else
{
if (gTasks[taskId].data[0] == 0)
return;
}
gTasks[taskId].data[0]++;
if (gTasks[taskId].data[0] == 3)
DestroyAnimVisualTask(taskId);
}
// Moves an orb from the target mon to the attacking mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
static void AnimMimicOrb(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
gBattleAnimArgs[0] *= -1;
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[1];
sprite->invisible = TRUE;
sprite->data[0]++;
break;
case 1:
sprite->invisible = FALSE;
if (sprite->affineAnimEnded)
{
ChangeSpriteAffineAnim(sprite, 1);
sprite->data[0] = 25;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = InitAndRunAnimFastLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
break;
}
}
}
// Animates a root that flickers away after some time.
// arg 0: x pixel offset
// arg 1: y pixel offset
// arg 2: sprite subpriority offset
// arg 3: sprite anim num
// arg 4: duration
static void AnimIngrainRoot(struct Sprite *sprite)
{
if (!sprite->data[0])
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
sprite->x2 = gBattleAnimArgs[0];
sprite->y2 = gBattleAnimArgs[1];
sprite->subpriority = gBattleAnimArgs[2] + 30;
StartSpriteAnim(sprite, gBattleAnimArgs[3]);
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[0]++;
if (sprite->y + sprite->y2 > 120)
sprite->y += sprite->y2 + sprite->y - 120;
}
sprite->callback = AnimRootFlickerOut;
}
// Places a root on the path to the target mon that flickers away after some time.
// arg 0: percent along the path to the target mon
// arg 1: x pixel offset
// arg 2: y pixel offset
// arg 3: sprite subpriority offset
// arg 4: sprite anum num
// arg 5: duration
static void AnimFrenzyPlantRoot(struct Sprite *sprite)
{
s16 attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
s16 attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
s16 targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
s16 targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
targetX -= attackerX;
targetY -= attackerY;
sprite->x = attackerX + targetX * gBattleAnimArgs[0] / 100;
sprite->y = attackerY + targetY * gBattleAnimArgs[0] / 100;
sprite->x2 = gBattleAnimArgs[1];
sprite->y2 = gBattleAnimArgs[2];
sprite->subpriority = gBattleAnimArgs[3] + 30;
StartSpriteAnim(sprite, gBattleAnimArgs[4]);
sprite->data[2] = gBattleAnimArgs[5];
sprite->callback = AnimRootFlickerOut;
sFrenzyPlantRootData.startX = sprite->x;
sFrenzyPlantRootData.startY = sprite->y;
sFrenzyPlantRootData.targetX = targetX;
sFrenzyPlantRootData.targetY = targetY;
}
static void AnimRootFlickerOut(struct Sprite *sprite)
{
if (++sprite->data[0] > (sprite->data[2] - 10))
sprite->invisible = sprite->data[0] % 2;
if (sprite->data[0] > sprite->data[2])
DestroyAnimSprite(sprite);
}
// Moves an orb in a fast wavy path.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: horizontal velocity
// arg 3: wave amplitude
// arg 4: duration
static void AnimIngrainOrb(struct Sprite *sprite)
{
if (!sprite->data[0])
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
}
sprite->data[0]++;
sprite->x2 = sprite->data[1] * sprite->data[0];
sprite->y2 = Sin((sprite->data[0] * 20) & 0xFF, sprite->data[2]);
if (sprite->data[0] > sprite->data[3])
DestroyAnimSprite(sprite);
}
static void InitItemBagData(struct Sprite *sprite, s16 c)
{
int a = (sprite->x << 8) | sprite->y;
int b = (sprite->data[6] << 8) | sprite->data[7];
c <<= 8;
sprite->data[5] = a;
sprite->data[6] = b;
sprite->data[7] = c;
}
bool8 moveAlongLinearPath(struct Sprite *sprite)
{
u16 xStartPos = (u8)(sprite->data[5] >> 8);
u16 yStartPos = (u8)sprite->data[5];
s32 xEndPos = (u8)(sprite->data[6] >> 8);
s32 yEndPos = (u8)sprite->data[6];
s16 totalTime = sprite->data[7] >> 8;
s16 currentTime = sprite->data[7] & 0xFF;
s16 yEndPos_2;
s16 r0;
s32 var1;
s32 vaxEndPos;
if (xEndPos == 0)
xEndPos = -32;
else if (xEndPos == 255)
xEndPos = DISPLAY_WIDTH + 32;
yEndPos_2 = yEndPos - yStartPos;
r0 = xEndPos - xStartPos;
var1 = r0 * currentTime / totalTime;
vaxEndPos = yEndPos_2 * currentTime / totalTime;
sprite->x = var1 + xStartPos;
sprite->y = vaxEndPos + yStartPos;
if (++currentTime == totalTime)
return TRUE;
sprite->data[7] = (totalTime << 8) | currentTime;
return FALSE;
}
static void AnimItemSteal_Step2(struct Sprite *sprite)
{
if (sprite->data[0] == 10)
StartSpriteAffineAnim(sprite, 1);
sprite->data[0]++;
if (sprite->data[0] > 50)
DestroyAnimSprite(sprite);
}
static void AnimItemSteal_Step1(struct Sprite *sprite)
{
sprite->data[0] += sprite->data[3] * 128 / sprite->data[4];
if (sprite->data[0] >= 128)
{
sprite->data[1]++;
sprite->data[0] = 0;
}
sprite->y2 = Sin(sprite->data[0] + 128, 30 - sprite->data[1] * 8);
if (moveAlongLinearPath(sprite))
{
sprite->y2 = 0;
sprite->data[0] = 0;
sprite->callback = AnimItemSteal_Step2;
}
}
static void AnimPresent(struct Sprite *sprite)
{
s16 targetX;
s16 targetY;
InitSpritePosToAnimAttacker(sprite, FALSE);
targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget)
{
sprite->data[6] = targetX;
sprite->data[7] = targetY + 10;
InitItemBagData(sprite, 60);
sprite->data[3] = 1;
}
else
{
sprite->data[6] = targetX;
sprite->data[7] = targetY + 10;
InitItemBagData(sprite, 60);
sprite->data[3] = 3;
}
sprite->data[4] = 60;
sprite->callback = AnimItemSteal_Step1;
}
static void AnimKnockOffOpponentsItem(struct Sprite *sprite)
{
int zero;
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
zero = 0;
if (sprite->data[0] > 0x7F)
{
sprite->data[1]++;
sprite->data[0] = zero;
}
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
if (moveAlongLinearPath(sprite))
{
sprite->y2 = zero;
sprite->data[0] = zero;
DestroyAnimSprite(sprite);
}
}
static void AnimKnockOffItem(struct Sprite *sprite)
{
s16 targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
sprite->data[6] = 0;
sprite->data[7] = targetY + 10;
InitItemBagData(sprite, 40);
sprite->data[3] = 3;
sprite->data[4] = 60;
sprite->callback = AnimItemSteal_Step1;
}
else
{
sprite->data[6] = 255;
sprite->data[7] = targetY + 10;
if (IsContest())
sprite->data[6] = 0;
InitItemBagData(sprite, 40);
sprite->data[3] = 3;
sprite->data[4] = 60;
sprite->callback = AnimKnockOffOpponentsItem;
}
}
// Animates a heal particle upward.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: vertical velocity
// arg 3: unused
static void AnimPresentHealParticle(struct Sprite *sprite)
{
if (!sprite->data[0])
{
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->data[1] = gBattleAnimArgs[2];
}
sprite->data[0]++;
sprite->y2 = sprite->data[1] * sprite->data[0];
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimItemSteal(struct Sprite *sprite)
{
s16 attackerX;
s16 attackerY;
InitSpritePosToAnimTarget(sprite, FALSE);
attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
if (BATTLE_PARTNER(gBattleAnimTarget) == gBattleAnimAttacker)
{
sprite->data[6] = attackerX;
sprite->data[7] = attackerY + 10;
InitItemBagData(sprite, 60);
sprite->data[3] = 1;
}
else
{
sprite->data[6] = attackerX;
sprite->data[7] = attackerY + 10;
InitItemBagData(sprite, 60);
sprite->data[3] = 3;
}
sprite->data[4] = 60;
sprite->callback = AnimItemSteal_Step3;
}
static void AnimItemSteal_Step3(struct Sprite *sprite)
{
int zero;
sprite->data[0] += ((sprite->data[3] * 128) / sprite->data[4]);
zero = 0;
if (sprite->data[0] > 127)
{
sprite->data[1]++;
sprite->data[0] = zero;
}
sprite->y2 = Sin(sprite->data[0] + 0x80, 30 - sprite->data[1] * 8);
if (sprite->y2 == 0)
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
if (moveAlongLinearPath(sprite))
{
sprite->y2 = 0;
sprite->data[0] = 0;
sprite->callback = AnimItemSteal_Step2;
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
}
// Moves a bag in a circular motion.
// arg 0: y position
// arg 1: initial wave offset
static void AnimTrickBag(struct Sprite *sprite)
{
int a;
int b;
if (!sprite->data[0])
{
if (!IsContest())
{
sprite->data[1] = gBattleAnimArgs[1];
sprite->x = 120;
}
else
{
a = gBattleAnimArgs[1] - 32;
if (a < 0)
b = gBattleAnimArgs[1] + 0xDF;
else
b = a;
sprite->data[1] = a - ((b >> 8) << 8);
sprite->x = 70;
}
sprite->y = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[0];
sprite->data[4] = 20;
sprite->x2 = Cos(sprite->data[1], 60);
sprite->y2 = Sin(sprite->data[1], 20);
sprite->callback = AnimTrickBag_Step1;
if (sprite->data[1] > 0 && sprite->data[1] < 192)
sprite->subpriority = 31;
else
sprite->subpriority = 29;
}
}
static void AnimTrickBag_Step1(struct Sprite *sprite)
{
switch (sprite->data[3])
{
case 0:
if (sprite->data[2] > 78)
{
sprite->data[3] = 1;
StartSpriteAffineAnim(sprite, 1);
break;
}
else
{
sprite->data[2] += sprite->data[4] / 10;
sprite->data[4] += 3;
sprite->y = sprite->data[2];
break;
}
break;
case 1:
if (sprite->data[3] && sprite->affineAnimEnded)
{
sprite->data[0] = 0;
sprite->data[2] = 0;
sprite->callback = AnimTrickBag_Step2;
}
break;
}
}
static void AnimTrickBag_Step2(struct Sprite *sprite)
{
if (sprite->data[2] == gTrickBagCoordinates[sprite->data[0]][1])
{
if (gTrickBagCoordinates[sprite->data[0]][2] == 127)
{
sprite->data[0] = 0;
sprite->callback = AnimTrickBag_Step3;
}
sprite->data[2] = 0;
sprite->data[0]++;
}
else
{
sprite->data[2]++;
sprite->data[1] = (gTrickBagCoordinates[sprite->data[0]][0] * gTrickBagCoordinates[sprite->data[0]][2] + sprite->data[1]) & 0xFF;
if (!IsContest())
{
if ((u16)(sprite->data[1] - 1) < 191)
sprite->subpriority = 31;
else
sprite->subpriority = 29;
}
sprite->x2 = Cos(sprite->data[1], 60);
sprite->y2 = Sin(sprite->data[1], 20);
}
}
static void AnimTrickBag_Step3(struct Sprite *sprite)
{
if (sprite->data[0] > 20)
DestroyAnimSprite(sprite);
sprite->invisible = sprite->data[0] % 2;
sprite->data[0]++;
}
void AnimTask_LeafBlade(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[4] = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 1;
task->data[6] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->data[7] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
task->data[10] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_WIDTH);
task->data[11] = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT);
task->data[5] = (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) ? 1 : -1;
task->data[9] = 56 - (task->data[5] * 64);
task->data[8] = task->data[7] - task->data[9] + task->data[6];
task->data[2] = CreateSprite(&gLeafBladeSpriteTemplate, task->data[8], task->data[9], task->data[4]);
if (task->data[2] == MAX_SPRITES)
DestroyAnimVisualTask(taskId);
gSprites[task->data[2]].data[0] = 10;
gSprites[task->data[2]].data[1] = task->data[8];
gSprites[task->data[2]].data[2] = task->data[6] - (task->data[10] / 2 + 10) * task->data[5];
gSprites[task->data[2]].data[3] = task->data[9];
gSprites[task->data[2]].data[4] = task->data[7] + (task->data[11] / 2 + 10) * task->data[5];
gSprites[task->data[2]].data[5] = LeafBladeGetPosFactor(&gSprites[task->data[2]]);
InitAnimArcTranslation(&gSprites[task->data[2]]);
task->func = AnimTask_LeafBlade_Step;
}
static void AnimTask_LeafBlade_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
struct Sprite *sprite = &gSprites[task->data[2]];
int a = task->data[0];
switch (a)
{
case 4:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 5;
task->data[0] = 0xFF;
}
break;
case 8:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 9;
task->data[0] = 0xFF;
}
break;
case 0:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 1;
task->data[0] = 0xFF;
}
break;
case 1:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[6];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[7];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[4] += 2;
task->data[3] = a;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
case 2:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 3;
task->data[0] = 0xFF;
}
break;
case 3:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[6] - ((task->data[10] / 2) + 10) * task->data[5];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[7] - ((task->data[11] / 2) + 10) * task->data[5];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[3] = 2;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
case 5:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[6] + ((task->data[10] / 2) + 10) * task->data[5];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[7] + ((task->data[11] / 2) + 10) * task->data[5];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[4] -= 2;
task->data[3] = 3;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
case 6:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 7;
task->data[0] = 0xFF;
}
break;
case 7:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[6];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[7];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[4] += 2;
task->data[3] = 4;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
case 9:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[6] - ((task->data[10] / 2) + 10) * task->data[5];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[7] + ((task->data[11] / 2) + 10) * task->data[5];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[3] = 5;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
case 10:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
task->data[15] = 11;
task->data[0] = 0xFF;
}
break;
case 11:
{
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 10;
sprite->data[1] = sprite->x;
sprite->data[2] = task->data[8];
sprite->data[3] = sprite->y;
sprite->data[4] = task->data[9];
sprite->data[5] = LeafBladeGetPosFactor(sprite);
task->data[4] -= 2;
task->data[3] = 6;
sprite->subpriority = task->data[4];
StartSpriteAnim(sprite, task->data[3]);
InitAnimArcTranslation(sprite);
task->data[0]++;
break;
}
case 12:
AnimTask_LeafBlade_Step2(task, taskId);
if (TranslateAnimHorizontalArc(sprite))
{
DestroySprite(sprite);
task->data[0]++;
}
break;
case 13:
if (task->data[12] == 0)
DestroyAnimVisualTask(taskId);
break;
case 0xFF:
if (++task->data[1] > 5)
{
task->data[1] = 0;
task->data[0] = task->data[15];
}
break;
}
}
static s16 LeafBladeGetPosFactor(struct Sprite *sprite)
{
s16 var = 8;
if (sprite->data[4] < sprite->y)
var = -var;
return var;
}
static void AnimTask_LeafBlade_Step2(struct Task *task, u8 taskId)
{
task->data[14]++;
if (task->data[14] > 0)
{
u8 spriteId;
s16 spriteX;
s16 spriteY;
task->data[14] = 0;
spriteX = gSprites[task->data[2]].x + gSprites[task->data[2]].x2;
spriteY = gSprites[task->data[2]].y + gSprites[task->data[2]].y2;
spriteId = CreateSprite(&gLeafBladeSpriteTemplate, spriteX, spriteY, task->data[4]);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].data[6] = taskId;
gSprites[spriteId].data[7] = 12;
gTasks[taskId].data[12]++;
gSprites[spriteId].data[0] = task->data[13] & 1;
gTasks[taskId].data[13]++;
StartSpriteAnim(&gSprites[spriteId], task->data[3]);
gSprites[spriteId].subpriority = task->data[4];
gSprites[spriteId].callback = AnimTask_LeafBlade_Step2_Callback;
}
}
}
static void AnimTask_LeafBlade_Step2_Callback(struct Sprite *sprite)
{
sprite->data[0]++;
if (sprite->data[0] > 1)
{
sprite->data[0] = 0;
sprite->invisible ^= 1;
sprite->data[1]++;
if (sprite->data[1] > 8)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
DestroySprite(sprite);
}
}
}
static void AnimFlyingParticle(struct Sprite *sprite)
{
u8 battler;
if (!gBattleAnimArgs[6])
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
{
sprite->data[4] = 0;
sprite->data[2] = gBattleAnimArgs[3];
sprite->x = 0xFFF0;
}
else
{
sprite->data[4] = 1;
sprite->data[2] = -gBattleAnimArgs[3];
sprite->x = 0x100;
}
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[3] = gBattleAnimArgs[4];
switch (gBattleAnimArgs[5])
{
case 0:
sprite->y = gBattleAnimArgs[0];
sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
break;
case 1:
sprite->y = gBattleAnimArgs[0];
sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
break;
case 2:
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[0];
sprite->oam.priority = GetBattlerSpriteBGPriority(battler);
break;
case 3:
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[0];
GetAnimBattlerSpriteId(ANIM_TARGET);
sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
break;
}
sprite->callback = AnimFlyingParticle_Step;
}
static void AnimFlyingParticle_Step(struct Sprite *sprite)
{
int a = sprite->data[7];
sprite->data[7]++;
sprite->y2 = (sprite->data[1] * gSineTable[sprite->data[0]]) >> 8;
sprite->x2 = sprite->data[2] * a;
sprite->data[0] = (sprite->data[3] * a) & 0xFF;
if (!sprite->data[4])
{
if (sprite->x2 + sprite->x <= 0xF7)
return;
}
else
{
if (sprite->x2 + sprite->x > -16)
return;
}
DestroySpriteAndMatrix(sprite);
}
void AnimTask_CycleMagicalLeafPal(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[8] = OBJ_PLTT_ID(IndexOfSpritePaletteTag(ANIM_TAG_LEAF));
task->data[12] = OBJ_PLTT_ID(IndexOfSpritePaletteTag(ANIM_TAG_RAZOR_LEAF));
task->data[0]++;
break;
case 1:
if (++task->data[9] >= 0)
{
task->data[9] = 0;
BlendPalette(task->data[8], 16, task->data[10], gMagicalLeafBlendColors[task->data[11]]);
BlendPalette(task->data[12], 16, task->data[10], gMagicalLeafBlendColors[task->data[11]]);
if (++task->data[10] == 17)
{
task->data[10] = 0;
if (++task->data[11] == 7)
task->data[11] = 0;
}
}
break;
}
if (gBattleAnimArgs[7] == -1)
DestroyAnimVisualTask(taskId);
}
static void AnimNeedleArmSpike(struct Sprite *sprite)
{
u8 a;
u8 b;
u16 c;
u16 x;
u16 y;
if (gBattleAnimArgs[4] == 0)
{
DestroyAnimSprite(sprite);
}
else
{
if (gBattleAnimArgs[0] == 0)
{
a = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
else
{
a = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->data[0] = gBattleAnimArgs[4];
if (gBattleAnimArgs[1] == 0)
{
sprite->x = gBattleAnimArgs[2] + a;
sprite->y = gBattleAnimArgs[3] + b;
sprite->data[5] = a;
sprite->data[6] = b;
}
else
{
sprite->x = a;
sprite->y = b;
sprite->data[5] = gBattleAnimArgs[2] + a;
sprite->data[6] = gBattleAnimArgs[3] + b;
}
x = sprite->x;
sprite->data[1] = x * 16;
y = sprite->y;
sprite->data[2] = y * 16;
sprite->data[3] = (sprite->data[5] - sprite->x) * 16 / gBattleAnimArgs[4];
sprite->data[4] = (sprite->data[6] - sprite->y) * 16 / gBattleAnimArgs[4];
c = ArcTan2Neg(sprite->data[5] - x, sprite->data[6] - y);
if (IsContest())
c -= 0x8000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, c);
sprite->callback = AnimNeedleArmSpike_Step;
}
}
static void AnimNeedleArmSpike_Step(struct Sprite *sprite)
{
if (sprite->data[0])
{
sprite->data[1] += sprite->data[3];
sprite->data[2] += sprite->data[4];
sprite->x = sprite->data[1] >> 4 ;
sprite->y = sprite->data[2] >> 4 ;
sprite->data[0]--;
}
else
{
DestroySpriteAndMatrix(sprite);
}
}
static void AnimWhipHit_WaitEnd(struct Sprite *sprite)
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimSlidingHit(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
else
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimWhipHit(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
StartSpriteAnim(sprite, 1);
sprite->callback = AnimWhipHit_WaitEnd;
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
}
static void AnimFlickeringPunch(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[3] = gBattleAnimArgs[4];
sprite->data[5] = gBattleAnimArgs[5];
StartSpriteAffineAnim(sprite, gBattleAnimArgs[6]);
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = TranslateSpriteLinearAndFlicker;
}
// Moves the sprite in a diagonally slashing motion across the target mon.
// Used by moves such as MOVE_CUT and MOVE_AERIAL_ACE.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: slice direction; 0 = right-to-left, 1 = left-to-right
static void AnimCuttingSlice(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
sprite->y += 8;
sprite->callback = AnimSlice_Step;
if (gBattleAnimArgs[2] == 0)
{
sprite->x += gBattleAnimArgs[0];
}
else
{
sprite->x -= gBattleAnimArgs[0];
sprite->hFlip = 1;
}
sprite->y += gBattleAnimArgs[1];
sprite->data[1] -= 0x400;
sprite->data[2] += 0x400;
sprite->data[5] = gBattleAnimArgs[2];
if (sprite->data[5] == 1)
sprite->data[1] = -sprite->data[1];
}
static void AnimAirCutterSlice(struct Sprite *sprite)
{
u8 x, y;
switch (gBattleAnimArgs[3])
{
case 1:
x = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_X);
y = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_Y);
break;
case 2:
x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget)))
{
x = (GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_X) + x) / 2;
y = (GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimTarget), BATTLER_COORD_Y) + y) / 2;
}
break;
case 0:
default:
x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
break;
}
sprite->x = x;
sprite->y = y;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
sprite->y += 8;
sprite->callback = AnimSlice_Step;
if (gBattleAnimArgs[2] == 0)
{
sprite->x += gBattleAnimArgs[0];
}
else
{
sprite->x -= gBattleAnimArgs[0];
sprite->hFlip = 1;
}
sprite->y += gBattleAnimArgs[1];
sprite->data[1] -= 0x400;
sprite->data[2] += 0x400;
sprite->data[5] = gBattleAnimArgs[2];
if (sprite->data[5] == 1)
sprite->data[1] = -sprite->data[1];
}
static void AnimSlice_Step(struct Sprite *sprite)
{
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
if (sprite->data[5] == 0)
sprite->data[1] += 0x18;
else
sprite->data[1] -= 0x18;
sprite->data[2] -= 0x18;
sprite->x2 = sprite->data[3] >> 8;
sprite->y2 = sprite->data[4] >> 8;
sprite->data[0]++;
if (sprite->data[0] == 20)
{
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->data[0] = 3;
sprite->callback = WaitAnimForDuration;
}
}
static void UnusedFlickerAnim(struct Sprite *sprite)
{
if (sprite->data[2] > 1)
{
if (sprite->data[3] & 1)
{
sprite->invisible = FALSE;
gSprites[sprite->data[0]].invisible = FALSE;
gSprites[sprite->data[1]].invisible = FALSE;
}
else
{
sprite->invisible = TRUE;
gSprites[sprite->data[0]].invisible = TRUE;
gSprites[sprite->data[1]].invisible = TRUE;
}
sprite->data[2] = 0;
sprite->data[3]++;
}
else
{
sprite->data[2]++;
}
if (sprite->data[3] == 10)
{
DestroySprite(&gSprites[sprite->data[0]]);
DestroySprite(&gSprites[sprite->data[1]]);
DestroyAnimSprite(sprite);
}
}
static void AnimCirclingMusicNote(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[2];
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x -= gBattleAnimArgs[0];
else
sprite->x += gBattleAnimArgs[0];
StartSpriteAnim(sprite, gBattleAnimArgs[5]);
sprite->data[1] = -gBattleAnimArgs[3];
sprite->y += gBattleAnimArgs[1];
sprite->data[3] = gBattleAnimArgs[4];
sprite->callback = AnimCirclingMusicNote_Step;
sprite->callback(sprite);
}
static void AnimCirclingMusicNote_Step(struct Sprite *sprite)
{
sprite->x2 = Cos(sprite->data[0], 100);
sprite->y2 = Sin(sprite->data[0], 20);
if (sprite->data[0] < 128)
sprite->subpriority = 0;
else
sprite->subpriority = 14;
sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF;
sprite->data[5] += 130;
sprite->y2 += sprite->data[5] >> 8;
sprite->data[2]++;
if (sprite->data[2] == sprite->data[3])
DestroyAnimSprite(sprite);
}
static void AnimProtect(struct Sprite *sprite)
{
if (IsContest())
gBattleAnimArgs[1] += 8;
sprite->x = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord2(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER || IsContest())
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker) + 1;
else
sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = (IndexOfSpritePaletteTag(ANIM_TAG_PROTECT) << 4) + 0x100;
sprite->data[7] = 16;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7]));
sprite->callback = AnimProtect_Step;
}
static void AnimProtect_Step(struct Sprite *sprite)
{
int i, id, savedPal;
sprite->data[5] += 96;
sprite->x2 = -(sprite->data[5] >> 8);
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
savedPal = gPlttBufferFaded[sprite->data[2] + 1];
i = 0;
while (i < 6)
{
id = sprite->data[2] + ++i;
gPlttBufferFaded[id] = gPlttBufferFaded[id + 1];
}
gPlttBufferFaded[sprite->data[2] + 7] = savedPal;
}
if (sprite->data[7] > 6 && sprite->data[0] >0 && ++sprite->data[6] > 1)
{
sprite->data[6] = 0;
sprite->data[7] -= 1;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7]));
}
if (sprite->data[0] > 0)
{
sprite->data[0] -= 1;
}
else if (++sprite->data[6] > 1)
{
sprite->data[6] = 0;
sprite->data[7]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - sprite->data[7], sprite->data[7]));
if (sprite->data[7] == 16)
{
sprite->invisible = TRUE;
sprite->callback = DestroyAnimSpriteAndDisableBlend;
}
}
}
static void AnimMilkBottle(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + 0xFFE8;
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->data[6] = 0;
sprite->data[7] = 16;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
sprite->callback = AnimMilkBottle_Step1;
}
static void AnimMilkBottle_Step1(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (++sprite->data[2] > 0)
{
sprite->data[2] = 0;
if (((++sprite->data[1]) & 1) != 0)
{
if (sprite->data[6] <= 15)
sprite->data[6]++;
}
else if (sprite->data[7] > 0)
sprite->data[7]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
if (sprite->data[6] == 16 && sprite->data[7] == 0)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
}
break;
case 1:
if (++sprite->data[1] > 8)
{
sprite->data[1] = 0;
StartSpriteAffineAnim(sprite, 1);
sprite->data[0]++;
}
break;
case 2:
AnimMilkBottle_Step2(sprite, 16, 4);
if (++sprite->data[1] > 2)
{
sprite->data[1] = 0;
sprite->y++;
}
if (++sprite->data[2] <= 29)
break;
if (sprite->data[2] & 1)
{
if (sprite->data[6] > 0)
sprite->data[6]--;
}
else if (sprite->data[7] <= 15)
{
sprite->data[7]++;
}
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
if (sprite->data[6] == 0 && sprite->data[7] == 16)
{
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->data[0]++;
}
break;
case 3:
sprite->invisible = TRUE;
sprite->data[0]++;
break;
case 4:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
DestroyAnimSprite(sprite);
break;
}
}
static void AnimMilkBottle_Step2(struct Sprite *sprite, int unk1, int unk2)
{
if (sprite->data[3] <= 11)
sprite->data[4] += 2;
if ((u16)(sprite->data[3] - 0x12) <= 0x17)
sprite->data[4] -= 2;
if ((sprite->data[3]) > 0x2F)
sprite->data[4] += 2;
sprite->x2 = sprite->data[4] / 9;
sprite->y2 = sprite->data[4] / 14;
if (sprite->y2 < 0)
sprite->y2 *= -1;
sprite->data[3]++;
if (sprite->data[3] > 0x3B)
sprite->data[3] = 0;
}
static void AnimGrantingStars(struct Sprite *sprite)
{
if (!gBattleAnimArgs[2])
SetSpriteCoordsToAnimAttackerCoords(sprite);
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = gBattleAnimArgs[5];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteLinearFixedPoint;
}
static void AnimSparklingStars(struct Sprite *sprite)
{
u8 battler;
if (!gBattleAnimArgs[2])
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(battler)))
{
SetAverageBattlerPositions(battler, gBattleAnimArgs[6], &sprite->x, &sprite->y);
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
}
else
{
if (!gBattleAnimArgs[6])
{
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y) + gBattleAnimArgs[1];
}
else
{
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
}
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
}
sprite->data[0] = gBattleAnimArgs[5];
sprite->data[1] = gBattleAnimArgs[3];
sprite->data[2] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = TranslateSpriteLinearFixedPoint;
}
static void AnimBubbleBurst(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
else
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
StartSpriteAnim(sprite, 1);
}
sprite->callback = AnimBubbleBurst_Step;
}
static void AnimBubbleBurst_Step(struct Sprite *sprite)
{
if (++sprite->data[0] > 30)
{
sprite->y2 = (30 - sprite->data[0]) / 3;
sprite->x2 = Sin(sprite->data[1] * 4, 3);
sprite->data[1]++;
}
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimSleepLetterZ(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[3] = 1;
}
else
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[3] = 0xFFFF;
StartSpriteAffineAnim(sprite, 1);
}
sprite->callback = AnimSleepLetterZ_Step;
}
static void AnimSleepLetterZ_Step(struct Sprite *sprite)
{
sprite->y2 = -(sprite->data[0] / 0x28);
sprite->x2 = sprite->data[4] / 10;
sprite->data[4] += sprite->data[3] * 2;
sprite->data[0] += sprite->data[1];
if (++sprite->data[1] > 60)
DestroySpriteAndMatrix(sprite);
}
static void AnimLockOnTarget(struct Sprite *sprite)
{
sprite->x -= 32;
sprite->y -= 32;
sprite->data[0] = 20;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step1);
}
static void AnimLockOnTarget_Step1(struct Sprite *sprite)
{
switch (sprite->data[5] & 1)
{
case 0:
sprite->data[0] = 1;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step1);
break;
case 1:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 8;
sprite->data[2] = sprite->x + gInclineMonCoordTable[sprite->data[5] >> 8][0];
sprite->data[4] = sprite->y + gInclineMonCoordTable[sprite->data[5] >> 8][1];
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step2);
sprite->data[5] += 0x100;
PlaySE12WithPanning(SE_M_LOCK_ON, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
break;
}
sprite->data[5] ^= 1;
}
static void AnimLockOnTarget_Step2(struct Sprite *sprite)
{
if ((sprite->data[5] >> 8) == 4)
{
sprite->data[0] = 10;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step3);
}
else
{
sprite->callback = AnimLockOnTarget_Step1;
}
}
static void AnimLockOnTarget_Step3(struct Sprite *sprite)
{
s16 a;
s16 b;
if (sprite->oam.affineParam == 0)
{
sprite->data[0] = 3;
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step4);
}
else
{
switch (sprite->oam.affineParam)
{
case 1:
a = -8;
b = -8;
break;
case 2:
a = -8;
b = 8;
break;
case 3:
a = 8;
b = -8;
break;
default:
a = 8;
b = 8;
break;
}
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 6;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + a;
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + b;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, AnimLockOnTarget_Step5);
}
}
static void AnimLockOnTarget_Step4(struct Sprite *sprite)
{
if (sprite->data[2] == 0)
{
if ((sprite->data[1] += 3) > 16)
sprite->data[1] = 16;
}
else if ((sprite->data[1] -= 3) < 0)
{
sprite->data[1] = 0;
}
BlendPalettes(GetBattlePalettesMask(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE), sprite->data[1], RGB(31, 31, 31));
if (sprite->data[1] == 16)
{
int pal;
sprite->data[2]++;
pal = sprite->oam.paletteNum;
LoadPalette(&gPlttBufferUnfaded[OBJ_PLTT_ID(pal) + 8], OBJ_PLTT_ID(pal) + 1, PLTT_SIZEOF(2));
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
}
else if (sprite->data[1] == 0)
{
sprite->callback = AnimLockOnTarget_Step5;
}
}
static void AnimLockOnTarget_Step5(struct Sprite *sprite)
{
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
{
sprite->data[1] = 0;
sprite->data[0] = 0;
sprite->callback = AnimLockOnTarget_Step6;
}
}
static void AnimLockOnTarget_Step6(struct Sprite *sprite)
{
if (sprite->data[0] % 3 == 0)
{
sprite->data[1]++;
sprite->invisible ^= 1;
}
sprite->data[0]++;
if (sprite->data[1] == 8)
DestroyAnimSprite(sprite);
}
static void AnimLockOnMoveTarget(struct Sprite *sprite)
{
sprite->oam.affineParam = gBattleAnimArgs[0];
if ((s16)sprite->oam.affineParam == 1)
{
sprite->x -= 0x18;
sprite->y -= 0x18;
}
else if ((s16)sprite->oam.affineParam == 2)
{
sprite->x -= 0x18;
sprite->y += 0x18;
sprite->oam.matrixNum = ST_OAM_VFLIP;
}
else if ((s16)sprite->oam.affineParam == 3)
{
sprite->x += 0x18;
sprite->y -= 0x18;
sprite->oam.matrixNum = ST_OAM_HFLIP;
}
else
{
sprite->x += 0x18;
sprite->y += 0x18;
sprite->oam.matrixNum = ST_OAM_HFLIP | ST_OAM_VFLIP;
}
sprite->oam.tileNum = (sprite->oam.tileNum + 16);
sprite->callback = AnimLockOnTarget;
sprite->callback(sprite);
}
static void AnimBowMon(struct Sprite *sprite)
{
sprite->invisible = TRUE;
sprite->data[0] = 0;
switch (gBattleAnimArgs[0])
{
case 0:
sprite->callback = AnimBowMon_Step1;
break;
case 1:
sprite->callback = AnimBowMon_Step2;
break;
case 2:
sprite->callback = AnimBowMon_Step3;
break;
default:
sprite->callback = AnimBowMon_Step4;
break;
}
}
static void AnimBowMon_Step1(struct Sprite *sprite)
{
sprite->data[0] = 6;
sprite->data[1] = (GetBattlerSide(gBattleAnimAttacker)) ? 2 : -2;
sprite->data[2] = 0;
sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker];
StoreSpriteCallbackInData6(sprite, AnimBowMon_Step1_Callback);
sprite->callback = TranslateSpriteLinearById;
}
static void AnimBowMon_Step1_Callback(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker];
PrepareBattlerSpriteForRotScale(sprite->data[3], ST_OAM_OBJ_NORMAL);
sprite->data[4] = (sprite->data[6] = GetBattlerSide(gBattleAnimAttacker)) ? 0x300 : 0xFFFFFD00;
sprite->data[5] = 0;
}
sprite->data[5] += sprite->data[4];
SetSpriteRotScale(sprite->data[3], 0x100, 0x100, sprite->data[5]);
SetBattlerSpriteYOffsetFromRotation(sprite->data[3]);
if (++sprite->data[0] > 3)
{
sprite->data[0] = 0;
sprite->callback = AnimBowMon_Step4;
}
}
static void AnimBowMon_Step2(struct Sprite *sprite)
{
sprite->data[0] = 4;
sprite->data[1] = (GetBattlerSide(gBattleAnimAttacker)) ? -3 : 3;
sprite->data[2] = 0;
sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker];
StoreSpriteCallbackInData6(sprite, AnimBowMon_Step4);
sprite->callback = TranslateSpriteLinearById;
}
static void AnimBowMon_Step3(struct Sprite *sprite)
{
if (++sprite->data[0] > 8)
{
sprite->data[0] = 0;
sprite->callback = AnimBowMon_Step3_Callback;
}
}
static void AnimBowMon_Step3_Callback(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker];
sprite->data[6] = GetBattlerSide(gBattleAnimAttacker);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->data[4] = 0xFC00;
sprite->data[5] = 0xC00;
}
else
{
sprite->data[4] = 0x400;
sprite->data[5] = 0xF400;
}
}
sprite->data[5] += sprite->data[4];
SetSpriteRotScale(sprite->data[3], 0x100, 0x100, sprite->data[5]);
SetBattlerSpriteYOffsetFromRotation(sprite->data[3]);
if (++sprite->data[0] > 2)
{
ResetSpriteRotScale(sprite->data[3]);
sprite->callback = AnimBowMon_Step4;
}
}
static void AnimBowMon_Step4(struct Sprite *sprite)
{
DestroyAnimSprite(sprite);
}
static void AnimTipMon(struct Sprite *sprite)
{
sprite->data[0] = 0;
sprite->callback = AnimTipMon_Step;
}
static void AnimTipMon_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->data[1] = 0;
sprite->data[2] = gBattlerSpriteIds[gBattleAnimAttacker];
sprite->data[3] = GetBattlerSide(gBattleAnimAttacker);
sprite->data[4] = (sprite->data[3] != B_SIDE_PLAYER) ? 0x200 : -0x200;
sprite->data[5] = 0;
PrepareBattlerSpriteForRotScale(sprite->data[2], ST_OAM_OBJ_NORMAL);
sprite->data[0]++;
// fall through
case 1:
sprite->data[5] += sprite->data[4];
SetSpriteRotScale(sprite->data[2], 0x100, 0x100, sprite->data[5]);
SetBattlerSpriteYOffsetFromRotation(sprite->data[2]);
if (++sprite->data[1] > 3)
{
sprite->data[1] = 0;
sprite->data[4] *= -1;
sprite->data[0]++;
}
break;
case 2:
sprite->data[5] += sprite->data[4];
SetSpriteRotScale(sprite->data[2], 0x100, 0x100, sprite->data[5]);
SetBattlerSpriteYOffsetFromRotation(sprite->data[2]);
if (++sprite->data[1] > 3)
{
ResetSpriteRotScale(sprite->data[2]);
DestroyAnimSprite(sprite);
}
break;
}
}
void AnimTask_SkullBashPosition(u8 taskId)
{
u8 side;
gTasks[taskId].data[0] = gBattlerSpriteIds[gBattleAnimAttacker];
side = GetBattlerSide(gBattleAnimAttacker);
gTasks[taskId].data[1] = side;
gTasks[taskId].data[2] = 0;
switch (gBattleAnimArgs[0])
{
default:
DestroyAnimVisualTask(taskId);
break;
case 0:
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = 8;
gTasks[taskId].data[4] = 0;
gTasks[taskId].data[5] = 3;
if (side == B_SIDE_PLAYER)
gTasks[taskId].data[5] *= -1;
gTasks[taskId].func = AnimTask_SkullBashPositionSet;
break;
case 1:
gTasks[taskId].data[3] = 8;
gTasks[taskId].data[4] = 0x600;
gTasks[taskId].data[5] = 0xC0;
if (side == B_SIDE_PLAYER)
{
gTasks[taskId].data[4] = -gTasks[taskId].data[4];
gTasks[taskId].data[5] = -gTasks[taskId].data[5];
}
gTasks[taskId].func = AnimTask_SkullBashPositionReset;
break;
}
}
static void AnimTask_SkullBashPositionSet(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[2])
{
case 0:
if (task->data[3])
{
task->data[4] += task->data[5];
gSprites[task->data[0]].x2 = task->data[4];
task->data[3]--;
}
else
{
task->data[3] = 8;
task->data[4] = 0;
task->data[5] = (task->data[1] == 0) ? -0xC0 : 0xC0;
PrepareBattlerSpriteForRotScale(task->data[0], ST_OAM_OBJ_NORMAL);
task->data[2]++;
}
break;
case 1:
if (task->data[3])
{
task->data[4] += task->data[5];
SetSpriteRotScale(task->data[0], 0x100, 0x100, task->data[4]);
SetBattlerSpriteYOffsetFromRotation(task->data[0]);
task->data[3]--;
}
else
{
task->data[3] = 8;
task->data[4] = gSprites[task->data[0]].x2;
task->data[5] = (task->data[1] == 0) ? 0x2 : -0x2;
task->data[6] = 1;
task->data[2]++;
}
break;
case 2:
if (task->data[3])
{
if (task->data[6])
{
task->data[6]--;
}
else
{
if (task->data[3] & 1)
gSprites[task->data[0]].x2 = task->data[4] + task->data[5];
else
gSprites[task->data[0]].x2 = task->data[4] - task->data[5];
task->data[6] = 1;
task->data[3]--;
}
}
else
{
gSprites[task->data[0]].x2 = task->data[4];
task->data[3] = 12;
task->data[2]++;
}
break;
case 3:
if (task->data[3])
{
task->data[3]--;
}
else
{
task->data[3] = 3;
task->data[4] = gSprites[task->data[0]].x2;
task->data[5] = (task->data[1] == 0) ? 8 : -8;
task->data[2]++;
}
break;
case 4:
if (task->data[3])
{
task->data[4] += task->data[5];
gSprites[task->data[0]].x2 = task->data[4];
task->data[3]--;
}
else
{
DestroyAnimVisualTask(taskId);
}
break;
}
}
static void AnimTask_SkullBashPositionReset(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (task->data[3])
{
task->data[4] -= task->data[5];
SetSpriteRotScale(task->data[0], 0x100, 0x100, task->data[4]);
SetBattlerSpriteYOffsetFromRotation(task->data[0]);
task->data[3]--;
}
else
{
ResetSpriteRotScale(task->data[0]);
DestroyAnimVisualTask(taskId);
}
}
static void AnimSlashSlice(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
}
sprite->data[0] = 0;
sprite->data[1] = 0;
StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSlice_Step3);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
static void AnimFalseSwipeSlice(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + 0xFFD0;
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSlice_Step1);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
static void AnimFalseSwipePositionedSlice(struct Sprite *sprite)
{
sprite->x = sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + 0xFFD0 + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
StartSpriteAnim(sprite, 1);
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->callback = AnimFalseSwipeSlice_Step3;
}
static void AnimFalseSwipeSlice_Step1(struct Sprite *sprite)
{
if (++sprite->data[0] > 8)
{
sprite->data[0] = 12;
sprite->data[1] = 8;
sprite->data[2] = 0;
StoreSpriteCallbackInData6(sprite, AnimFalseSwipeSlice_Step2);
sprite->callback = TranslateSpriteLinear;
}
}
static void AnimFalseSwipeSlice_Step2(struct Sprite *sprite)
{
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->callback = AnimFalseSwipeSlice_Step3;
}
static void AnimFalseSwipeSlice_Step3(struct Sprite *sprite)
{
if (++sprite->data[0] > 1)
{
sprite->data[0] = 0;
sprite->invisible = !sprite->invisible;
if (++sprite->data[1] > 8)
DestroyAnimSprite(sprite);
}
}
static void AnimEndureEnergy(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[2];
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[2];
}
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[3];
sprite->callback = AnimEndureEnergy_Step;
}
static void AnimEndureEnergy_Step(struct Sprite *sprite)
{
if (++sprite->data[0] > sprite->data[1])
{
sprite->data[0] = 0;
sprite->y--;
}
sprite->y -= sprite->data[0];
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
static void AnimSharpenSphere(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) - 12;
sprite->data[0] = 0;
sprite->data[1] = 2;
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = 0;
sprite->data[5] = BattleAnimAdjustPanning(SOUND_PAN_ATTACKER);
sprite->callback = AnimSharpenSphere_Step;
}
static void AnimSharpenSphere_Step(struct Sprite *sprite)
{
if (++sprite->data[0] >= sprite->data[1])
{
sprite->invisible = !sprite->invisible;
if (!sprite->invisible)
{
sprite->data[4]++;
if (!(sprite->data[4] & 1))
PlaySE12WithPanning(SE_M_SWAGGER2, sprite->data[5]);
}
sprite->data[0] = 0;
if (++sprite->data[2] > 1)
{
sprite->data[2] = 0;
sprite->data[1]++;
}
}
if (sprite->animEnded && sprite->data[1] > 16 && sprite->invisible)
DestroyAnimSprite(sprite);
}
static void AnimConversion(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
if (IsContest())
sprite->y += 10;
sprite->data[0]++;
}
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
DestroyAnimSprite(sprite);
}
void AnimTask_ConversionAlphaBlend(u8 taskId)
{
if (gTasks[taskId].data[2] == 1)
{
gBattleAnimArgs[7] = 0xFFFF;
gTasks[taskId].data[2]++;
}
else if (gTasks[taskId].data[2] == 2)
{
DestroyAnimVisualTask(taskId);
}
else
{
if (++gTasks[taskId].data[0] == 4)
{
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - gTasks[taskId].data[1], gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 16)
gTasks[taskId].data[2]++;
}
}
}
static void AnimConversion2(struct Sprite *sprite)
{
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->animPaused = 1;
sprite->data[0] = gBattleAnimArgs[2];
sprite->callback = AnimConversion2_Step;
}
static void AnimConversion2_Step(struct Sprite *sprite)
{
if (sprite->data[0])
{
sprite->data[0]--;
}
else
{
sprite->animPaused = 0;
sprite->data[0] = 30;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
}
void AnimTask_Conversion2AlphaBlend(u8 taskId)
{
if (++gTasks[taskId].data[0] == 4)
{
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 16)
DestroyAnimVisualTask(taskId);
}
}
// Unused
static void AnimTask_HideBattlersHealthbox(u8 taskId)
{
u8 i;
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleAnimArgs[0] == TRUE && GetBattlerSide(i) == B_SIDE_PLAYER)
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[i]);
if (gBattleAnimArgs[1] == TRUE && GetBattlerSide(i) == B_SIDE_OPPONENT)
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[i]);
}
DestroyAnimVisualTask(taskId);
}
// Unused
static void AnimTask_ShowBattlersHealthbox(u8 taskId)
{
u8 i;
for (i = 0; i < gBattlersCount; i++)
SetHealthboxSpriteVisible(gHealthboxSpriteIds[i]);
DestroyAnimVisualTask(taskId);
}
static void AnimMoon(struct Sprite *sprite)
{
if (IsContest())
{
sprite->x = 48;
sprite->y = 40;
}
else
{
sprite->x = gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1];
}
sprite->oam.shape = SPRITE_SHAPE(64x64);
sprite->oam.size = SPRITE_SIZE(64x64);
sprite->data[0] = 0;
sprite->callback = AnimMoon_Step;
}
static void AnimMoon_Step(struct Sprite *sprite)
{
if (sprite->data[0])
DestroyAnimSprite(sprite);
}
static void AnimMoonlightSparkle(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1];
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = 1;
sprite->callback = AnimMoonlightSparkle_Step;
}
static void AnimMoonlightSparkle_Step(struct Sprite *sprite)
{
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
if (sprite->data[2] < 120)
{
sprite->y++;
sprite->data[2]++;
}
}
if (sprite->data[0])
DestroyAnimSprite(sprite);
}
void AnimTask_MoonlightEndFade(u8 taskId)
{
int a = GetBattlePalettesMask(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) & 0xFFFF;
int b;
int c;
int d;
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = a;
gTasks[taskId].data[4] = 0;
gTasks[taskId].data[5] = 0;
gTasks[taskId].data[6] = 0;
gTasks[taskId].data[7] = 13;
gTasks[taskId].data[8] = 14;
gTasks[taskId].data[9] = 15;
b = GetBattleMonSpritePalettesMask(1, 1, 1, 1);
c = a | b;
StorePointerInVars(&gTasks[taskId].data[14], &gTasks[taskId].data[15], (void *)c);
b = b | (0x10000 << IndexOfSpritePaletteTag(ANIM_TAG_MOON));
d = IndexOfSpritePaletteTag(ANIM_TAG_GREEN_SPARKLE);
BeginNormalPaletteFade((0x10000 << d) | b, 0, 0, 16, RGB(27, 29, 31));
gTasks[taskId].func = AnimTask_MoonlightEndFade_Step;
gTasks[taskId].func(taskId);
}
static void AnimTask_MoonlightEndFade_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] > 0)
{
u16 color;
u16 bitmask;
u16 r3;
u16 i;
u16 j;
task->data[1] = 0;
if (++task->data[2] <= 15)
{
u16 red;
u16 green;
u16 blue;
task->data[4] += task->data[7];
task->data[5] += task->data[8];
task->data[6] += task->data[9];
red = task->data[4] >> 3;
green = task->data[5] >> 3;
blue = task->data[6] >> 3;
color = RGB(red, green, blue);
}
else
{
color = RGB(27, 29, 31);
task->data[0]++;
}
bitmask = 1;
r3 = 0;
for (i = 0; i <= 15; i++)
{
if (task->data[3] & bitmask)
{
for (j = 1; j <= 15; j++)
{
gPlttBufferFaded[r3 + j] = color;
}
}
bitmask <<= 1;
r3 += 16;
}
}
break;
case 1:
if (!gPaletteFade.active)
{
u8 spriteId;
for (spriteId = 0; spriteId < MAX_SPRITES; spriteId++)
{
if (gSprites[spriteId].template == &gMoonSpriteTemplate || gSprites[spriteId].template == &gMoonlightSparkleSpriteTemplate)
gSprites[spriteId].data[0] = 1;
}
task->data[1] = 0;
task->data[0]++;
}
break;
case 2:
if (++task->data[1] > 30)
{
BeginNormalPaletteFade((u32)LoadPointerFromVars(task->data[14], task->data[15]), 0, 16, 0, RGB(27, 29, 31));
task->data[0]++;
}
break;
case 3:
if (!gPaletteFade.active)
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimHornHit(struct Sprite *sprite)
{
if (gBattleAnimArgs[2] < 2)
gBattleAnimArgs[2] = 2;
if (gBattleAnimArgs[2] > 0x7F)
gBattleAnimArgs[2] = 0x7F;
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[2];
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
sprite->data[6] = sprite->x;
sprite->data[7] = sprite->y;
if (IsContest())
{
sprite->oam.matrixNum = ST_OAM_HFLIP;
sprite->x += 40;
sprite->y += 20;
sprite->data[2] = sprite->x << 7;
sprite->data[3] = -0x1400 / sprite->data[1];
sprite->data[4] = sprite->y << 7;
sprite->data[5] = -0xA00 / sprite->data[1];
}
else if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x -= 40;
sprite->y += 20;
sprite->data[2] = sprite->x << 7;
sprite->data[3] = 0x1400 / sprite->data[1];
sprite->data[4] = sprite->y << 7;
sprite->data[5] = -0xA00 / sprite->data[1];
}
else
{
sprite->x += 40;
sprite->y -= 20;
sprite->data[2] = sprite->x << 7;
sprite->data[3] = -0x1400 / sprite->data[1];
sprite->data[4] = sprite->y << 7;
sprite->data[5] = 0xA00 / sprite->data[1];
sprite->oam.matrixNum = (ST_OAM_HFLIP | ST_OAM_VFLIP);
}
sprite->callback = AnimHornHit_Step;
}
static void AnimHornHit_Step(struct Sprite *sprite)
{
sprite->data[2] += sprite->data[3];
sprite->data[4] += sprite->data[5];
sprite->x = sprite->data[2] >> 7;
sprite->y = sprite->data[4] >> 7;
if (--sprite->data[1] == 1)
{
sprite->x = sprite->data[6];
sprite->y = sprite->data[7];
}
if (sprite->data[1] == 0)
DestroyAnimSprite(sprite);
}
void AnimTask_DoubleTeam(u8 taskId)
{
u16 i;
int obj;
u16 r3;
u16 r4;
struct Task *task = &gTasks[taskId];
task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[1] = AllocSpritePalette(ANIM_TAG_BENT_SPOON);
r3 = OBJ_PLTT_ID(task->data[1]);
r4 = OBJ_PLTT_ID2(gSprites[task->data[0]].oam.paletteNum);
for (i = 1; i < 16; i++)
gPlttBufferUnfaded[r3 + i] = gPlttBufferUnfaded[r4 + i];
BlendPalette(r3, 16, 11, RGB(0, 0, 0));
task->data[3] = 0;
i = 0;
while (i < 2 && (obj = CloneBattlerSpriteWithBlend(0)) >= 0)
{
gSprites[obj].oam.paletteNum = task->data[1];
gSprites[obj].data[0] = 0;
gSprites[obj].data[1] = i << 7;
gSprites[obj].data[2] = taskId;
gSprites[obj].callback = AnimDoubleTeam;
task->data[3]++;
i++;
}
task->func = AnimTask_DoubleTeam_Step;
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
}
static void AnimTask_DoubleTeam_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (!task->data[3])
{
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON);
DestroyAnimVisualTask(taskId);
}
}
static void AnimDoubleTeam(struct Sprite *sprite)
{
if (++sprite->data[3] > 1)
{
sprite->data[3] = 0;
sprite->data[0]++;
}
if (sprite->data[0] > 64)
{
gTasks[sprite->data[2]].data[3]--;
DestroySpriteWithActiveSheet(sprite);
}
else
{
sprite->data[4] = gSineTable[sprite->data[0]] / 6;
sprite->data[5] = gSineTable[sprite->data[0]] / 13;
sprite->data[1] = (sprite->data[1] + sprite->data[5]) & 0xFF;
sprite->x2 = Sin(sprite->data[1], sprite->data[4]);
}
}
static void AnimSuperFang(struct Sprite *sprite)
{
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
void AnimTask_MusicNotesRainbowBlend(u8 taskId)
{
u16 i;
u16 j;
u16 index;
index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[0][0]);
if (index != 0xFF)
{
index = (index << 4) + 0x100;
for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable[0]); i++)
gPlttBufferFaded[index + i] = gParticlesColorBlendTable[0][i];
}
for (j = 1; j < ARRAY_COUNT(gParticlesColorBlendTable); j++)
{
index = AllocSpritePalette(gParticlesColorBlendTable[j][0]);
if (index != 0xFF)
{
index = (index << 4) + 0x100;
for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable[0]); i++)
gPlttBufferFaded[index + i] = gParticlesColorBlendTable[j][i];
}
}
DestroyAnimVisualTask(taskId);
}
// clears the rainbow effect for musical notes.
void AnimTask_MusicNotesClearRainbowBlend(u8 taskId)
{
u16 i;
for (i = 1; i < ARRAY_COUNT(gParticlesColorBlendTable); i++)
FreeSpritePaletteByTag(gParticlesColorBlendTable[i][0]);
DestroyAnimVisualTask(taskId);
}
#define sMoveTimer data[0]
#define sBlendTableIdx data[1]
#define sBlendTimer data[2]
#define sBlendCycleTime data[3]
#define sX data[4]
#define sY data[5]
#define sVelocX data[6]
#define sVelocY data[7]
static void AnimWavyMusicNotes(struct Sprite *sprite)
{
u8 index;
u8 x, y;
SetSpriteCoordsToAnimAttackerCoords(sprite);
StartSpriteAnim(sprite, gBattleAnimArgs[0]);
if ((index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[gBattleAnimArgs[1]][0])) != 0xFF)
sprite->oam.paletteNum = index;
sprite->sBlendTableIdx = gBattleAnimArgs[1];
sprite->sBlendTimer = 0;
sprite->sBlendCycleTime = gBattleAnimArgs[2];
if (IsContest())
{
x = 48;
y = 40;
}
else
{
x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->sX = sprite->x << 4;
sprite->sY = sprite->y << 4;
AnimWavyMusicNotes_CalcVelocity(x - sprite->x, y - sprite->y, &sprite->sVelocX, &sprite->sVelocY, 40);
sprite->callback = AnimWavyMusicNotes_Step;
}
static void AnimWavyMusicNotes_CalcVelocity(s16 x, s16 y, s16 *velocX, s16 *velocY, s8 xSpeedFactor)
{
int x2;
int time;
if (x < 0)
xSpeedFactor = -xSpeedFactor;
x2 = x * 256;
time = x2 / xSpeedFactor;
if (time == 0)
time = 1;
*velocX = x2 / time;
*velocY = (y * 256) / time;
}
static void AnimWavyMusicNotes_Step(struct Sprite *sprite)
{
s16 y, trigIdx;
u8 index;
sprite->sMoveTimer++;
trigIdx = sprite->sMoveTimer * 5 - ((sprite->sMoveTimer * 5 / 256) << 8);
sprite->sX += sprite->sVelocX;
sprite->sY += sprite->sVelocY;
sprite->x = sprite->sX >> 4;
sprite->y = sprite->sY >> 4;
sprite->y2 = Sin(trigIdx, 15);
y = sprite->y;
if (sprite->x < -16 || sprite->x > DISPLAY_WIDTH + 16 || y < -16 || y > DISPLAY_HEIGHT - 32)
{
DestroySpriteAndMatrix(sprite);
}
else
{
if (sprite->sBlendCycleTime && ++sprite->sBlendTimer > sprite->sBlendCycleTime)
{
sprite->sBlendTimer = 0;
if (++sprite->sBlendTableIdx > (int)ARRAY_COUNT(gParticlesColorBlendTable) - 1)
sprite->sBlendTableIdx = 0;
index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[sprite->sBlendTableIdx][0]);
if (index != 0xFF)
sprite->oam.paletteNum = index;
}
}
}
static void AnimFlyingMusicNotes(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
gBattleAnimArgs[1] *= -1;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
StartSpriteAnim(sprite, gBattleAnimArgs[0]);
sprite->data[2] = 0;
sprite->data[3] = 0;
sprite->data[4] = sprite->x << 4;
sprite->data[5] = sprite->y << 4;
sprite->data[6] = (gBattleAnimArgs[1] << 4) / 5;
sprite->data[7] = (gBattleAnimArgs[2] << 7) / 5;
sprite->callback = AnimFlyingMusicNotes_Step;
}
static void AnimFlyingMusicNotes_Step(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[6];
sprite->data[5] += sprite->data[7];
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
if (sprite->data[0] > 5 && sprite->data[3] == 0)
{
sprite->data[2] = (sprite->data[2] + 16) & 0xFF;
sprite->x2 = Cos(sprite->data[2], 18);
sprite->y2 = Sin(sprite->data[2], 18);
if (sprite->data[2] == 0)
sprite->data[3] = 1;
}
if (++sprite->data[0] == 48)
DestroySpriteAndMatrix(sprite);
}
static void AnimBellyDrumHand(struct Sprite *sprite)
{
s16 a;
if (gBattleAnimArgs[0] == 1)
{
sprite->oam.matrixNum = ST_OAM_HFLIP;
a = 16;
}
else
{
a = -16;
}
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + a;
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + 8;
sprite->data[0] = 8;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
void AnimSlowFlyingMusicNotes(struct Sprite *sprite)
{
s16 xDiff;
u8 index;
SetSpriteCoordsToAnimAttackerCoords(sprite);
sprite->y += 8;
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
index = IndexOfSpritePaletteTag(gParticlesColorBlendTable[gBattleAnimArgs[2]][0]);
if (index != 0xFF)
sprite->oam.paletteNum = index;
xDiff = (gBattleAnimArgs[0] == 0) ? -32 : 32;
sprite->data[0] = 40;
sprite->data[1] = sprite->x;
sprite->data[2] = xDiff + sprite->data[1];
sprite->data[3] = sprite->y;
sprite->data[4] = sprite->data[3] - 40;
InitAnimLinearTranslation(sprite);
sprite->data[5] = gBattleAnimArgs[3];
sprite->callback = AnimSlowFlyingMusicNotes_Step;
}
static void AnimSlowFlyingMusicNotes_Step(struct Sprite *sprite)
{
if (AnimTranslateLinear(sprite) == 0)
{
s16 xDiff;
xDiff = Sin(sprite->data[5], 8);
if (sprite->x2 < 0)
xDiff = -xDiff;
sprite->x2 += xDiff;
sprite->y2 += Sin(sprite->data[5], 4);
sprite->data[5] = (sprite->data[5] + 8) & 0xFF;
}
else
{
DestroyAnimSprite(sprite);
}
}
void SetSpriteNextToMonHead(u8 battler, struct Sprite *sprite)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) + 8;
else
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) - 8;
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) - (s16)GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_HEIGHT) / 4;
}
static void AnimThoughtBubble(struct Sprite *sprite)
{
u8 animNum;
u8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
SetSpriteNextToMonHead(battler, sprite);
animNum = (GetBattlerSide(battler) == B_SIDE_PLAYER) ? 0 : 1;
sprite->data[0] = gBattleAnimArgs[1];
sprite->data[1] = animNum + 2;
StartSpriteAnim(sprite, animNum);
StoreSpriteCallbackInData6(sprite, AnimThoughtBubble_Step);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
static void AnimThoughtBubble_Step(struct Sprite *sprite)
{
if (--sprite->data[0] == 0)
{
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
StartSpriteAnim(sprite, sprite->data[1]);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
}
static void AnimMetronomeFinger(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
SetSpriteNextToMonHead(battler, sprite);
sprite->data[0] = 0;
StoreSpriteCallbackInData6(sprite, AnimMetronomeFinger_Step);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
static void AnimMetronomeFinger_Step(struct Sprite *sprite)
{
if (++sprite->data[0] > 16)
{
StartSpriteAffineAnim(sprite, 1);
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
}
static void AnimFollowMeFinger(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
sprite->x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_TOP);
if (sprite->y <= 9)
sprite->y = 10;
sprite->data[0] = 1;
sprite->data[1] = 0;
sprite->data[2] = sprite->subpriority;
sprite->data[3] = sprite->subpriority + 4;
sprite->data[4] = 0;
StoreSpriteCallbackInData6(sprite, AnimFollowMeFinger_Step1);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
static void AnimFollowMeFinger_Step1(struct Sprite *sprite)
{
if (++sprite->data[4] > 12)
sprite->callback = AnimFollowMeFinger_Step2;
}
static void AnimFollowMeFinger_Step2(struct Sprite *sprite)
{
s16 x1, x2;
sprite->data[1] += 4;
if (sprite->data[1] > 254)
{
if (--sprite->data[0] == 0)
{
sprite->x2 = 0;
sprite->callback = AnimMetronomeFinger_Step;
return;
}
else
{
sprite->data[1] &= 0xFF;
}
}
if (sprite->data[1] > 0x4F)
sprite->subpriority = sprite->data[3];
if (sprite->data[1] > 0x9F)
sprite->subpriority = sprite->data[2];
x1 = gSineTable[sprite->data[1]];
x2 = x1 >> 3;
sprite->x2 = (x1 >> 3) + (x2 >> 1);
}
static void AnimTauntFinger(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == 0)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
SetSpriteNextToMonHead(battler, sprite);
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{
StartSpriteAnim(sprite, 0);
sprite->data[0] = 2;
}
else
{
StartSpriteAnim(sprite, 1);
sprite->data[0] = 3;
}
sprite->callback = AnimTauntFinger_Step1;
}
static void AnimTauntFinger_Step1(struct Sprite *sprite)
{
if (++sprite->data[1] > 10)
{
sprite->data[1] = 0;
StartSpriteAnim(sprite, sprite->data[0]);
StoreSpriteCallbackInData6(sprite, AnimTauntFinger_Step2);
sprite->callback = RunStoredCallbackWhenAnimEnds;
}
}
static void AnimTauntFinger_Step2(struct Sprite *sprite)
{
if (++sprite->data[1] > 5)
DestroyAnimSprite(sprite);
}
#include "global.h"
#include "malloc.h"
#include "battle.h"
#include "battle_anim.h"
#include "bg.h"
#include "contest.h"
#include "data.h"
#include "decompress.h"
#include "dma3.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "palette.h"
#include "pokemon_icon.h"
#include "random.h"
#include "scanline_effect.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "util.h"
#include "constants/battle_anim.h"
#include "constants/rgb.h"
#include "constants/songs.h"
#include "constants/weather.h"
extern const struct SpriteTemplate gThoughtBubbleSpriteTemplate;
static void AnimBlackSmoke(struct Sprite *);
static void AnimBlackSmoke_Step(struct Sprite *);
static void AnimWhiteHalo(struct Sprite *);
static void AnimWhiteHalo_Step1(struct Sprite *);
static void AnimWhiteHalo_Step2(struct Sprite *);
static void AnimTealAlert(struct Sprite *);
static void AnimMeanLookEye(struct Sprite *);
static void AnimMeanLookEye_Step1(struct Sprite *);
static void AnimMeanLookEye_Step2(struct Sprite *);
static void AnimMeanLookEye_Step3(struct Sprite *);
static void AnimMeanLookEye_Step4(struct Sprite *);
static void AnimSpikes(struct Sprite *);
static void AnimSpikes_Step1(struct Sprite *);
static void AnimSpikes_Step2(struct Sprite *);
static void AnimLeer(struct Sprite *);
static void AnimLetterZ(struct Sprite *);
static void AnimFang(struct Sprite *);
static void AnimSpotlight(struct Sprite *);
static void AnimSpotlight_Step1(struct Sprite *);
static void AnimSpotlight_Step2(struct Sprite *);
static void AnimClappingHand(struct Sprite *);
static void AnimClappingHand_Step(struct Sprite *);
static void AnimClappingHand2(struct Sprite *);
static void AnimRapidSpin(struct Sprite *);
static void AnimRapidSpin_Step(struct Sprite *);
static void AnimTriAttackTriangle(struct Sprite *);
static void AnimBatonPassPokeball(struct Sprite *);
static void AnimWishStar(struct Sprite *);
static void AnimWishStar_Step(struct Sprite *);
static void AnimMiniTwinklingStar(struct Sprite *);
static void AnimMiniTwinklingStar_Step(struct Sprite *);
static void AnimSwallowBlueOrb(struct Sprite *);
static void AnimGreenStar(struct Sprite *);
static void AnimGreenStar_Step1(struct Sprite *);
static void AnimGreenStar_Step2(struct Sprite *);
static void AnimGreenStar_Callback(struct Sprite *);
static void AnimWeakFrustrationAngerMark(struct Sprite *);
static void AnimSweetScentPetal(struct Sprite *);
static void AnimSweetScentPetal_Step(struct Sprite *);
static void AnimPainSplitProjectile(struct Sprite *);
static void AnimFlatterConfetti(struct Sprite *);
static void AnimFlatterConfetti_Step(struct Sprite *);
static void AnimFlatterSpotlight(struct Sprite *);
static void AnimFlatterSpotlight_Step(struct Sprite *);
static void AnimReversalOrb(struct Sprite *);
static void AnimReversalOrb_Step(struct Sprite *);
static void AnimYawnCloud(struct Sprite *);
static void AnimYawnCloud_Step(struct Sprite *);
static void AnimSmokeBallEscapeCloud(struct Sprite *);
static void AnimFacadeSweatDrop(struct Sprite *);
static void AnimRoarNoiseLine(struct Sprite *);
static void AnimRoarNoiseLine_Step(struct Sprite *);
static void AnimGlareEyeDot(struct Sprite *);
static void AnimAssistPawprint(struct Sprite *);
static void AnimSmellingSaltsHand(struct Sprite *);
static void AnimSmellingSaltsHand_Step(struct Sprite *);
static void AnimSmellingSaltExclamation(struct Sprite *);
static void AnimSmellingSaltExclamation_Step(struct Sprite *);
static void AnimHelpingHandClap(struct Sprite *);
static void AnimHelpingHandClap_Step(struct Sprite *);
static void AnimForesightMagnifyingGlass(struct Sprite *);
static void AnimForesightMagnifyingGlass_Step(struct Sprite *);
static void AnimMeteorMashStar(struct Sprite *);
static void AnimMeteorMashStar_Step(struct Sprite *sprite);
static void AnimBlockX(struct Sprite *);
static void AnimBlockX_Step(struct Sprite *);
static void AnimUnusedItemBagSteal(struct Sprite *);
static void AnimKnockOffStrike(struct Sprite *);
static void AnimKnockOffStrike_Step(struct Sprite *sprite);
static void AnimRecycle(struct Sprite *);
static void AnimRecycle_Step(struct Sprite *);
static void SetPsychicBackground_Step(u8);
static void FadeScreenToWhite_Step(u8);
static void RapinSpinMonElevation_Step(u8);
static void TormentAttacker_Step(u8);
static void TormentAttacker_Callback(struct Sprite *);
static void AnimTask_RockMonBackAndForth_Step(u8);
static void AnimTask_FlailMovement_Step(u8);
static void AnimTask_RolePlaySilhouette_Step1(u8);
static void AnimTask_RolePlaySilhouette_Step2(u8);
static void AnimTask_AcidArmor_Step(u8);
static void AnimTask_DeepInhale_Step(u8);
static void AnimTask_SquishAndSweatDroplets_Step(u8);
static void CreateSweatDroplets(u8, bool8);
static void AnimTask_FacadeColorBlend_Step(u8);
static void AnimTask_GlareEyeDots_Step(u8);
static void GetGlareEyeDotCoords(s16, s16, s16, s16, u8, u8, s16 *, s16 *);
static void AnimTask_BarrageBall_Step(u8);
static void AnimTask_SmellingSaltsSquish_Step(u8);
static void AnimTask_HelpingHandAttackerMovement_Step(u8);
static void AnimTask_MonToSubstituteDoll(u8);
static void AnimTask_OdorSleuthMovementWaitFinish(u8);
static void MoveOdorSleuthClone(struct Sprite *);
static void AnimTask_TeeterDanceMovement_Step(u8);
static void AnimTask_SlackOffSquish_Step(u8);
const union AnimCmd gScratchAnimCmds[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(16, 4),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_END,
};
const union AnimCmd *const gScratchAnimTable[] =
{
gScratchAnimCmds,
};
const struct SpriteTemplate gScratchSpriteTemplate =
{
.tileTag = ANIM_TAG_SCRATCH,
.paletteTag = ANIM_TAG_SCRATCH,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gScratchAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gBlackSmokeSpriteTemplate =
{
.tileTag = ANIM_TAG_BLACK_SMOKE,
.paletteTag = ANIM_TAG_BLACK_SMOKE,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBlackSmoke,
};
const struct SpriteTemplate gBlackBallSpriteTemplate =
{
.tileTag = ANIM_TAG_BLACK_BALL,
.paletteTag = ANIM_TAG_BLACK_BALL,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimThrowProjectile,
};
const union AnimCmd gOpeningEyeAnimCmds[] =
{
ANIMCMD_FRAME(0, 40),
ANIMCMD_FRAME(16, 8),
ANIMCMD_FRAME(32, 40),
ANIMCMD_END,
};
const union AnimCmd *const gOpeningEyeAnimTable[] =
{
gOpeningEyeAnimCmds,
};
const struct SpriteTemplate gOpeningEyeSpriteTemplate =
{
.tileTag = ANIM_TAG_OPENING_EYE,
.paletteTag = ANIM_TAG_OPENING_EYE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gOpeningEyeAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const struct SpriteTemplate gWhiteHaloSpriteTemplate =
{
.tileTag = ANIM_TAG_ROUND_WHITE_HALO,
.paletteTag = ANIM_TAG_ROUND_WHITE_HALO,
.oam = &gOamData_AffineOff_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWhiteHalo,
};
const struct SpriteTemplate gTealAlertSpriteTemplate =
{
.tileTag = ANIM_TAG_TEAL_ALERT,
.paletteTag = ANIM_TAG_TEAL_ALERT,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimTealAlert,
};
const union AffineAnimCmd gMeanLookEyeAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0),
AFFINEANIMCMD_FRAME(-0x20, 0x18, 0, 5),
AFFINEANIMCMD_FRAME(0x18, -0x20, 0, 5),
AFFINEANIMCMD_JUMP(1),
};
const union AffineAnimCmd gMeanLookEyeAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x30, 0x30, 0, 0),
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 6),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gMeanLookEyeAffineAnimTable[] =
{
gMeanLookEyeAffineAnimCmds1,
gMeanLookEyeAffineAnimCmds2,
};
const struct SpriteTemplate gMeanLookEyeSpriteTemplate =
{
.tileTag = ANIM_TAG_EYE,
.paletteTag = ANIM_TAG_EYE,
.oam = &gOamData_AffineDouble_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gMeanLookEyeAffineAnimTable,
.callback = AnimMeanLookEye,
};
const struct SpriteTemplate gSpikesSpriteTemplate =
{
.tileTag = ANIM_TAG_SPIKES,
.paletteTag = ANIM_TAG_SPIKES,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpikes,
};
const union AnimCmd gLeerAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(64, 3),
ANIMCMD_END,
};
const union AnimCmd *const gLeerAnimTable[] =
{
gLeerAnimCmds,
};
const struct SpriteTemplate gLeerSpriteTemplate =
{
.tileTag = ANIM_TAG_LEER,
.paletteTag = ANIM_TAG_LEER,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gLeerAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimLeer,
};
const union AnimCmd gLetterZAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_END,
};
const union AnimCmd *const gLetterZAnimTable[] =
{
gLetterZAnimCmds,
};
const union AffineAnimCmd gLetterZAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-7, -7, -3, 16),
AFFINEANIMCMD_FRAME(7, 7, 3, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gLetterZAffineAnimTable[] =
{
gLetterZAffineAnimCmds,
};
const struct SpriteTemplate gLetterZSpriteTemplate =
{
.tileTag = ANIM_TAG_LETTER_Z,
.paletteTag = ANIM_TAG_LETTER_Z,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gLetterZAnimTable,
.images = NULL,
.affineAnims = gLetterZAffineAnimTable,
.callback = AnimLetterZ,
};
const union AnimCmd gFangAnimCmds[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(16, 16),
ANIMCMD_FRAME(32, 4),
ANIMCMD_FRAME(48, 4),
ANIMCMD_END,
};
const union AnimCmd *const gFangAnimTable[] =
{
gFangAnimCmds,
};
const union AffineAnimCmd gFangAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
AFFINEANIMCMD_FRAME(-0x20, -0x20, 0, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gFangAffineAnimTable[] =
{
gFangAffineAnimCmds,
};
const struct SpriteTemplate gFangSpriteTemplate =
{
.tileTag = ANIM_TAG_FANG_ATTACK,
.paletteTag = ANIM_TAG_FANG_ATTACK,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = gFangAnimTable,
.images = NULL,
.affineAnims = gFangAffineAnimTable,
.callback = AnimFang,
};
const union AffineAnimCmd gSpotlightAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x0, 0x180, 0, 0),
AFFINEANIMCMD_FRAME(0x10, 0x0, 0, 20),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gSpotlightAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x140, 0x180, 0, 0),
AFFINEANIMCMD_FRAME(-0x10, 0x0, 0, 19),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gSpotlightAffineAnimTable[] =
{
gSpotlightAffineAnimCmds1,
gSpotlightAffineAnimCmds2,
};
const struct SpriteTemplate gSpotlightSpriteTemplate =
{
.tileTag = ANIM_TAG_SPOTLIGHT,
.paletteTag = ANIM_TAG_SPOTLIGHT,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSpotlightAffineAnimTable,
.callback = AnimSpotlight,
};
const struct SpriteTemplate gClappingHandSpriteTemplate =
{
.tileTag = ANIM_TAG_TAG_HAND,
.paletteTag = ANIM_TAG_TAG_HAND,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimClappingHand,
};
const struct SpriteTemplate gClappingHand2SpriteTemplate =
{
.tileTag = ANIM_TAG_TAG_HAND,
.paletteTag = ANIM_TAG_TAG_HAND,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimClappingHand2,
};
const union AnimCmd gRapidSpinAnimCmds[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(8, 2),
ANIMCMD_FRAME(16, 2),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gRapidSpinAnimTable[] =
{
gRapidSpinAnimCmds,
};
const struct SpriteTemplate gRapidSpinSpriteTemplate =
{
.tileTag = ANIM_TAG_RAPID_SPIN,
.paletteTag = ANIM_TAG_RAPID_SPIN,
.oam = &gOamData_AffineOff_ObjNormal_32x16,
.anims = gRapidSpinAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRapidSpin,
};
static const union AffineAnimCmd sAffineAnims_Torment[] =
{
AFFINEANIMCMD_FRAME(-12, 8, 0, 4),
AFFINEANIMCMD_FRAME(20, -20, 0, 4),
AFFINEANIMCMD_FRAME(-8, 12, 0, 4),
AFFINEANIMCMD_END,
};
const union AnimCmd gTriAttackTriangleAnimCmds[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_END,
};
const union AnimCmd *const gTriAttackTriangleAnimTable[] =
{
gTriAttackTriangleAnimCmds,
};
const union AffineAnimCmd gTriAttackTriangleAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, 0, 5, 40),
AFFINEANIMCMD_FRAME(0, 0, 10, 10),
AFFINEANIMCMD_FRAME(0, 0, 15, 10),
AFFINEANIMCMD_FRAME(0, 0, 20, 40),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gTriAttackTriangleAffineAnimTable[] =
{
gTriAttackTriangleAffineAnimCmds,
};
const struct SpriteTemplate gTriAttackTriangleSpriteTemplate =
{
.tileTag = ANIM_TAG_TRI_ATTACK_TRIANGLE,
.paletteTag = ANIM_TAG_TRI_ATTACK_TRIANGLE,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gTriAttackTriangleAnimTable,
.images = NULL,
.affineAnims = gTriAttackTriangleAffineAnimTable,
.callback = AnimTriAttackTriangle,
};
const union AnimCmd gEclipsingOrbAnimCmds[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_FRAME(32, 3, .hFlip = TRUE),
ANIMCMD_FRAME(16, 3, .hFlip = TRUE),
ANIMCMD_FRAME(0, 3, .hFlip = TRUE),
ANIMCMD_LOOP(1),
ANIMCMD_END,
};
const union AnimCmd *const gEclipsingOrbAnimTable[] =
{
gEclipsingOrbAnimCmds,
};
const struct SpriteTemplate gEclipsingOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_ECLIPSING_ORB,
.paletteTag = ANIM_TAG_ECLIPSING_ORB,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gEclipsingOrbAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSpriteOnMonPos,
};
const union AffineAnimCmd DefenseCurlDeformMonAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-12, 20, 0, 8),
AFFINEANIMCMD_FRAME(12, -20, 0, 8),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gBatonPassPokeballSpriteTemplate =
{
.tileTag = ANIM_TAG_POKEBALL,
.paletteTag = ANIM_TAG_POKEBALL,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBatonPassPokeball,
};
const struct SpriteTemplate gWishStarSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_STARS,
.paletteTag = ANIM_TAG_GOLD_STARS,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWishStar,
};
const struct SpriteTemplate gMiniTwinklingStarSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_STARS,
.paletteTag = ANIM_TAG_GOLD_STARS,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMiniTwinklingStar,
};
const union AffineAnimCmd gStockpileDeformMonAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(8, -8, 0, 12),
AFFINEANIMCMD_FRAME(-16, 16, 0, 12),
AFFINEANIMCMD_FRAME(8, -8, 0, 12),
AFFINEANIMCMD_LOOP(1),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gSpitUpDeformMonAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, 6, 0, 20),
AFFINEANIMCMD_FRAME(0, 0, 0, 20),
AFFINEANIMCMD_FRAME(0, -18, 0, 6),
AFFINEANIMCMD_FRAME(-18, -18, 0, 3),
AFFINEANIMCMD_FRAME(0, 0, 0, 15),
AFFINEANIMCMD_FRAME(4, 4, 0, 13),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gSwallowBlueOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_ORB,
.paletteTag = ANIM_TAG_BLUE_ORB,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSwallowBlueOrb,
};
const union AffineAnimCmd gSwallowDeformMonAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, 6, 0, 20),
AFFINEANIMCMD_FRAME(0, 0, 0, 20),
AFFINEANIMCMD_FRAME(7, -30, 0, 6),
AFFINEANIMCMD_FRAME(0, 0, 0, 20),
AFFINEANIMCMD_FRAME(-2, 3, 0, 20),
AFFINEANIMCMD_END,
};
const s8 gMorningSunLightBeamCoordsTable[] =
{
0xE8,
0x18,
0xFC,
0x00,
};
const union AnimCmd gGreenStarAnimCmds1[] =
{
ANIMCMD_FRAME(0, 6),
ANIMCMD_FRAME(4, 6),
ANIMCMD_JUMP(0),
};
const union AnimCmd gGreenStarAnimCmds2[] =
{
ANIMCMD_FRAME(8, 6),
ANIMCMD_END,
};
const union AnimCmd gGreenStarAnimCmds3[] =
{
ANIMCMD_FRAME(12, 6),
ANIMCMD_END,
};
const union AnimCmd *const gGreenStarAnimTable[] =
{
gGreenStarAnimCmds1,
gGreenStarAnimCmds2,
gGreenStarAnimCmds3,
};
const struct SpriteTemplate gGreenStarSpriteTemplate =
{
.tileTag = ANIM_TAG_GREEN_STAR,
.paletteTag = ANIM_TAG_GREEN_STAR,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gGreenStarAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGreenStar,
};
const s8 gDoomDesireLightBeamCoordTable[] =
{
0x78,
0x50,
0x28,
0x00,
};
const u8 gDoomDesireLightBeamDelayTable[] =
{
0,
0,
0,
0,
50,
};
const union AffineAnimCmd gStrongFrustrationAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, -15, 0, 7),
AFFINEANIMCMD_FRAME(0, 15, 0, 7),
AFFINEANIMCMD_LOOP(2),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gWeakFrustrationAngerMarkSpriteTemplate =
{
.tileTag = ANIM_TAG_ANGER,
.paletteTag = ANIM_TAG_ANGER,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimWeakFrustrationAngerMark,
};
const union AnimCmd gSweetScentPetalAnimCmds1[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(1, 8),
ANIMCMD_FRAME(2, 8),
ANIMCMD_FRAME(3, 8),
ANIMCMD_FRAME(3, 8, .vFlip = TRUE),
ANIMCMD_FRAME(2, 8, .vFlip = TRUE),
ANIMCMD_FRAME(0, 8, .vFlip = TRUE),
ANIMCMD_FRAME(1, 8, .vFlip = TRUE),
ANIMCMD_JUMP(0),
};
const union AnimCmd gSweetScentPetalAnimCmds2[] =
{
ANIMCMD_FRAME(0, 8, .hFlip = TRUE),
ANIMCMD_FRAME(1, 8, .hFlip = TRUE),
ANIMCMD_FRAME(2, 8, .hFlip = TRUE),
ANIMCMD_FRAME(3, 8, .hFlip = TRUE),
ANIMCMD_FRAME(3, 8, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(2, 8, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(0, 8, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_FRAME(1, 8, .vFlip = TRUE, .hFlip = TRUE),
ANIMCMD_JUMP(0),
};
const union AnimCmd gSweetScentPetalAnimCmds3[] =
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_END,
};
const union AnimCmd *const gSweetScentPetalAnimCmdTable[] =
{
gSweetScentPetalAnimCmds1,
gSweetScentPetalAnimCmds2,
gSweetScentPetalAnimCmds3,
};
const struct SpriteTemplate gSweetScentPetalSpriteTemplate =
{
.tileTag = ANIM_TAG_PINK_PETAL,
.paletteTag = ANIM_TAG_PINK_PETAL,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gSweetScentPetalAnimCmdTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSweetScentPetal,
};
static const u16 sUnusedPalette[] = INCBIN_U16("graphics/battle_anims/unused/unknown.gbapal");
const union AnimCmd gPainSplitAnimCmds[] =
{
ANIMCMD_FRAME(0, 5),
ANIMCMD_FRAME(4, 9),
ANIMCMD_FRAME(8, 5),
ANIMCMD_END,
};
const union AnimCmd *const gPainSplitAnimCmdTable[] =
{
gPainSplitAnimCmds,
};
const struct SpriteTemplate gPainSplitProjectileSpriteTemplate =
{
.tileTag = ANIM_TAG_PAIN_SPLIT,
.paletteTag = ANIM_TAG_PAIN_SPLIT,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gPainSplitAnimCmdTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimPainSplitProjectile,
};
const struct SpriteTemplate gFlatterConfettiSpriteTemplate =
{
.tileTag = ANIM_TAG_CONFETTI,
.paletteTag = ANIM_TAG_CONFETTI,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFlatterConfetti,
};
const struct SpriteTemplate gFlatterSpotlightSpriteTemplate =
{
.tileTag = ANIM_TAG_SPOTLIGHT,
.paletteTag = ANIM_TAG_SPOTLIGHT,
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSpotlightAffineAnimTable,
.callback = AnimFlatterSpotlight,
};
const struct SpriteTemplate gReversalOrbSpriteTemplate =
{
.tileTag = ANIM_TAG_BLUE_ORB,
.paletteTag = ANIM_TAG_BLUE_ORB,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimReversalOrb,
};
const union AffineAnimCmd gDeepInhaleAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(16, 0, 0, 4),
AFFINEANIMCMD_FRAME(0, -3, 0, 16),
AFFINEANIMCMD_FRAME(4, 0, 0, 4),
AFFINEANIMCMD_FRAME(0, 0, 0, 24),
AFFINEANIMCMD_FRAME(-5, 3, 0, 16),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gYawnCloudAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
AFFINEANIMCMD_FRAME(-8, -8, 0, 8),
AFFINEANIMCMD_FRAME(8, 8, 0, 8),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gYawnCloudAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0),
AFFINEANIMCMD_FRAME(8, 8, 0, 8),
AFFINEANIMCMD_FRAME(-8, -8, 0, 8),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gYawnCloudAffineAnimCmds3[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(8, 8, 0, 8),
AFFINEANIMCMD_FRAME(-8, -8, 0, 8),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gYawnCloudAffineAnimTable[] =
{
gYawnCloudAffineAnimCmds1,
gYawnCloudAffineAnimCmds2,
gYawnCloudAffineAnimCmds3,
};
const struct SpriteTemplate gYawnCloudSpriteTemplate =
{
.tileTag = ANIM_TAG_PINK_CLOUD,
.paletteTag = ANIM_TAG_PINK_CLOUD,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gYawnCloudAffineAnimTable,
.callback = AnimYawnCloud,
};
const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0),
AFFINEANIMCMD_FRAME(-4, -6, 0, 16),
AFFINEANIMCMD_FRAME(4, 6, 0, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0),
AFFINEANIMCMD_FRAME(4, 6, 0, 16),
AFFINEANIMCMD_FRAME(-4, -6, 0, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds3[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(4, 6, 0, 16),
AFFINEANIMCMD_FRAME(-4, -6, 0, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd gSmokeBallEscapeCloudAffineAnimCmds4[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(8, 10, 0, 30),
AFFINEANIMCMD_FRAME(-8, -10, 0, 16),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gSmokeBallEscapeCloudAffineAnimTable[] =
{
gSmokeBallEscapeCloudAffineAnimCmds1,
gSmokeBallEscapeCloudAffineAnimCmds2,
gSmokeBallEscapeCloudAffineAnimCmds3,
gSmokeBallEscapeCloudAffineAnimCmds4,
};
const struct SpriteTemplate gSmokeBallEscapeCloudSpriteTemplate =
{
.tileTag = ANIM_TAG_PINK_CLOUD,
.paletteTag = ANIM_TAG_PINK_CLOUD,
.oam = &gOamData_AffineDouble_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gSmokeBallEscapeCloudAffineAnimTable,
.callback = AnimSmokeBallEscapeCloud,
};
const union AffineAnimCmd gFacadeSquishAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(-16, 16, 0, 6),
AFFINEANIMCMD_FRAME(16, -16, 0, 12),
AFFINEANIMCMD_FRAME(-16, 16, 0, 6),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gFacadeSweatDropSpriteTemplate =
{
.tileTag = ANIM_TAG_SWEAT_DROP,
.paletteTag = ANIM_TAG_SWEAT_DROP,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimFacadeSweatDrop,
};
const u16 gFacadeBlendColors[] = {
RGB(28, 25, 1),
RGB(28, 21, 5),
RGB(27, 18, 8),
RGB(27, 14, 11),
RGB(26, 10, 15),
RGB(26, 7, 18),
RGB(25, 3, 21),
RGB(25, 0, 25),
RGB(25, 0, 23),
RGB(25, 0, 20),
RGB(25, 0, 16),
RGB(25, 0, 13),
RGB(26, 0, 10),
RGB(26, 0, 6),
RGB(26, 0, 3),
RGB(27, 0, 0),
RGB(27, 1, 0),
RGB(27, 5, 0),
RGB(27, 9, 0),
RGB(27, 12, 0),
RGB(28, 16, 0),
RGB(28, 19, 0),
RGB(28, 23, 0),
RGB(29, 27, 0),
};
const union AnimCmd gRoarNoiseLineAnimCmds1[] =
{
ANIMCMD_FRAME(0, 3),
ANIMCMD_FRAME(16, 3),
ANIMCMD_JUMP(0),
};
const union AnimCmd gRoarNoiseLineAnimCmds2[] =
{
ANIMCMD_FRAME(32, 3),
ANIMCMD_FRAME(48, 3),
ANIMCMD_JUMP(0),
};
const union AnimCmd *const gRoarNoiseLineAnimTable[] =
{
gRoarNoiseLineAnimCmds1,
gRoarNoiseLineAnimCmds2,
};
const struct SpriteTemplate gRoarNoiseLineSpriteTemplate =
{
.tileTag = ANIM_TAG_NOISE_LINE,
.paletteTag = ANIM_TAG_NOISE_LINE,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gRoarNoiseLineAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimRoarNoiseLine,
};
const struct SpriteTemplate gGlareEyeDotSpriteTemplate =
{
.tileTag = ANIM_TAG_SMALL_RED_EYE,
.paletteTag = ANIM_TAG_SMALL_RED_EYE,
.oam = &gOamData_AffineOff_ObjNormal_8x8,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimGlareEyeDot,
};
const struct SpriteTemplate gAssistPawprintSpriteTemplate =
{
.tileTag = ANIM_TAG_PAW_PRINT,
.paletteTag = ANIM_TAG_PAW_PRINT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimAssistPawprint,
};
const union AffineAnimCmd gBarrageBallAffineAnimCmds1[] =
{
AFFINEANIMCMD_FRAME(0, 0, -4, 24),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gBarrageBallAffineAnimCmds2[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
AFFINEANIMCMD_FRAME(0, 0, 4, 24),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gBarrageBallAffineAnimTable[] =
{
gBarrageBallAffineAnimCmds1,
gBarrageBallAffineAnimCmds2,
};
const struct SpriteTemplate gBarrageBallSpriteTemplate =
{
.tileTag = ANIM_TAG_RED_BALL,
.paletteTag = ANIM_TAG_RED_BALL,
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gBarrageBallAffineAnimTable,
.callback = SpriteCallbackDummy,
};
const struct SpriteTemplate gSmellingSaltsHandSpriteTemplate =
{
.tileTag = ANIM_TAG_TAG_HAND,
.paletteTag = ANIM_TAG_TAG_HAND,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSmellingSaltsHand,
};
const union AffineAnimCmd gSmellingSaltsSquishAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, -16, 0, 6),
AFFINEANIMCMD_FRAME(0, 16, 0, 6),
AFFINEANIMCMD_END,
};
const struct SpriteTemplate gSmellingSaltExclamationSpriteTemplate =
{
.tileTag = ANIM_TAG_SMELLINGSALT_EFFECT,
.paletteTag = ANIM_TAG_SMELLINGSALT_EFFECT,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimSmellingSaltExclamation,
};
const struct SpriteTemplate gHelpingHandClapSpriteTemplate =
{
.tileTag = ANIM_TAG_TAG_HAND,
.paletteTag = ANIM_TAG_TAG_HAND,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimHelpingHandClap,
};
const struct SpriteTemplate gForesightMagnifyingGlassSpriteTemplate =
{
.tileTag = ANIM_TAG_MAGNIFYING_GLASS,
.paletteTag = ANIM_TAG_MAGNIFYING_GLASS,
.oam = &gOamData_AffineOff_ObjBlend_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimForesightMagnifyingGlass,
};
const struct SpriteTemplate gMeteorMashStarSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_STARS,
.paletteTag = ANIM_TAG_GOLD_STARS,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimMeteorMashStar,
};
static const struct SpriteTemplate sUnusedStarBurstSpriteTemplate =
{
.tileTag = ANIM_TAG_GOLD_STARS,
.paletteTag = ANIM_TAG_GOLD_STARS,
.oam = &gOamData_AffineOff_ObjNormal_16x16,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimParticleBurst,
};
const struct SpriteTemplate gBlockXSpriteTemplate =
{
.tileTag = ANIM_TAG_X_SIGN,
.paletteTag = ANIM_TAG_X_SIGN,
.oam = &gOamData_AffineOff_ObjNormal_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimBlockX,
};
static const struct SpriteTemplate sUnusedItemBagStealSpriteTemplate =
{
.tileTag = ANIM_TAG_ITEM_BAG,
.paletteTag = ANIM_TAG_ITEM_BAG,
.oam = &gOamData_AffineOff_ObjNormal_32x32,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = AnimUnusedItemBagSteal,
};
const union AnimCmd gKnockOffStrikeAnimCmds[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_END,
};
const union AnimCmd *const gKnockOffStrikeAnimTable[] =
{
gKnockOffStrikeAnimCmds,
};
const union AffineAnimCmd gKnockOffStrikeAffineanimCmds1[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, -4, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd gKnockOffStrikeAffineanimCmds2[] =
{
AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0, 0, 4, 8),
AFFINEANIMCMD_END,
};
const union AffineAnimCmd *const gKnockOffStrikeAffineAnimTable[] =
{
gKnockOffStrikeAffineanimCmds1,
gKnockOffStrikeAffineanimCmds2,
};
const struct SpriteTemplate gKnockOffStrikeSpriteTemplate =
{
.tileTag = ANIM_TAG_SLAM_HIT_2,
.paletteTag = ANIM_TAG_SLAM_HIT_2,
.oam = &gOamData_AffineNormal_ObjNormal_64x64,
.anims = gKnockOffStrikeAnimTable,
.images = NULL,
.affineAnims = gKnockOffStrikeAffineAnimTable,
.callback = AnimKnockOffStrike,
};
const union AffineAnimCmd gRecycleSpriteAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, 0, -4, 64),
AFFINEANIMCMD_JUMP(0),
};
const union AffineAnimCmd *const gRecycleSpriteAffineAnimTable[] =
{
gRecycleSpriteAffineAnimCmds,
};
const struct SpriteTemplate gRecycleSpriteTemplate =
{
.tileTag = ANIM_TAG_RECYCLE,
.paletteTag = ANIM_TAG_RECYCLE,
.oam = &gOamData_AffineNormal_ObjBlend_64x64,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gRecycleSpriteAffineAnimTable,
.callback = AnimRecycle,
};
const union AffineAnimCmd gSlackOffSquishAffineAnimCmds[] =
{
AFFINEANIMCMD_FRAME(0, 16, 0, 4),
AFFINEANIMCMD_FRAME(-2, 0, 0, 8),
AFFINEANIMCMD_FRAME(0, 4, 0, 4),
AFFINEANIMCMD_FRAME(0, 0, 0, 24),
AFFINEANIMCMD_FRAME(1, -5, 0, 16),
AFFINEANIMCMD_END,
};
static void AnimBlackSmoke(struct Sprite *sprite)
{
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
if (!gBattleAnimArgs[3])
sprite->data[0] = gBattleAnimArgs[2];
else
sprite->data[0] = -gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[4];
sprite->callback = AnimBlackSmoke_Step;
}
static void AnimBlackSmoke_Step(struct Sprite *sprite)
{
if (sprite->data[1] > 0)
{
sprite->x2 = sprite->data[2] >> 8;
sprite->data[2] += sprite->data[0];
sprite->invisible ^= 1;
sprite->data[1]--;
}
else
{
DestroyAnimSprite(sprite);
}
}
void AnimTask_SmokescreenImpact(u8 taskId)
{
SmokescreenImpact(
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + 8,
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + 8,
FALSE);
DestroyAnimVisualTask(taskId);
}
static void AnimWhiteHalo(struct Sprite *sprite)
{
sprite->data[0] = 90;
sprite->callback = WaitAnimForDuration;
sprite->data[1] = 7;
StoreSpriteCallbackInData6(sprite, AnimWhiteHalo_Step1);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
}
static void AnimWhiteHalo_Step1(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], 16 - sprite->data[1]));
if (--sprite->data[1] < 0)
{
sprite->invisible = TRUE;
sprite->callback = AnimWhiteHalo_Step2;
}
}
static void AnimWhiteHalo_Step2(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
static void AnimTealAlert(struct Sprite *sprite)
{
u16 rotation;
u8 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
u8 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
InitSpritePosToAnimTarget(sprite, TRUE);
rotation = ArcTan2Neg(sprite->x - x, sprite->y - y);
rotation += 0x6000;
if (IsContest())
rotation += 0x4000;
TrySetSpriteRotScale(sprite, FALSE, 0x100, 0x100, rotation);
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = x;
sprite->data[4] = y;
sprite->callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimMeanLookEye(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
sprite->data[0] = 4;
sprite->callback = AnimMeanLookEye_Step1;
}
static void AnimMeanLookEye_Step1(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0]));
if (sprite->data[1])
sprite->data[0]--;
else
sprite->data[0]++;
if (sprite->data[0] == 15 || sprite->data[0] == 4)
sprite->data[1] ^= 1;
if (sprite->data[2]++ > 70)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
StartSpriteAffineAnim(sprite, 1);
sprite->data[2] = 0;
sprite->invisible = TRUE;
sprite->affineAnimPaused = 1;
sprite->callback = AnimMeanLookEye_Step2;
}
}
static void AnimMeanLookEye_Step2(struct Sprite *sprite)
{
if (sprite->data[2]++ > 9)
{
sprite->invisible = FALSE;
sprite->affineAnimPaused = 0;
if (sprite->affineAnimEnded)
sprite->callback = AnimMeanLookEye_Step3;
}
}
static void AnimMeanLookEye_Step3(struct Sprite *sprite)
{
switch (sprite->data[3])
{
case 0:
case 1:
sprite->x2 = 1;
sprite->y2 = 0;
break;
case 2:
case 3:
sprite->x2 = -1;
sprite->y2 = 0;
break;
case 4:
case 5:
sprite->x2 = 0;
sprite->y2 = 1;
break;
case 6:
default:
sprite->x2 = 0;
sprite->y2 = -1;
break;
}
if (++sprite->data[3] > 7)
sprite->data[3] = 0;
if (sprite->data[4]++ > 15)
{
sprite->data[0] = 16;
sprite->data[1] = 0;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 0));
sprite->callback = AnimMeanLookEye_Step4;
}
}
static void AnimMeanLookEye_Step4(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[0], 16 - sprite->data[0]));
if (sprite->data[1]++ > 1)
{
sprite->data[0]--;
sprite->data[1] = 0;
}
if (sprite->data[0] == 0)
sprite->invisible = TRUE;
if (sprite->data[0] < 0)
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimSprite(sprite);
}
}
void AnimTask_SetPsychicBackground(u8 taskId)
{
gTasks[taskId].func = SetPsychicBackground_Step;
gAnimVisualTaskCount--;
}
static void SetPsychicBackground_Step(u8 taskId)
{
int i;
u16 lastColor;
u8 paletteIndex = GetBattleBgPaletteNum();
if (++gTasks[taskId].data[5] == 4)
{
lastColor = gPlttBufferFaded[paletteIndex * 16 + 11];
for (i = 10; i > 0; i--)
gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i];
gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor;
gTasks[taskId].data[5] = 0;
}
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
DestroyTask(taskId);
}
void AnimTask_FadeScreenToWhite(u8 taskId)
{
gTasks[taskId].func = FadeScreenToWhite_Step;
gAnimVisualTaskCount--;
}
static void FadeScreenToWhite_Step(u8 taskId)
{
int i;
u16 lastColor;
u8 paletteIndex = GetBattleBgPaletteNum();
if (++gTasks[taskId].data[5] == 4)
{
lastColor = gPlttBufferFaded[paletteIndex * 16 + 11];
for (i = 10; i > 0; i--)
gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i];
gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor;
lastColor = gPlttBufferUnfaded[paletteIndex * 16 + 11];
for (i = 10; i > 0; i--)
gPlttBufferUnfaded[paletteIndex * 16 + i + 1] = gPlttBufferUnfaded[paletteIndex * 16 + i];
gPlttBufferUnfaded[paletteIndex * 16 + 1] = lastColor;
gTasks[taskId].data[5] = 0;
}
if ((u16)gBattleAnimArgs[7] == 0xFFFF)
DestroyTask(taskId);
}
static void AnimSpikes(struct Sprite *sprite)
{
u16 x;
u16 y;
InitSpritePosToAnimAttacker(sprite, TRUE);
SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &x, &y);
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = x + gBattleAnimArgs[2];
sprite->data[4] = y + gBattleAnimArgs[3];
sprite->data[5] = -50;
InitAnimArcTranslation(sprite);
sprite->callback = AnimSpikes_Step1;
}
static void AnimSpikes_Step1(struct Sprite *sprite)
{
if (TranslateAnimHorizontalArc(sprite))
{
sprite->data[0] = 30;
sprite->data[1] = 0;
sprite->callback = WaitAnimForDuration;
StoreSpriteCallbackInData6(sprite, AnimSpikes_Step2);
}
}
static void AnimSpikes_Step2(struct Sprite *sprite)
{
if (sprite->data[1] & 1)
sprite->invisible ^= 1;
if (++sprite->data[1] == 16)
DestroyAnimSprite(sprite);
}
static void AnimLeer(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
sprite->y += gBattleAnimArgs[1];
sprite->callback = RunStoredCallbackWhenAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
static void AnimLetterZ(struct Sprite *sprite)
{
int var0;
if (sprite->data[0] == 0)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
if (!IsContest())
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
}
else
{
sprite->data[1] = -1 * gBattleAnimArgs[2];
sprite->data[2] = -1 * gBattleAnimArgs[3];
}
}
else
{
sprite->data[1] = -1 * gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[3];
}
}
sprite->data[0]++;
var0 = (sprite->data[0] * 20) & 0xFF;
sprite->data[3] += sprite->data[1];
sprite->data[4] += sprite->data[2];
sprite->x2 = sprite->data[3] / 2;
sprite->y2 = Sin(var0 & 0xFF, 5) + (sprite->data[4] / 2);
if ((u16)(sprite->x + sprite->x2) > DISPLAY_WIDTH)
DestroyAnimSprite(sprite);
}
static void AnimFang(struct Sprite *sprite)
{
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
void AnimTask_IsTargetPlayerSide(u8 taskId)
{
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT)
gBattleAnimArgs[ARG_RET_ID] = FALSE;
else
gBattleAnimArgs[ARG_RET_ID] = TRUE;
DestroyAnimVisualTask(taskId);
}
void AnimTask_IsHealingMove(u8 taskId)
{
if (gAnimMoveDmg > 0)
gBattleAnimArgs[ARG_RET_ID] = FALSE;
else
gBattleAnimArgs[ARG_RET_ID] = TRUE;
DestroyAnimVisualTask(taskId);
}
static void AnimSpotlight(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->oam.objMode = ST_OAM_OBJ_WINDOW;
sprite->invisible = TRUE;
sprite->callback = AnimSpotlight_Step1;
}
static void AnimSpotlight_Step1(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->invisible = FALSE;
if (sprite->affineAnimEnded)
sprite->data[0]++;
break;
case 1:
case 3:
sprite->data[1] += 117;
sprite->x2 = sprite->data[1] >> 8;
if (++sprite->data[2] == 21)
{
sprite->data[2] = 0;
sprite->data[0]++;
}
break;
case 2:
sprite->data[1] -= 117;
sprite->x2 = sprite->data[1] >> 8;
if (++sprite->data[2] == 41)
{
sprite->data[2] = 0;
sprite->data[0]++;
}
break;
case 4:
ChangeSpriteAffineAnim(sprite, 1);
sprite->data[0]++;
break;
case 5:
if (sprite->affineAnimEnded)
{
sprite->invisible = TRUE;
sprite->callback = AnimSpotlight_Step2;
}
break;
}
}
static void AnimSpotlight_Step2(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
DestroyAnimSprite(sprite);
}
static void AnimClappingHand(struct Sprite *sprite)
{
if (gBattleAnimArgs[3] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
}
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->oam.tileNum += 16;
if (gBattleAnimArgs[2] == 0)
{
sprite->oam.matrixNum = ST_OAM_HFLIP;
sprite->x2 = -12;
sprite->data[1] = 2;
}
else
{
sprite->x2 = 12;
sprite->data[1] = -2;
}
sprite->data[0] = gBattleAnimArgs[4];
if (sprite->data[3] != 255)
sprite->data[3] = gBattleAnimArgs[2];
sprite->callback = AnimClappingHand_Step;
}
static void AnimClappingHand_Step(struct Sprite *sprite)
{
if (sprite->data[2] == 0)
{
sprite->x2 += sprite->data[1];
if (sprite->x2 == 0)
{
sprite->data[2]++;
if (sprite->data[3] == 0)
{
PlaySE1WithPanning(SE_M_ENCORE, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
}
}
else
{
sprite->x2 -= sprite->data[1];
if (abs(sprite->x2) == 12)
{
sprite->data[0]--;
sprite->data[2]--;
}
}
if (sprite->data[0] == 0)
DestroyAnimSprite(sprite);
}
static void AnimClappingHand2(struct Sprite *sprite)
{
sprite->oam.objMode = ST_OAM_OBJ_WINDOW;
sprite->data[3] = 255;
AnimClappingHand(sprite);
}
void AnimTask_CreateSpotlight(u8 taskId)
{
if (IsContest())
{
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ);
gBattle_WIN1H = WIN_RANGE(152, DISPLAY_WIDTH);
gBattle_WIN1V = WIN_RANGE(0, DISPLAY_HEIGHT);
SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN0V);
}
else
{
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ);
gBattle_WIN1H = WIN_RANGE(0, DISPLAY_WIDTH);
gBattle_WIN1V = WIN_RANGE(120, DISPLAY_HEIGHT);
SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN1H);
SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON);
}
DestroyAnimVisualTask(taskId);
}
void AnimTask_RemoveSpotlight(u8 taskId)
{
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
gBattle_WIN1H = 0;
gBattle_WIN1V = 0;
if (!IsContest())
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON);
DestroyAnimVisualTask(taskId);
}
static void AnimRapidSpin(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y);
}
sprite->y2 = gBattleAnimArgs[2];
sprite->data[0] = (sprite->y2 > gBattleAnimArgs[3]);
sprite->data[1] = 0;
sprite->data[2] = gBattleAnimArgs[4];
sprite->data[3] = gBattleAnimArgs[5];
sprite->data[4] = gBattleAnimArgs[3];
sprite->callback = AnimRapidSpin_Step;
}
static void AnimRapidSpin_Step(struct Sprite *sprite)
{
sprite->data[1] = (sprite->data[1] + sprite->data[2]) & 0xFF;
sprite->x2 = gSineTable[sprite->data[1]] >> 4;
sprite->y2 += sprite->data[3];
if (sprite->data[0])
{
if (sprite->y2 < sprite->data[4])
DestroyAnimSprite(sprite);
}
else
{
if (sprite->y2 > sprite->data[4])
DestroyAnimSprite(sprite);
}
}
void AnimTask_RapinSpinMonElevation(u8 taskId)
{
s16 var0;
u8 toBG2;
s16 var2;
int var3;
int var4;
s16 i;
struct ScanlineEffectParams scanlineParams;
struct Task *task = &gTasks[taskId];
if (!gBattleAnimArgs[0])
{
var0 = GetBattlerYCoordWithElevation(gBattleAnimAttacker);
toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
}
else
{
var0 = GetBattlerYCoordWithElevation(gBattleAnimTarget);
toBG2 = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
}
task->data[0] = var0 + 36;
task->data[1] = task->data[0];
task->data[2] = var0 - 33;
if (task->data[2] < 0)
task->data[2] = 0;
task->data[3] = task->data[0];
task->data[4] = 8;
task->data[5] = gBattleAnimArgs[1];
task->data[6] = 0;
task->data[7] = 0;
if (toBG2 == 1)
{
var3 = gBattle_BG1_X;
task->data[8] = var3;
var4 = var3 + DISPLAY_WIDTH;
}
else
{
var3 = gBattle_BG2_X;
task->data[8] = var3;
var4 = var3 + DISPLAY_WIDTH;
}
task->data[9] = var4;
task->data[10] = gBattleAnimArgs[2];
if (!gBattleAnimArgs[2])
{
task->data[11] = var4;
var2 = task->data[8];
}
else
{
task->data[11] = var3;
var2 = task->data[9];
}
task->data[15] = 0;
i = task->data[2];
while (i <= task->data[3])
{
gScanlineEffectRegBuffers[0][i] = var2;
gScanlineEffectRegBuffers[1][i] = var2;
i++;
}
if (toBG2 == 1)
scanlineParams.dmaDest = &REG_BG1HOFS;
else
scanlineParams.dmaDest = &REG_BG2HOFS;
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
ScanlineEffect_SetParams(scanlineParams);
task->func = RapinSpinMonElevation_Step;
}
static void RapinSpinMonElevation_Step(u8 taskId)
{
s16 i;
struct Task *task = &gTasks[taskId];
task->data[0] -= task->data[5];
if (task->data[0] < task->data[2])
task->data[0] = task->data[2];
if (task->data[4] == 0)
{
task->data[1] -= task->data[5];
if (task->data[1] < task->data[2])
{
task->data[1] = task->data[2];
task->data[15] = 1;
}
}
else
{
task->data[4]--;
}
if (++task->data[6] > 1)
{
task->data[6] = 0;
task->data[7] = task->data[7] == 0 ? 1 : 0;
if (task->data[7])
task->data[12] = task->data[8];
else
task->data[12] = task->data[9];
}
i = task->data[0];
while (i < task->data[1])
{
gScanlineEffectRegBuffers[0][i] = task->data[12];
gScanlineEffectRegBuffers[1][i] = task->data[12];
i++;
}
i = task->data[1];
while (i <= task->data[3])
{
gScanlineEffectRegBuffers[0][i] = task->data[11];
gScanlineEffectRegBuffers[1][i] = task->data[11];
i++;
}
if (task->data[15])
{
if (task->data[10])
gScanlineEffect.state = 3;
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_TormentAttacker(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
task->data[4] = 32;
task->data[5] = -20;
task->data[6] = 0;
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->func = TormentAttacker_Step;
}
static void TormentAttacker_Step(u8 taskId)
{
int var0, var1;
s16 x, y;
u16 i, j;
u8 spriteId;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
var0 = task->data[2];
if (task->data[1] & 1)
{
var1 = task->data[4];
x = var0 - var1;
}
else
{
var1 = task->data[4];
x = var0 + var1;
}
y = task->data[3] + task->data[5];
spriteId = CreateSprite(&gThoughtBubbleSpriteTemplate, x, y, 6 - task->data[1]);
PlaySE12WithPanning(SE_M_METRONOME, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].hFlip = task->data[1] & 1;
gSprites[spriteId].callback = SpriteCallbackDummy;
}
if (task->data[1] & 1)
{
task->data[4] -= 6;
task->data[5] -= 6;
}
PrepareAffineAnimInTaskData(task, task->data[15], sAffineAnims_Torment);
task->data[1]++;
task->data[0] = 1;
break;
case 1:
if (!RunAffineAnimFromTaskData(task))
{
if (task->data[1] == 6)
{
task->data[6] = 8;
task->data[0] = 3;
}
else
{
if (task->data[1] <= 2)
task->data[6] = 10;
else
task->data[6] = 0;
task->data[0] = 2;
}
}
break;
case 2:
if (task->data[6] != 0)
task->data[6]--;
else
task->data[0] = 0;
break;
case 3:
if (task->data[6] != 0)
task->data[6]--;
else
task->data[0] = 4;
break;
case 4:
for (i = 0, j = 0; i < MAX_SPRITES; i++)
{
if (gSprites[i].template == &gThoughtBubbleSpriteTemplate)
{
gSprites[i].data[0] = taskId;
gSprites[i].data[1] = 6;
StartSpriteAnim(&gSprites[i], 2);
gSprites[i].callback = TormentAttacker_Callback;
if (++j == 6)
break;
}
}
task->data[6] = j;
task->data[0] = 5;
break;
case 5:
if (task->data[6] == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void TormentAttacker_Callback(struct Sprite *sprite)
{
if (sprite->animEnded)
{
gTasks[sprite->data[0]].data[sprite->data[1]]--;
DestroySprite(sprite);
}
}
static void AnimTriAttackTriangle(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
InitSpritePosToAnimAttacker(sprite, FALSE);
if (++sprite->data[0] < 40)
{
u16 var = sprite->data[0];
if ((var & 1) == 0)
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
}
if (sprite->data[0] > 30)
sprite->invisible = FALSE;
if (sprite->data[0] == 61)
{
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->x2 = 0;
sprite->y2 = 0;
sprite->data[0] = 20;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->callback = StartAnimLinearTranslation;
}
}
void AnimTask_DefenseCurlDeformMon(u8 taskId)
{
switch (gTasks[taskId].data[0])
{
case 0:
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), DefenseCurlDeformMonAffineAnimCmds);
gTasks[taskId].data[0]++;
break;
case 1:
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimBatonPassPokeball(struct Sprite *sprite)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
switch (sprite->data[0])
{
case 0:
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
sprite->data[1] = 256;
sprite->data[2] = 256;
sprite->data[0]++;
break;
case 1:
sprite->data[1] += 96;
sprite->data[2] -= 26;
SetSpriteRotScale(spriteId, sprite->data[1], sprite->data[2], 0);
if (++sprite->data[3] == 5)
sprite->data[0]++;
// fall through
case 2:
sprite->data[1] += 96;
sprite->data[2] += 48;
SetSpriteRotScale(spriteId, sprite->data[1], sprite->data[2], 0);
if (++sprite->data[3] == 9)
{
sprite->data[3] = 0;
gSprites[spriteId].invisible = TRUE;
ResetSpriteRotScale(spriteId);
sprite->data[0]++;
}
break;
case 3:
sprite->y2 -= 6;
if (sprite->y + sprite->y2 < -32)
DestroyAnimSprite(sprite);
break;
}
}
static void AnimWishStar(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x = -16;
else
sprite->x = DISPLAY_WIDTH + 16;
sprite->y = 0;
sprite->callback = AnimWishStar_Step;
}
static void AnimWishStar_Step(struct Sprite *sprite)
{
u32 newX;
sprite->data[0] += 72;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x2 = sprite->data[0] >> 4;
else
sprite->x2 = -(sprite->data[0] >> 4);
sprite->data[1] += 16;
sprite->y2 += sprite->data[1] >> 8;
if (++sprite->data[2] % 3 == 0)
{
CreateSpriteAndAnimate(
&gMiniTwinklingStarSpriteTemplate,
sprite->x + sprite->x2,
sprite->y + sprite->y2,
sprite->subpriority + 1);
}
newX = sprite->x + sprite->x2 + 32;
if (newX > DISPLAY_WIDTH + 64)
DestroyAnimSprite(sprite);
}
static void AnimMiniTwinklingStar(struct Sprite *sprite)
{
u8 rand;
s8 y;
rand = Random2() & 3;
if (rand == 0)
sprite->oam.tileNum += 4;
else
sprite->oam.tileNum += 5;
y = Random2() & 7;
if (y > 3)
y = -y;
sprite->y2 = y;
sprite->callback = AnimMiniTwinklingStar_Step;
}
static void AnimMiniTwinklingStar_Step(struct Sprite *sprite)
{
if (++sprite->data[0] < 30)
{
if (++sprite->data[1] == 2)
{
sprite->invisible ^= 1;
sprite->data[1] = 0;
}
}
else
{
if (sprite->data[1] == 2)
sprite->invisible = FALSE;
if (sprite->data[1] == 3)
{
sprite->invisible = TRUE;
sprite->data[1] = -1;
}
sprite->data[1]++;
}
if (sprite->data[0] > 60)
DestroySprite(sprite);
}
void AnimTask_StockpileDeformMon(u8 taskId)
{
if (!gTasks[taskId].data[0])
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gStockpileDeformMonAffineAnimCmds);
gTasks[taskId].data[0]++;
}
else
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_SpitUpDeformMon(u8 taskId)
{
if (!gTasks[taskId].data[0])
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gSpitUpDeformMonAffineAnimCmds);
gTasks[taskId].data[0]++;
}
else
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
}
static void AnimSwallowBlueOrb(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[1] = 0x900;
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0]++;
break;
case 1:
sprite->y2 -= sprite->data[1] >> 8;
sprite->data[1] -= 96;
if (sprite->y + sprite->y2 > sprite->data[2])
DestroyAnimSprite(sprite);
break;
}
}
void AnimTask_SwallowDeformMon(u8 taskId)
{
if (!gTasks[taskId].data[0])
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gSwallowDeformMonAffineAnimCmds);
gTasks[taskId].data[0]++;
}
else
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
}
void AnimTask_TransformMon(u8 taskId)
{
int i, j;
u8 position;
struct BattleAnimBgData animBg;
u8 *dest;
u8 *src;
u16 *bgTilemap;
u16 stretch;
switch (gTasks[taskId].data[0])
{
case 0:
SetGpuReg(REG_OFFSET_MOSAIC, 0);
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
SetAnimBgAttribute(1, BG_ANIM_MOSAIC, 1);
else
SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 1);
gTasks[taskId].data[10] = gBattleAnimArgs[0];
gTasks[taskId].data[0]++;
break;
case 1:
if (gTasks[taskId].data[2]++ > 1)
{
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[1]++;
stretch = gTasks[taskId].data[1];
SetGpuReg(REG_OFFSET_MOSAIC, (stretch << 4) | stretch);
if (stretch == 15)
gTasks[taskId].data[0]++;
}
break;
case 2:
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]);
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
if (IsContest())
position = B_POSITION_PLAYER_LEFT;
else
position = GetBattlerPosition(gBattleAnimAttacker);
src = gMonSpritesGfxPtr->sprites.ptr[position] + (gBattleMonForms[gBattleAnimAttacker] << 11);
dest = animBg.bgTiles;
CpuCopy32(src, dest, MON_PIC_SIZE);
LoadBgTiles(1, animBg.bgTiles, 0x800, animBg.tilesOffset);
if (IsContest())
{
if (IsSpeciesNotUnown(gContestResources->moveAnim->species) != IsSpeciesNotUnown(gContestResources->moveAnim->targetSpecies))
{
bgTilemap = (u16 *)animBg.bgTilemap;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 4; j++)
{
u16 temp = bgTilemap[j + i * 0x20];
bgTilemap[j + i * 0x20] = bgTilemap[(7 - j) + i * 0x20];
bgTilemap[(7 - j) + i * 0x20] = temp;
}
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
bgTilemap[j + i * 0x20] ^= 0x400;
}
}
}
if (IsSpeciesNotUnown(gContestResources->moveAnim->targetSpecies))
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].affineAnims = gAffineAnims_BattleSpriteContest;
else
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].affineAnims = gAffineAnims_BattleSpriteOpponentSide;
StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], BATTLER_AFFINE_NORMAL);
}
gTasks[taskId].data[0]++;
break;
case 3:
if (gTasks[taskId].data[2]++ > 1)
{
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[1]--;
stretch = gTasks[taskId].data[1];
SetGpuReg(REG_OFFSET_MOSAIC, (stretch << 4) | stretch);
if (stretch == 0)
gTasks[taskId].data[0]++;
}
break;
case 4:
SetGpuReg(REG_OFFSET_MOSAIC, 0);
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
SetAnimBgAttribute(1, BG_ANIM_MOSAIC, 0);
else
SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 0);
if (!IsContest())
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
{
if (gTasks[taskId].data[10] == 0)
SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies);
}
}
DestroyAnimVisualTask(taskId);
break;
}
}
void AnimTask_IsMonInvisible(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible;
DestroyAnimVisualTask(taskId);
}
void AnimTask_CastformGfxDataChange(u8 taskId)
{
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, TRUE);
DestroyAnimVisualTask(taskId);
}
void AnimTask_MorningSunLightBeam(u8 taskId)
{
struct BattleAnimBgData animBg;
switch (gTasks[taskId].data[0])
{
case 0:
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgTilemapHandleContest(&animBg, &gBattleAnimMaskTilemap_LightBeam, FALSE);
if (IsContest())
{
gBattle_BG1_X = -56;
gBattle_BG1_Y = 0;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattle_BG1_X = -135;
else
gBattle_BG1_X = -10;
gBattle_BG1_Y = 0;
}
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimMaskImage_LightBeam, animBg.tilesOffset);
LoadCompressedPalette(gBattleAnimMaskPalette_LightBeam, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].data[10] = gBattle_BG1_X;
gTasks[taskId].data[11] = gBattle_BG1_Y;
gTasks[taskId].data[0]++;
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
break;
case 1:
if (gTasks[taskId].data[4]++ > 0)
{
gTasks[taskId].data[4] = 0;
if (++gTasks[taskId].data[1] > 12)
gTasks[taskId].data[1] = 12;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 12)
gTasks[taskId].data[0]++;
}
break;
case 2:
if (--gTasks[taskId].data[1] < 0)
gTasks[taskId].data[1] = 0;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]));
if (!gTasks[taskId].data[1])
{
gBattle_BG1_X = gMorningSunLightBeamCoordsTable[gTasks[taskId].data[2]] + gTasks[taskId].data[10];
if (++gTasks[taskId].data[2] == 4)
gTasks[taskId].data[0] = 4;
else
gTasks[taskId].data[0] = 3;
}
break;
case 3:
if (++gTasks[taskId].data[3] == 4)
{
gTasks[taskId].data[3] = 0;
gTasks[taskId].data[0] = 1;
PlaySE12WithPanning(SE_M_MORNING_SUN, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
}
break;
case 4:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimGreenStar(struct Sprite *sprite)
{
s16 xOffset;
u8 spriteId1;
u8 spriteId2;
xOffset = Random2();
xOffset &= 0x3F;
if (xOffset > 31)
xOffset = 32 - xOffset;
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + xOffset;
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + 32;
sprite->data[1] = gBattleAnimArgs[0];
sprite->data[2] = gBattleAnimArgs[1];
spriteId1 = CreateSprite(&gGreenStarSpriteTemplate, sprite->x, sprite->y, sprite->subpriority + 1);
spriteId2 = CreateSprite(&gGreenStarSpriteTemplate, sprite->x, sprite->y, sprite->subpriority + 1);
StartSpriteAnim(&gSprites[spriteId1], 1);
StartSpriteAnim(&gSprites[spriteId2], 2);
gSprites[spriteId1].data[1] = gBattleAnimArgs[0];
gSprites[spriteId1].data[2] = gBattleAnimArgs[1];
gSprites[spriteId2].data[1] = gBattleAnimArgs[0];
gSprites[spriteId2].data[2] = gBattleAnimArgs[1];
gSprites[spriteId1].data[7] = -1;
gSprites[spriteId2].data[7] = -1;
gSprites[spriteId1].invisible = TRUE;
gSprites[spriteId2].invisible = TRUE;
gSprites[spriteId1].callback = AnimGreenStar_Callback;
gSprites[spriteId2].callback = AnimGreenStar_Callback;
sprite->data[6] = spriteId1;
sprite->data[7] = spriteId2;
sprite->callback = AnimGreenStar_Step1;
}
static void AnimGreenStar_Step1(struct Sprite *sprite)
{
s16 delta = sprite->data[3] + sprite->data[2];
sprite->y2 -= delta >> 8;
sprite->data[3] += sprite->data[2];
sprite->data[3] &= 0xFF;
if (sprite->data[4] == 0 && sprite->y2 < -8)
{
gSprites[sprite->data[6]].invisible = FALSE;
sprite->data[4]++;
}
if (sprite->data[4] == 1 && sprite->y2 < -16)
{
gSprites[sprite->data[7]].invisible = FALSE;
sprite->data[4]++;
}
if (--sprite->data[1] == -1)
{
sprite->invisible = TRUE;
sprite->callback = AnimGreenStar_Step2;
}
}
static void AnimGreenStar_Step2(struct Sprite *sprite)
{
if (gSprites[sprite->data[6]].callback == SpriteCallbackDummy
&& gSprites[sprite->data[7]].callback == SpriteCallbackDummy)
{
DestroySprite(&gSprites[sprite->data[6]]);
DestroySprite(&gSprites[sprite->data[7]]);
DestroyAnimSprite(sprite);
}
}
static void AnimGreenStar_Callback(struct Sprite *sprite)
{
if (!sprite->invisible)
{
s16 delta = sprite->data[3] + sprite->data[2];
sprite->y2 -= delta >> 8;
sprite->data[3] += sprite->data[2];
sprite->data[3] &= 0xFF;
if (--sprite->data[1] == -1)
{
sprite->invisible = TRUE;
sprite->callback = SpriteCallbackDummy;
}
}
}
void AnimTask_DoomDesireLightBeam(u8 taskId)
{
struct BattleAnimBgData animBg;
switch (gTasks[taskId].data[0])
{
case 0:
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, 13));
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgTilemapHandleContest(&animBg, &gBattleAnimMaskTilemap_LightBeam, FALSE);
if (IsContest())
{
gBattle_BG1_X = -56;
gBattle_BG1_Y = 0;
}
else
{
u8 position = GetBattlerPosition(gBattleAnimTarget);
if (IsDoubleBattle() == TRUE)
{
if (position == B_POSITION_OPPONENT_LEFT)
gBattle_BG1_X = -155;
if (position == B_POSITION_OPPONENT_RIGHT)
gBattle_BG1_X = -115;
if (position == B_POSITION_PLAYER_LEFT)
gBattle_BG1_X = 14;
if (position == B_POSITION_PLAYER_RIGHT)
gBattle_BG1_X = -20;
}
else
{
if (position == B_POSITION_OPPONENT_LEFT)
gBattle_BG1_X = -135;
if (position == B_POSITION_PLAYER_LEFT)
gBattle_BG1_X = -10;
}
gBattle_BG1_Y = 0;
}
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimMaskImage_LightBeam, animBg.tilesOffset);
LoadCompressedPalette(gBattleAnimMaskPalette_LightBeam, BG_PLTT_ID(animBg.paletteId), PLTT_SIZE_4BPP);
gTasks[taskId].data[10] = gBattle_BG1_X;
gTasks[taskId].data[11] = gBattle_BG1_Y;
gTasks[taskId].data[0]++;
break;
case 1:
gTasks[taskId].data[3] = 0;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT)
gBattle_BG1_X = gTasks[taskId].data[10] + gDoomDesireLightBeamCoordTable[gTasks[taskId].data[2]];
else
gBattle_BG1_X = gTasks[taskId].data[10] - gDoomDesireLightBeamCoordTable[gTasks[taskId].data[2]];
if (++gTasks[taskId].data[2] == 5)
gTasks[taskId].data[0] = 5;
else
gTasks[taskId].data[0]++;
break;
case 2:
if (--gTasks[taskId].data[1] <= 4)
gTasks[taskId].data[1] = 5;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 5)
gTasks[taskId].data[0]++;
break;
case 3:
if (++gTasks[taskId].data[3] > gDoomDesireLightBeamDelayTable[gTasks[taskId].data[2]])
gTasks[taskId].data[0]++;
break;
case 4:
if (++gTasks[taskId].data[1] > 13)
gTasks[taskId].data[1] = 13;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(3, gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 13)
gTasks[taskId].data[0] = 1;
break;
case 5:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyAnimVisualTask(taskId);
break;
}
}
// Briefly vertically grows and shrinks the attacking mon's sprite.
// No args.
void AnimTask_StrongFrustrationGrowAndShrink(u8 taskId)
{
if (gTasks[taskId].data[0] == 0)
{
PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(ANIM_ATTACKER), gStrongFrustrationAffineAnimCmds);
gTasks[taskId].data[0]++;
}
else
{
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
}
// Animates an anger mark near the mon's head.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
static void AnimWeakFrustrationAngerMark(struct Sprite *sprite)
{
if (sprite->data[0] == 0)
{
InitSpritePosToAnimAttacker(sprite, FALSE);
sprite->data[0]++;
}
else if (sprite->data[0]++ > 20)
{
sprite->data[1] += 160;
sprite->data[2] += 128;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->x2 = -(sprite->data[1] >> 8);
else
sprite->x2 = sprite->data[1] >> 8;
sprite->y2 += sprite->data[2] >> 8;
if (sprite->y2 > 64)
DestroyAnimSprite(sprite);
}
}
// Rocks the mon back and forth. This is done on a pivot so it is done via rotation.
// arg 0: which battler
// arg 1: number of rocks
// arg 2: rotation speed increase
void AnimTask_RockMonBackAndForth(u8 taskId)
{
u8 side;
struct Task *task = &gTasks[taskId];
if (!gBattleAnimArgs[1])
{
DestroyAnimVisualTask(taskId);
return;
}
if (gBattleAnimArgs[2] < 0)
gBattleAnimArgs[2] = 0;
if (gBattleAnimArgs[2] > 2)
gBattleAnimArgs[2] = 2;
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 8 - (2 * gBattleAnimArgs[2]);
task->data[4] = 0x100 + (gBattleAnimArgs[2] * 128);
task->data[5] = gBattleAnimArgs[2] + 2;
task->data[6] = gBattleAnimArgs[1] - 1;
task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
side = GetBattlerSide(gBattleAnimAttacker);
else
side = GetBattlerSide(gBattleAnimTarget);
if (side == B_SIDE_OPPONENT)
{
task->data[4] *= -1;
task->data[5] *= -1;
}
PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL);
task->func = AnimTask_RockMonBackAndForth_Step;
}
static void AnimTask_RockMonBackAndForth_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
gSprites[task->data[15]].x2 += task->data[5];
task->data[2] -= task->data[4];
SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]);
SetBattlerSpriteYOffsetFromRotation(task->data[15]);
if (++task->data[1] >= task->data[3])
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 1:
gSprites[task->data[15]].x2 -= task->data[5];
task->data[2] += task->data[4];
SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]);
SetBattlerSpriteYOffsetFromRotation(task->data[15]);
if (++task->data[1] >= task->data[3] * 2)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 2:
gSprites[task->data[15]].x2 += task->data[5];
task->data[2] -= task->data[4];
SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]);
SetBattlerSpriteYOffsetFromRotation(task->data[15]);
if (++task->data[1] >= task->data[3])
{
if (task->data[6])
{
task->data[6]--;
task->data[1] = 0;
task->data[0] = 0;
}
else
{
task->data[0]++;
}
}
break;
case 3:
ResetSpriteRotScale(task->data[15]);
DestroyAnimVisualTask(taskId);
break;
}
}
// Floats a petal across the screen towards the target mon's side.
// arg 0: initial y pixel offset
// arg 1: sprite anim num
// arg 2: unused
static void AnimSweetScentPetal(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x = 0;
sprite->y = gBattleAnimArgs[0];
}
else
{
sprite->x = DISPLAY_WIDTH;
sprite->y = gBattleAnimArgs[0] - 30;
}
sprite->data[2] = gBattleAnimArgs[2];
StartSpriteAnim(sprite, gBattleAnimArgs[1]);
sprite->callback = AnimSweetScentPetal_Step;
}
static void AnimSweetScentPetal_Step(struct Sprite *sprite)
{
sprite->data[0] += 3;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
sprite->x += 5;
sprite->y -= 1;
if (sprite->x > DISPLAY_WIDTH)
DestroyAnimSprite(sprite);
sprite->y2 = Sin(sprite->data[0] & 0xFF, 16);
}
else
{
sprite->x -= 5;
sprite->y += 1;
if (sprite->x < 0)
DestroyAnimSprite(sprite);
sprite->y2 = Cos(sprite->data[0] & 0xFF, 16);
}
}
// Moves the mon sprite in a flailing back-and-forth motion.
// arg 0: which battler
void AnimTask_FlailMovement(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 0;
task->data[12] = 0x20;
task->data[13] = 0x40;
task->data[14] = 0x800;
task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL);
task->func = AnimTask_FlailMovement_Step;
}
static void AnimTask_FlailMovement_Step(u8 taskId)
{
int temp;
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[2] += 0x200;
if (task->data[2] >= task->data[14])
{
s16 diff = task->data[14] - task->data[2];
s16 div = diff / (task->data[14] * 2);
s16 mod = diff % (task->data[14] * 2);
if ((div & 1) == 0)
{
task->data[2] = task->data[14] - mod;
task->data[0] = 1;
}
else
{
task->data[2] = mod - task->data[14];
}
}
break;
case 1:
task->data[2] -= 0x200;
if (task->data[2] <= -task->data[14])
{
s16 diff = task->data[14] - task->data[2];
s16 div = diff / (task->data[14] * 2);
s16 mod = diff % (task->data[14] * 2);
if ((1 & div) == 0)
{
task->data[2] = mod - task->data[14];
task->data[0] = 0;
}
else
{
task->data[2] = task->data[14] - mod;
}
}
break;
case 2:
ResetSpriteRotScale(task->data[15]);
DestroyAnimVisualTask(taskId);
return;
}
SetSpriteRotScale(task->data[15], 0x100, 0x100, task->data[2]);
SetBattlerSpriteYOffsetFromRotation(task->data[15]);
gSprites[task->data[15]].x2 = -(((temp = task->data[2]) >= 0 ? task->data[2] : temp + 63) >> 6);
if (++task->data[1] > 8)
{
if (task->data[12])
{
task->data[12]--;
task->data[14] -= task->data[13];
if (task->data[14] < 16)
task->data[14] = 16;
}
else
{
task->data[0] = 2;
}
}
}
// Makes a spark-like projectile fall on top of the mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: which battler
static void AnimPainSplitProjectile(struct Sprite *sprite)
{
if (!sprite->data[0])
{
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[1] = 0x80;
sprite->data[2] = 0x300;
sprite->data[3] = gBattleAnimArgs[1];
sprite->data[0]++;
}
else
{
sprite->x2 = sprite->data[1] >> 8;
sprite->y2 += sprite->data[2] >> 8;
if (sprite->data[4] == 0 && sprite->y2 > -sprite->data[3])
{
sprite->data[4] = 1;
sprite->data[2] = (-sprite->data[2] / 3) * 2;
}
sprite->data[1] += 192;
sprite->data[2] += 128;
if (sprite->animEnded)
DestroyAnimSprite(sprite);
}
}
// Performs one of several affine transformations on the mon sprite.
// arg 0: which battler
// arg 1: which transformation
void AnimTask_PainSplitMovement(u8 taskId)
{
u8 spriteId;
if (gTasks[taskId].data[0] == 0)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
gTasks[taskId].data[11] = gBattleAnimAttacker;
else
gTasks[taskId].data[11] = gBattleAnimTarget;
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gTasks[taskId].data[10] = spriteId;
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
switch (gBattleAnimArgs[1])
{
case 0:
SetSpriteRotScale(spriteId, 0xE0, 0x140, 0);
SetBattlerSpriteYOffsetFromYScale(spriteId);
break;
case 1:
SetSpriteRotScale(spriteId, 0xD0, 0x130, 0xF00);
SetBattlerSpriteYOffsetFromYScale(spriteId);
if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER)
gSprites[spriteId].y2 += 16;
break;
case 2:
SetSpriteRotScale(spriteId, 0xD0, 0x130, 0xF100);
SetBattlerSpriteYOffsetFromYScale(spriteId);
if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER)
gSprites[spriteId].y2 += 16;
break;
}
gSprites[spriteId].x2 = 2;
gTasks[taskId].data[0]++;
}
else
{
spriteId = gTasks[taskId].data[10];
if (++gTasks[taskId].data[2] == 3)
{
gTasks[taskId].data[2] = 0;
gSprites[spriteId].x2 = -gSprites[spriteId].x2;
}
if (++gTasks[taskId].data[1] == 13)
{
ResetSpriteRotScale(spriteId);
gSprites[spriteId].x2 = 0;
gSprites[spriteId].y2 = 0;
DestroyAnimVisualTask(taskId);
}
}
}
// Move a piece of confetti in a slightly-random speed across the screen.
// arg 0: which battler the confetti starts from
static void AnimFlatterConfetti(struct Sprite *sprite)
{
u8 tileOffset;
int rand1;
int rand2;
tileOffset = Random2() % 12;
sprite->oam.tileNum += tileOffset;
rand1 = Random2() & 0x1FF;
rand2 = Random2() & 0xFF;
if (rand1 & 1)
sprite->data[0] = 0x5E0 + rand1;
else
sprite->data[0] = 0x5E0 - rand1;
if (rand2 & 1)
sprite->data[1] = 0x480 + rand2;
else
sprite->data[1] = 0x480 - rand2;
sprite->data[2] = gBattleAnimArgs[0];
if (sprite->data[2] == ANIM_ATTACKER)
sprite->x = -8;
else
sprite->x = 248;
sprite->y = 104;
sprite->callback = AnimFlatterConfetti_Step;
}
static void AnimFlatterConfetti_Step(struct Sprite *sprite)
{
if (sprite->data[2] == 0)
{
sprite->x2 += sprite->data[0] >> 8;
sprite->y2 -= sprite->data[1] >> 8;
}
else
{
sprite->x2 -= sprite->data[0] >> 8;
sprite->y2 -= sprite->data[1] >> 8;
}
sprite->data[0] -= 22;
sprite->data[1] -= 48;
if (sprite->data[0] < 0)
sprite->data[0] = 0;
if (++sprite->data[3] == 31)
DestroyAnimSprite(sprite);
}
// Uses a spotlight sprite as a light mask to illuminate the target mon. The spotlight grows and shrinks.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: duration of fully-opened spotlight
static void AnimFlatterSpotlight(struct Sprite *sprite)
{
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
sprite->data[0] = gBattleAnimArgs[2];
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->oam.objMode = ST_OAM_OBJ_WINDOW;
sprite->invisible = TRUE;
sprite->callback = AnimFlatterSpotlight_Step;
}
static void AnimFlatterSpotlight_Step(struct Sprite *sprite)
{
switch (sprite->data[1])
{
case 0:
sprite->invisible = FALSE;
if (sprite->affineAnimEnded)
sprite->data[1]++;
break;
case 1:
if (--sprite->data[0] == 0)
{
ChangeSpriteAffineAnim(sprite, 1);
sprite->data[1]++;
}
break;
case 2:
if (sprite->affineAnimEnded)
{
sprite->invisible = TRUE;
sprite->data[1]++;
}
break;
case 3:
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
DestroyAnimSprite(sprite);
break;
}
}
// Spins an orb around the attacking mon, while its path radius grows and shrinks.
// arg 0: duration
// arg 1: initial wave offset
static void AnimReversalOrb(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
sprite->data[0] = gBattleAnimArgs[0];
sprite->data[1] = gBattleAnimArgs[1];
sprite->callback = AnimReversalOrb_Step;
sprite->callback(sprite);
}
static void AnimReversalOrb_Step(struct Sprite *sprite)
{
sprite->x2 = Sin(sprite->data[1], sprite->data[2] >> 8);
sprite->y2 = Cos(sprite->data[1], sprite->data[3] >> 8);
sprite->data[1] = (sprite->data[1] + 9) & 0xFF;
if ((u16)sprite->data[1] < 64 || sprite->data[1] > 195)
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) - 1;
else
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + 1;
if (!sprite->data[5])
{
sprite->data[2] += 0x400;
sprite->data[3] += 0x100;
sprite->data[4]++;
if (sprite->data[4] == sprite->data[0])
{
sprite->data[4] = 0;
sprite->data[5] = 1;
}
}
else if (sprite->data[5] == 1)
{
sprite->data[2] -= 0x400;
sprite->data[3] -= 0x100;
sprite->data[4]++;
if (sprite->data[4] == sprite->data[0])
DestroyAnimSprite(sprite);
}
}
// Copies the target mon's sprite, and makes a white silhouette that shrinks away.
void AnimTask_RolePlaySilhouette(u8 taskId)
{
bool8 isBackPic;
u32 personality;
u32 otId;
u16 species;
s16 xOffset;
u32 priority;
u8 spriteId;
s16 coord1, coord2;
GetAnimBattlerSpriteId(ANIM_ATTACKER);
if (IsContest())
{
isBackPic = TRUE;
personality = gContestResources->moveAnim->targetPersonality;
otId = gContestResources->moveAnim->otId;
species = gContestResources->moveAnim->targetSpecies;
xOffset = 20;
priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
isBackPic = FALSE;
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
{
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES);
else
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES);
}
else
{
species = gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies;
}
xOffset = 20;
priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
}
else
{
isBackPic = TRUE;
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY);
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE)
{
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES);
else
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES);
}
else
{
species = gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies;
}
xOffset = -20;
priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
}
}
coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y);
spriteId = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId, gBattleAnimTarget, TRUE);
gSprites[spriteId].oam.priority = priority;
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND;
FillPalette(RGB_WHITE, OBJ_PLTT_ID(gSprites[spriteId].oam.paletteNum), PLTT_SIZE_4BPP);
gSprites[spriteId].oam.priority = priority;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]));
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].func = AnimTask_RolePlaySilhouette_Step1;
}
static void AnimTask_RolePlaySilhouette_Step1(u8 taskId)
{
if (gTasks[taskId].data[10]++ > 1)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[1]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]));
if (gTasks[taskId].data[1] == 10)
{
gTasks[taskId].data[10] = 256;
gTasks[taskId].data[11] = 256;
gTasks[taskId].func = AnimTask_RolePlaySilhouette_Step2;
}
}
}
static void AnimTask_RolePlaySilhouette_Step2(u8 taskId)
{
u8 spriteId = gTasks[taskId].data[0];
gTasks[taskId].data[10] -= 16;
gTasks[taskId].data[11] += 128;
gSprites[spriteId].oam.affineMode |= ST_OAM_AFFINE_DOUBLE_MASK;
TrySetSpriteRotScale(&gSprites[spriteId], TRUE, gTasks[taskId].data[10], gTasks[taskId].data[11], 0);
if (++gTasks[taskId].data[12] == 9)
{
ResetSpriteRotScale_PreserveAffine(&gSprites[spriteId]);
DestroySpriteAndFreeResources_(&gSprites[spriteId]);
gTasks[taskId].func = DestroyAnimVisualTaskAndDisableBlend;
}
}
// Performs a wavy transformation on the mon's sprite, and fades out.
// arg 0: which battler
void AnimTask_AcidArmor(u8 taskId)
{
u8 battler;
u16 bgX, bgY;
s16 y, i;
struct ScanlineEffectParams scanlineParams;
struct Task *task = &gTasks[taskId];
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
task->data[0] = 0;
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 16;
task->data[4] = 0;
task->data[5] = battler;
task->data[6] = 32;
task->data[7] = 0;
task->data[8] = 24;
if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
task->data[8] *= -1;
task->data[13] = GetBattlerYCoordWithElevation(battler) - 34;
if (task->data[13] < 0)
task->data[13] = 0;
task->data[14] = task->data[13] + 66;
task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (GetBattlerSpriteBGPriorityRank(battler) == 1)
{
scanlineParams.dmaDest = &REG_BG1HOFS;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1);
bgX = gBattle_BG1_X;
bgY = gBattle_BG1_Y;
}
else
{
scanlineParams.dmaDest = &REG_BG2HOFS;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG2);
bgX = gBattle_BG2_X;
bgY = gBattle_BG2_Y;
}
for (y = 0, i = 0; y < 160; y++, i += 2)
{
gScanlineEffectRegBuffers[0][i] = bgX;
gScanlineEffectRegBuffers[1][i] = bgX;
gScanlineEffectRegBuffers[0][i + 1] = bgY;
gScanlineEffectRegBuffers[1][i + 1] = bgY;
}
scanlineParams.dmaControl = SCANLINE_EFFECT_DMACNT_32BIT;
scanlineParams.initState = 1;
scanlineParams.unused9 = 0;
ScanlineEffect_SetParams(scanlineParams);
task->func = AnimTask_AcidArmor_Step;
}
static void AnimTask_AcidArmor_Step(u8 taskId)
{
struct Task *task;
s16 var1;
s16 var2;
s16 bgX, bgY;
s16 offset;
s16 var0;
s16 i;
s16 sineIndex;
s16 var3;
task = &gTasks[taskId];
if (GetBattlerSpriteBGPriorityRank(task->data[5]) == 1)
{
bgX = gBattle_BG1_X;
bgY = gBattle_BG1_Y;
}
else
{
bgX = gBattle_BG2_X;
bgY = gBattle_BG2_Y;
}
switch (task->data[0])
{
case 0:
offset = task->data[14] * 2;
var1 = 0;
var2 = 0;
i = 0;
task->data[1] = (task->data[1] + 2) & 0xFF;
sineIndex = task->data[1];
task->data[9] = 0x7E0 / task->data[6];
task->data[10] = -((task->data[7] * 2) / task->data[9]);
task->data[11] = task->data[7];
var3 = task->data[11] >> 5;
task->data[12] = var3;
var0 = task->data[14];
while (var0 > task->data[13])
{
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset + 1] = (i - var2) + bgY;
gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset] = bgX + var3 + (gSineTable[sineIndex] >> 5);
sineIndex = (sineIndex + 10) & 0xFF;
task->data[11] += task->data[10];
var3 = task->data[11] >> 5;
task->data[12] = var3;
i++;
offset -= 2;
var1 += task->data[6];
var2 = var1 >> 5;
var0--;
}
var0 *= 2;
while (var0 >= 0)
{
gScanlineEffectRegBuffers[0][var0] = bgX + 240;
gScanlineEffectRegBuffers[1][var0] = bgX + 240;
var0 -= 2;
}
if (++task->data[6] > 63)
{
task->data[6] = 64;
task->data[2]++;
if (task->data[2] & 1)
task->data[3]--;
else
task->data[4]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
if (task->data[3] == 0 && task->data[4] == 16)
{
task->data[2] = 0;
task->data[3] = 0;
task->data[0]++;
}
}
else
{
task->data[7] += task->data[8];
}
break;
case 1:
if (++task->data[2] > 12)
{
gScanlineEffect.state = 3;
task->data[2] = 0;
task->data[0]++;
}
break;
case 2:
task->data[2]++;
if (task->data[2] & 1)
task->data[3]++;
else
task->data[4]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4]));
if (task->data[3] == 16 && task->data[4] == 0)
{
task->data[2] = 0;
task->data[3] = 0;
task->data[0]++;
}
break;
case 3:
DestroyAnimVisualTask(taskId);
break;
}
}
// Runs an affine animation that makes it look like the mon is inhaling deeply.
// arg 0: which battler
void AnimTask_DeepInhale(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareAffineAnimInTaskData(&gTasks[taskId], task->data[15], gDeepInhaleAffineAnimCmds);
task->func = AnimTask_DeepInhale_Step;
}
static void AnimTask_DeepInhale_Step(u8 taskId)
{
u16 var0;
struct Task *task = &gTasks[taskId];
var0 = task->data[0];
task->data[0]++;
var0 -= 20;
if (var0 < 23)
{
if (++task->data[1] > 1)
{
task->data[1] = 0;
task->data[2]++;
if (task->data[2] & 1)
gSprites[task->data[15]].x2 = 1;
else
gSprites[task->data[15]].x2 = -1;
}
}
else
{
gSprites[task->data[15]].x2 = 0;
}
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}
static void InitYawnCloudPosition(struct Sprite *sprite, s16 startX, s16 startY, s16 destX, s16 destY, u16 duration)
{
sprite->x = startX;
sprite->y = startY;
sprite->data[4] = startX << 4;
sprite->data[5] = startY << 4;
sprite->data[6] = ((destX - startX) << 4) / duration;
sprite->data[7] = ((destY - startY) << 4) / duration;
}
static void UpdateYawnCloudPosition(struct Sprite *sprite)
{
sprite->data[4] += sprite->data[6];
sprite->data[5] += sprite->data[7];
sprite->x = sprite->data[4] >> 4;
sprite->y = sprite->data[5] >> 4;
}
// Drifts a cloud in a wavy path towards the target mon.
// arg 0: which affine anim
static void AnimYawnCloud(struct Sprite *sprite)
{
s16 destX = sprite->x;
s16 destY = sprite->y;
SetSpriteCoordsToAnimAttackerCoords(sprite);
StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]);
InitYawnCloudPosition(sprite, sprite->x, sprite->y, destX, destY, 64);
sprite->data[0] = 0;
sprite->callback = AnimYawnCloud_Step;
}
static void AnimYawnCloud_Step(struct Sprite *sprite)
{
int index;
sprite->data[0]++;
index = (sprite->data[0] * 8) & 0xFF;
UpdateYawnCloudPosition(sprite);
sprite->y2 = Sin(index, 8);
if (sprite->data[0] > 58)
{
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
sprite->data[2]++;
sprite->invisible = sprite->data[2] & 1;
if (sprite->data[2] > 3)
DestroySpriteAndMatrix(sprite);
}
}
}
// Animates a cloud coming from the smoke ball.
// arg 0: ?
// arg 1: initial x pixel offset
// arg 2: initial y pixel offset
// arg 3: time until destroyed
static void AnimSmokeBallEscapeCloud(struct Sprite *sprite)
{
sprite->data[0] = gBattleAnimArgs[3];
StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]);
if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
sprite->callback = DestroyAnimSpriteAfterTimer;
}
static void AnimTask_SlideMonForFocusBand_Step2(u8 taskId)
{
u16 var0 = 0;
u16 var1 = 0;
gTasks[taskId].data[0]--;
if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1))
{
if (gTasks[taskId].data[9] == 0)
{
gTasks[taskId].data[9] = gTasks[taskId].data[4];
gTasks[taskId].data[4] = -gTasks[taskId].data[4];
}
else
{
gTasks[taskId].data[9] = 0;
}
if (gTasks[taskId].data[10] == 0)
{
gTasks[taskId].data[10] = gTasks[taskId].data[5];
gTasks[taskId].data[5] = -gTasks[taskId].data[5];
}
else
{
gTasks[taskId].data[10] = 0;
}
gTasks[taskId].data[1] = gTasks[taskId].data[13];
}
var0 = gTasks[taskId].data[7];
var1 = gTasks[taskId].data[8];
if (gTasks[taskId].data[2] & 0x8000)
gSprites[gTasks[taskId].data[15]].x2 = gTasks[taskId].data[9] - (var0 >> 8);
else
gSprites[gTasks[taskId].data[15]].x2 = gTasks[taskId].data[9] + (var0 >> 8);
if (gTasks[taskId].data[3] & 0x8000)
gSprites[gTasks[taskId].data[15]].y2 = gTasks[taskId].data[10] - (var1 >> 8);
else
gSprites[gTasks[taskId].data[15]].y2 = gTasks[taskId].data[10] + (var1 >> 8);
if (gTasks[taskId].data[0] < 1)
{
DestroyTask(taskId);
gAnimVisualTaskCount--;
}
}
static void AnimTask_SlideMonForFocusBand_Step1(u8 taskId)
{
u16 var0 = 0;
u16 var1 = 0;
gTasks[taskId].data[0]--;
if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1))
{
if (gTasks[taskId].data[9] == 0)
{
gTasks[taskId].data[9] = gTasks[taskId].data[4];
gTasks[taskId].data[4] = -gTasks[taskId].data[4];
}
else
{
gTasks[taskId].data[9] = var0;
}
if (gTasks[taskId].data[10] == 0)
{
gTasks[taskId].data[10] = gTasks[taskId].data[5];
gTasks[taskId].data[5] = -gTasks[taskId].data[5];
}
else
{
gTasks[taskId].data[10] = 0;
}
gTasks[taskId].data[1] = gTasks[taskId].data[13];
}
var0 = (gTasks[taskId].data[2] & 0x7FFF) + gTasks[taskId].data[7];
var1 = (gTasks[taskId].data[3] & 0x7FFF) + gTasks[taskId].data[8];
if (gTasks[taskId].data[2] & 0x8000)
gSprites[gTasks[taskId].data[15]].x2 = gTasks[taskId].data[9] - (var0 >> 8);
else
gSprites[gTasks[taskId].data[15]].x2 = gTasks[taskId].data[9] + (var0 >> 8);
if (gTasks[taskId].data[3] & 0x8000)
gSprites[gTasks[taskId].data[15]].y2 = gTasks[taskId].data[10] - (var1 >> 8);
else
gSprites[gTasks[taskId].data[15]].y2 = gTasks[taskId].data[10] + (var1 >> 8);
gTasks[taskId].data[7] = var0;
gTasks[taskId].data[8] = var1;
if (gTasks[taskId].data[0] < 1)
{
gTasks[taskId].data[0] = 30;
gTasks[taskId].data[13] = 0;
gTasks[taskId].func = AnimTask_SlideMonForFocusBand_Step2;
}
}
void AnimTask_SlideMonForFocusBand(u8 taskId)
{
gTasks[taskId].data[15] = gBattlerSpriteIds[gBattleAnimAttacker];
gTasks[taskId].data[14] = gBattleAnimArgs[0];
gTasks[taskId].data[0] = gBattleAnimArgs[0];
gTasks[taskId].data[13] = gBattleAnimArgs[6];
if (gBattleAnimArgs[3])
gTasks[taskId].data[6] = gTasks[taskId].data[6] | -0x8000;
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gTasks[taskId].data[2] = gBattleAnimArgs[1];
gTasks[taskId].data[3] = gBattleAnimArgs[2];
}
else
{
if (gBattleAnimArgs[1] & 0x8000)
gTasks[taskId].data[2] = gBattleAnimArgs[1] & 0x7FFF;
else
gTasks[taskId].data[2] = gBattleAnimArgs[1] | -0x8000;
if (gBattleAnimArgs[2] & 0x8000)
gTasks[taskId].data[3] = gBattleAnimArgs[2] & 0x7FFF;
else
gTasks[taskId].data[3] = gBattleAnimArgs[2] | -0x8000;
}
gTasks[taskId].data[8] = 0;
gTasks[taskId].data[7] = 0;
gTasks[taskId].data[4] = gBattleAnimArgs[4];
gTasks[taskId].data[5] = gBattleAnimArgs[5];
gTasks[taskId].func = AnimTask_SlideMonForFocusBand_Step1;
}
#define IDX_ACTIVE_SPRITES 2 // Used by the sprite callback to modify the number of active sprites
// Task data for AnimTask_SquishAndSweatDroplets
#define tState data[0]
#define tTimer data[1]
#define tActiveSprites data[IDX_ACTIVE_SPRITES]
#define tNumSquishes data[3]
#define tBaseX data[4]
#define tBaseY data[5]
#define tSubpriority data[6]
// data[7]-data[15] used by PrepareAffineAnimInTaskData
#define tBattlerSpriteId data[15]
// Sprite data for AnimFacadeSweatDrop
#define sTimer data[0]
#define sVelocX data[1]
#define sVelocY data[2]
#define sTaskId data[3]
#define sActiveSpritesIdx data[4]
// Squishes the mon vertically and emits sweat droplets a few times.
// arg 0: battler
// arg 1: num squishes
void AnimTask_SquishAndSweatDroplets(u8 taskId)
{
u8 battler;
struct Task *task = &gTasks[taskId];
if (!gBattleAnimArgs[1])
DestroyAnimVisualTask(taskId);
task->tState = 0;
task->tTimer = 0;
task->tActiveSprites = 0;
task->tNumSquishes = gBattleAnimArgs[1];
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
task->tBaseX = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
task->tBaseY = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y);
task->tSubpriority = GetBattlerSpriteSubpriority(battler);
task->tBattlerSpriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareAffineAnimInTaskData(task, task->tBattlerSpriteId, gFacadeSquishAffineAnimCmds);
task->func = AnimTask_SquishAndSweatDroplets_Step;
}
static void AnimTask_SquishAndSweatDroplets_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
task->tTimer++;
if (task->tTimer == 6)
CreateSweatDroplets(taskId, TRUE);
if (task->tTimer == 18)
CreateSweatDroplets(taskId, FALSE);
if (!RunAffineAnimFromTaskData(task))
{
if (--task->tNumSquishes == 0)
{
// Animation is finished
task->tState++;
}
else
{
// Animation continues, more droplet sprites to create
task->tTimer = 0;
PrepareAffineAnimInTaskData(task, task->tBattlerSpriteId, gFacadeSquishAffineAnimCmds);
}
}
break;
case 1:
// Wait for sprites to be destroyed before ending task
if (task->tActiveSprites == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void CreateSweatDroplets(u8 taskId, bool8 lowerDroplets)
{
u8 i;
s8 xOffset, yOffset;
struct Task *task;
s16 xCoords[4];
s16 yCoords[2];
task = &gTasks[taskId];
if (!lowerDroplets)
{
xOffset = 18;
yOffset = -20;
}
else
{
xOffset = 30;
yOffset = 20;
}
xCoords[0] = task->tBaseX - xOffset;
xCoords[1] = task->tBaseX - xOffset - 4;
xCoords[2] = task->tBaseX + xOffset;
xCoords[3] = task->tBaseX + xOffset + 4;
yCoords[0] = task->tBaseY + yOffset;
yCoords[1] = task->tBaseY + yOffset + 6;
for (i = 0; i < 4; i++)
{
u8 spriteId = CreateSprite(&gFacadeSweatDropSpriteTemplate, xCoords[i], yCoords[i & 1], task->tSubpriority - 5);
if (spriteId != MAX_SPRITES)
{
gSprites[spriteId].sTimer = 0;
gSprites[spriteId].sVelocX = i < 2 ? -2 : 2; // First two travel left, remaining travel right
gSprites[spriteId].sVelocY = -1;
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sActiveSpritesIdx = IDX_ACTIVE_SPRITES;
task->tActiveSprites++;
}
}
}
static void AnimFacadeSweatDrop(struct Sprite *sprite)
{
sprite->x += sprite->sVelocX;
sprite->y += sprite->sVelocY;
if (++sprite->sTimer > 6)
{
gTasks[sprite->sTaskId].data[sprite->sActiveSpritesIdx]--;
DestroySprite(sprite);
}
}
#undef IDX_ACTIVE_SPRITES
#undef tState
#undef tTimer
#undef tActiveSprites
#undef tNumSquishes
#undef tBaseX
#undef tBaseY
#undef tSubpriority
#undef tBattlerSpriteId
#undef sTimer
#undef sVelocX
#undef sVelocY
#undef sTaskId
#undef sActiveSpritesIdx
// Blends the mon sprite's color with a rotating set of colors.
// arg 0: battler
// arg 1: duration
void AnimTask_FacadeColorBlend(u8 taskId)
{
u8 spriteId;
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = gBattleAnimArgs[1];
spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
gTasks[taskId].data[2] = OBJ_PLTT_ID(gSprites[spriteId].oam.paletteNum);
gTasks[taskId].func = AnimTask_FacadeColorBlend_Step;
}
static void AnimTask_FacadeColorBlend_Step(u8 taskId)
{
if (gTasks[taskId].data[1])
{
BlendPalette(gTasks[taskId].data[2], 16, 8, gFacadeBlendColors[gTasks[taskId].data[0]]);
if (++gTasks[taskId].data[0] > 23)
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1]--;
}
else
{
BlendPalette(gTasks[taskId].data[2], 16, 0, RGB(0, 0, 0));
DestroyAnimVisualTask(taskId);
}
}
// The sliding circle effect used by Refresh and Aromatherapy
void AnimTask_StatusClearedEffect(u8 taskId)
{
StartMonScrollingBgMask(
taskId,
0,
0x1A0,
gBattleAnimAttacker,
gBattleAnimArgs[0],
10,
2,
30,
gCureBubblesGfx,
gCureBubblesTilemap,
gCureBubblesPal);
}
// Moves a noise line from the mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: which direction (0 = upward, 1 = downward, 2 = horizontal)
static void AnimRoarNoiseLine(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X) + gBattleAnimArgs[0];
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y) + gBattleAnimArgs[1];
if (gBattleAnimArgs[2] == 0)
{
sprite->data[0] = 0x280;
sprite->data[1] = -0x280;
}
else if (gBattleAnimArgs[2] == 1)
{
sprite->vFlip = 1;
sprite->data[0] = 0x280;
sprite->data[1] = 0x280;
}
else
{
StartSpriteAnim(sprite, 1);
sprite->data[0] = 0x280;
}
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->data[0] = -sprite->data[0];
sprite->hFlip = 1;
}
sprite->callback = AnimRoarNoiseLine_Step;
}
static void AnimRoarNoiseLine_Step(struct Sprite *sprite)
{
sprite->data[6] += sprite->data[0];
sprite->data[7] += sprite->data[1];
sprite->x2 = sprite->data[6] >> 8;
sprite->y2 = sprite->data[7] >> 8;
if (++sprite->data[5] == 14)
DestroyAnimSprite(sprite);
}
#define IDX_ACTIVE_SPRITES 10 // Used by the sprite callback to modify the number of active sprites
// Task data for AnimTask_GlareEyeDots
#define tState data[0]
#define tTimer data[1]
#define tPairNum data[2]
#define tPairMax data[5]
#define tDotOffset data[6]
#define tIsContest data[7]
#define tActiveSprites data[IDX_ACTIVE_SPRITES]
#define tStartX data[11]
#define tStartY data[12]
#define tEndX data[13]
#define tEndY data[14]
// Sprite data for AnimGlareEyeDot
#define sTimer data[0]
#define sTaskId data[1]
#define sActiveSpritesIdx data[2]
// Makes a series of dots in a trail from the attacker to the target.
// arg 0: unused
void AnimTask_GlareEyeDots(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (IsContest())
{
task->tPairMax = 8;
task->tDotOffset = 3;
task->tIsContest = TRUE;
}
else
{
task->tPairMax = 12;
task->tDotOffset = 3;
task->tIsContest = FALSE;
}
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
task->tStartX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) + GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4;
else
task->tStartX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4;
task->tStartY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_HEIGHT) / 4;
task->tEndX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->tEndY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
task->func = AnimTask_GlareEyeDots_Step;
}
static void AnimTask_GlareEyeDots_Step(u8 taskId)
{
u8 i;
s16 x, y;
struct Task *task = &gTasks[taskId];
switch (task->tState)
{
case 0:
// Wait to create next pair of dots
if (++task->tTimer > 3)
{
task->tTimer = 0;
GetGlareEyeDotCoords(
task->tStartX,
task->tStartY,
task->tEndX,
task->tEndY,
task->tPairMax,
task->tPairNum,
&x,
&y);
// Create dot pair
for (i = 0; i < 2; i++)
{
u8 spriteId = CreateSprite(&gGlareEyeDotSpriteTemplate, x, y, 35);
if (spriteId != MAX_SPRITES)
{
if (!task->tIsContest)
{
if (i == 0)
gSprites[spriteId].x2 = gSprites[spriteId].y2 = -task->tDotOffset;
else
gSprites[spriteId].x2 = gSprites[spriteId].y2 = task->tDotOffset;
}
else
{
if (i == 0)
{
gSprites[spriteId].x2 = -task->tDotOffset;
gSprites[spriteId].y2 = task->tDotOffset;
}
else
{
gSprites[spriteId].x2 = task->tDotOffset;
gSprites[spriteId].y2 = -task->tDotOffset;
}
}
gSprites[spriteId].sTimer = 0;
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sActiveSpritesIdx = IDX_ACTIVE_SPRITES;
task->tActiveSprites++;
}
}
if (task->tPairNum == task->tPairMax)
task->tState++;
task->tPairNum++;
}
break;
case 1:
// Wait for sprites to be destroyed before ending task
if (task->tActiveSprites == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void GetGlareEyeDotCoords(s16 startX, s16 startY, s16 endX, s16 endY, u8 pairMax, u8 pairNum, s16 *x, s16 *y)
{
int x2;
int y2;
if (pairNum == 0)
{
*x = startX;
*y = startY;
return;
}
if (pairNum >= pairMax)
{
*x = endX;
*y = endY;
return;
}
pairMax--;
x2 = (startX << 8) + pairNum * (((endX - startX) << 8) / pairMax);
y2 = (startY << 8) + pairNum * (((endY - startY) << 8) / pairMax);
*x = x2 >> 8;
*y = y2 >> 8;
}
static void AnimGlareEyeDot(struct Sprite *sprite)
{
if (++sprite->sTimer > 36)
{
gTasks[sprite->sTaskId].data[sprite->sActiveSpritesIdx]--;
DestroySprite(sprite);
}
}
#undef IDX_ACTIVE_SPRITES
#undef tState
#undef tTimer
#undef tPairNum
#undef tPairMax
#undef tDotOffset
#undef tIsContest
#undef tActiveSprites
#undef tStartX
#undef tStartY
#undef tEndX
#undef tEndY
#undef sTimer
#undef sTaskId
#undef sActiveSpritesIdx
// Moves a pawprint in a straight line.
// arg 0: initial x position
// arg 1: initial y position
// arg 2: destination x position
// arg 3: destination y position
// arg 4: duration
static void AnimAssistPawprint(struct Sprite *sprite)
{
sprite->x = gBattleAnimArgs[0];
sprite->y = gBattleAnimArgs[1];
sprite->data[2] = gBattleAnimArgs[2];
sprite->data[4] = gBattleAnimArgs[3];
sprite->data[0] = gBattleAnimArgs[4];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = InitAndRunAnimFastLinearTranslation;
}
// Moves a ball in an arc twoards the target, and rotates the ball while arcing.
// No args.
void AnimTask_BarrageBall(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) / 4;
task->data[15] = CreateSprite(&gBarrageBallSpriteTemplate, task->data[11], task->data[12], GetBattlerSpriteSubpriority(gBattleAnimTarget) - 5);
if (task->data[15] != MAX_SPRITES)
{
gSprites[task->data[15]].data[0] = 16;
gSprites[task->data[15]].data[2] = task->data[13];
gSprites[task->data[15]].data[4] = task->data[14];
gSprites[task->data[15]].data[5] = -32;
InitAnimArcTranslation(&gSprites[task->data[15]]);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
StartSpriteAffineAnim(&gSprites[task->data[15]], 1);
task->func = AnimTask_BarrageBall_Step;
}
else
{
DestroyAnimVisualTask(taskId);
}
}
static void AnimTask_BarrageBall_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] > 1)
{
task->data[1] = 0;
TranslateAnimHorizontalArc(&gSprites[task->data[15]]);
if (++task->data[2] > 7)
task->data[0]++;
}
break;
case 1:
if (TranslateAnimHorizontalArc(&gSprites[task->data[15]]))
{
task->data[1] = 0;
task->data[2] = 0;
task->data[0]++;
}
break;
case 2:
if (++task->data[1] > 1)
{
task->data[1] = 0;
task->data[2]++;
gSprites[task->data[15]].invisible = task->data[2] & 1;
if (task->data[2] == 16)
{
FreeOamMatrix(gSprites[task->data[15]].oam.matrixNum);
DestroySprite(&gSprites[task->data[15]]);
task->data[0]++;
}
}
break;
case 3:
DestroyAnimVisualTask(taskId);
break;
}
}
// Moves a hand back and forth in a squishing motion.
// arg 0: which battler
// arg 1: horizontal flip
// arg 2: num squishes
static void AnimSmellingSaltsHand(struct Sprite *sprite)
{
u8 battler;
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
battler = gBattleAnimAttacker;
else
battler = gBattleAnimTarget;
sprite->oam.tileNum += 16;
sprite->data[6] = gBattleAnimArgs[2];
sprite->data[7] = gBattleAnimArgs[1] == 0 ? -1 : 1;
sprite->y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET);
if (gBattleAnimArgs[1] == 0)
{
sprite->oam.matrixNum |= ST_OAM_HFLIP;
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_LEFT) - 8;
}
else
{
sprite->x = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_RIGHT) + 8;
}
sprite->callback = AnimSmellingSaltsHand_Step;
}
static void AnimSmellingSaltsHand_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
sprite->x2 += sprite->data[7];
if (++sprite->data[2] == 12)
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[1] == 8)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 2:
sprite->x2 -= sprite->data[7] * 4;
if (++sprite->data[1] == 6)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 3:
sprite->x2 += sprite->data[7] * 3;
if (++sprite->data[1] == 8)
{
if (--sprite->data[6])
{
sprite->data[1] = 0;
sprite->data[0]--;
}
else
{
DestroyAnimSprite(sprite);
}
}
break;
}
}
// Squishes the mon horizontally a few times.
// arg 0: which mon
// arg 1: number of squishes
void AnimTask_SmellingSaltsSquish(u8 taskId)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
DestroyAnimVisualTask(taskId);
}
else
{
gTasks[taskId].data[0] = gBattleAnimArgs[1];
gTasks[taskId].data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], gSmellingSaltsSquishAffineAnimCmds);
gTasks[taskId].func = AnimTask_SmellingSaltsSquish_Step;
}
}
static void AnimTask_SmellingSaltsSquish_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (++task->data[1] > 1)
{
task->data[1] = 0;
if (!(task->data[2] & 1))
gSprites[task->data[15]].x2 = 2;
else
gSprites[task->data[15]].x2 = -2;
}
if (!RunAffineAnimFromTaskData(task))
{
gSprites[task->data[15]].x2 = 0;
if (--task->data[0])
{
PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], gSmellingSaltsSquishAffineAnimCmds);
task->data[1] = 0;
task->data[2] = 0;
}
else
{
DestroyAnimVisualTask(taskId);
}
}
}
// Blinks an exclamation image over the mon a few times.
// arg 0: which mon
// arg 1: blink delay
// arg 2: number of blinks
static void AnimSmellingSaltExclamation(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP);
}
else
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_TOP);
}
if (sprite->y < 8)
sprite->y = 8;
sprite->data[0] = 0;
sprite->data[1] = gBattleAnimArgs[1];
sprite->data[2] = 0;
sprite->data[3] = gBattleAnimArgs[2];
sprite->callback = AnimSmellingSaltExclamation_Step;
}
static void AnimSmellingSaltExclamation_Step(struct Sprite *sprite)
{
if (++sprite->data[0] >= sprite->data[1])
{
sprite->data[0] = 0;
sprite->data[2] = (sprite->data[2] + 1) & 1;
sprite->invisible = sprite->data[2];
if (sprite->data[2] && --sprite->data[3] == 0)
DestroyAnimSprite(sprite);
}
}
// Claps a hand several times.
// arg 0: which hand
// arg 1:
static void AnimHelpingHandClap(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
sprite->oam.matrixNum |= ST_OAM_HFLIP;
sprite->x = 100;
sprite->data[7] = 1;
}
else
{
sprite->x = 140;
sprite->data[7] = -1;
}
sprite->y = 56;
sprite->callback = AnimHelpingHandClap_Step;
}
static void AnimHelpingHandClap_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->y -= sprite->data[7] * 2;
if (sprite->data[1] & 1)
sprite->x -= sprite->data[7] * 2;
if (++sprite->data[1] == 9)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[1] == 4)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 2:
sprite->data[1]++;
sprite->y += sprite->data[7] * 3;
sprite->x2 = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3);
if (sprite->data[1] == 12)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 3:
if (++sprite->data[1] == 2)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 4:
sprite->data[1]++;
sprite->y -= sprite->data[7] * 3;
sprite->x2 = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3);
if (sprite->data[1] == 12)
sprite->data[0]++;
break;
case 5:
sprite->data[1]++;
sprite->y += sprite->data[7] * 3;
sprite->x2 = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3);
if (sprite->data[1] == 15)
sprite->oam.tileNum += 16;
if (sprite->data[1] == 18)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 6:
sprite->x += sprite->data[7] * 6;
if (++sprite->data[1] == 9)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 7:
sprite->x += sprite->data[7] * 2;
if (++sprite->data[1] == 1)
{
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 8:
sprite->x -= sprite->data[7] * 3;
if (++sprite->data[1] == 5)
DestroyAnimSprite(sprite);
break;
}
}
// Repeatedly moves the attacking mon in a horizontal lunging motion.
// No args.
void AnimTask_HelpingHandAttackerMovement(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
if (!IsContest())
{
if (IsDoubleBattle() == TRUE)
{
int attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
int partnerX = GetBattlerSpriteCoord(BATTLE_PARTNER(gBattleAnimAttacker), BATTLER_COORD_X);
if (attackerX > partnerX)
task->data[14] = 1;
else
task->data[14] = -1;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
task->data[14] = -1;
else
task->data[14] = 1;
}
}
else
{
task->data[14] = 1;
}
task->func = AnimTask_HelpingHandAttackerMovement_Step;
}
static void AnimTask_HelpingHandAttackerMovement_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
if (++task->data[1] == 13)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 1:
gSprites[task->data[15]].x2 -= task->data[14] * 3;
if (++task->data[1] == 6)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 2:
gSprites[task->data[15]].x2 += task->data[14] * 3;
if (++task->data[1] == 6)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 3:
if (++task->data[1] == 2)
{
task->data[1] = 0;
if (task->data[2] == 0)
{
task->data[2]++;
task->data[0] = 1;
}
else
{
task->data[0]++;
}
}
break;
case 4:
gSprites[task->data[15]].x2 += task->data[14];
if (++task->data[1] == 3)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 5:
if (++task->data[1] == 6)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 6:
gSprites[task->data[15]].x2 -= task->data[14] * 4;
if (++task->data[1] == 5)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 7:
gSprites[task->data[15]].x2 += task->data[14] * 4;
if (++task->data[1] == 5)
{
task->data[1] = 0;
task->data[0]++;
}
break;
case 8:
gSprites[task->data[15]].x2 = 0;
DestroyAnimVisualTask(taskId);
break;
}
}
// Moves a magnifying glass around in straight lines.
// arg 0: magnifying glass target mon
static void AnimForesightMagnifyingGlass(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
{
InitSpritePosToAnimAttacker(sprite, TRUE);
sprite->data[7] = gBattleAnimAttacker;
}
else
{
sprite->data[7] = gBattleAnimTarget;
}
if (GetBattlerSide(sprite->data[7]) == B_SIDE_OPPONENT)
sprite->oam.matrixNum = ST_OAM_HFLIP;
sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]);
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
sprite->callback = AnimForesightMagnifyingGlass_Step;
}
static void AnimForesightMagnifyingGlass_Step(struct Sprite *sprite)
{
u16 x, y;
switch (sprite->data[5])
{
case 0:
switch (sprite->data[6])
{
default:
sprite->data[6] = 0;
case 0:
case 4:
x = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_RIGHT) - 4;
y = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_BOTTOM) - 4;
break;
case 1:
x = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_RIGHT) - 4;
y = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_TOP) + 4;
break;
case 2:
x = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_LEFT) + 4;
y = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_BOTTOM) - 4;
break;
case 3:
x = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_LEFT) + 4;
y = GetBattlerSpriteCoordAttr(sprite->data[7], BATTLER_COORD_ATTR_TOP) - 4;
break;
case 5:
x = GetBattlerSpriteCoord(sprite->data[7], BATTLER_COORD_X_2);
y = GetBattlerSpriteCoord(sprite->data[7], BATTLER_COORD_Y_PIC_OFFSET);
break;
}
if (sprite->data[6] == 4)
sprite->data[0] = 24;
else if (sprite->data[6] == 5)
sprite->data[0] = 6;
else
sprite->data[0] = 12;
sprite->data[1] = sprite->x;
sprite->data[2] = x;
sprite->data[3] = sprite->y;
sprite->data[4] = y;
InitAnimLinearTranslation(sprite);
sprite->data[5]++;
break;
case 1:
if (AnimTranslateLinear(sprite))
{
switch (sprite->data[6])
{
default:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[0] = 0;
sprite->data[5]++;
sprite->data[6]++;
break;
case 4:
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->data[5] = 0;
sprite->data[6]++;
break;
case 5:
sprite->data[0] = 0;
sprite->data[1] = 16;
sprite->data[2] = 0;
sprite->data[5] = 3;
break;
}
}
break;
case 2:
if (++sprite->data[0] == 4)
sprite->data[5] = 0;
break;
case 3:
if (!(sprite->data[0] & 1))
sprite->data[1]--;
else
sprite->data[2]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[1], sprite->data[2]));
if (++sprite->data[0] == 32)
{
sprite->invisible = TRUE;
sprite->data[5]++;
}
break;
case 4:
DestroyAnimSprite(sprite);
break;
}
}
static void AnimMeteorMashStar_Step(struct Sprite *sprite)
{
sprite->x2 = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4];
sprite->y2 = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4];
if (!(sprite->data[5] & 1))
{
CreateSprite(
&gMiniTwinklingStarSpriteTemplate,
sprite->x + sprite->x2,
sprite->y + sprite->y2, 5);
}
if (sprite->data[5] == sprite->data[4])
DestroyAnimSprite(sprite);
sprite->data[5]++;
}
// Moves a shooting star across the screen that leaves little twinkling stars behind its path.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
// arg 2: destination x pixel offset
// arg 3: destination y pixel offset
// arg 4: duration
static void AnimMeteorMashStar(struct Sprite *sprite)
{
s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2); // unused local variable
s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET); // unused local variable
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER || IsContest())
{
sprite->data[0] = sprite->x - gBattleAnimArgs[0];
sprite->data[2] = sprite->x - gBattleAnimArgs[2];
}
else
{
sprite->data[0] = sprite->x + gBattleAnimArgs[0];
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
}
sprite->data[1] = sprite->y + gBattleAnimArgs[1];
sprite->data[3] = sprite->y + gBattleAnimArgs[3];
sprite->data[4] = gBattleAnimArgs[4];
sprite->x = sprite->data[0];
sprite->y = sprite->data[1];
sprite->callback = AnimMeteorMashStar_Step;
}
void AnimTask_MonToSubstitute(u8 taskId)
{
int i;
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
if (gTasks[taskId].data[0] == 0)
{
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_NORMAL);
gTasks[taskId].data[1] = 0x100;
gTasks[taskId].data[2] = 0x100;
gTasks[taskId].data[0]++;
}
else if (gTasks[taskId].data[0] == 1)
{
gTasks[taskId].data[1] += 0x60;
gTasks[taskId].data[2] -= 0xD;
SetSpriteRotScale(spriteId, gTasks[taskId].data[1], gTasks[taskId].data[2], 0);
if (++gTasks[taskId].data[3] == 9)
{
gTasks[taskId].data[3] = 0;
ResetSpriteRotScale(spriteId);
gSprites[spriteId].invisible = TRUE;
gTasks[taskId].data[0]++;
}
}
else
{
LoadBattleMonGfxAndAnimate(gBattleAnimAttacker, FALSE, spriteId);
if (IsContest())
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].affineAnims = gAffineAnims_BattleSpriteContest;
StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], BATTLER_AFFINE_NORMAL);
}
for (i = 0; i < NUM_TASK_DATA; i++)
gTasks[taskId].data[i] = 0;
gTasks[taskId].func = AnimTask_MonToSubstituteDoll;
}
}
static void AnimTask_MonToSubstituteDoll(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
switch (gTasks[taskId].data[0])
{
case 0:
gSprites[spriteId].y2 = -200;
gSprites[spriteId].x2 = 200;
gSprites[spriteId].invisible = FALSE;
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[0]++;
break;
case 1:
gTasks[taskId].data[10] += 112;
gSprites[spriteId].y2 += gTasks[taskId].data[10] >> 8;
if (gSprites[spriteId].y + gSprites[spriteId].y2 >= -32)
gSprites[spriteId].x2 = 0;
if (gSprites[spriteId].y2 > 0)
gSprites[spriteId].y2 = 0;
if (gSprites[spriteId].y2 == 0)
{
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
gTasks[taskId].data[10] -= 0x800;
gTasks[taskId].data[0]++;
}
break;
case 2:
gTasks[taskId].data[10] -= 112;
if (gTasks[taskId].data[10] < 0)
gTasks[taskId].data[10] = 0;
gSprites[spriteId].y2 -= gTasks[taskId].data[10] >> 8;
if (gTasks[taskId].data[10] == 0)
gTasks[taskId].data[0]++;
break;
case 3:
gTasks[taskId].data[10] += 112;
gSprites[spriteId].y2 += gTasks[taskId].data[10] >> 8;
if (gSprites[spriteId].y2 > 0)
gSprites[spriteId].y2 = 0;
if (gSprites[spriteId].y2 == 0)
{
PlaySE12WithPanning(SE_M_BUBBLE2, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER));
DestroyAnimVisualTask(taskId);
}
break;
}
}
// Moves down an X that flickers and disappears.
// No args.
static void AnimBlockX(struct Sprite *sprite)
{
s16 y;
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 2;
y = -144;
}
else
{
sprite->subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + 2;
y = -96;
}
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
sprite->y2 = y;
sprite->callback = AnimBlockX_Step;
}
static void AnimBlockX_Step(struct Sprite *sprite)
{
switch (sprite->data[0])
{
case 0:
sprite->y2 += 10;
if (sprite->y2 >= 0)
{
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->y2 = 0;
sprite->data[0]++;
}
break;
case 1:
sprite->data[1] += 4;
sprite->y2 = -(gSineTable[sprite->data[1]] >> 3);
if (sprite->data[1] > 0x7F)
{
PlaySE12WithPanning(SE_M_SKETCH, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->data[1] = 0;
sprite->y2 = 0;
sprite->data[0]++;
}
break;
case 2:
sprite->data[1] += 6;
sprite->y2 = -(gSineTable[sprite->data[1]] >> 4);
if (sprite->data[1] > 0x7F)
{
sprite->data[1] = 0;
sprite->y2 = 0;
sprite->data[0]++;
}
break;
case 3:
if (++sprite->data[1] > 8)
{
PlaySE12WithPanning(SE_M_LEER, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->data[1] = 0;
sprite->data[0]++;
}
break;
case 4:
if (++sprite->data[1] > 8)
{
sprite->data[1] = 0;
sprite->data[2]++;
sprite->invisible = sprite->data[2] & 1;
if (sprite->data[2] == 7)
DestroyAnimSprite(sprite);
}
break;
}
}
// Quickly moves two clones of the target mon back and forth.
// No args.
void AnimTask_OdorSleuthMovement(u8 taskId)
{
s16 spriteId1, spriteId2;
if (IsContest())
{
DestroyAnimVisualTask(taskId);
return;
}
spriteId1 = CloneBattlerSpriteWithBlend(ANIM_TARGET);
if (spriteId1 < 0)
{
DestroyAnimVisualTask(taskId);
return;
}
spriteId2 = CloneBattlerSpriteWithBlend(ANIM_TARGET);
if (spriteId2 < 0)
{
DestroySpriteWithActiveSheet(&gSprites[spriteId1]);
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId2].x2 += 24;
gSprites[spriteId1].x2 -= 24;
gSprites[spriteId2].data[0] = 0;
gSprites[spriteId1].data[0] = 0;
gSprites[spriteId2].data[1] = 0;
gSprites[spriteId1].data[1] = 0;
gSprites[spriteId2].data[2] = 0;
gSprites[spriteId1].data[2] = 0;
gSprites[spriteId2].data[3] = 16;
gSprites[spriteId1].data[3] = -16;
gSprites[spriteId2].data[4] = 0;
gSprites[spriteId1].data[4] = 128;
gSprites[spriteId2].data[5] = 24;
gSprites[spriteId1].data[5] = 24;
gSprites[spriteId2].data[6] = taskId;
gSprites[spriteId1].data[6] = taskId;
gSprites[spriteId2].data[7] = 0;
gSprites[spriteId1].data[7] = 0;
gTasks[taskId].data[0] = 2;
if (!gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible)
{
gSprites[spriteId2].invisible = FALSE;
gSprites[spriteId1].invisible = TRUE;
}
else
{
gSprites[spriteId2].invisible = TRUE;
gSprites[spriteId1].invisible = TRUE;
}
gSprites[spriteId2].oam.objMode = ST_OAM_OBJ_NORMAL;
gSprites[spriteId1].oam.objMode = ST_OAM_OBJ_NORMAL;
gSprites[spriteId2].callback = MoveOdorSleuthClone;
gSprites[spriteId1].callback = MoveOdorSleuthClone;
gTasks[taskId].func = AnimTask_OdorSleuthMovementWaitFinish;
}
static void AnimTask_OdorSleuthMovementWaitFinish(u8 taskId)
{
if (gTasks[taskId].data[0] == 0)
DestroyAnimVisualTask(taskId);
}
static void MoveOdorSleuthClone(struct Sprite *sprite)
{
if (++sprite->data[1] > 1)
{
sprite->data[1] = 0;
if (!gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].invisible)
sprite->invisible ^= 1;
}
sprite->data[4] = sprite->data[4] + sprite->data[3];
sprite->data[4] &= 0xFF;
sprite->x2 = Cos(sprite->data[4], sprite->data[5]);
switch (sprite->data[0])
{
case 0:
if (++sprite->data[2] == 60)
{
sprite->data[2] = 0;
sprite->data[0]++;
}
break;
case 1:
if (++sprite->data[2] > 0)
{
sprite->data[2] = 0;
sprite->data[5] -= 2;
if (sprite->data[5] < 0)
{
gTasks[sprite->data[6]].data[sprite->data[7]]--;
DestroySpriteWithActiveSheet(sprite);
}
}
break;
}
}
void AnimTask_GetReturnPowerLevel(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = 0;
if (gAnimFriendship < 60)
gBattleAnimArgs[ARG_RET_ID] = 0;
if (gAnimFriendship > 60 && gAnimFriendship < 92)
gBattleAnimArgs[ARG_RET_ID] = 1;
if (gAnimFriendship > 91 && gAnimFriendship < 201)
gBattleAnimArgs[ARG_RET_ID] = 2;
if (gAnimFriendship > 200)
gBattleAnimArgs[ARG_RET_ID] = 3;
DestroyAnimVisualTask(taskId);
}
// Makes the mon run out of screen, run past the opposing mon, and return to its original position.
// No args.
void AnimTask_SnatchOpposingMonMove(u8 taskId)
{
u8 spriteId, spriteId2;
int personality;
int otId;
u16 species;
u8 subpriority;
bool8 isBackPic;
s16 x;
switch (gTasks[taskId].data[0])
{
case 0:
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gTasks[taskId].data[1] += 0x800;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
gSprites[spriteId].x2 += (gTasks[taskId].data[1] >> 8);
else
gSprites[spriteId].x2 -= (gTasks[taskId].data[1] >> 8);
gTasks[taskId].data[1] &= 0xFF;
x = gSprites[spriteId].x + gSprites[spriteId].x2;
if (x < -32 || x > DISPLAY_WIDTH + 32)
{
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[0]++;
}
break;
case 1:
if (IsContest())
{
personality = gContestResources->moveAnim->personality;
otId = gContestResources->moveAnim->otId;
species = gContestResources->moveAnim->species;
subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker);
isBackPic = FALSE;
x = -32;
}
else
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY);
otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies;
subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1;
isBackPic = FALSE;
x = DISPLAY_WIDTH + 32;
}
else
{
personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY);
otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies;
subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority - 1;
isBackPic = TRUE;
x = -32;
}
}
spriteId2 = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId, gBattleAnimAttacker, FALSE);
if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies != SPECIES_NONE)
BlendPalette(OBJ_PLTT_ID(gSprites[spriteId2].oam.paletteNum), 16, 6, RGB_WHITE);
gTasks[taskId].data[15] = spriteId2;
gTasks[taskId].data[0]++;
break;
case 2:
spriteId2 = gTasks[taskId].data[15];
gTasks[taskId].data[1] += 0x800;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
gSprites[spriteId2].x2 -= (gTasks[taskId].data[1] >> 8);
else
gSprites[spriteId2].x2 += (gTasks[taskId].data[1] >> 8);
gTasks[taskId].data[1] &= 0xFF;
x = gSprites[spriteId2].x + gSprites[spriteId2].x2;
if (gTasks[taskId].data[14] == 0)
{
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
if (x < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X))
{
gTasks[taskId].data[14]++;
gBattleAnimArgs[7] = 0xFFFF;
}
}
else
{
if (x > GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X))
{
gTasks[taskId].data[14]++;
gBattleAnimArgs[7] = 0xFFFF;
}
}
}
if (x < -32 || x > DISPLAY_WIDTH + 32)
{
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[0]++;
}
break;
case 3:
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
spriteId2 = gTasks[taskId].data[15];
DestroySpriteAndFreeResources_(&gSprites[spriteId2]);
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
gSprites[spriteId].x2 = -gSprites[spriteId].x - 32;
else
gSprites[spriteId].x2 = DISPLAY_WIDTH + 32 - gSprites[spriteId].x;
gTasks[taskId].data[0]++;
break;
case 4:
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gTasks[taskId].data[1] += 0x800;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
{
gSprites[spriteId].x2 += (gTasks[taskId].data[1] >> 8);
if (gSprites[spriteId].x2 + gSprites[spriteId].x >= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X))
gSprites[spriteId].x2 = 0;
}
else
{
gSprites[spriteId].x2 -= (gTasks[taskId].data[1] >> 8);
if (gSprites[spriteId].x2 + gSprites[spriteId].x <= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X))
gSprites[spriteId].x2 = 0;
}
gTasks[taskId].data[1] &= 0xFF;
if (gSprites[spriteId].x2 == 0)
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimUnusedItemBagSteal(struct Sprite *sprite)
{
switch (sprite->data[7])
{
case 0:
if (gBattleAnimArgs[7] == -1)
{
PlaySE12WithPanning(SE_M_VITAL_THROW, BattleAnimAdjustPanning(SOUND_PAN_TARGET));
sprite->y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 16;
sprite->data[0] = -32;
sprite->data[7]++;
sprite->invisible = FALSE;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT && !IsContest())
sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority - 1;
}
else
{
sprite->invisible = TRUE;
}
break;
case 1:
sprite->y2 = Sin(sprite->data[1], sprite->data[0]);
sprite->data[1] += 5;
if (sprite->data[1] > 0x7F)
{
sprite->data[0] = sprite->data[0] / 2;
sprite->data[3]++;
sprite->data[1] -= 0x7F;
}
sprite->data[2] += 0x100;
if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->x2 -= (sprite->data[2] >> 8);
else
sprite->x2 += (sprite->data[2] >> 8);
sprite->data[2] &= 0xFF;
if (sprite->data[3] == 2)
DestroyAnimSprite(sprite);
break;
}
}
// Quickly moves the mon towards its partner and back.
// No args.
void AnimTask_SnatchPartnerMove(u8 taskId)
{
s16 attackerX, targetX;
u8 spriteId;
switch (gTasks[taskId].data[15])
{
case 0:
attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X);
targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
gTasks[taskId].data[0] = 6;
if (attackerX > targetX)
gTasks[taskId].data[0] *= -1;
gTasks[taskId].data[1] = attackerX;
gTasks[taskId].data[2] = targetX;
gTasks[taskId].data[15]++;
break;
case 1:
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
gSprites[spriteId].x2 += gTasks[taskId].data[0];
if (gTasks[taskId].data[0] > 0)
{
if (gSprites[spriteId].x + gSprites[spriteId].x2 >= gTasks[taskId].data[2])
gTasks[taskId].data[15]++;
}
else
{
if (gSprites[spriteId].x + gSprites[spriteId].x2 <= gTasks[taskId].data[2])
gTasks[taskId].data[15]++;
}
break;
case 2:
gTasks[taskId].data[0] *= -1;
gTasks[taskId].data[15]++;
break;
case 3:
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
gSprites[spriteId].x2 += gTasks[taskId].data[0];
if (gTasks[taskId].data[0] < 0)
{
if (gSprites[spriteId].x + gSprites[spriteId].x2 <= gTasks[taskId].data[1])
gTasks[taskId].data[15]++;
}
else
{
if (gSprites[spriteId].x + gSprites[spriteId].x2 >= gTasks[taskId].data[1])
gTasks[taskId].data[15]++;
}
break;
case 4:
default:
spriteId = gBattlerSpriteIds[gBattleAnimAttacker];
gSprites[spriteId].x2 = 0;
DestroyAnimVisualTask(taskId);
break;
}
}
// Moves the mon's sprite back and forth in an unpredictable swaying motion.
// No args.
void AnimTask_TeeterDanceMovement(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[3] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[4] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
task->data[6] = gSprites[task->data[3]].y;
task->data[5] = gSprites[task->data[3]].x;
task->data[9] = 0;
task->data[11] = 0;
task->data[10] = 1;
task->data[12] = 0;
task->func = AnimTask_TeeterDanceMovement_Step;
}
static void AnimTask_TeeterDanceMovement_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
switch (task->data[0])
{
case 0:
task->data[11] += 8;
task->data[11] &= 0xFF;
gSprites[task->data[3]].x2 = gSineTable[task->data[11]] >> 5;
task->data[9] += 2;
task->data[9] &= 0xFF;
gSprites[task->data[3]].x = (gSineTable[task->data[9]] >> 3) * task->data[4] + task->data[5];
if (task->data[9] == 0)
{
gSprites[task->data[3]].x = task->data[5];
task->data[0]++;
}
break;
case 1:
task->data[11] += 8;
task->data[11] &= 0xFF;
gSprites[task->data[3]].x2 = gSineTable[task->data[11]] >> 5;
if (task->data[11] == 0)
{
gSprites[task->data[3]].x2 = 0;
task->data[0]++;
}
break;
case 2:
DestroyAnimVisualTask(taskId);
break;
}
}
static void AnimKnockOffStrike_Step(struct Sprite *sprite)
{
// These two cases are identical.
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
sprite->data[1] += sprite->data[0];
sprite->data[1] &= 0xFF;
}
else
{
sprite->data[1] += sprite->data[0];
sprite->data[1] &= 0xFF;
}
sprite->x2 = Cos(sprite->data[1], 20);
sprite->y2 = Sin(sprite->data[1], 20);
if (sprite->animEnded)
DestroyAnimSprite(sprite);
sprite->data[2]++;
}
// Animates a strike that swipes downard at the target mon.
// arg 0: initial x pixel offset
// arg 1: initial y pixel offset
static void AnimKnockOffStrike(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
sprite->x -= gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
sprite->data[0] = -11;
sprite->data[1] = 192;
StartSpriteAffineAnim(sprite, 1);
}
else
{
sprite->data[0] = 11;
sprite->data[1] = 192;
sprite->x += gBattleAnimArgs[0];
sprite->y += gBattleAnimArgs[1];
}
sprite->callback = AnimKnockOffStrike_Step;
}
// Gradually fades a rotating recyle arrow sprite in and back out.
// No args.
static void AnimRecycle(struct Sprite *sprite)
{
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP);
if (sprite->y < 16)
sprite->y = 16;
sprite->data[6] = 0;
sprite->data[7] = 16;
sprite->callback = AnimRecycle_Step;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
}
static void AnimRecycle_Step(struct Sprite *sprite)
{
switch (sprite->data[2])
{
case 0:
if (++sprite->data[0] > 1)
{
sprite->data[0] = 0;
if (!(sprite->data[1] & 1))
{
if (sprite->data[6] < 16)
sprite->data[6]++;
}
else
{
if (sprite->data[7] != 0)
sprite->data[7]--;
}
sprite->data[1]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
if (sprite->data[7] == 0)
sprite->data[2]++;
}
break;
case 1:
if (++sprite->data[0] == 10)
{
sprite->data[0] = 0;
sprite->data[1] = 0;
sprite->data[2]++;
}
break;
case 2:
if (++sprite->data[0] > 1)
{
sprite->data[0] = 0;
if (!(sprite->data[1] & 1))
{
if (sprite->data[6] != 0)
sprite->data[6]--;
}
else
{
if (sprite->data[7] < 16)
sprite->data[7]++;
}
sprite->data[1]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
if (sprite->data[7] == 16)
sprite->data[2]++;
}
break;
case 3:
DestroySpriteAndMatrix(sprite);
break;
}
}
void AnimTask_GetWeather(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_NONE;
if (gWeatherMoveAnim & B_WEATHER_SUN)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SUN;
else if (gWeatherMoveAnim & B_WEATHER_RAIN)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_RAIN;
else if (gWeatherMoveAnim & B_WEATHER_SANDSTORM)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM;
else if (gWeatherMoveAnim & B_WEATHER_HAIL)
gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL;
DestroyAnimVisualTask(taskId);
}
// Squishes the mon sprite vertically, and shakes it back and forth.
// arg 0: which battler
void AnimTask_SlackOffSquish(u8 taskId)
{
struct Task *task = &gTasks[taskId];
task->data[0] = 0;
task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
PrepareAffineAnimInTaskData(task, task->data[15], gSlackOffSquishAffineAnimCmds);
task->func = AnimTask_SlackOffSquish_Step;
}
static void AnimTask_SlackOffSquish_Step(u8 taskId)
{
struct Task *task = &gTasks[taskId];
gTasks[taskId].data[0]++;
if (gTasks[taskId].data[0] > 16 && gTasks[taskId].data[0] < 40)
{
if (++task->data[1] > 2)
{
task->data[1] = 0;
task->data[2]++;
if (!(task->data[2] & 1))
gSprites[task->data[15]].x2 = -1;
else
gSprites[task->data[15]].x2 = 1;
}
}
else
{
gSprites[task->data[15]].x2 = 0;
}
if (!RunAffineAnimFromTaskData(&gTasks[taskId]))
DestroyAnimVisualTask(taskId);
}`.replace(/\n\/\/.*?(?=\n)/g, '\n').replace(/\n\n\n/g, '\n\n');