papermario/src/190B20.c

3118 lines
103 KiB
C

#include "common.h"
#include "nu/nusys.h"
#include "effects.h"
#include "battle/battle.h"
#include "script_api/battle.h"
#include "model.h"
#include "sprite.h"
EvtScript D_80293820 = {
EVT_WAIT(LVar0)
EVT_LOOP(4)
EVT_CALL(SetBattleCamParam, 4, 11)
EVT_WAIT(1)
EVT_CALL(SetBattleCamParam, 4, 5)
EVT_WAIT(1)
EVT_END_LOOP
EVT_CALL(SetBattleCamParam, 4, 8)
EVT_RETURN
EVT_END
};
f32 D_802938A4 = 0.0f;
s16 D_802938A8 = 4;
EffectInstance* gDamageCountEffects[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
};
s32 gDamageCountTimers[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
Gfx D_80293970[] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsDPSetCycleType(G_CYC_1CYCLE),
gsDPSetTexturePersp(G_TP_NONE),
gsDPSetTextureDetail(G_TD_CLAMP),
gsDPSetTextureLOD(G_TL_TILE),
gsDPSetTextureFilter(G_TF_POINT),
gsDPSetTextureLUT(G_TT_NONE),
gsDPSetTextureConvert(G_TC_FILT),
gsSPEndDisplayList(),
};
s32 D_802939C0 = 0;
// from 17D6A0
extern s32 bMarioDefenseTable[];
extern s32 bPlayerStatusTable[];
extern ActorBlueprint bPlayerActorBlueprint;
extern ActorPartBlueprint bMarioParts[];
extern PartnerDMAData bPartnerDmaTable[];
s32 func_80265CE8(AnimID*, s32);
// WIP work from Unnunu + a permuter do-while I added
#ifdef NON_MATCHING
// TOOD remove gotos
void create_target_list(Actor* actor, s32 arg1) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* playerActor = battleStatus->playerActor;
Actor* partnerActor = battleStatus->partnerActor;
s32 s5 = 0;
SelectableTarget* targetData = actor->targetData;
SelectableTarget* s0;
SelectableTarget* target;
Actor* targetActor;
ActorPart* targetPart;
s8* targetIndexList;
s32 numParts;
s32 i, j;
f32 f6, f8, f10;
f32 f2, f12, f14;
u8 sp10;
f32 sp14;
s32 sp18 = FALSE;
s32 sp1C;
s32 fp;
s32 a02;
ActorPartBlueprint* partBlueprint;
s32 index1;
s32 index2;
s32 a22;
if (battleStatus->currentTargetListFlags & 0x80000000) {
actor->targetListLength = -1;
return;
}
if (battleStatus->currentTargetListFlags & 0x8) {
targetData->actorID = ACTOR_PLAYER;
targetData->partID = 1;
if (!arg1) {
targetData->pos.x = playerActor->currentPos.x + playerActor->size.x * 0.3 * playerActor->scalingFactor;
targetData->pos.y = playerActor->currentPos.y + playerActor->size.y * 0.9 * playerActor->scalingFactor;
targetData->pos.z = playerActor->currentPos.z;
} else {
targetData->pos.x = playerActor->homePos.x + playerActor->size.x * 0.3 * playerActor->scalingFactor;
targetData->pos.y = playerActor->homePos.y + playerActor->size.y * 0.9 * playerActor->scalingFactor;
targetData->pos.z = playerActor->homePos.z;
}
targetData->unk_10 = -100;
s5++;
targetData++;
}
if ((battleStatus->currentTargetListFlags & 0x100) && partnerActor != NULL) {
targetData->actorID = ACTOR_PARTNER;
targetData->partID = 1;
if (!arg1) {
targetData->pos.x = partnerActor->currentPos.x + partnerActor->size.x * 0.1 * partnerActor->scalingFactor;
targetData->pos.y = partnerActor->currentPos.y + partnerActor->size.y * 0.8 * partnerActor->scalingFactor;
targetData->pos.z = partnerActor->currentPos.z;
} else {
targetData->pos.x = partnerActor->homePos.x + partnerActor->size.x * 0.1 * partnerActor->scalingFactor;
targetData->pos.y = partnerActor->homePos.y + partnerActor->size.y * 0.8 * partnerActor->scalingFactor;
targetData->pos.z = partnerActor->homePos.z;
}
targetData->unk_10 = -50;
s5++;
targetData++;
}
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
targetActor = battleStatus->enemyActors[i];
if (targetActor == NULL) {
continue;
}
if ((battleStatus->currentTargetListFlags & 0x100) || (battleStatus->currentTargetListFlags & 0x8)) {
break;
}
targetPart = targetActor->partsTable;
numParts = targetActor->numParts;
for (j = 0; j < numParts; targetPart = targetPart->nextPart, j++) {
if (!(targetPart->flags & 0x20000)) {
partBlueprint = targetPart->staticData;
if (!(targetPart->flags & 0x100000)) {
fp = !arg1; // TODO ??????
if (fp) {
f6 = targetActor->currentPos.x;
f8 = targetActor->currentPos.y;
f10 = targetActor->currentPos.z;
} else {
f6 = targetActor->homePos.x;
f8 = targetActor->homePos.y;
f10 = targetActor->homePos.z;
}
f6 += targetPart->partOffset.x * targetActor->scalingFactor;
if (!(targetActor->flags & 0x800)) {
f8 += targetPart->partOffset.y * targetActor->scalingFactor;
}
f10 += targetPart->partOffset.z * targetActor->scalingFactor;
f12 = f6;
f6 = targetActor->scalingFactor;
f6 = f12 + targetPart->targetOffset.x * f6;
f2 = f8;
f14 = f10 + 5.0f;
if (!(targetActor->flags & 0x800)) {
f8 = f2 + targetPart->targetOffset.y * targetActor->scalingFactor;
}
} else {
f8 = targetPart->absolutePosition.y;
f10 = targetPart->absolutePosition.z;
f12 = targetPart->absolutePosition.x;
f2 = f8;
f14 = f10 + 5.0f;
f6 = f12 + targetPart->targetOffset.x;
if (!(targetActor->flags & 0x800)) {
f8 = f2 + targetPart->targetOffset.y;
}
}
targetData->actorID = ACTOR_CLASS_ENEMY | i;
targetData->partID = partBlueprint->index;
targetData->pos.x = f6;
targetData->pos.y = f8;
targetData->pos.z = f10;
targetData->unk_10 = 0;
if ((targetActor->flags & 0x4000) && !(targetActor->flags & 0x10)) {
targetData->unk_10 = 100;
}
targetData->unk_10 += targetPart->unk_70;
targetData->unk_0A = f12 + targetData->unk_10 * 100;
targetData->unk_0C = f2;
targetData->unk_0E = f14;
if (targetData->unk_0C < 40) {
targetData->homeRow = 0;
} else if (targetData->unk_0C < 85) {
targetData->homeRow = 1;
} else if (targetData->unk_0C < 100) {
targetData->homeRow = 2;
} else {
targetData->homeRow = 3;
}
if (targetData->unk_0A < 25) {
targetData->homeCol = 0;
} else if (targetData->unk_0A < 65) {
targetData->homeCol = 1;
} else if (targetData->unk_0A < 105) {
targetData->homeCol = 2;
} else {
targetData->homeCol = 3;
}
if (targetData->unk_0E < -30) {
targetData->layer = 0;
} else {
targetData->layer = 1;
}
s5++;
targetData++;
}
}
}
actor->selectedTargetIndex = 0;
actor->targetListLength = s5;
do {
// @bug this should be % 4
sp1C = battleStatus->targetHomeIndex & 4;
fp = battleStatus->targetHomeIndex / 4;
targetData = actor->targetData;
s5 = actor->targetListLength;
for (i = 0; i < s5; i++) {
s0 = &targetData[i];
targetActor = get_actor(s0->actorID);
targetPart = get_actor_part(targetActor, s0->partID);
if (s0->actorID == ACTOR_PLAYER || s0->actorID == ACTOR_PARTNER) {
continue;
}
if (battleStatus->currentTargetListFlags & 0x80000000) {
a02 = 1;
goto END2;
}
if (!(gBattleStatus.flags2 & 0x4000) && battleStatus->darknessMode > 0) {
get_screen_overlay_params(1, &sp10, &sp14);
if (sp14 >= 215.0f) {
a02 = 1;
sp18 = 1;
goto END2;
}
}
if (battleStatus->currentTargetListFlags & 0x8000) {
if (!(targetPart->flags & 0x800000) || (targetActor->flags & 0x40) || (targetPart->flags & 0x40)) {
a02 = 1;
} else {
a02 = 0;
}
} else {
a02 = 0;
}
END2:
if (a02) {
for (j = i; j < s5 - 1; j++) {
actor->targetData[j] = actor->targetData[j + 1];
}
s5--;
i--;
}
}
for (i = 0; i < s5; i++) {
s0 = &targetData[i];
targetActor = get_actor(s0->actorID);
targetPart = get_actor_part(targetActor, s0->partID);
if (s0->actorID == ACTOR_PLAYER || s0->actorID == ACTOR_PARTNER) {
continue;
}
if ((battleStatus->currentTargetListFlags & 0x800) && (targetPart->targetFlags & 0x1)) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x1000) && (targetPart->targetFlags & 0x2)) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x20000) && ((targetActor->flags & 0x80) || (targetPart->flags & 0x80))) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x400) && (targetActor->flags & 0x800)) {
a02 = 1;
goto END;
}
if (!(battleStatus->currentTargetListFlags & 0x10000) && (targetActor->flags & 0x4000)) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x40000) && (targetActor->flags & 0x800)) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x4) && s0->homeRow != 0) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x10) && s0->homeRow >= 2) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x40) && s0->homeRow <= 0) {
a02 = 1;
goto END;
}
if ((battleStatus->currentTargetListFlags & 0x4000) && !(targetPart->flags & 0x20)) {
a22 = 0;
for (j = 0; j < s5; j++) {
target = &targetData[j];
if (s0 != target) {
if (s0->layer == target->layer &&
s0->homeCol == target->homeCol &&
s0->homeRow < target->homeRow) {
a22 = 1;
break;
}
}
}
if (a22) {
a02 = 1;
goto END;
}
}
if (battleStatus->currentTargetListFlags & 0x2000) {
a22 = 0;
for (j = 0; j < s5; j++) {
target = &targetData[j];
if (s0 != target) {
if (s0->layer == target->layer &&
s0->homeRow == target->homeRow &&
s0->homeCol > target->homeCol) {
a22 = 1;
break;
}
}
}
if (a22) {
a02 = 1;
goto END;
}
}
if ((battleStatus->currentTargetListFlags & 0x20) && (targetActor->flags & 0x200)) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x100000) && s0->homeRow == fp + 1) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x200000) && s0->homeRow == fp - 1) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x400000) && s0->homeCol == sp1C - 1) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x800000) && s0->homeCol == sp1C + 1) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x100000) && s0->homeRow < fp) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x200000) && s0->homeRow > fp) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x400000) && s0->homeCol > sp1C) {
a02 = 1;
} else if ((battleStatus->currentTargetListFlags & 0x800000) && s0->homeCol < sp1C) {
a02 = 1;
} else {
a02 = 0;
}
END:
if (a02) {
for (j = i; j < s5 - 1; j++) {
actor->targetData[j] = actor->targetData[j + 1];
}
s5--;
i--;
}
}
} while (0); // TODO required to match
actor->targetListLength = s5;
if (s5 == 0 && sp18) {
gBattleStatus.flags2 |= 0x1000;
} else {
gBattleStatus.flags2 &= ~0x1000;
}
targetIndexList = actor->targetIndexList;
targetData = actor->targetData;
s5 = actor->targetListLength;
for (i = 0; i < s5; i++) {
targetIndexList[i] = i;
}
for (i = 0; i < s5 - 1; i++) {
for (j = i + 1; j < s5; j++) {
index1 = targetIndexList[i];
index2 = targetIndexList[j];
s0 = &targetData[index1];
target = &targetData[index2];
if (s0->pos.x + s0->unk_10 * 10 > target->pos.x + target->unk_10 * 10) {
targetIndexList[i] = targetIndexList[j];
targetIndexList[j] = index1;
}
}
}
}
#else
void create_target_list(Actor* actor, s32 arg1);
INCLUDE_ASM(s32, "190B20", create_target_list);
#endif
void func_80266DAC(Actor* actor, s32 arg1);
void player_create_target_list(Actor* actor) {
create_target_list(actor, 0);
}
void enemy_create_target_list(Actor* actor) {
create_target_list(actor, 1);
}
s32 func_80263064(Actor* actor0, Actor* actor1, s32 unused) {
s32 ret = 0;
SelectableTarget* target = actor0->targetData;
s32 numParts;
ActorPart* part;
s32 i;
if (actor1 == NULL) {
return ret;
}
numParts = actor1->numParts;
part = actor1->partsTable;
for (i = 0; i < numParts; i++) {
if (!(part->flags & ACTOR_PART_FLAG_NO_TARGET)) {
if (!(part->flags & ACTOR_PART_FLAG_MULTI_TARGET)) {
continue;
} else {
ActorPartBlueprint* bp = part->staticData;
f32 x, y, z;
if (!(part->flags & ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) {
x = actor1->currentPos.x;
y = actor1->currentPos.y;
z = actor1->currentPos.z;
x += part->partOffset.x;
if (!(actor1->flags & ACTOR_FLAG_UPSIDE_DOWN)) {
y += part->partOffset.y;
} else {
y -= part->partOffset.y;
}
z += part->partOffset.z;
x += part->targetOffset.x;
if (!(actor1->flags & ACTOR_FLAG_UPSIDE_DOWN)) {
y += part->targetOffset.y;
} else {
y -= part->targetOffset.y;
}
} else {
x = part->absolutePosition.x;
y = part->absolutePosition.y;
z = part->absolutePosition.z;
x += part->targetOffset.x;
if (!(actor1->flags & ACTOR_FLAG_UPSIDE_DOWN)) {
y += part->targetOffset.y;
} else {
y -= part->targetOffset.y;
}
}
actor0->targetActorID = target->actorID = actor1->actorID;
actor0->targetPartIndex = target->partID = bp->index;
target->pos.x = x;
target->pos.y = y;
target->pos.z = z;
target->unk_10 = 0;
target++;
ret++;
}
}
part = part->nextPart;
}
actor0->targetListLength = ret;
return ret;
}
s32 func_80263230(Actor* arg0, Actor* arg1) {
return func_80263064(arg0, arg1, 0);
}
void func_8026324C(Actor* arg0, Actor* arg1) {
func_80263064(arg0, arg1, 1);
}
void func_80263268(void) {
BattleStatus* battleStatus = &gBattleStatus;
PlayerData* playerData = &gPlayerData;
Actor* partner = battleStatus->partnerActor;
battleStatus->changePartnerAllowed = 0;
if (partner != NULL) {
s32 partnersEnabled;
s32 i;
battleStatus->changePartnerAllowed = 1;
partnersEnabled = 0;
for (i = 0; i < ARRAY_COUNT(playerData->partners); i++) {
if (playerData->partners[i].enabled) {
partnersEnabled++;
}
}
if (partnersEnabled >= 2) {
if (partner->koStatus == STATUS_DAZE) {
battleStatus->changePartnerAllowed = 0;
} else if (partner->debuff == STATUS_FROZEN) {
battleStatus->changePartnerAllowed = 0;
} else if (playerData->currentPartner == PARTNER_GOOMPA) {
battleStatus->changePartnerAllowed = -1;
}
} else {
battleStatus->changePartnerAllowed = -1;
}
} else {
battleStatus->changePartnerAllowed = -1;
}
}
void func_80263300(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* player = battleStatus->playerActor;
PlayerData* playerData = &gPlayerData;
s32 cond;
s32 i;
battleStatus->menuStatus[0] = 0;
cond = FALSE;
for (i = 0; i < ARRAY_COUNT(playerData->invItems); i++) {
s16 itemID = playerData->invItems[i];
if (itemID != 0) {
ItemData* itemData = &gItemTable[itemID];
if (itemData->typeFlags & ITEM_TYPE_FLAG_BATTLE_USABLE) {
battleStatus->moveCategory = BTL_MENU_TYPE_ITEMS;
battleStatus->moveArgument = playerData->invItems[i];
battleStatus->currentTargetListFlags = itemData->targetFlags;
player_create_target_list(player);
if (player->targetListLength != 0) {
battleStatus->menuStatus[0]++;
cond = TRUE;
}
}
}
}
if (!cond) {
battleStatus->menuStatus[0] = 0;
}
}
s32 btl_are_all_enemies_defeated(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* enemy;
s32 enemiesStillAlive = FALSE;
s32 i;
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
enemy = battleStatus->enemyActors[i];
if (enemy != NULL) {
if(!(enemy->flags & (ACTOR_FLAG_NO_DMG_APPLY | ACTOR_FLAG_TARGET_ONLY))) {
enemiesStillAlive = TRUE;
}
}
}
return !enemiesStillAlive;
}
s32 btl_check_enemies_defeated(void) {
if (btl_are_all_enemies_defeated()) {
btl_set_state(BATTLE_STATE_VICTORY);
return TRUE;
}
return FALSE;
}
s32 btl_check_player_defeated(void) {
if (gPlayerData.curHP > 0) {
return FALSE;
}
gDefeatedBattleState = gBattleState;
gDefeatedBattleSubstate = gBattleSubState;
btl_set_state(BATTLE_STATE_DEFEAT);
return TRUE;
}
void btl_init_menu_boots(void) {
BattleStatus* battleStatus = &gBattleStatus;
PlayerData* playerData = &gPlayerData;
Actor* player = battleStatus->playerActor;
MoveData* move;
s32 i;
s32 moveCount;
s32 hasAnyBadgeMoves;
s32 fpCost;
// If you don't have boots equipped, disable this menu
if (playerData->bootsLevel == -1) {
battleStatus->menuStatus[1] = 0;
return;
}
for (i = 0; i < ARRAY_COUNT(battleStatus->submenuMoves); i++) {
battleStatus->submenuMoves[i] = MOVE_NONE;
}
// Standard jump move
moveCount = 1;
battleStatus->submenuMoves[0] = playerData->bootsLevel + MOVE_JUMP1;
battleStatus->submenuIcons[0] = ITEM_PARTNER_ATTACK;
// Jump badges
do {
for (i = 0; i < ARRAY_COUNT(playerData->equippedBadges); i++) {
s16 badge = playerData->equippedBadges[i];
if (badge != ITEM_NONE) {
MoveData* moveTable = gMoveTable;
u8 moveID = gItemTable[badge].moveID;
move = &moveTable[moveID];
if (move->category == MOVE_TYPE_JUMP) {
battleStatus->submenuMoves[moveCount] = moveID;
battleStatus->submenuIcons[moveCount] = playerData->equippedBadges[i];
moveCount++;
}
}
}
} while (0);
battleStatus->submenuMoveCount = moveCount;
hasAnyBadgeMoves = FALSE;
for (i = 0; i < battleStatus->submenuMoveCount; i++) {
move = &gMoveTable[battleStatus->submenuMoves[i]];
// Calculate FP cost
fpCost = move->costFP;
if (fpCost != 0) {
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_SAVER);
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_FANATIC) * 2;
if (fpCost < 1) {
fpCost = 1;
}
}
// See if there are any targets for this move
battleStatus->moveCategory = BTL_MENU_TYPE_JUMP;
battleStatus->moveArgument = playerData->bootsLevel;
battleStatus->currentTargetListFlags = move->flags; // Controls target filters
player_create_target_list(player);
// If there are targets, enable the move
if (player->targetListLength != 0) {
hasAnyBadgeMoves = TRUE;
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_ENABLED;
}
// If you don't have enough FP, disable the move
if (playerData->curFP < fpCost) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NOT_ENOUGH_FP;
}
// If there are no targets available, disable the move
if (player->targetListLength == 0) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NO_TARGETS_2;
}
if (gBattleStatus.flags2 & BS_FLAGS2_NO_TARGET_AVAILABLE) {
battleStatus->submenuStatus[moveCount] = BATTLE_SUBMENU_STATUS_NO_TARGETS;
}
}
if (!hasAnyBadgeMoves) {
// Only the standard jump is available - no badge moves.
// Selecting this submenu should immediately pick the standard jump move
battleStatus->menuStatus[1] = -1;
} else {
// Enable this submenu
battleStatus->menuStatus[1] = 1;
}
}
void btl_init_menu_hammer(void) {
BattleStatus* battleStatus = &gBattleStatus;
PlayerData* playerData = &gPlayerData;
Actor* player = battleStatus->playerActor;
MoveData* move;
s32 i;
s32 moveCount;
s32 hasAnyBadgeMoves;
s32 fpCost;
// If you don't have a hammer, disable this menu
if (playerData->hammerLevel == -1) {
battleStatus->menuStatus[2] = 0;
return;
}
for (i = 0; i < ARRAY_COUNT(battleStatus->submenuMoves); i++) {
battleStatus->submenuMoves[i] = 0;
}
// Standard hammer move
moveCount = 1;
battleStatus->submenuMoves[0] = playerData->hammerLevel + MOVE_HAMMER1;
battleStatus->submenuIcons[0] = ITEM_PARTNER_ATTACK;
// Hammer badges
do {
for (i = 0; i < ARRAY_COUNT(playerData->equippedBadges); i++) {
s16 badge = playerData->equippedBadges[i];
if (badge != MOVE_NONE) {
MoveData* moveTable = gMoveTable;
u8 moveID = gItemTable[badge].moveID;
move = &moveTable[moveID];
if (move->category == MOVE_TYPE_HAMMER) {
battleStatus->submenuMoves[moveCount] = moveID;
battleStatus->submenuIcons[moveCount] = playerData->equippedBadges[i];
moveCount++;
}
}
}
} while (0);
battleStatus->submenuMoveCount = moveCount;
hasAnyBadgeMoves = FALSE;
for (i = 0; i < battleStatus->submenuMoveCount; i++) {
move = &gMoveTable[battleStatus->submenuMoves[i]];
// Calculate FP cost
fpCost = move->costFP;
if (fpCost != 0) {
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_SAVER);
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_FANATIC) * 2;
if (fpCost < 1) {
fpCost = 1;
}
}
// See if there are any targets for this move
battleStatus->moveCategory = BTL_MENU_TYPE_SMASH;
battleStatus->moveArgument = playerData->hammerLevel;
battleStatus->currentTargetListFlags = move->flags;
player_create_target_list(player);
// If there are targets, enable the move
if (player->targetListLength != 0) {
hasAnyBadgeMoves = TRUE;
battleStatus->submenuStatus[i] = 1;
}
// If you don't have enough FP, disable the move
if (playerData->curFP < fpCost) {
battleStatus->submenuStatus[i] = 0;
}
// If there are no targets available, disable the move
if (player->targetListLength == 0) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NO_TARGETS_2;
}
if (gBattleStatus.flags2 & BS_FLAGS2_NO_TARGET_AVAILABLE) {
battleStatus->submenuStatus[moveCount] = BATTLE_SUBMENU_STATUS_NO_TARGETS;
}
}
if (!hasAnyBadgeMoves) {
// Only the standard hammer is available - no badge moves.
// Selecting this submenu should immediately pick the standard hammer move
battleStatus->menuStatus[2] = -1;
} else {
// Enable this submenu
battleStatus->menuStatus[2] = 1;
}
}
void btl_init_menu_partner(void) {
PlayerData* playerData = &gPlayerData;
BattleStatus* battleStatus = &gBattleStatus;
Actor* player = battleStatus->playerActor;
Actor* partner = battleStatus->partnerActor;
s32 fpCost;
s32 i;
s32 hasAnyBadgeMoves;
for (i = 0; i < ARRAY_COUNT(battleStatus->submenuMoves); i++) {
battleStatus->submenuMoves[i] = 0;
}
// In the move table (enum MoveIDs), partners get move IDs set up like this:
//
// Move ID offset | Description | Goombario example
// ----------------+----------------------+-------------------
// 0 | No rank only | Headbonk
// 1 | Super rank only | Headbonk (2)
// 2 | Ultra rank only | Headbonk (3)
// 3 | Always unlocked | Tattle
// 4 | Unlocked after super | Charge
// 5 | Unlocked after ultra | Multibonk
battleStatus->submenuMoveCount = partner->actorBlueprint->level + 2;
// Offsets 0,1,2
battleStatus->submenuMoves[0] =
playerData->currentPartner * 6
+ (MOVE_HEADBONK1 - 6)
+ partner->actorBlueprint->level;
// Offsets 3,4,5
for (i = 1; i < battleStatus->submenuMoveCount; i++) {
battleStatus->submenuMoves[i] =
playerData->currentPartner * 6
+ (MOVE_TATTLE - 6)
+ (i - 1);
}
hasAnyBadgeMoves = FALSE;
for (i = 0; i < battleStatus->submenuMoveCount; i++){
MoveData* move = &gMoveTable[battleStatus->submenuMoves[i]];
fpCost = move->costFP;
if (fpCost != 0) {
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_SAVER);
fpCost -= player_team_is_ability_active(player, ABILITY_FLOWER_FANATIC) * 2;
if (fpCost < 1) {
fpCost = 1;
}
}
battleStatus->moveCategory = BTL_MENU_TYPE_CHANGE_PARTNER;
battleStatus->moveArgument = partner->actorBlueprint->level;
battleStatus->currentTargetListFlags = move->flags;
player_create_target_list(partner);
if (partner->targetListLength != 0){
hasAnyBadgeMoves = TRUE;
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_ENABLED;
}
if (partner->targetListLength == 0) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NO_TARGETS_2;
}
if (playerData->curFP < fpCost) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NOT_ENOUGH_FP;
}
if (gBattleStatus.flags2 & BS_FLAGS2_NO_TARGET_AVAILABLE) {
battleStatus->submenuStatus[i] = BATTLE_SUBMENU_STATUS_NO_TARGETS;
}
}
if (!hasAnyBadgeMoves) {
battleStatus->menuStatus[3] = -1;
} else {
battleStatus->menuStatus[3] = 1;
}
}
s32 count_power_plus(s32 damageType) {
s32 count;
s32 i;
if (gGameStatusPtr->peachFlags & PEACH_STATUS_FLAG_IS_PEACH) {
return 0;
}
count = 0;
for (i = 0; i < ARRAY_COUNT(gPlayerData.equippedBadges); i++) {
u8 moveID = gItemTable[gPlayerData.equippedBadges[i]].moveID;
if (gMoveTable[moveID].category == MOVE_TYPE_ATTACK_UP && moveID == MOVE_POWER_PLUS) {
if (gBattleStatus.flags1 & BS_FLAGS1_10 || damageType & DAMAGE_TYPE_JUMP) {
count++;
}
}
}
return count;
}
void deduct_current_move_fp(void) {
BattleStatus* battleStatus = &gBattleStatus;
PlayerData* playerData = &gPlayerData;
Actor* actor = battleStatus->playerActor;
s32 fpCost = gMoveTable[battleStatus->selectedMoveID].costFP;
if (fpCost != 0) {
fpCost -= player_team_is_ability_active(actor, ABILITY_FLOWER_SAVER);
fpCost -= player_team_is_ability_active(actor, ABILITY_FLOWER_FANATIC) * 2;
if (fpCost < 1) {
fpCost = 1;
}
}
playerData->curFP -= fpCost;
}
void reset_actor_turn_info(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
actor = battleStatus->enemyActors[i];
if (actor != NULL) {
actor->hpChangeCounter = 0;
actor->damageCounter = 0;
actor->unk_204 = 0;
}
}
actor = battleStatus->playerActor;
actor->hpChangeCounter = 0;
actor->damageCounter = 0;
actor->unk_204 = 0;
actor = battleStatus->partnerActor;
if (actor != NULL) {
actor->hpChangeCounter = 0;
actor->damageCounter = 0;
actor->unk_204 = 0;
}
}
void func_80263CC4(s32 arg0) {
start_script(&D_80293820, 10, 0)->varTable[0] = arg0;
}
void set_animation(s32 actorID, s32 partID, AnimID animID) {
if ((s32) animID >= 0) {
Actor* actor = get_actor(actorID);
ActorPart* part;
switch (actorID & ACTOR_CLASS_MASK) {
case ACTOR_CLASS_PLAYER:
part = &actor->partsTable[0];
if (part->currentAnimation != animID) {
part->currentAnimation = animID;
spr_update_player_sprite(PLAYER_SPRITE_MAIN, animID, part->animationRate);
}
break;
case ACTOR_CLASS_PARTNER:
if (partID != 0) {
part = get_actor_part(actor, partID);
if (part == NULL) {
part = &actor->partsTable[0];
}
} else {
part = &actor->partsTable[0];
}
if (part->currentAnimation != animID) {
part->currentAnimation = animID;
spr_update_sprite(part->spriteInstanceID, animID, part->animationRate);
part->animNotifyValue = spr_get_notify_value(part->spriteInstanceID);
}
break;
case ACTOR_CLASS_ENEMY:
part = get_actor_part(actor, partID);
if (part->currentAnimation != animID) {
part->currentAnimation = animID;
spr_update_sprite(part->spriteInstanceID, animID, part->animationRate);
part->animNotifyValue = spr_get_notify_value(part->spriteInstanceID);
}
break;
}
}
}
void func_80263E08(Actor* actor, ActorPart* part, AnimID anim) {
if ((s32) anim >= 0) {
switch (actor->actorID & ACTOR_CLASS_MASK) {
case ACTOR_CLASS_PLAYER:
if (part->currentAnimation != anim) {
part->currentAnimation = anim;
spr_update_player_sprite(PLAYER_SPRITE_MAIN, anim, part->animationRate);
}
break;
case ACTOR_CLASS_PARTNER:
case ACTOR_CLASS_ENEMY:
if (part->currentAnimation != anim) {
part->currentAnimation = anim;
spr_update_sprite(part->spriteInstanceID, anim, part->animationRate);
part->animNotifyValue = spr_get_notify_value(part->spriteInstanceID);
}
break;
}
}
}
void set_animation_rate(s32 actorID, s32 partID, f32 rate) {
Actor* actor = get_actor(actorID);
ActorPart* part;
switch (actorID & ACTOR_CLASS_MASK) {
case ACTOR_CLASS_PARTNER:
if (partID != 0) {
part = get_actor_part(actor, partID);
if (part != NULL) {
part->animationRate = rate;
return;
}
}
actor->partsTable[0].animationRate = rate;
break;
case ACTOR_CLASS_PLAYER:
case ACTOR_CLASS_ENEMY:
part = get_actor_part(actor, partID);
part->animationRate = rate;
break;
}
}
void set_actor_yaw(s32 actorID, s32 yaw) {
get_actor(actorID)->yaw = yaw;
}
void set_part_yaw(s32 actorID, s32 partID, s32 value) {
get_actor_part(get_actor(actorID), partID)->yaw = value;
}
void set_part_flag_bits(s32 actorID, s32 partID, s32 flags) {
Actor* actor = get_actor(actorID);
ActorPart* part;
switch (actorID & ACTOR_CLASS_MASK) {
case ACTOR_CLASS_PLAYER:
actor->flags |= flags;
break;
case ACTOR_CLASS_PARTNER:
case ACTOR_CLASS_ENEMY:
if (partID == 0) {
actor->flags |= flags;
} else {
part = get_actor_part(actor, partID);
part->flags |= flags;
}
break;
}
}
void clear_part_flag_bits(s32 actorID, s32 partID, s32 flags) {
Actor* actor = get_actor(actorID);
ActorPart* part;
switch (actorID & ACTOR_CLASS_MASK) {
case ACTOR_CLASS_PLAYER:
actor->flags &= ~flags;
break;
case ACTOR_CLASS_PARTNER:
case ACTOR_CLASS_ENEMY:
if (partID == 0) {
actor->flags &= ~flags;
} else {
part = get_actor_part(actor, partID);
part->flags &= ~flags;
}
break;
}
}
void add_xz_vec3f(Vec3f* vector, f32 speed, f32 angleDeg) {
f32 angleRad = DEG_TO_RAD(angleDeg);
f32 sinAngleRad = sin_rad(angleRad);
f32 cosAngleRad = cos_rad(angleRad);
vector->x += speed * sinAngleRad;
vector->z += -speed * cosAngleRad;
}
void add_xz_vec3f_copy1(Vec3f* vector, f32 speed, f32 angleDeg) {
f32 angleRad = DEG_TO_RAD(angleDeg);
f32 sinAngleRad = sin_rad(angleRad);
f32 cosAngleRad = cos_rad(angleRad);
vector->x += speed * sinAngleRad;
vector->z += -speed * cosAngleRad;
}
void add_xz_vec3f_copy2(Vec3f* vector, f32 speed, f32 angleDeg) {
f32 angleRad = DEG_TO_RAD(angleDeg);
f32 sinAngleRad = sin_rad(angleRad);
f32 cosAngleRad = cos_rad(angleRad);
vector->x += speed * sinAngleRad;
vector->z += -speed * cosAngleRad;
}
void play_movement_dust_effects(s32 var0, f32 xPos, f32 yPos, f32 zPos, f32 angleDeg) {
f32 theta;
f32 sinTheta;
f32 cosTheta;
if (var0 == 2) {
fx_landing_dust(0, xPos, yPos + 0.0f, zPos, D_802938A4);
} else if (var0 == 1) {
D_802938A8 = 4;
} else if (D_802938A8++ >= 4) {
D_802938A8 = 0;
theta = DEG_TO_RAD(clamp_angle(-angleDeg));
sinTheta = sin_rad(theta);
cosTheta = cos_rad(theta);
fx_walking_dust(
0,
xPos + (sinTheta * 24.0f * 0.2f),
yPos + 1.5f,
zPos + (cosTheta * 24.0f * 0.2f),
sinTheta,
cosTheta
);
}
}
ActorPart* get_actor_part(Actor* actor, s32 partID) {
ActorPart* part = &actor->partsTable[0];
if (partID < 0 || part->nextPart == NULL) {
return part;
}
while (part != NULL) {
if (part->staticData->index == partID) {
return part;
}
part = part->nextPart;
}
return NULL;
}
void load_player_actor(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* player;
ActorPart* part;
DecorationTable* decorationTable;
ActorPartMovement* partMovement;
s32 i;
s32 j;
player = battleStatus->playerActor = heap_malloc(sizeof(*player));
ASSERT(player != NULL);
player->unk_134 = battleStatus->unk_93++;
player->footStepCounter = 0;
player->flags = 0;
player->actorBlueprint = &bPlayerActorBlueprint;
player->actorType = bPlayerActorBlueprint.type;
if ((gBattleStatus.flags2 & BS_FLAGS2_PEACH_BATTLE) || (gGameStatusPtr->demoFlags & 2)) {
player->homePos.x = player->currentPos.x = -130.0f;
player->homePos.y = player->currentPos.y = 0.0f;
player->homePos.z = player->currentPos.z = -10.0f;
} else {
player->homePos.x = player->currentPos.x = -95.0f;
player->homePos.y = player->currentPos.y = 0.0f;
player->homePos.z = player->currentPos.z = 0.0f;
}
player->headOffset.x = 0;
player->headOffset.y = 0;
player->headOffset.z = 0;
player->rotation.x = 0.0f;
player->rotation.y = 0.0f;
player->rotation.z = 0.0f;
player->rotationPivotOffset.x = 0;
player->rotationPivotOffset.y = 0;
player->rotationPivotOffset.z = 0;
player->verticalRenderOffset = 0;
player->yaw = 0.0f;
player->renderMode = RENDER_MODE_ALPHATEST;
player->scale.x = 1.0f;
player->scale.y = 1.0f;
player->scale.z = 1.0f;
player->scaleModifier.x = 1.0f;
player->scaleModifier.y = 1.0f;
player->scaleModifier.z = 1.0f;
player->size.x = player->actorBlueprint->size.x;
player->size.y = player->actorBlueprint->size.y;
player->actorID = 0;
player->healthBarPosition.x = player->currentPos.x;
player->healthBarPosition.y = player->currentPos.y;
player->healthBarPosition.z = player->currentPos.z;
player->scalingFactor = 1.0f;
player->attackResultEffect = NULL;
player->unk_204 = 0;
player->unk_205 = 0;
player->unk_194 = 0;
player->unk_195 = 0;
player->unk_196 = 0;
player->unk_197 = 0;
player->idleSource = NULL;
player->takeTurnSource = NULL;
player->handleEventSource = NULL;
player->handlePhaseSource = NULL;
player->idleScript = NULL;
player->takeTurnScript = NULL;
player->handleEventScript = NULL;
player->handlePhaseScript = NULL;
player->turnPriority = 0;
player->statusTable = bPlayerStatusTable;
player->debuff = 0;
player->debuffDuration = 0;
player->staticStatus = 0;
player->staticDuration = 0;
player->stoneStatus = 0;
player->stoneDuration = 0;
player->koStatus = 0;
player->koDuration = 0;
player->transparentStatus = 0;
player->transparentDuration = 0;
player->isGlowing = 0;
player->unk_21E = 0;
player->disableDismissTimer = 0;
player->attackBoost = 0;
player->defenseBoost = 0;
player->chillOutAmount = 0;
player->chillOutTurns = 0;
player->statusAfflicted = 0;
player->actorTypeData1[0] = bActorSoundTable[player->actorType].walk[0];
player->actorTypeData1[1] = bActorSoundTable[player->actorType].walk[1];
player->actorTypeData1[2] = bActorSoundTable[player->actorType].fly[0];
player->actorTypeData1[3] = bActorSoundTable[player->actorType].fly[1];
player->actorTypeData1[4] = bActorSoundTable[player->actorType].jump;
player->actorTypeData1[5] = bActorSoundTable[player->actorType].hurt;
player->actorTypeData1b[0] = bActorSoundTable[player->actorType].delay[0];
player->actorTypeData1b[1] = bActorSoundTable[player->actorType].delay[1];
for (i = 0; i < ARRAY_COUNT(player->loopingSoundID); i++) {
player->loopingSoundID[i] = 0;
}
part = heap_malloc(sizeof(*part));
player->partsTable = part;
ASSERT(part != NULL)
player->numParts = 1;
part->staticData = bMarioParts;
part->partOffset.x = 0;
part->partOffset.y = 0;
part->partOffset.z = 0;
part->partOffset.x = 12;
part->partOffset.y = 32;
part->partOffset.z = 5;
part->decorationTable = NULL;
part->flags = 0;
part->targetFlags = 0;
part->partOffsetFloat.x = 0.0f;
part->partOffsetFloat.y = 0.0f;
part->partOffsetFloat.z = 0.0f;
part->rotationPivotOffset.x = 0;
part->rotationPivotOffset.y = 0;
part->rotationPivotOffset.z = 0;
part->visualOffset.x = 0;
part->visualOffset.y = 0;
part->visualOffset.z = 0;
part->absolutePosition.x = 0.0f;
part->absolutePosition.y = 0.0f;
part->absolutePosition.z = 0.0f;
part->defenseTable = bMarioDefenseTable;
if (gBattleStatus.flags2 & BS_FLAGS2_PEACH_BATTLE) {
part->idleAnimations = bPeachIdleAnims;
} else {
part->idleAnimations = bMarioIdleAnims;
}
part->eventFlags = 0;
part->elementalImmunities = 0;
part->opacity = 255;
part->size.y = player->size.y;
part->size.x = player->size.x;
part->yaw = 0.0f;
part->targetOffset.x = 0;
part->targetOffset.y = 0;
part->unk_70 = 0;
part->rotation.x = 0.0f;
part->rotation.y = 0.0f;
part->rotation.z = 0.0f;
part->scale.x = 1.0f;
part->scale.y = 1.0f;
part->scale.z = 1.0f;
part->verticalStretch = 1;
part->unkOffset[0] = 0;
part->unkOffset[1] = 0;
part->animationRate = 1.0f;
part->currentAnimation = func_80265CE8(part->idleAnimations, 1U);
part->nextPart = NULL;
part->partTypeData[0] = bActorSoundTable[player->actorType].walk[0];
part->partTypeData[1] = bActorSoundTable[player->actorType].walk[1];
part->partTypeData[2] = bActorSoundTable[player->actorType].fly[0];
part->partTypeData[3] = bActorSoundTable[player->actorType].fly[1];
part->partTypeData[4] = bActorSoundTable[player->actorType].jump;
part->partTypeData[5] = bActorSoundTable[player->actorType].hurt;
part->actorTypeData2b[0] = bActorSoundTable[player->actorType].delay[0];
part->actorTypeData2b[1] = bActorSoundTable[player->actorType].delay[1];
if (part->idleAnimations != NULL) {
s32 j;
part->decorationTable = heap_malloc(sizeof(*decorationTable));
decorationTable = part->decorationTable;
ASSERT(decorationTable != NULL);
decorationTable->unk_6C0 = 0;
decorationTable->unk_750 = 0;
decorationTable->unk_764 = 0;
decorationTable->unk_768 = 0;
decorationTable->unk_7D8 = 0;
decorationTable->unk_7D9 = 0;
for (j = 0; j < ARRAY_COUNT(decorationTable->posX); j++) {
decorationTable->posX[j] = player->currentPos.x;
decorationTable->posY[j] = player->currentPos.y;
decorationTable->posZ[j] = player->currentPos.z;
}
decorationTable->unk_7DA = 3;
decorationTable->unk_7DB = 0;
decorationTable->effectType = 0;
for (j = 0; j < ARRAY_COUNT(decorationTable->effect); j++) {
decorationTable->effect[j] = NULL;
decorationTable->type[j] = 0;
}
}
partMovement = part->movement = heap_malloc(sizeof(*partMovement));
ASSERT(partMovement != NULL);
player->shadow.id = create_shadow_type(0, player->currentPos.x, player->currentPos.y, player->currentPos.z);
player->shadowScale = player->size.x / 24.0;
player->hudElementDataIndex = create_status_icon_set();
player->disableEffect = fx_disable_x(0, -142.0f, 34.0f, 1.0f, 0);
player->icePillarEffect = NULL;
if (is_ability_active(ABILITY_ZAP_TAP)) {
player->staticStatus = STATUS_STATIC;
player->staticDuration = 127;
}
}
void load_partner_actor(void) {
PlayerData* playerData = &gPlayerData;
BattleStatus* battleStatus = &gBattleStatus;
Actor* partnerActor;
ActorBlueprint* actorBP;
Evt* takeTurnScript;
s32 partCount;
s32 currentPartner;
PartnerDMAData* partnerData;
f32 x;
f32 y;
f32 z;
ActorPart* part;
s32 i;
s32 i2;
currentPartner = playerData->currentPartner;
battleStatus->partnerActor = NULL;
if (currentPartner != PARTNER_NONE) {
partnerData = &bPartnerDmaTable[currentPartner];
actorBP = partnerData->ActorBlueprint;
ASSERT(actorBP != NULL);
nuPiReadRom(partnerData->dmaStart, partnerData->dmaDest, partnerData->dmaEnd - partnerData->dmaStart);
if ((gBattleStatus.flags2 & BS_FLAGS2_PEACH_BATTLE) || (gGameStatusPtr->demoFlags & 2)) {
x = -95.0f;
y = partnerData->y;
z = 0.0f;
gBattleStatus.flags1 |= BS_FLAGS1_PLAYER_IN_BACK;
} else {
x = -130.0f;
y = partnerData->y;
z = -10.0f;
}
partCount = actorBP->partCount;
battleStatus->partnerActor = heap_malloc(sizeof(*partnerActor));
partnerActor = battleStatus->partnerActor;
ASSERT(partnerActor != NULL);
actorBP->level = playerData->partners[playerData->currentPartner].level;
partnerActor->unk_134 = battleStatus->unk_93++;
partnerActor->footStepCounter = 0;
partnerActor->actorBlueprint = actorBP;
partnerActor->actorType = actorBP->type;
partnerActor->flags = actorBP->flags;
partnerActor->homePos.x = partnerActor->currentPos.x = x;
partnerActor->homePos.y = partnerActor->currentPos.y = y;
partnerActor->homePos.z = partnerActor->currentPos.z = z;
partnerActor->headOffset.x = 0;
partnerActor->headOffset.y = 0;
partnerActor->headOffset.z = 0;
partnerActor->currentHP = actorBP->maxHP;
partnerActor->numParts = partCount;
partnerActor->idleSource = NULL;
partnerActor->takeTurnSource = actorBP->initScript;
partnerActor->handleEventSource = NULL;
partnerActor->handlePhaseSource = NULL;
partnerActor->idleScript = NULL;
partnerActor->takeTurnScript = NULL;
partnerActor->handleEventScript = NULL;
partnerActor->handlePhaseScript = NULL;
partnerActor->turnPriority = 0;
partnerActor->enemyIndex = 0;
partnerActor->yaw = 0.0f;
partnerActor->rotation.x = 0.0f;
partnerActor->rotation.y = 0.0f;
partnerActor->rotation.z = 0.0f;
partnerActor->rotationPivotOffset.x = 0;
partnerActor->rotationPivotOffset.y = 0;
partnerActor->rotationPivotOffset.z = 0;
partnerActor->scale.x = 1.0f;
partnerActor->scale.y = 1.0f;
partnerActor->scale.z = 1.0f;
partnerActor->scaleModifier.x = 1.0f;
partnerActor->scaleModifier.y = 1.0f;
partnerActor->scaleModifier.z = 1.0f;
partnerActor->verticalRenderOffset = 0;
partnerActor->size.x = actorBP->size.x;
partnerActor->size.y = actorBP->size.y;
partnerActor->healthBarPosition.x = partnerActor->homePos.x;
partnerActor->healthBarPosition.y = partnerActor->homePos.y;
partnerActor->healthBarPosition.z = partnerActor->homePos.z;
partnerActor->scalingFactor = 1.0f;
partnerActor->attackResultEffect = NULL;
partnerActor->unk_204 = 0;
partnerActor->unk_205 = 0;
partnerActor->unk_194 = 0;
partnerActor->unk_195 = 0;
partnerActor->unk_196 = 0;
partnerActor->unk_197 = 0;
partnerActor->renderMode = RENDER_MODE_ALPHATEST;
partnerActor->actorID = ACTOR_PARTNER;
partnerActor->statusTable = actorBP->statusTable;
partnerActor->debuff = 0;
partnerActor->debuffDuration = 0;
partnerActor->staticStatus = 0;
partnerActor->staticDuration = 0;
partnerActor->stoneStatus = 0;
partnerActor->stoneDuration = 0;
partnerActor->koStatus = 0;
partnerActor->koDuration = 0;
partnerActor->transparentStatus = 0;
partnerActor->transparentDuration = 0;
partnerActor->isGlowing = 0;
partnerActor->unk_21E = 0;
partnerActor->disableDismissTimer = 0;
partnerActor->attackBoost = 0;
partnerActor->defenseBoost = 0;
partnerActor->chillOutAmount = 0;
partnerActor->chillOutTurns = 0;
partnerActor->statusAfflicted = 0;
partnerActor->actorTypeData1[0] = bActorSoundTable[partnerActor->actorType].walk[0];
partnerActor->actorTypeData1[1] = bActorSoundTable[partnerActor->actorType].walk[1];
partnerActor->actorTypeData1[2] = bActorSoundTable[partnerActor->actorType].fly[0];
partnerActor->actorTypeData1[3] = bActorSoundTable[partnerActor->actorType].fly[1];
partnerActor->actorTypeData1[4] = bActorSoundTable[partnerActor->actorType].jump;
partnerActor->actorTypeData1[5] = bActorSoundTable[partnerActor->actorType].hurt;
partnerActor->actorTypeData1b[0] = bActorSoundTable[partnerActor->actorType].delay[0];
partnerActor->actorTypeData1b[1] = bActorSoundTable[partnerActor->actorType].delay[1];
for (i2 = 0; i2 < ARRAY_COUNT(partnerActor->loopingSoundID); i2++) {
partnerActor->loopingSoundID[i2] = 0;
}
part = heap_malloc(sizeof(*part));
partnerActor->partsTable = part;
ASSERT(part != NULL);
for (i = 0; i < partCount; i++) {
ActorPartBlueprint* ActorPartBlueprint = &actorBP->partsData[i];
part->decorationTable = NULL;
part->staticData = ActorPartBlueprint;
part->flags = ActorPartBlueprint->flags | ACTOR_PART_FLAG_4;
part->targetFlags = 0;
part->partOffsetFloat.x = part->partOffset.x = ActorPartBlueprint->posOffset.x;
part->partOffsetFloat.y = part->partOffset.y = ActorPartBlueprint->posOffset.y;
part->partOffsetFloat.z = part->partOffset.z = ActorPartBlueprint->posOffset.z;
part->visualOffset.x = 0;
part->visualOffset.y = 0;
part->visualOffset.z = 0;
part->absolutePosition.x = 0.0f;
part->absolutePosition.y = 0.0f;
part->absolutePosition.z = 0.0f;
part->defenseTable = ActorPartBlueprint->defenseTable;
part->idleAnimations = ActorPartBlueprint->idleAnimations;
part->eventFlags = ActorPartBlueprint->eventFlags;
part->elementalImmunities = ActorPartBlueprint->elementImmunityFlags;
part->opacity = ActorPartBlueprint->opacity;
part->size.y = partnerActor->size.y;
part->size.x = partnerActor->size.x;
part->yaw = 0.0f;
part->targetOffset.x = ActorPartBlueprint->targetOffset.x;
part->targetOffset.y = ActorPartBlueprint->targetOffset.y;
part->unk_70 = 0;
part->rotationPivotOffset.x = 0;
part->rotationPivotOffset.y = 0;
part->rotationPivotOffset.z = 0;
part->rotation.x = 0.0f;
part->rotation.y = 0.0f;
part->rotation.z = 0.0f;
part->scale.x = 1.0f;
part->scale.y = 1.0f;
part->scale.z = 1.0f;
part->verticalStretch = 1;
part->unkOffset[0] = 0;
part->unkOffset[1] = 0;
part->partTypeData[0] = bActorSoundTable[partnerActor->actorType].walk[0];
part->partTypeData[1] = bActorSoundTable[partnerActor->actorType].walk[1];
part->partTypeData[2] = bActorSoundTable[partnerActor->actorType].fly[0];
part->partTypeData[3] = bActorSoundTable[partnerActor->actorType].fly[1];
part->partTypeData[4] = bActorSoundTable[partnerActor->actorType].jump;
part->partTypeData[5] = bActorSoundTable[partnerActor->actorType].hurt;
part->actorTypeData2b[0] = bActorSoundTable[partnerActor->actorType].delay[0];
part->actorTypeData2b[1] = bActorSoundTable[partnerActor->actorType].delay[1];
if (part->idleAnimations != NULL) {
DecorationTable* decorationTable;
s32 j;
part->decorationTable = heap_malloc(sizeof(*decorationTable));
decorationTable = part->decorationTable;
ASSERT(decorationTable != NULL);
decorationTable->unk_6C0 = 0;
decorationTable->unk_750 = 0;
decorationTable->unk_764 = 0;
decorationTable->unk_768 = 0;
decorationTable->unk_7D8 = 0;
decorationTable->unk_7D9 = 0;
for (j = 0; j < ARRAY_COUNT(decorationTable->posX); j++) {
decorationTable->posX[j] = partnerActor->currentPos.x;
decorationTable->posY[j] = partnerActor->currentPos.y;
decorationTable->posZ[j] = partnerActor->currentPos.z;
}
decorationTable->unk_7DA = 3;
decorationTable->unk_7DB = 0;
decorationTable->effectType = 0;
for (j = 0; j < ARRAY_COUNT(decorationTable->effect); j++) {
decorationTable->effect[j] = NULL;
decorationTable->type[j] = 0;
}
}
if (part->flags >= 0) {
part->movement = heap_malloc(sizeof(*part->movement));
ASSERT(part->movement != NULL);
}
part->animationRate = 1.0f;
part->currentAnimation = 0;
part->spriteInstanceID = -1;
if (part->idleAnimations != NULL) {
part->currentAnimation = func_80265CE8(part->idleAnimations, 1);
part->spriteInstanceID = spr_load_npc_sprite(part->currentAnimation | SPRITE_ID_TAIL_ALLOCATE, NULL);
}
if (i + 1 >= partCount) {
part->nextPart = NULL;
continue;
}
part->nextPart = heap_malloc(sizeof(*part->nextPart));
part = part->nextPart;
if (part == NULL) {
PANIC();
}
part->nextPart = NULL;
}
partnerActor->shadow.id = create_shadow_type(0, partnerActor->currentPos.x, partnerActor->currentPos.y, partnerActor->currentPos.z);
partnerActor->shadowScale = partnerActor->size.x / 24.0;
partnerActor->hudElementDataIndex = create_status_icon_set();
partnerActor->disableEffect = fx_disable_x(0, -142.0f, 34.0f, 1.0f, 0);
partnerActor->icePillarEffect = NULL;
takeTurnScript = start_script(partnerActor->takeTurnSource, EVT_PRIORITY_A, 0);
partnerActor->takeTurnScriptID = takeTurnScript->id;
takeTurnScript->owner1.actorID = ACTOR_PARTNER;
}
}
Actor* create_actor(Formation formation) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* actor;
ActorBlueprint* formationActor;
ActorPart* part;
ActorPartBlueprint* partBP;
Evt* takeTurnScript;
s32 partCount;
f32 x, y, z;
DecorationTable* decorationTable;
s32 i, j, k;
if (formation->home.index >= EVT_LIMIT) {
x = btl_actorHomePositions[formation->home.index].x;
y = btl_actorHomePositions[formation->home.index].y;
z = btl_actorHomePositions[formation->home.index].z;
} else {
x = formation->home.vec->x;
y = formation->home.vec->y;
z = formation->home.vec->z;
}
formationActor = formation->actor;
partCount = formationActor->partCount;
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
if (battleStatus->enemyActors[i] == NULL) {
break;
}
}
actor = battleStatus->enemyActors[i] = heap_malloc(sizeof(*actor));
ASSERT(actor != NULL);
actor->unk_134 = battleStatus->unk_93++;
actor->footStepCounter = 0;
actor->actorBlueprint = formationActor;
actor->actorType = formationActor->type;
actor->flags = formationActor->flags;
actor->homePos.x = actor->currentPos.x = x;
actor->homePos.y = actor->currentPos.y = y;
actor->homePos.z = actor->currentPos.z = z;
actor->headOffset.x = 0;
actor->headOffset.y = 0;
actor->headOffset.z = 0;
actor->maxHP = actor->currentHP = formationActor->maxHP;
actor->numParts = partCount;
actor->idleSource = NULL;
actor->takeTurnSource = formationActor->initScript;
actor->handleEventSource = NULL;
actor->handlePhaseSource = NULL;
actor->idleScript = NULL;
actor->takeTurnScript = NULL;
actor->handleEventScript = NULL;
actor->turnPriority = formation->priority;
actor->enemyIndex = i;
actor->yaw = 0.0f;
actor->rotation.x = 0.0f;
actor->rotation.y = 0.0f;
actor->rotation.z = 0.0f;
actor->rotationPivotOffset.x = 0;
actor->rotationPivotOffset.y = 0;
actor->rotationPivotOffset.z = 0;
actor->scale.x = 1.0f;
actor->scale.y = 1.0f;
actor->scale.z = 1.0f;
actor->scaleModifier.x = 1.0f;
actor->scaleModifier.y = 1.0f;
actor->scaleModifier.z = 1.0f;
actor->verticalRenderOffset = 0;
actor->extraCoinBonus = 0;
actor->size.x = formationActor->size.x;
actor->size.y = formationActor->size.y;
actor->scalingFactor = 1.0f;
actor->unk_194 = 0;
actor->unk_195 = 0;
actor->unk_196 = 0;
actor->unk_197 = 0;
actor->unk_198.x = 0;
actor->unk_198.y = 0;
actor->unk_206 = 0;
actor->attackResultEffect = NULL;
actor->unk_204 = 0;
actor->unk_205 = 0;
actor->healthBarPosition.x = actor->currentPos.x + formationActor->hpBarOffset.x;
actor->healthBarPosition.y = actor->currentPos.y + formationActor->hpBarOffset.y;
actor->healthBarPosition.z = actor->currentPos.z;
if (actor->flags & ACTOR_FLAG_UPSIDE_DOWN) {
actor->healthBarPosition.y = actor->currentPos.y - actor->size.y - formationActor->hpBarOffset.y;
}
actor->statusTable = formationActor->statusTable;
actor->debuff = 0;
actor->debuffDuration = 0;
actor->staticStatus = 0;
actor->staticDuration = 0;
actor->stoneStatus = 0;
actor->stoneDuration = 0;
actor->koStatus = 0;
actor->koDuration = 0;
actor->transparentStatus = 0;
actor->transparentDuration = 0;
actor->isGlowing = 0;
actor->unk_21E = 0;
actor->disableDismissTimer = 0;
actor->attackBoost = 0;
actor->defenseBoost = 0;
actor->chillOutAmount = 0;
actor->chillOutTurns = 0;
actor->statusAfflicted = 0;
actor->actorTypeData1[0] = bActorSoundTable[actor->actorType].walk[0];
actor->actorTypeData1[1] = bActorSoundTable[actor->actorType].walk[1];
actor->actorTypeData1[2] = bActorSoundTable[actor->actorType].fly[0];
actor->actorTypeData1[3] = bActorSoundTable[actor->actorType].fly[1];
actor->actorTypeData1[4] = bActorSoundTable[actor->actorType].jump;
actor->actorTypeData1[5] = bActorSoundTable[actor->actorType].hurt;
actor->actorTypeData1b[0] = bActorSoundTable[actor->actorType].delay[0];
actor->actorTypeData1b[1] = bActorSoundTable[actor->actorType].delay[1];
for (i = 0; i < ARRAY_COUNT(actor->loopingSoundID); i++) {
actor->loopingSoundID[i] = 0;
}
actor->state.varTable[0] = formation->var0;
actor->state.varTable[1] = formation->var1;
actor->state.varTable[2] = formation->var2;
actor->state.varTable[3] = formation->var3;
actor->renderMode = RENDER_MODE_ALPHATEST;
actor->instigatorValue = 0;
part = heap_malloc(sizeof(*part));
actor->partsTable = part;
ASSERT(part != NULL);
for (j = 0; j < partCount; j++) {
ActorPartBlueprint* actorPartBP = &formationActor->partsData[j];
part->decorationTable = NULL;
part->staticData = actorPartBP;
part->flags = actorPartBP->flags | ACTOR_PART_FLAG_4;
part->targetFlags = 0;
part->partOffsetFloat.x = part->partOffset.x = actorPartBP->posOffset.x;
part->partOffsetFloat.y = part->partOffset.y = actorPartBP->posOffset.y;
part->partOffsetFloat.z = part->partOffset.z = actorPartBP->posOffset.z;
part->visualOffset.x = 0;
part->visualOffset.y = 0;
part->visualOffset.z = 0;
part->absolutePosition.x = actor->currentPos.x;
part->absolutePosition.y = actor->currentPos.y;
part->absolutePosition.z = actor->currentPos.z;
part->currentPos.x = actor->currentPos.x;
part->currentPos.y = actor->currentPos.y;
part->currentPos.z = actor->currentPos.z;
part->defenseTable = actorPartBP->defenseTable;
part->idleAnimations = actorPartBP->idleAnimations;
part->eventFlags = actorPartBP->eventFlags;
part->elementalImmunities = actorPartBP->elementImmunityFlags;
part->opacity = actorPartBP->opacity;
if (part->opacity < 255) {
actor->renderMode = RENDER_MODE_SURFACE_XLU_LAYER3;
}
part->size.y = actor->size.y;
part->size.x = actor->size.x;
part->yaw = 0.0f;
part->targetOffset.x = actorPartBP->targetOffset.x;
part->targetOffset.y = actorPartBP->targetOffset.y;
part->unk_70 = 0;
part->projectileTargetOffset.x = actorPartBP->projectileTargetOffset.x;
part->projectileTargetOffset.y = actorPartBP->projectileTargetOffset.y;
part->rotation.x = 0.0f;
part->rotation.y = 0.0f;
part->rotation.z = 0.0f;
part->rotationPivotOffset.x = 0;
part->rotationPivotOffset.y = 0;
part->rotationPivotOffset.z = 0;
part->scale.x = 1.0f;
part->scale.y = 1.0f;
part->scale.z = 1.0f;
part->verticalStretch = 1;
part->unkOffset[0] = 0;
part->unkOffset[1] = 0;
part->partTypeData[0] = bActorSoundTable[actor->actorType].walk[0];
part->partTypeData[1] = bActorSoundTable[actor->actorType].walk[1];
part->partTypeData[2] = bActorSoundTable[actor->actorType].fly[0];
part->partTypeData[3] = bActorSoundTable[actor->actorType].fly[1];
part->partTypeData[4] = bActorSoundTable[actor->actorType].jump;
part->partTypeData[5] = bActorSoundTable[actor->actorType].hurt;
part->actorTypeData2b[0] = bActorSoundTable[actor->actorType].delay[0];
part->actorTypeData2b[1] = bActorSoundTable[actor->actorType].delay[1];
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
part->decorationTable = heap_malloc(sizeof(*decorationTable));
decorationTable = part->decorationTable;
ASSERT(decorationTable != NULL);
decorationTable->unk_6C0 = 0;
decorationTable->unk_750 = 0;
decorationTable->unk_764 = 0;
decorationTable->unk_768 = 0;
decorationTable->unk_7D8 = 0;
decorationTable->unk_7D9 = 0;
for (k = 0; k < ARRAY_COUNT(decorationTable->posX); k++) {
decorationTable->posX[k] = actor->currentPos.x;
decorationTable->posY[k] = actor->currentPos.y;
decorationTable->posZ[k] = actor->currentPos.z;
}
decorationTable->unk_7DA = 3;
decorationTable->unk_7DB = 0;
decorationTable->effectType = 0;
for (k = 0; k < ARRAY_COUNT(decorationTable->effect); k++) {
decorationTable->effect[k] = NULL;
decorationTable->type[k] = 0;
}
}
if (part->flags >= 0) {
part->movement = heap_malloc(sizeof(*part->movement));
ASSERT(part->movement != NULL);
}
if (actor->flags & ACTOR_FLAG_TARGET_ONLY) {
part->flags |= ACTOR_PART_FLAG_4000;
}
part->animationRate = 1.0f;
part->currentAnimation = 0;
part->spriteInstanceID = -1;
if (part->idleAnimations != NULL) {
part->currentAnimation = func_80265CE8(part->idleAnimations, 1) & ~SPRITE_ID_TAIL_ALLOCATE;
part->spriteInstanceID = spr_load_npc_sprite(part->currentAnimation, NULL);
}
if (j + 1 >= partCount) {
part->nextPart = NULL;
continue;
}
part->nextPart = heap_malloc(sizeof(*part->nextPart));
part = part->nextPart;
if (part == NULL) {
PANIC();
}
part->nextPart = NULL;
}
actor->hpFraction = 25;
actor->actorID = actor->enemyIndex | 0x200;
takeTurnScript = start_script(actor->takeTurnSource, EVT_PRIORITY_A, 0);
actor->takeTurnScriptID = takeTurnScript->id;
takeTurnScript->owner1.enemyID = actor->enemyIndex | 0x200;
actor->shadow.id = create_shadow_type(0, actor->currentPos.x, actor->currentPos.y, actor->currentPos.z);
actor->shadowScale = actor->size.x / 24.0;
actor->disableEffect = fx_disable_x(0, -142.0f, 34.0f, 1.0f, 0);
actor->icePillarEffect = NULL;
actor->hudElementDataIndex = create_status_icon_set();
return actor;
}
s32 func_80265CE8(AnimID* animations, s32 statusKey) {
AnimID foundAnim;
if (animations == NULL) {
return 0;
}
foundAnim = 0;
while (animations[DICTIONARY_KEY] != NULL) {
if (animations[DICTIONARY_KEY] == STATUS_NORMAL) {
foundAnim = animations[DICTIONARY_VALUE];
}
if (animations[DICTIONARY_KEY] == statusKey) {
foundAnim = animations[DICTIONARY_VALUE];
break;
}
animations += DICTIONARY_SIZE;
}
return foundAnim;
}
s32 func_80265D44(s32 animID) {
BattleStatus* battleStatus = &gBattleStatus;
PlayerData* playerData = &gPlayerData;
Actor* player = battleStatus->playerActor;
u32* anim = &player->partsTable->idleAnimations[0];
s32 ret;
if (anim == NULL) {
return 0;
}
ret = 0;
// TODO use animation id enum once it exists
if (!(battleStatus->flags2 & BS_FLAGS2_PEACH_BATTLE)) {
if (playerData->curHP < 6) {
if (animID == 1) {
animID = 26;
}
if (animID == 18) {
animID = 22;
}
if (animID == 28) {
animID = 29;
}
}
if (player->debuff == STATUS_POISON) {
if (animID == 1) {
animID = 26;
}
if (animID == 18) {
animID = 22;
}
if (animID == 28) {
animID = 29;
}
}
if (player->debuff == STATUS_DIZZY && animID == 18) {
animID = 24;
}
}
while (*anim != NULL) {
if (*anim == 1) {
ret = anim[1];
}
if (*anim == animID) {
ret = anim[1];
break;
}
anim += 2;
}
return ret;
}
s32 lookup_defense(s32* defenseTable, s32 elementKey) {
s32 normalDefense = 0;
while (defenseTable[DICTIONARY_KEY] != ELEMENT_END) {
if (defenseTable[DICTIONARY_KEY] == ELEMENT_NORMAL) {
normalDefense = defenseTable[DICTIONARY_VALUE];
}
if (defenseTable[DICTIONARY_KEY] == elementKey) {
normalDefense = defenseTable[DICTIONARY_VALUE];
break;
}
defenseTable += DICTIONARY_SIZE;
}
// Fall back to normal defense if given element is not specified in table
return normalDefense;
}
s32 lookup_status_chance(s32* statusTable, s32 statusKey) {
s32 defaultChance = 0;
while (statusTable[DICTIONARY_KEY] != STATUS_END) {
if (statusTable[DICTIONARY_KEY] == STATUS_DEFAULT) {
defaultChance = statusTable[DICTIONARY_VALUE];
}
if (statusTable[DICTIONARY_KEY] == statusKey) {
defaultChance = statusTable[DICTIONARY_VALUE];
break;
}
statusTable += DICTIONARY_SIZE;
}
// Fall back to normal chance if given element is not specified in table
return defaultChance;
}
s32 lookup_status_duration_mod(s32* statusTable, s32 statusKey) {
s32 defaultTurnMod = 0;
while (statusTable[DICTIONARY_KEY] != ELEMENT_END) {
if (statusTable[DICTIONARY_KEY] == STATUS_DEFAULT_TURN_MOD) {
defaultTurnMod = statusTable[DICTIONARY_VALUE];
}
if (statusTable[DICTIONARY_KEY] == statusKey) {
defaultTurnMod = statusTable[DICTIONARY_VALUE];
break;
}
statusTable += DICTIONARY_SIZE;
}
// Fall back to normal duration if given element is not specified in table
return defaultTurnMod;
}
s32 inflict_status(Actor* target, s32 statusTypeKey, s32 duration) {
BattleStatus* battleStatus = &gBattleStatus;
EffectInstance* effect;
switch (statusTypeKey) {
case STATUS_FEAR:
case STATUS_DIZZY:
case STATUS_PARALYZE:
case STATUS_SLEEP:
case STATUS_FROZEN:
case STATUS_STOP:
case STATUS_POISON:
case STATUS_SHRINK:
if (target->actorID != ACTOR_PLAYER || (!is_ability_active(ABILITY_FEELING_FINE) &&
!is_ability_active(ABILITY_BERSERKER) && battleStatus->hustleTurns == 0)) {
if (target->actorID != ACTOR_PARTNER) {
if (target->debuff != statusTypeKey) {
target->statusAfflicted = statusTypeKey;
}
target->disableEffect->data.disableX->koDuration = 0;
target->debuff = statusTypeKey;
target->debuffDuration = duration;
if ((s8)duration > 9) {
target->debuffDuration = 9;
}
switch (statusTypeKey) {
case STATUS_FROZEN:
if (target->actorID != ACTOR_PARTNER) {
effect = target->icePillarEffect;
if (effect != NULL) {
effect->flags |= EFFECT_INSTANCE_FLAG_10;
}
target->icePillarEffect = fx_ice_pillar(0, target->currentPos.x, target->currentPos.y,
target->currentPos.z, 1.0f, 0);
create_status_debuff(target->hudElementDataIndex, STATUS_FROZEN);
}
return TRUE;
case STATUS_SLEEP:
func_80266DAC(target, 3);
create_status_debuff(target->hudElementDataIndex, STATUS_SLEEP);
return TRUE;
case STATUS_PARALYZE:
func_80266DAC(target, 7);
create_status_debuff(target->hudElementDataIndex, STATUS_PARALYZE);
return TRUE;
case STATUS_DIZZY:
create_status_debuff(target->hudElementDataIndex, STATUS_DIZZY);
return TRUE;
case STATUS_FEAR:
func_80266DAC(target, 5);
create_status_debuff(target->hudElementDataIndex, STATUS_FEAR);
return TRUE;
case STATUS_POISON:
func_80266DAC(target, 6);
create_status_debuff(target->hudElementDataIndex, STATUS_POISON);
return TRUE;
case STATUS_SHRINK:
create_status_debuff(target->hudElementDataIndex, STATUS_SHRINK);
return TRUE;
}
}
return TRUE;
} else {
return FALSE;
}
break;
case STATUS_STATIC:
if (target->actorID != ACTOR_PARTNER) {
target->staticStatus = statusTypeKey;
target->staticDuration = duration;
if ((s8)duration > 9) {
target->staticDuration = 9;
}
target->statusAfflicted = STATUS_STATIC;
func_80266DAC(target, 4);
create_status_static(target->hudElementDataIndex, STATUS_STATIC);
}
return TRUE;
case STATUS_STONE:
if (target->actorID != ACTOR_PARTNER) {
target->stoneStatus = STATUS_STONE;
target->stoneDuration = duration;
if ((s8)duration > 9) {
target->stoneDuration = 9;
}
target->statusAfflicted = STATUS_STONE;
}
return TRUE;
case STATUS_DAZE:
if (target->koStatus < statusTypeKey) {
target->koStatus = STATUS_DAZE;
target->koDuration = duration;
if ((s8)duration > 9) {
target->koDuration = 9;
}
target->statusAfflicted = STATUS_DAZE;
}
return TRUE;
case STATUS_TRANSPARENT:
if (target->actorID != ACTOR_PARTNER) {
target->transparentStatus = STATUS_TRANSPARENT;
target->transparentDuration = duration;
if ((s8)duration > 9) {
target->transparentDuration = 9;
}
target->statusAfflicted = STATUS_TRANSPARENT;
create_status_transparent(target->hudElementDataIndex, STATUS_TRANSPARENT);
}
return TRUE;
case STATUS_END:
case STATUS_NORMAL:
case STATUS_DEFAULT:
default:
return TRUE;
}
}
s32 inflict_partner_ko(Actor* target, s32 statusTypeKey, s32 duration) {
if (statusTypeKey == STATUS_DAZE) {
if (statusTypeKey != target->koStatus) {
inflict_status(target, STATUS_DAZE, duration);
sfx_play_sound(SOUND_2107);
} else {
target->koDuration += duration;
if (target->koDuration > 9) {
target->koDuration = 9;
}
}
}
return TRUE;
}
s32 get_defense(Actor* actor, s32* defenseTable, s32 elementFlags) {
s32 defense;
s32 minDefense = 255;
if (defenseTable != NULL) {
#define CHECK_DEFENSE(element) \
if (elementFlags & DAMAGE_TYPE_##element) { \
defense = lookup_defense(defenseTable, ELEMENT_##element); \
if (defense < minDefense) { \
minDefense = defense; \
} \
} \
CHECK_DEFENSE(FIRE);
CHECK_DEFENSE(WATER);
CHECK_DEFENSE(ICE);
CHECK_DEFENSE(MAGIC);
CHECK_DEFENSE(SMASH);
CHECK_DEFENSE(JUMP);
CHECK_DEFENSE(COSMIC);
CHECK_DEFENSE(BLAST);
CHECK_DEFENSE(SHOCK);
CHECK_DEFENSE(QUAKE);
CHECK_DEFENSE(THROW);
#undef CHECK_DEFENSE
}
// If no element flags were set, fall back to normal defense.
if (minDefense == 255) {
defense = lookup_defense(defenseTable, ELEMENT_NORMAL);
if (defense < 255) {
minDefense = defense;
}
}
if (elementFlags & DAMAGE_TYPE_IGNORE_DEFENSE) {
if (minDefense == 99) {
// Immune
minDefense = 999;
} else if (minDefense > 0) {
minDefense = 0;
}
}
return minDefense;
}
void func_802664DC(f32 x, f32 y, f32 z, s32 attack, s32 a) {
s32 i;
for (i = 0; i < 1; i++) {
if (gDamageCountEffects[i] == NULL) {
break;
}
}
if (i > 0) {
i = 0;
gDamageCountEffects[i]->data.damageIndicator->effectDurationTimer = 5;
gDamageCountEffects[i] = NULL;
}
if (a == 0) {
a = -55;
} else {
a = 55;
}
fx_damage_indicator(0, x, y, z, 10.0f, a, attack, &gDamageCountEffects[i]);
gDamageCountTimers[i] = 40;
}
void show_damage_popup(f32 x, f32 y, f32 z, s32 attack, s32 a) {
s32 i;
for (i = 0; i < ARRAY_COUNT(gDamageCountEffects); i++) {
if (gDamageCountEffects[i] == NULL) {
break;
}
}
if (i > ARRAY_COUNT(gDamageCountEffects) - 1) {
i = 0;
gDamageCountEffects[i]->data.damageIndicator->effectDurationTimer = 5;
gDamageCountEffects[i] = NULL;
}
if (a == 0) {
a = -55;
} else {
a = 55;
}
fx_damage_indicator(0, x, y, z, 10.0f, a, attack, &gDamageCountEffects[i]);
gDamageCountTimers[i] = 40;
}
void func_80266684(void) {
s32 i;
for (i = 0; i < ARRAY_COUNT(gDamageCountEffects); i++) {
if (gDamageCountEffects[i] != NULL) {
gDamageCountTimers[i]--;
if (gDamageCountTimers[i] == 0) {
gDamageCountEffects[i]->data.damageIndicator->effectDurationTimer = 5;
gDamageCountEffects[i] = NULL;
}
}
};
}
void func_802666E4(Actor* actor, f32 x, f32 y, f32 z, s32 damage) {
BattleStatus* battleStatus = &gBattleStatus;
s32 var_t0;
if (damage < 3) {
var_t0 = 0;
} else if (damage < 5) {
var_t0 = 1;
} else if (damage < 9) {
var_t0 = 2;
} else {
var_t0 = 3;
}
do {
if (battleStatus->currentAttackElement & DAMAGE_TYPE_FIRE) {
fx_ring_blast(0, x, y, z, 1.0f, 24);
} else if (battleStatus->currentAttackElement & DAMAGE_TYPE_SHOCK) {
apply_shock_effect(actor);
} else if (battleStatus->currentAttackElement & DAMAGE_TYPE_WATER) {
fx_water_splash(0, x, y, z, 1.0f, 24);
} else {
fx_firework(0, x, y, z, 1.0, var_t0);
}
} while (0); // required to match
}
// grossness
void func_802667F0(s32 arg0, Actor* actor, f32 x, f32 y, f32 z) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* player;
s32 new_var; // TODO required to match
s32 type;
actor->attackResultEffect = actor->attackResultEffect; // TODO required to match
player = battleStatus->playerActor;
if (actor->attackResultEffect == NULL) {
type = 0;
switch (arg0) {
case 0:
type = 0;
actor->unk_204 = 1;
break;
case 1:
type = 4;
actor->unk_204 = 0;
break;
case 2:
type = 3;
actor->unk_204 = 0;
break;
case 3:
type = 2;
actor->unk_204 = 2;
break;
case 4:
type = 0;
actor->unk_204 = 0;
break;
case 5:
type = player->unk_204;
player->unk_204++;
if (player->unk_204 > 2) {
player->unk_204 = 2;
}
break;
}
actor->attackResultEffect = fx_attack_result_text(type, x, y, z - 10.0f, 12.0f, 90);
actor->unk_205 = 80;
new_var = 2; // TODO required to match
} else {
actor->attackResultEffect->data.attackResultText->unk_18 = 0;
type = actor->unk_204;
new_var = arg0; // TODO required to match
switch (new_var) { // TODO required to match
case 0:
actor->unk_204++;
if (actor->unk_204 > 2) {
actor->unk_204 = 2;
}
break;
case 1:
type = 4;
break;
case 2:
type = 3;
break;
case 3:
type = 2;
break;
case 4:
type = 0;
break;
case 5:
type = player->unk_204;
player->unk_204++;
if (player->unk_204 > 2) {
player->unk_204 = 2;
}
break;
}
actor->attackResultEffect = fx_attack_result_text(type, x, y, z - 10.0f, 12.0f, 90);
actor->unk_205 = 80;
}
}
void func_80266970(Actor* target) {
target->unk_204 = 0;
}
void func_80266978(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* actor;
s32 i;
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
actor = gBattleStatus.enemyActors[i];
if (actor != NULL) {
if (actor->unk_205 == 0x3C) {
if (actor->attackResultEffect != 0) {
actor->attackResultEffect->data.attackResultText->unk_24 = 0;
}
}
if (actor->unk_205 == 5) {
if (actor->attackResultEffect != 0) {
actor->attackResultEffect->data.attackResultText->unk_18 = 0;
actor->attackResultEffect = NULL;
}
}
if (actor->unk_205 > 0) {
actor->unk_205--;
}
}
}
actor = battleStatus->playerActor;
if (actor != NULL) {
if (actor->unk_205 == 60) {
if (actor->attackResultEffect != NULL) {
actor->attackResultEffect->data.attackResultText->unk_24 = 0;
}
}
if (actor->unk_205 == 5) {
if (actor->attackResultEffect != NULL) {
actor->attackResultEffect->data.attackResultText->unk_18 = 0;
actor->attackResultEffect = NULL;
}
}
if (actor->unk_205 > 0) {
actor->unk_205--;
}
}
actor = battleStatus->partnerActor;
if (actor != NULL) {
if (actor->unk_205 == 60) {
if (actor->attackResultEffect != NULL) {
actor->attackResultEffect->data.attackResultText->unk_24 = 0;
}
}
if (actor->unk_205 == 5) {
if (actor->attackResultEffect != NULL) {
actor->attackResultEffect->data.attackResultText->unk_18 = 0;
actor->attackResultEffect = NULL;
}
}
if (actor->unk_205 > 0) {
actor->unk_205--;
}
}
}
void func_80266ADC(Actor* target) {
target->unk_206 = -1;
target->flags |= ACTOR_FLAG_80000;
}
void func_80266AF8(Actor* target) {
target->unk_206 = 0;
target->flags &= ~ACTOR_FLAG_80000;
}
void func_80266B14(void) {
s32 i;
for (i = 0; i < ARRAY_COUNT(gBattleStatus.enemyActors); i++) {
Actor* enemy = gBattleStatus.enemyActors[i];
if (enemy != NULL) {
if (enemy->unk_206 > 0) {
enemy->unk_206--;
if (enemy->unk_206 == 0) {
enemy->flags &= ~ACTOR_FLAG_80000;
}
}
}
}
}
// TODO dumb label required to match, clean up
s32 try_inflict_status(Actor* actor, s32 statusTypeKey, s32 statusKey) {
BattleStatus* battleStatus = &gBattleStatus;
s32 chance;
s32 duration;
if (battleStatus->statusChance == STATUS_CHANCE_IGNORE_RES) {
duration = battleStatus->statusDuration;
duration += lookup_status_duration_mod(actor->statusTable, statusKey);
return inflict_status_set_duration(actor, statusTypeKey, statusKey, duration);
}
duration = 0;
if (actor->statusTable != NULL) {
if (!(battleStatus->currentAttackStatus & STATUS_FLAG_RIGHT_ON)) {
chance = lookup_status_chance(actor->statusTable, statusTypeKey);
} else {
if (lookup_status_chance(actor->statusTable, statusTypeKey) != 0) {
chance = 100;
} else {
goto meow;
}
}
if (chance > 0) {
chance = (chance * battleStatus->statusChance) / 100;
if (chance > 0 && chance >= rand_int(100)) {
duration = 3;
duration += lookup_status_duration_mod(actor->statusTable, statusKey);
}
}
} else {
duration = 3;
}
meow:
if (duration > 0) {
if (battleStatus->currentAttackStatus < 0) {
duration = battleStatus->statusDuration;
duration += lookup_status_duration_mod(actor->statusTable, statusKey);
inflict_status(actor, statusTypeKey, duration);
} else {
inflict_status(actor, statusTypeKey, duration);
}
} else {
duration = 0;
}
return duration;
}
s32 inflict_status_set_duration(Actor* actor, s32 statusTypeKey, s32 statusDurationKey, s32 duration) {
s32 var0 = duration; // TODO required to match, look into
s32 statusDuration = 0;
if (actor->statusTable == NULL || lookup_status_chance(actor->statusTable, statusTypeKey) > 0) {
statusDuration = var0;
}
if (statusDuration > 0) {
return inflict_status(actor, statusTypeKey, statusDuration);
} else {
var0 = 0;
}
return 0;
}
void func_80266D6C(ActorPart* part, s32 arg1) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
DecorationTable* decorationTable = part->decorationTable;
if (decorationTable->unk_6C0 != arg1) {
decorationTable->unk_6C0 = arg1;
decorationTable->unk_6C2 = 0;
decorationTable->unk_6C1 = 1;
}
}
}
void func_80266DAC(Actor* actor, s32 arg1) {
ActorPart* partIt = &actor->partsTable[0];
while (partIt != NULL) {
if (!(partIt->flags & ACTOR_PART_FLAG_INVISIBLE) &&
(partIt->idleAnimations != NULL) &&
!(partIt->flags & ACTOR_PART_FLAG_2))
{
func_80266D6C(partIt, arg1);
}
partIt = partIt->nextPart;
}
}
void func_80266E14(ActorPart* part) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
part->decorationTable->unk_6C0 = 0;
}
}
// TODO: improve match
void func_80266E40(Actor* actor) {
ActorPart* partIt = actor->partsTable;
s8 e = 0xE;
s8 f = 0xF;
while (partIt != NULL) {
DecorationTable* decorationTable = partIt->decorationTable;
do {
if (!(partIt->flags & (ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION | ACTOR_PART_FLAG_INVISIBLE)) &&
(partIt->idleAnimations != NULL) &&
!(partIt->flags & ACTOR_PART_FLAG_2))
{
if (decorationTable->unk_6C0 != e && decorationTable->unk_6C0 != f) {
decorationTable->unk_6C0 = 0;
}
}
} while (0); // required to match
partIt = partIt->nextPart;
}
}
void func_80266EA8(ActorPart* part, s32 arg1) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
DecorationTable* decorationTable = part->decorationTable;
if (decorationTable->unk_750 != arg1) {
decorationTable->unk_750 = arg1;
decorationTable->unk_752 = 0;
decorationTable->unk_751 = 1;
}
}
}
void func_80266EE8(Actor* actor, s32 arg1) {
ActorPart* partIt = &actor->partsTable[0];
while (partIt != NULL) {
if (!(partIt->flags & (ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION | ACTOR_PART_FLAG_INVISIBLE)) &&
(partIt->idleAnimations != NULL) &&
!(partIt->flags & ACTOR_PART_FLAG_2))
{
func_80266EA8(partIt, arg1);
}
partIt = partIt->nextPart;
}
}
void func_80266F60(ActorPart* part) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
part->decorationTable->unk_750 = 0;
}
}
void func_80266F8C(Actor* actor) {
ActorPart* actorPart = &actor->partsTable[0];
while (actorPart != NULL) {
DecorationTable* decorationTable = actorPart->decorationTable;
do {
if (!(actorPart->flags & (ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION | ACTOR_PART_FLAG_INVISIBLE)) &&
actorPart->idleAnimations != NULL &&
!(actorPart->flags & ACTOR_PART_FLAG_2))
{
decorationTable->unk_750 = 0;
}
} while (0); // required to match
actorPart = actorPart->nextPart;
}
}
void func_80266FD8(ActorPart* part, s32 arg1) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
DecorationTable* decorationTable = part->decorationTable;
if (decorationTable->unk_764 != arg1) {
decorationTable->unk_764 = arg1;
decorationTable->unk_766 = 0;
decorationTable->unk_765 = 1;
}
}
}
void func_80267018(Actor* actor, s32 arg1) {
ActorPart* actorPart = &actor->partsTable[0];
while (actorPart != NULL) {
if (!(actorPart->flags & (ACTOR_PART_FLAG_INVISIBLE | ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION)) &&
actorPart->decorationTable != NULL && !(actorPart->flags & ACTOR_PART_FLAG_2) &&
actorPart->idleAnimations != NULL)
{
func_80266FD8(actorPart, arg1);
}
actorPart = actorPart->nextPart;
}
}
void func_8026709C(ActorPart* part) {
if (part->idleAnimations != NULL && !(part->flags & ACTOR_PART_FLAG_2)) {
part->decorationTable->unk_764 = 0;
}
}
void func_802670C8(Actor* actor) {
ActorPart* partIt;
for (partIt = actor->partsTable; partIt != NULL; partIt = partIt->nextPart) {
DecorationTable* decorationTable = partIt->decorationTable;
do {
if (!(partIt->flags & (ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION | ACTOR_PART_FLAG_INVISIBLE)) &&
(partIt->idleAnimations != NULL) &&
!(partIt->flags & ACTOR_PART_FLAG_2))
{
decorationTable->unk_764 = 0;
}
} while (0); // TODO make match better
}
}
void add_part_decoration(ActorPart* part, s32 decorationIndex, s32 decorationType) {
if ((part->idleAnimations) && !(part->flags & ACTOR_PART_FLAG_2)) {
DecorationTable* decorationTable = part->decorationTable;
_remove_part_decoration(part, decorationIndex);
decorationTable->type[decorationIndex] = decorationType;
decorationTable->changed[decorationIndex] = TRUE;
decorationTable->state[decorationIndex] = 0;
_add_part_decoration(part);
}
}
void add_actor_decoration(Actor* actor, s32 decorationIndex, s32 decorationType) {
ActorPart* part;
for (part = actor->partsTable; part != NULL; part = part->nextPart) {
if (!(part->flags & (ACTOR_PART_FLAG_INVISIBLE | ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION))
&& part->idleAnimations
&& !(part->flags & ACTOR_PART_FLAG_2)
) {
add_part_decoration(part, decorationIndex, decorationType);
}
}
}
void remove_part_decoration(ActorPart* part, s32 decorationIndex) {
_remove_part_decoration(part, decorationIndex);
}
void remove_actor_decoration(Actor* actor, s32 decorationIndex) {
ActorPart* part;
for (part = actor->partsTable; part != NULL; part = part->nextPart) {
if (!(part->flags & (ACTOR_PART_FLAG_INVISIBLE | ACTOR_PART_FLAG_USE_ABSOLUTE_POSITION))
&& part->idleAnimations
&& !(part->flags & ACTOR_PART_FLAG_2)
) {
remove_part_decoration(part, decorationIndex);
}
}
}
s32 player_team_is_ability_active(Actor* actor, s32 ability) {
s32 actorClass = actor->actorID & ACTOR_CLASS_MASK;
s32 hasAbility = FALSE;
switch (actorClass) {
case ACTOR_CLASS_PLAYER:
if (!(gBattleStatus.flags2 & BS_FLAGS2_PEACH_BATTLE)) {
hasAbility = is_ability_active(ability);
}
break;
case ACTOR_CLASS_PARTNER:
hasAbility = is_partner_ability_active(ability);
break;
case ACTOR_CLASS_ENEMY:
break;
}
return hasAbility;
}
void create_part_shadow(s32 actorID, s32 partID) {
ActorPart* part = get_actor_part(get_actor(actorID), partID);
part->flags &= ~ACTOR_PART_FLAG_4;
part->shadowIndex = create_shadow_type(0, part->currentPos.x, part->currentPos.y, part->currentPos.z);
part->shadowScale = part->size.x / 24.0;
}
void remove_part_shadow(s32 actorID, s32 partID) {
ActorPart* part = get_actor_part(get_actor(actorID), partID);
part->flags |= ACTOR_PART_FLAG_4;
delete_shadow(part->shadowIndex);
}
void create_part_shadow_by_ref(UNK_TYPE arg0, ActorPart* part) {
part->flags &= ~ACTOR_PART_FLAG_4;
part->shadowIndex = create_shadow_type(0, part->currentPos.x, part->currentPos.y, part->currentPos.z);
part->shadowScale = part->size.x / 24.0;
}
void remove_player_buffs(s32 buffs) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* player = battleStatus->playerActor;
Actor* partner = battleStatus->partnerActor;
ActorPart* playerPartsTable = player->partsTable;
if (buffs & PLAYER_BUFF_JUMP_CHARGE) {
battleStatus->jumpCharge = 0;
battleStatus->flags1 &= ~BS_FLAGS1_JUMP_CHARGED;
}
if (buffs & PLAYER_BUFF_HAMMER_CHARGE) {
battleStatus->hammerCharge = 0;
battleStatus->flags1 &= ~BS_FLAGS1_HAMMER_CHARGED;
}
if (buffs & PLAYER_BUFF_STONE) {
player->stoneDuration = 0;
player->stoneStatus = 0;
}
if (buffs & PLAYER_BUFF_HUSTLE) {
battleStatus->hustleTurns = 0;
battleStatus->flags1 &= ~BS_FLAGS1_HUSTLED;
}
if (buffs & PLAYER_BUFF_STATIC && (player->staticStatus != 0)) {
player->staticDuration = 0;
player->staticStatus = 0;
remove_status_static(player->hudElementDataIndex);
}
if (buffs & PLAYER_BUFF_TRANSPARENT && (player->transparentStatus != 0)) {
player->transparentDuration = 0;
player->transparentStatus = 0;
playerPartsTable->flags &= ~0x100;
remove_status_transparent(player->hudElementDataIndex);
}
if (buffs & PLAYER_BUFF_WATER_BLOCK && (battleStatus->waterBlockTurnsLeft != 0)) {
battleStatus->waterBlockTurnsLeft = 0;
battleStatus->buffEffect->data.partnerBuff->unk_0C[FX_BUFF_DATA_WATER_BLOCK].turnsLeft = 0;
battleStatus->waterBlockEffect->flags |= 0x10;
fx_water_block(1, player->currentPos.x, player->currentPos.y + 18.0f, player->currentPos.z + 5.0f, 1.5f, 0xA);
fx_water_splash(0, player->currentPos.x - 10.0f, player->currentPos.y + 5.0f, player->currentPos.z + 5.0f, 1.0f, 0x18);
fx_water_splash(0, player->currentPos.x - 15.0f, player->currentPos.y + 32.0f, player->currentPos.z + 5.0f, 1.0f, 0x18);
fx_water_splash(1, player->currentPos.x + 15.0f, player->currentPos.y + 22.0f, player->currentPos.z + 5.0f, 1.0f, 0x18);
battleStatus->waterBlockEffect = NULL;
sfx_play_sound(SOUND_299);
}
if (buffs & PLAYER_BUFF_TURBO_CHARGE && (battleStatus->turboChargeTurnsLeft != 0)) {
battleStatus->turboChargeTurnsLeft = 0;
battleStatus->buffEffect->data.partnerBuff->unk_0C[FX_BUFF_DATA_TURBO_CHARGE].turnsLeft = 0;
}
if (buffs & PLAYER_BUFF_CLOUD_NINE && (battleStatus->cloudNineTurnsLeft != 0)) {
battleStatus->cloudNineTurnsLeft = 0;
battleStatus->buffEffect->data.partnerBuff->unk_0C[FX_BUFF_DATA_CLOUD_NINE].turnsLeft = 0;
remove_effect(battleStatus->cloudNineEffect);
battleStatus->cloudNineEffect = NULL;
}
if (partner != NULL && (buffs & PLAYER_BUFF_PARTNER_GLOWING)) {
partner->isGlowing = FALSE;
gBattleStatus.flags1 &= ~BS_FLAGS1_40000000;
}
}
void btl_update_ko_status(void) {
BattleStatus* battleStatus = &gBattleStatus;
Actor* player = battleStatus->playerActor;
Actor* partner = battleStatus->partnerActor;
s32 koDuration = player->koDuration;
s32 i;
player->koDuration = player->debuffDuration;
if (player->koDuration > 0) {
player->koStatus = STATUS_DAZE;
player->disableEffect->data.disableX->koDuration = player->koDuration;
if (koDuration == 0) {
sfx_play_sound(SOUND_2107);
}
}
if (partner != NULL) {
if (partner->koDuration < partner->debuffDuration) {
partner->koStatus = STATUS_DAZE;
partner->koDuration = partner->debuffDuration;
}
if (partner->koDuration > 0) {
partner->koStatus = STATUS_DAZE;
partner->disableEffect->data.disableX->koDuration = partner->koDuration;
}
}
for (i = 0; i < ARRAY_COUNT(battleStatus->enemyActors); i++) {
Actor* enemy = battleStatus->enemyActors[i];
if (enemy != NULL) {
enemy->koDuration = enemy->debuffDuration;
if (enemy->koDuration > 0) {
enemy->koStatus = STATUS_DAZE;
enemy->disableEffect->data.disableX->koDuration = enemy->koDuration;
}
}
}
}
void btl_appendGfx_prim_quad(u8 r, u8 g, u8 b, u8 a, u16 left, u16 top, u16 right, u16 bottom) {
gDPPipeSync(gMainGfxPos++);
gSPDisplayList(gMainGfxPos++, D_80293970);
if (a == 255) {
gDPSetRenderMode(gMainGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
gDPSetCombineLERP(gMainGfxPos++, 0, 0, 0, PRIMITIVE, 0, 0, 0, 1, 0, 0, 0, PRIMITIVE, 0, 0, 0, 1);
} else {
gDPSetRenderMode(gMainGfxPos++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
gDPSetCombineMode(gMainGfxPos++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
}
gDPSetPrimColor(gMainGfxPos++, 0, 0, r, g, b, a);
gDPFillRectangle(gMainGfxPos++, left, top, right, bottom);
gDPPipeSync(gMainGfxPos++);
gDPSetRenderMode(gMainGfxPos++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
gDPSetCombineMode(gMainGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
}
void btl_draw_prim_quad(u8 r, u8 g, u8 b, u8 a, u16 left, u16 top, u16 arg6, u16 arg7) {
u16 right = left + arg6;
u16 bottom = top + arg7;
btl_appendGfx_prim_quad(r, g, b, a, left, top, right, bottom);
}
void reset_all_actor_sounds(Actor* actor) {
ActorPart* partIt = &actor->partsTable[0];
actor->actorTypeData1[0] = bActorSoundTable[actor->actorType].walk[0];
actor->actorTypeData1[1] = bActorSoundTable[actor->actorType].walk[1];
actor->actorTypeData1[2] = bActorSoundTable[actor->actorType].fly[0];
actor->actorTypeData1[3] = bActorSoundTable[actor->actorType].fly[1];
actor->actorTypeData1[4] = bActorSoundTable[actor->actorType].jump;
actor->actorTypeData1[5] = bActorSoundTable[actor->actorType].hurt;
actor->actorTypeData1b[0] = bActorSoundTable[actor->actorType].delay[0];
actor->actorTypeData1b[1] = bActorSoundTable[actor->actorType].delay[1];
while (partIt != NULL) {
partIt->partTypeData[0] = actor->actorTypeData1[0];
partIt->partTypeData[1] = actor->actorTypeData1[1];
partIt->partTypeData[2] = actor->actorTypeData1[2];
partIt->partTypeData[3] = actor->actorTypeData1[3];
partIt->partTypeData[4] = actor->actorTypeData1[4];
partIt->partTypeData[5] = actor->actorTypeData1[5];
partIt->actorTypeData2b[0] = actor->actorTypeData1b[0];
partIt->actorTypeData2b[1] = actor->actorTypeData1b[1];
partIt = partIt->nextPart;
}
}
void hide_foreground_models_unchecked(void) {
Stage* stage = gBattleStatus.currentStage;
if (stage != NULL && stage->foregroundModelList != NULL) {
s32* idList = stage->foregroundModelList;
while (*idList != STAGE_MODEL_LIST_END) {
s32 id = *idList++;
if (id >= 0) {
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(id));
model->flags |= MODEL_FLAG_HIDDEN;
}
}
}
}
void show_foreground_models_unchecked(void) {
Stage* stage = gBattleStatus.currentStage;
if (stage != NULL && stage->foregroundModelList != NULL) {
s32* idList = stage->foregroundModelList;
while (*idList != STAGE_MODEL_LIST_END) {
s32 id = *idList++;
if (id >= 0) {
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(id));
model->flags &= ~MODEL_FLAG_HIDDEN;
}
}
}
}
void hide_foreground_models(void) {
Stage* stage = gBattleStatus.currentStage;
if (stage != NULL && stage->foregroundModelList != NULL) {
s32* idList = stage->foregroundModelList;
while (*idList != STAGE_MODEL_LIST_END) {
s32 id = *idList++;
if (id < 0) {
break;
} else {
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(id));
model->flags |= MODEL_FLAG_HIDDEN;
}
}
}
}
void show_foreground_models(void) {
Stage* stage = gBattleStatus.currentStage;
if (stage != NULL && stage->foregroundModelList != NULL) {
s32* idList = stage->foregroundModelList;
while (*idList != STAGE_MODEL_LIST_END) {
s32 id = *idList++;
if (id < 0) {
break;
} else {
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(id));
model->flags &= ~MODEL_FLAG_HIDDEN;
}
}
}
}
#include "common/StartRumbleWithParams.inc.c"
EvtScript D_802939C4 = {
EVT_CALL(N(StartRumbleWithParams), 256, 30)
EVT_CALL(N(StartRumbleWithParams), 200, 15)
EVT_CALL(N(StartRumbleWithParams), 50, 15)
EVT_RETURN
EVT_END
};
EvtScript D_80293A10 = {
EVT_CALL(N(StartRumbleWithParams), 100, 20)
EVT_RETURN
EVT_END
};
EvtScript D_80293A34 = {
EVT_CALL(N(StartRumbleWithParams), 150, 20)
EVT_RETURN
EVT_END
};
EvtScript D_80293A58 = {
EVT_CALL(N(StartRumbleWithParams), 200, 30)
EVT_RETURN
EVT_END
};
EvtScript D_80293A7C = {
EVT_CALL(N(StartRumbleWithParams), 256, 40)
EVT_RETURN
EVT_END
};
EvtScript D_80293AA0 = {
EVT_CALL(N(StartRumbleWithParams), 256, 60)
EVT_RETURN
EVT_END
};
EvtScript D_80293AC4 = {
EVT_CALL(N(StartRumbleWithParams), 100, 20)
EVT_RETURN
EVT_END
};
EvtScript D_80293AE8 = {
EVT_CALL(N(StartRumbleWithParams), 150, 20)
EVT_RETURN
EVT_END
};
EvtScript D_80293B0C = {
EVT_CALL(N(StartRumbleWithParams), 200, 30)
EVT_RETURN
EVT_END
};
EvtScript D_80293B30 = {
EVT_CALL(N(StartRumbleWithParams), 256, 40)
EVT_RETURN
EVT_END
};
EvtScript D_80293B54 = {
EVT_CALL(N(StartRumbleWithParams), 256, 60)
EVT_RETURN
EVT_END
};
void start_rumble_type(u32 arg0) {
if (D_802939C0 != 0) {
kill_script_by_ID(D_802939C0);
}
switch (arg0) {
case 0:
break;
case 1:
D_802939C0 = start_script(&D_802939C4, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 2:
D_802939C0 = start_script(&D_80293A10, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 3:
D_802939C0 = start_script(&D_80293A34, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 4:
D_802939C0 = start_script(&D_80293A58, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 5:
D_802939C0 = start_script(&D_80293A7C, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 6:
D_802939C0 = start_script(&D_80293AA0, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
case 7:
case 8:
case 9:
case 10:
case 11:
D_802939C0 = start_script(&D_80293AC4, EVT_PRIORITY_A, EVT_FLAG_RUN_IMMEDIATELY)->id;
break;
}
}