mirror of
https://github.com/snesrev/zelda3.git
synced 2025-12-19 18:05:55 -05:00
4329 lines
145 KiB
C
4329 lines
145 KiB
C
#include "sprite.h"
|
|
#include "dungeon.h"
|
|
#include "hud.h"
|
|
#include "load_gfx.h"
|
|
#include "overworld.h"
|
|
#include "variables.h"
|
|
#include "tagalong.h"
|
|
#include "overlord.h"
|
|
#include "ancilla.h"
|
|
#include "player.h"
|
|
#include "misc.h"
|
|
#include "overlord.h"
|
|
#include "tile_detect.h"
|
|
#include "sprite_main.h"
|
|
#include "assets.h"
|
|
static const uint16 kOamGetBufferPos_Tab0[6] = {0x171, 0x201, 0x31, 0xc1, 0x141, 0x1d1};
|
|
static const uint16 kOamGetBufferPos_Tab1[48] = {
|
|
0x30, 0x50, 0x80, 0xb0, 0xe0, 0x110, 0x140, 0x170, 0x1d0, 0x1d4, 0x1dc, 0x1e0, 0x1e4, 0x1ec, 0x1f0, 0x1f8,
|
|
0, 4, 8, 0xc, 0x10, 0x14, 0x18, 0x1c, 0x30, 0x38, 0x50, 0x68, 0x80, 0x98, 0xb0, 0xc8,
|
|
0x120, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1a0, 0x1b8,
|
|
};
|
|
static const uint8 kSprite2_ReturnIfRecoiling_Masks[6] = {3, 1, 0, 0, 0xc, 3};
|
|
static const int8 kSpriteHitbox_XLo[32] = {
|
|
2, 3, 0, -3, -6, 0, 2, -8, 0, -4, -8, 0, -8, -16, 2, 2,
|
|
2, 2, 2, -8, 2, 2, -16, -8, -12, 4, -4, -12, 5, -32, -2, 4,
|
|
};
|
|
static const int8 kSpriteHitbox_XHi[32] = {
|
|
0, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, -1, 0, 0,
|
|
0, 0, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0,
|
|
};
|
|
static const uint8 kSpriteHitbox_XSize[32] = {
|
|
12, 1, 16, 20, 20, 8, 4, 32, 48, 24, 32, 32, 32, 48, 12, 12,
|
|
60, 124, 12, 32, 4, 12, 48, 32, 40, 8, 24, 24, 5, 80, 4, 8,
|
|
};
|
|
static const int8 kSpriteHitbox_YLo[32] = {
|
|
0, 3, 4, -4, -8, 2, 0, -16, 12, -4, -8, 0, -10, -16, 2, 2,
|
|
2, 2, -3, -12, 2, 10, 0, -12, 16, 4, -4, -12, 3, -16, -8, 10,
|
|
};
|
|
static const int8 kSpriteHitbox_YHi[32] = {
|
|
0, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, 0, -1, -1, 0, 0,
|
|
0, 0, -1, -1, 0, 0, 0, -1, 0, 0, -1, -1, 0, -1, -1, 0,
|
|
};
|
|
static const uint8 kSpriteHitbox_YSize[32] = {
|
|
14, 1, 16, 21, 24, 4, 8, 40, 20, 24, 40, 29, 36, 48, 60, 124,
|
|
12, 12, 17, 28, 4, 2, 28, 20, 10, 4, 24, 16, 5, 48, 8, 12,
|
|
};
|
|
static const uint8 kSpriteDamage_Tab2[4] = {6, 4, 0, 0};
|
|
static const uint8 kSpriteDamage_Tab3[4] = {4, 6, 0, 2};
|
|
static const uint8 kSprite_Func21_Sfx[9] = {0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f};
|
|
static const int8 kSparkleGarnish_XY[4] = {-4, 12, 3, 8};
|
|
static const uint8 kSpriteStunned_Main_Func1_Masks[7] = {0x7f, 0xf, 3, 1, 0, 0, 0};
|
|
static const uint8 kSprite_Func7_Tab[4] = {8, 4, 2, 1};
|
|
static const int8 kSprite_Func5_X[54] = {
|
|
8, 8, 2, 14, 8, 8, -2, 10, 8, 8, 1, 14, 4, 4, 4, 4,
|
|
4, 4, -2, 10, 8, 8, -25, 40, 8, 8, 2, 14, 8, 8, -8, 23,
|
|
8, 8, -20, 36, 8, 8, -1, 16, 8, 8, -1, 16, 8, 8, -8, 24,
|
|
8, 8, -8, 24, 8, 3,
|
|
};
|
|
static const int8 kSprite_Func5_Y[54] = {
|
|
6, 20, 13, 13, 0, 8, 4, 4, 1, 14, 8, 8, 4, 4, 4, 4,
|
|
-2, 10, 4, 4, -25, 40, 8, 8, 3, 16, 10, 10, -8, 25, 8, 8,
|
|
-20, 36, 8, 8, -1, 16, 8, 8, 14, 3, 8, 8, -8, 24, 8, 8,
|
|
-8, 32, 8, 8, 12, 4,
|
|
};
|
|
static const uint8 kSprite_SimplifiedTileAttr[256] = {
|
|
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 3, 3, 3,
|
|
0, 0, 0, 0, 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4,
|
|
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, 0, 0, 0, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
};
|
|
static const int8 kSprite_Func5_Tab3[256] = {
|
|
0, 1, 2, 3, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
|
|
1, 1, 1, 0, 0, 0, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
|
|
0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, -1, -1, -1, -1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
};
|
|
static const int8 kSlopedTile[32] = {
|
|
7, 6, 5, 4, 3, 2, 1, 0,
|
|
0, 1, 2, 3, 4, 5, 6, 7,
|
|
0, 1, 2, 3, 4, 5, 6, 7,
|
|
7, 6, 5, 4, 3, 2, 1, 0,
|
|
};
|
|
static const uint8 kSprite_Func1_Tab[8] = {15, 15, 24, 15, 15, 19, 15, 15};
|
|
static const uint8 kSprite_Func1_Tab2[8] = {6, 6, 6, 12, 6, 6, 6, 15};
|
|
static const uint8 kSprite_Func14_Damage[12] = {1, 2, 3, 4, 2, 3, 4, 5, 1, 1, 2, 3};
|
|
static const uint8 kEnemyDamages[128] = {
|
|
0, 1, 32, 255, 252, 251, 0, 0, 0, 2, 64, 4, 0, 0, 0, 0,
|
|
0, 4, 64, 2, 3, 0, 0, 0, 0, 8, 64, 4, 0, 0, 0, 0,
|
|
0, 16, 64, 8, 0, 0, 0, 0, 0, 16, 64, 8, 0, 0, 0, 0,
|
|
0, 4, 64, 16, 0, 0, 0, 0, 0, 255, 64, 255, 252, 251, 0, 0,
|
|
0, 4, 64, 255, 252, 251, 32, 0, 0, 100, 24, 100, 0, 0, 0, 0,
|
|
0, 249, 250, 255, 100, 0, 0, 0, 0, 8, 64, 253, 4, 16, 0, 0,
|
|
0, 8, 64, 254, 4, 0, 0, 0, 0, 16, 64, 253, 0, 0, 0, 0,
|
|
0, 254, 64, 16, 0, 0, 0, 0, 0, 32, 64, 255, 0, 0, 0, 250,
|
|
};
|
|
static const uint8 kSpriteInit_Flags2[243] = {
|
|
1, 2, 1, 0x82, 0x81, 0x84, 0x84, 0x84, 2, 0xf, 2, 1, 0x20, 3, 4, 0x84,
|
|
1, 5, 4, 1, 0x80, 4, 0xa2, 0x83, 4, 2, 0x82, 0x62, 0x82, 0x80, 0x80, 0x85,
|
|
1, 0xa5, 3, 4, 4, 0x83, 2, 1, 0x82, 0xa2, 0xa2, 0xa3, 0xaa, 0xa3, 0xa4, 0x82,
|
|
0x82, 0x83, 0x82, 0x80, 0x82, 0x82, 0xa5, 0x80, 0xa4, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, 6,
|
|
8, 8, 8, 8, 6, 8, 8, 8, 6, 7, 7, 2, 2, 0x22, 1, 1,
|
|
0x20, 0x82, 7, 0x85, 0xf, 0x21, 5, 0x83, 2, 1, 1, 1, 1, 7, 7, 7,
|
|
7, 0, 0x85, 0x83, 3, 0xa4, 0, 0, 0, 0, 9, 4, 0xa0, 0, 1, 0,
|
|
0, 3, 0x8b, 0x86, 0xc2, 0x82, 0x81, 4, 0x82, 0x21, 6, 3, 1, 3, 3, 3,
|
|
0, 0, 4, 5, 5, 3, 1, 2, 0, 0, 0, 2, 7, 0, 1, 1,
|
|
0x87, 6, 0, 0x83, 2, 0x22, 0x22, 0x22, 0x22, 4, 3, 5, 1, 1, 4, 1,
|
|
2, 8, 8, 0x80, 0x21, 3, 3, 3, 2, 2, 8, 0x8f, 0xa1, 0x81, 0x80, 0x80,
|
|
0x80, 0x80, 0xa1, 0x80, 0x81, 0x81, 0x86, 0x81, 0x82, 0x82, 0x80, 0x80, 0x83, 6, 0, 0,
|
|
5, 4, 6, 5, 2, 0, 0, 5, 4, 4, 7, 0xb, 0xc, 0xc, 6, 6,
|
|
3, 0xa4, 4, 0x82, 0x81, 0x83, 0x10, 0x10, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x81,
|
|
0x82, 0x83, 0x83, 0x81, 0x82, 0x81, 0x82, 0xa0, 0xa1, 0xa3, 0xa1, 0xa1, 0xa1, 0x83, 0x85, 0x83,
|
|
0x83, 0x83, 0x83,
|
|
};
|
|
static const uint8 kSpriteInit_Health[243] = {
|
|
12, 6, 255, 3, 3, 3, 3, 3, 2, 12, 4, 255, 0, 3, 12, 2,
|
|
0, 20, 4, 4, 0, 255, 0, 2, 3, 8, 0, 0, 0, 0, 0, 0,
|
|
8, 3, 8, 2, 2, 0, 3, 255, 0, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 0, 3, 0, 3, 3, 3, 0, 3, 0, 0, 0, 0, 3, 2, 255,
|
|
2, 6, 4, 8, 6, 8, 6, 4, 8, 8, 8, 4, 4, 2, 2, 2,
|
|
255, 8, 255, 48, 16, 8, 8, 255, 2, 0, 0, 255, 255, 255, 255, 255,
|
|
255, 255, 255, 255, 4, 4, 255, 255, 255, 255, 16, 3, 0, 2, 4, 1,
|
|
255, 4, 255, 0, 0, 0, 0, 255, 0, 0, 96, 255, 24, 255, 255, 255,
|
|
3, 4, 255, 16, 8, 8, 0, 255, 32, 32, 32, 32, 32, 8, 8, 4,
|
|
8, 64, 48, 255, 2, 255, 255, 255, 255, 16, 4, 2, 4, 4, 8, 8,
|
|
8, 16, 64, 64, 8, 4, 8, 4, 4, 8, 12, 16, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 48, 255,
|
|
255, 255, 255, 8, 0, 0, 0, 32, 0, 8, 5, 40, 40, 40, 90, 16,
|
|
24, 64, 0, 4, 0, 0, 255, 255, 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, 0, 0,
|
|
};
|
|
const uint8 kSpriteInit_BumpDamage[243] = {
|
|
0x83, 0x83, 0x81, 2, 2, 2, 2, 2, 1, 0x13, 1, 1, 1, 1, 8, 1,
|
|
1, 8, 5, 3, 0x40, 4, 0, 2, 3, 0x85, 0, 1, 0, 0x40, 0, 0,
|
|
6, 0, 5, 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 2, 2,
|
|
0, 1, 1, 3, 1, 3, 1, 1, 3, 3, 3, 1, 3, 1, 1, 1,
|
|
1, 1, 1, 0x11, 0x14, 1, 1, 2, 5, 0, 0, 4, 4, 8, 8, 8,
|
|
8, 4, 0, 4, 3, 2, 2, 2, 2, 2, 3, 1, 0, 0, 1, 0x80,
|
|
5, 1, 0, 0, 0, 0x40, 0, 4, 0, 0, 0x14, 4, 6, 4, 4, 4,
|
|
4, 3, 4, 4, 4, 1, 4, 4, 0x15, 5, 4, 5, 0x15, 0x15, 3, 5,
|
|
0, 5, 0x15, 5, 5, 6, 6, 6, 6, 5, 3, 6, 5, 5, 3, 3,
|
|
3, 6, 0x17, 0x15, 0x15, 5, 5, 1, 0x85, 0x83, 5, 4, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x17, 0x17, 5,
|
|
5, 5, 4, 3, 2, 0x10, 0, 6, 0, 5, 7, 0x17, 0x17, 0x17, 0x15, 7,
|
|
6, 0x10, 0, 3, 3, 0, 0x19, 0x19, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteInit_Flags3[243] = {
|
|
0x19, 0xb, 0x1b, 0x4b, 0x41, 0x41, 0x41, 0x4d, 0x1d, 1, 0x1d, 0x19, 0x8d, 0x1b, 9, 0x9d,
|
|
0x3d, 1, 9, 0x11, 0x40, 1, 0x4d, 0x19, 7, 0x1d, 0x59, 0x80, 0x4d, 0x40, 1, 0x49,
|
|
0x1b, 0x41, 3, 0x13, 0x15, 0x41, 0x18, 0x1b, 0x41, 0x47, 0xf, 0x49, 0x4b, 0x4d, 0x41, 0x47,
|
|
0x49, 0x4d, 0x49, 0x40, 0x4d, 0x47, 0x49, 0x41, 0x74, 0x47, 0x5b, 0x58, 0x51, 0x49, 0x1d, 0x5d,
|
|
3, 0x19, 0x1b, 0x17, 0x19, 0x17, 0x19, 0x1b, 0x17, 0x17, 0x17, 0x1b, 0xd, 9, 0x19, 0x19,
|
|
0x49, 0x5d, 0x5b, 0x49, 0xd, 3, 0x13, 0x41, 0x1b, 0x5b, 0x5d, 0x43, 0x43, 0x4d, 0x4d, 0x4d,
|
|
0x4d, 0x4d, 0x49, 1, 0, 0x41, 0x4d, 0x4d, 0x4d, 0x4d, 0x1d, 9, 0xc4, 0xd, 0xd, 9,
|
|
3, 3, 0x4b, 0x47, 0x47, 0x49, 0x49, 0x41, 0x47, 0x36, 0x8b, 0x49, 0x1d, 0x49, 0x43, 0x43,
|
|
0x43, 0xb, 0x41, 0xd, 7, 0xb, 0x1d, 0x43, 0xd, 0x43, 0xd, 0x1d, 0x4d, 0x4d, 0x1b, 0x1b,
|
|
0xa, 0xb, 0, 5, 0xd, 1, 1, 1, 1, 0xb, 5, 1, 1, 1, 7, 0x17,
|
|
0x19, 0xd, 0xd, 0x80, 0x4d, 0x19, 0x17, 0x19, 0xb, 9, 0xd, 0x4a, 0x12, 0x49, 0xc3, 0xc3,
|
|
0xc3, 0xc3, 0x76, 0x40, 0x59, 0x41, 0x58, 0x4f, 0x73, 0x5b, 0x44, 0x41, 0x51, 0xa, 0xb, 0xb,
|
|
0x4b, 0, 0x40, 0x5b, 0xd, 0, 0, 0xd, 0x4b, 0xb, 0x59, 0x41, 0xb, 0xd, 1, 0xd,
|
|
0xd, 0, 0x50, 0x4c, 0x44, 0x51, 1, 1, 0xf2, 0xf8, 0xf4, 0xf2, 0xd4, 0xd4, 0xd4, 0xf8,
|
|
0xf8, 0xf4, 0xf4, 0xd8, 0xf8, 0xd8, 0xdf, 0xc8, 0x69, 0xc1, 0xd2, 0xd2, 0xdc, 0xc7, 0xc1, 0xc7,
|
|
0xc7, 0xc7, 0xc1,
|
|
};
|
|
static const uint8 kSpriteInit_Flags4[243] = {
|
|
0, 0, 0, 0x43, 0x43, 0x43, 0x43, 0x43, 0, 0, 0, 0, 0x1c, 0, 0, 2,
|
|
1, 3, 0, 0, 3, 0xc0, 7, 0, 0, 0, 7, 0x45, 0x43, 0, 0x40, 0xd,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0xd, 7,
|
|
7, 7, 7, 3, 7, 7, 7, 0x40, 3, 7, 0xd, 0, 7, 7, 0, 0,
|
|
9, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0, 0, 0, 0,
|
|
0x80, 0x12, 9, 9, 0, 0x40, 0, 0xc, 0, 0, 0, 0x40, 0x40, 0x10, 0x10, 0x2e,
|
|
0x2e, 0x40, 0x1e, 0x53, 0, 0xa, 0, 0, 0, 0, 0x12, 0x12, 0x40, 0, 0, 0x40,
|
|
0x19, 0, 0, 0xa, 0xd, 0xa, 0xa, 0x80, 0xa, 0x41, 0, 0x40, 0, 0x49, 0, 0,
|
|
0xc0, 0, 0x40, 0, 0, 0x40, 0, 0, 9, 0x80, 0xc0, 0, 0x40, 0, 0, 0x80,
|
|
0, 0, 0x18, 0x5a, 0, 0xd4, 0xd4, 0xd4, 0xd4, 0, 0x40, 0, 0x80, 0x80, 0x40, 0x40,
|
|
0x40, 0, 9, 0x1d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xa, 0x1b, 0x1b,
|
|
0x1b, 0x1b, 0x41, 0, 3, 7, 7, 3, 0xa, 0, 1, 0xa, 0xa, 9, 0, 0,
|
|
0, 0, 9, 0, 0, 0x40, 0x40, 0, 0, 0, 0, 0x89, 0x80, 0x80, 0, 0x1c,
|
|
0, 0x40, 0, 0, 0x1c, 7, 3, 3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
0x44, 0x44, 0x44, 0x43, 0x44, 0x43, 0x40, 0xc0, 0xc0, 0xc7, 0xc3, 0xc3, 0xc0, 0x1b, 8, 0x1b,
|
|
0x1b, 0x1b, 3,
|
|
};
|
|
static const uint8 kSpriteInit_Flags[243] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0xa, 0, 1, 0x30, 0, 0, 0x20,
|
|
0x10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0x20, 0, 4, 0,
|
|
0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x68,
|
|
0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0, 0, 0, 0,
|
|
0, 0, 2, 2, 2, 0, 0, 0x70, 0, 0, 0, 0x90, 0x90, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x60, 0x60, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 2, 0, 0, 0x70, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0xb0, 0, 0xc2, 0, 0x20, 0, 2, 0, 0, 0,
|
|
0, 0, 2, 0, 0xb0, 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa0, 0, 0,
|
|
0, 4, 2, 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, 0, 0xc2, 0, 0,
|
|
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0,
|
|
0, 0, 0, 0, 0, 0, 0xa, 0xa, 0x10, 0x10, 0x10, 0x10, 0, 0, 0, 0x10,
|
|
0x10, 0x10, 0x10, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteInit_Flags5[243] = {
|
|
0x83, 0x96, 0x84, 0x80, 0x80, 0x80, 0x80, 0x80, 2, 0, 2, 0x80, 0xa0, 0x83, 0x97, 0x80,
|
|
0x80, 0x94, 0x91, 7, 0, 0x80, 0, 0x80, 0x92, 0x96, 0x80, 0xa0, 0, 0, 0, 0x80,
|
|
4, 0x80, 0x82, 6, 6, 0, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
|
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0, 0, 0x80, 0x80, 0x90,
|
|
0x80, 0x91, 0x91, 0x91, 0x97, 0x91, 0x95, 0x95, 0x93, 0x97, 0x14, 0x91, 0x92, 0x81, 0x82, 0x82,
|
|
0x80, 0x85, 0x80, 0x80, 0x80, 4, 4, 0x80, 0x91, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
|
0x80, 0, 0x80, 0x80, 0x82, 0x8a, 0x80, 0x80, 0x80, 0x80, 0x92, 0x91, 0x80, 0x82, 0x81, 0x81,
|
|
0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x97, 0x80, 0x80, 0x80,
|
|
0x80, 0xc2, 0x80, 0x15, 0x15, 0x17, 6, 0, 0x80, 0, 0xc0, 0x13, 0x40, 0, 2, 6,
|
|
0x10, 0x14, 0, 0, 0x40, 0, 0, 0, 0, 0x13, 0x46, 0x11, 0x80, 0x80, 0, 0,
|
|
0, 0x10, 0, 0, 0, 0x16, 0x16, 0x16, 0x81, 0x87, 0x82, 0, 0x80, 0x80, 0, 0,
|
|
0, 0, 0x80, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0x80, 0, 0, 0, 0x17, 0, 0x12, 0, 0, 0, 0, 0, 0x10,
|
|
0x17, 0, 0x40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0,
|
|
0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteInit_DeflBits[243] = {
|
|
0, 0, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0, 0x81, 0, 0, 0x48, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0x48, 0x24, 0x80, 0, 0,
|
|
0, 0x20, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80,
|
|
0x80, 0, 0, 0, 0, 0, 0, 0x80, 0, 0x80, 0, 2, 0, 0, 0, 4,
|
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0x84, 0, 0x81, 5, 1, 0x40, 8, 0xa0, 0, 0, 0, 0, 0, 0x84, 0x84, 0x84,
|
|
0x84, 8, 0x80, 0x80, 0x80, 0, 0x80, 0x80, 0x80, 0x80, 0, 8, 0x80, 0, 0, 0,
|
|
0x40, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 4, 0, 0,
|
|
0, 0, 0x80, 4, 4, 0, 0, 0x48, 0, 0, 4, 0, 1, 1, 0, 0,
|
|
0x80, 0, 0, 0, 0x40, 8, 8, 8, 8, 0, 0, 0, 0x80, 0x80, 0, 0,
|
|
0, 4, 1, 5, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0x80, 0x80,
|
|
0x80, 0x80, 0x82, 0x80, 0, 0, 0x80, 0, 0, 0x80, 0x80, 0, 0, 1, 1, 0x40,
|
|
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 5, 5, 5, 0x80, 0x80,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0x82, 0x82, 8, 0x80, 0x20, 0x80,
|
|
0x80, 0x80, 0x20,
|
|
};
|
|
static const int8 kPlayerDamages[30] = {
|
|
2, 1, 1, 4, 4, 4, 0, 0, 0, 8, 4, 2, 8, 8, 8, 16,
|
|
8, 4, 32, 16, 8, 32, 24, 16, 24, 16, 8, 64, 48, 24,
|
|
};
|
|
static const uint8 kPlayerActionBoxRun_YHi[4] = {0xff, 0, 0, 0};
|
|
static const uint8 kPlayerActionBoxRun_YLo[4] = {(uint8)-8, 16, 8, 8};
|
|
static const uint8 kPlayerActionBoxRun_XHi[4] = {0, 0, 0xff, 0};
|
|
static const uint8 kPlayerActionBoxRun_XLo[4] = {0, 0, (uint8)-8, 8};
|
|
static const int8 kPlayer_SetupActionHitBox_X[65] = {
|
|
0, 2, 0, 0, -8, 0, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0,
|
|
0, 2, 4, 4, 0, 0, -4, -4, -6, 2, 1, 1, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 2, 2, 4, 4, 2, 2, 2, 2, 0, 0, 0, 0,
|
|
0, 0, 0, 0, -4, -4, -10, 0, 2, 2, 0, 0, 0, 0, 0, 0,
|
|
0,
|
|
};
|
|
static const int8 kPlayer_SetupActionHitBox_W[65] = {
|
|
15, 4, 8, 8, 8, 8, 12, 8, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0, 4, 16, 12, 8, 8, 12, 11, 12, 4, 6, 6, 0, 0, 0, 0,
|
|
0, 8, 8, 8, 10, 14, 15, 4, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0, 8, 8, 8, 10, 14, 15, 4, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0,
|
|
};
|
|
static const int8 kPlayer_SetupActionHitBox_Y[65] = {
|
|
0, 2, 0, 2, 4, 4, 4, 7, 2, 2, 1, 1, 0, 0, 0, 0,
|
|
0, 2, 0, 2, -4, -3, -8, 0, 0, 2, 1, 1, 0, 0, 0, 0,
|
|
0, 0, 0, 0, -2, 0, -4, 1, 2, 2, 1, 1, 0, 0, 0, 0,
|
|
0, 0, 0, 0, -2, 0, -4, 1, 2, 2, 1, 1, 0, 0, 0, 0,
|
|
0,
|
|
};
|
|
static const int8 kPlayer_SetupActionHitBox_H[65] = {
|
|
15, 4, 8, 2, 12, 8, 12, 8, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0, 4, 8, 4, 12, 12, 12, 4, 8, 4, 6, 4, 0, 0, 0, 0,
|
|
0, 8, 8, 8, 8, 8, 12, 4, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0, 8, 8, 8, 8, 8, 12, 4, 4, 4, 6, 6, 0, 0, 0, 0,
|
|
0,
|
|
};
|
|
static const int8 kPlayer_SetupActionHitBox_Tab4[13] = {
|
|
1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1
|
|
};
|
|
static const uint8 kSprite_PrepAndDrawSingleLarge_Tab1[236] = {
|
|
200, 0, 107, 0, 0, 0, 0, 0, 0, 203, 0, 8, 10, 11, 0, 0,
|
|
13, 0, 0, 86, 0, 0, 15, 17, 0, 19, 0, 0, 0, 0, 20, 0,
|
|
21, 27, 0, 42, 42, 248, 0, 182, 0, 0, 0, 170, 0, 0, 28, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 243, 243, 0, 187, 39, 0, 0, 66, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 63, 0, 0, 0, 64, 64,
|
|
68, 0, 0, 0, 0, 71, 70, 0, 0, 72, 74, 101, 101, 0, 0, 0,
|
|
0, 0, 143, 0, 0, 76, 78, 78, 78, 78, 0, 48, 36, 50, 56, 60,
|
|
129, 0, 82, 0, 0, 0, 0, 0, 0, 92, 0, 98, 94, 0, 0, 0,
|
|
101, 102, 0, 0, 0, 0, 110, 14, 0, 59, 66, 0, 0, 117, 120, 123,
|
|
0, 0, 207, 0, 132, 141, 141, 141, 141, 0, 148, 117, 160, 0, 0, 162,
|
|
166, 0, 0, 0, 177, 0, 181, 0, 189, 0, 0, 0, 105, 0, 0, 0,
|
|
0, 0, 92, 0, 214, 230, 0, 0, 0, 219, 218, 233, 0, 0, 190, 192,
|
|
106, 0, 249, 215, 0, 0, 0, 216, 0, 0, 222, 227, 0, 0, 0, 235,
|
|
0, 0, 0, 0, 0, 0, 244, 244, 29, 31, 31, 31, 32, 32, 32, 33,
|
|
34, 35, 35, 37, 40, 106, 246, 41, 0, 0, 205, 206,
|
|
};
|
|
static const uint8 kSprite_PrepAndDrawSingleLarge_Tab2[251] = {
|
|
0xa0, 0xa2, 0xa0, 0xa2, 0x80, 0x82, 0x80, 0x82, 0xea, 0xec, 0x84, 0x4e, 0x61, 0xbd, 0x8c, 0x20,
|
|
0x22, 0xc0, 0xc2, 0xe6, 0xe4, 0x82, 0xaa, 0x84, 0xac, 0x80, 0xa0, 0xca, 0xaf, 0x29, 0x39, 0xb,
|
|
0x6e, 0x60, 0x62, 0x63, 0x4c, 0xea, 0xec, 0x24, 0x6b, 0x24, 0x22, 0x24, 0x26, 0x20, 0x30, 0x21,
|
|
0x2a, 0x24, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0x84, 0x80, 0x82, 0x6e,
|
|
0x40, 0x42, 0xe6, 0xe8, 0x80, 0x82, 0xc8, 0x8d, 0xe3, 0xe5, 0xc5, 0xe1, 4, 0x24, 0xe, 0x2e,
|
|
0xc, 0xa, 0x9c, 0xc7, 0xb6, 0xb7, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0xe4, 0xf4, 2, 2,
|
|
0, 4, 0xc6, 0xcc, 0xce, 0x28, 0x84, 0x82, 0x80, 0xe5, 0x24, 0, 2, 4, 0xa0, 0xaa,
|
|
0xa4, 0xa6, 0xac, 0xa2, 0xa8, 0xa6, 0x88, 0x86, 0x8e, 0xae, 0x8a, 0x42, 0x44, 0x42, 0x44, 0x64,
|
|
0x66, 0xcc, 0xcc, 0xca, 0x87, 0x97, 0x8e, 0xae, 0xac, 0x8c, 0x8e, 0xaa, 0xac, 0xd2, 0xf3, 0x84,
|
|
0xa2, 0x84, 0xa4, 0xe7, 0x8a, 0xa8, 0x8a, 0xa8, 0x88, 0xa0, 0xa4, 0xa2, 0xa6, 0xa6, 0xa6, 0xa6,
|
|
0x7e, 0x7f, 0x8a, 0x88, 0x8c, 0xa6, 0x86, 0x8e, 0xac, 0x86, 0xbb, 0xac, 0xa9, 0xb9, 0xaa, 0xba,
|
|
0xbc, 0x8a, 0x8e, 0x8a, 0x86, 0xa, 0xc2, 0xc4, 0xe2, 0xe4, 0xc6, 0xea, 0xec, 0xff, 0xe6, 0xc6,
|
|
0xcc, 0xec, 0xce, 0xee, 0x4c, 0x6c, 0x4e, 0x6e, 0xc8, 0xc4, 0xc6, 0x88, 0x8c, 0x24, 0xe0, 0xae,
|
|
0xc0, 0xc8, 0xc4, 0xc6, 0xe2, 0xe0, 0xee, 0xae, 0xa0, 0x80, 0xee, 0xc0, 0xc2, 0xbf, 0x8c, 0xaa,
|
|
0x86, 0xa8, 0xa6, 0x2c, 0x28, 6, 0xdf, 0xcf, 0xa9, 0x46, 0x46, 0xea, 0xc0, 0xc2, 0xe0, 0xe8,
|
|
0xe2, 0xe6, 0xe4, 0xb, 0x8e, 0xa0, 0xec, 0xea, 0xe9, 0x48, 0x58,
|
|
};
|
|
static const uint8 kOverworldAreaSprcollSizes[192] = {
|
|
4, 4, 2, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 4, 4, 2, 4, 4,
|
|
4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
4, 4, 2, 2, 2, 4, 4, 2, 4, 4, 2, 2, 2, 4, 4, 2,
|
|
4, 4, 2, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 4, 4, 2, 4, 4,
|
|
4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
4, 4, 2, 2, 2, 4, 4, 2, 4, 4, 2, 2, 2, 4, 4, 2,
|
|
4, 4, 2, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 4, 4, 2, 4, 4,
|
|
4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
4, 4, 2, 2, 2, 4, 4, 2, 4, 4, 2, 2, 2, 4, 4, 2,
|
|
};
|
|
static const uint16 kOam_ResetRegionBases[6] = {0x30, 0x1d0, 0, 0x30, 0x120, 0x140};
|
|
static const uint8 kGarnish_OamMemSize[23] = {
|
|
0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
8, 4, 4, 4, 8, 16,
|
|
};
|
|
static HandlerFuncK *const kGarnish_Funcs[22] = {
|
|
&Garnish01_FireSnakeTail,
|
|
&Garnish02_MothulaBeamTrail,
|
|
&Garnish03_FallingTile,
|
|
&Garnish04_LaserTrail,
|
|
&Garnish_SimpleSparkle,
|
|
&Garnish06_ZoroTrail,
|
|
&Garnish07_BabasuFlash,
|
|
&Garnish08_KholdstareTrail,
|
|
&Garnish09_LightningTrail,
|
|
&Garnish0A_CannonSmoke,
|
|
&Garnish_WaterTrail,
|
|
&Garnish0C_TrinexxIceBreath,
|
|
NULL,
|
|
&Garnish0E_TrinexxFireBreath,
|
|
&Garnish0F_BlindLaserTrail,
|
|
&Garnish10_GanonBatFlame,
|
|
&Garnish11_WitheringGanonBatFlame,
|
|
&Garnish12_Sparkle,
|
|
&Garnish13_PyramidDebris,
|
|
&Garnish14_KakKidDashDust,
|
|
&Garnish15_ArrghusSplash,
|
|
&Garnish16_ThrownItemDebris,
|
|
};
|
|
static const uint8 kSpriteFall_Tab1[32] = {
|
|
13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 3, 3, 3, 3,
|
|
3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteFall_Tab2[32] = {
|
|
5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3,
|
|
3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteFall_Tab3[16] = {0xff, 0x3f, 0x1f, 0xf, 0xf, 7, 3, 1, 0xff, 0x3f, 0x1f, 0xf, 7, 3, 1, 0};
|
|
static const int8 kSpriteFall_Tab4[4] = {0, 4, 8, 0};
|
|
static const DrawMultipleData kSpriteDrawFall0Data[12] = {
|
|
{0, 0, 0x0146, 2},
|
|
{0, 0, 0x0148, 2},
|
|
{0, 0, 0x014a, 2},
|
|
{4, 4, 0x014c, 0},
|
|
{4, 4, 0x00b7, 0},
|
|
{4, 4, 0x0080, 0},
|
|
{0, 0, 0x016c, 2},
|
|
{0, 0, 0x016e, 2},
|
|
{0, 0, 0x014e, 2},
|
|
{4, 4, 0x015c, 0},
|
|
{4, 4, 0x00b7, 0},
|
|
{4, 4, 0x0080, 0},
|
|
};
|
|
static const int8 kSpriteDrawFall1_X[56] = {
|
|
-4, 4, -4, 12, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
-4, 12, -4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
-4, 12, -4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
4, 0, 0, 0, 4, 0, 0, 0,
|
|
};
|
|
static const int8 kSpriteDrawFall1_Y[56] = {
|
|
-4, -4, 4, 12, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
-4, -4, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
-4, -4, 12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
|
4, 0, 0, 0, 4, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteDrawFall1_Char[56] = {
|
|
0xae, 0xa8, 0xa6, 0xaf, 0xaa, 0, 0, 0, 0xac, 0, 0, 0, 0xbe, 0, 0, 0,
|
|
0xa8, 0xae, 0xaf, 0xa6, 0xaa, 0, 0, 0, 0xac, 0, 0, 0, 0xbe, 0, 0, 0,
|
|
0xa6, 0xaf, 0xae, 0xa8, 0xaa, 0, 0, 0, 0xac, 0, 0, 0, 0xbe, 0, 0, 0,
|
|
0xb6, 0, 0, 0, 0x80, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteDrawFall1_Flags[56] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0x40, 0x40, 0x40, 0x40, 0x40, 0, 0, 0, 0x40, 0, 0, 0, 0x40, 0, 0, 0,
|
|
0x80, 0x80, 0x80, 0x80, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0,
|
|
1, 0, 0, 0, 1, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpriteDrawFall1_Ext[56] = {
|
|
0, 2, 2, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
|
2, 0, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
|
2, 0, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const int8 kSpriteDistress_X[4] = {-3, 2, 7, 11};
|
|
static const int8 kSpriteDistress_Y[4] = {-5, -7, -7, -5};
|
|
static const uint8 kPikitDropItems[4] = {0xdc, 0xe1, 0xd9, 0xe6};
|
|
static const uint8 kPrizeMasks[7] = { 1, 1, 1, 0, 1, 1, 1 };
|
|
static const uint8 kPrizeItems[56] = {
|
|
0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd8, 0xd8, 0xd9, 0xda, 0xd9, 0xda, 0xdb, 0xda, 0xd9, 0xda, 0xda,
|
|
0xe0, 0xdf, 0xdf, 0xda, 0xe0, 0xdf, 0xd8, 0xdf, 0xdc, 0xdc, 0xdc, 0xdd, 0xdc, 0xdc, 0xde, 0xdc,
|
|
0xe1, 0xd8, 0xe1, 0xe2, 0xe1, 0xd8, 0xe1, 0xe2, 0xdf, 0xd9, 0xd8, 0xe1, 0xdf, 0xdc, 0xd9, 0xd8,
|
|
0xd8, 0xe3, 0xe0, 0xdb, 0xde, 0xd8, 0xdb, 0xe2,
|
|
};
|
|
static const uint8 kPrizeZ[15] = {0, 0x24, 0x24, 0x24, 0x20, 0x20, 0x20, 0x24, 0x24, 0x24, 0x24, 0, 0x24, 0x20, 0x20};
|
|
static const int8 kPerishOverlay_X[32] = {
|
|
0, 0, 0, 8, 0, 8, 0, 8, 8, 8, 0, 8, 0, 8, 0, 8,
|
|
0, 8, 0, 8, 0, 8, 0, 8, -3, 11, -3, 11, -6, 14, -6, 14,
|
|
};
|
|
static const int8 kPerishOverlay_Y[32] = {
|
|
0, 0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 8,
|
|
0, 0, 8, 8, 0, 0, 8, 8, -3, -3, 11, 11, -6, -6, 14, 14,
|
|
};
|
|
static const uint8 kPerishOverlay_Char[32] = {
|
|
0, 0xb9, 0, 0, 0xb4, 0xb5, 0xb5, 0xb4, 0xb9, 0, 0, 0, 0xb5, 0xb4, 0xb4, 0xb5,
|
|
0xa8, 0xa8, 0xb8, 0xb8, 0xa8, 0xa8, 0xb8, 0xb8, 0xa9, 0xa9, 0xa9, 0xa9, 0x9b, 0x9b, 0x9b, 0x9b,
|
|
};
|
|
static const uint8 kPerishOverlay_Flags[32] = {
|
|
4, 4, 4, 4, 4, 4, 0xc4, 0xc4, 0x44, 4, 4, 4, 0x44, 0x44, 0x84, 0x84,
|
|
4, 0x44, 4, 0x44, 4, 0x44, 4, 0x44, 0x44, 4, 0xc4, 0x84, 4, 0x44, 0x84, 0xc4,
|
|
};
|
|
static HandlerFuncK *const kSprite_ExecuteSingle[12] = {
|
|
&Sprite_inactiveSprite,
|
|
&SpriteModule_Fall1,
|
|
&SpriteModule_Poof,
|
|
&SpriteModule_Drown,
|
|
&SpriteModule_Explode,
|
|
&SpriteModule_Fall2,
|
|
&SpriteModule_Die,
|
|
&SpriteModule_Burn,
|
|
&SpriteModule_Initialize,
|
|
&SpriteActive_Main,
|
|
&SpriteModule_Carried,
|
|
&SpriteModule_Stunned,
|
|
};
|
|
// it's not my job to tell you what to think, my job is to think about what you tell me'
|
|
#define R0 WORD(g_ram[0])
|
|
#define R2 WORD(g_ram[2])
|
|
static const uint8 kSpawnSecretItems[22] = {
|
|
0xd9, 0x3e, 0x79, 0xd9, 0xdc, 0xd8, 0xda, 0xe4, 0xe1, 0xdc, 0xd8, 0xdf, 0xe0, 0xb, 0x42, 0xd3,
|
|
0x41, 0xd4, 0xd9, 0xe3, 0xd8, 0,
|
|
};
|
|
static const uint8 kSpawnSecretItem_SpawnFlag[22] = {
|
|
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0,
|
|
0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint8 kSpawnSecretItem_XLo[22] = {
|
|
4, 0, 4, 4, 0, 4, 4, 4, 4, 0, 4, 4, 4, 0, 0, 0,
|
|
0, 0, 4, 0, 4, 4,
|
|
};
|
|
static const uint8 kSpawnSecretItem_IgnoreProj[22] = {
|
|
1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
|
|
0, 0, 1, 1, 1, 1,
|
|
};
|
|
static const uint8 kSpawnSecretItem_ZVel[22] = {
|
|
16, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 16, 10, 16, 0, 0,
|
|
0, 0, 16, 0, 0, 0,
|
|
};
|
|
static const uint8 kSprite_ReturnIfLifted_Dirs[4] = {4, 6, 0, 2};
|
|
static const uint8 kAbsorbable_Tab1[15] = {0, 1, 1, 1, 2, 2, 2, 0, 1, 1, 2, 2, 1, 2, 2};
|
|
static const uint8 kAbsorbable_Tab2[19] = {0, 0, 0, 0, 1, 2, 3, 0, 0, 4, 5, 0, 0, 0, 0, 2, 4, 6, 2};
|
|
static const int16 kNumberedAbsorbable_X[18] = { 0, 0, 8, 0, 0, 8, 0, 0, 8, 0, 0, 2, 0, 0, 2, 0, 0, 0, };
|
|
static const int16 kNumberedAbsorbable_Y[18] = { 0, 0, 8, 0, 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 8, 0, 8, 8, };
|
|
static const uint8 kNumberedAbsorbable_Char[18] = { 0x6e, 0x6e, 0x68, 0x6e, 0x6e, 0x78, 0x6e, 0x6e, 0x79, 0x63, 0x73, 0x69, 0x63, 0x73, 0x6a, 0x63, 0x73, 0x73, };
|
|
static const uint8 kNumberedAbsorbable_Ext[18] = { 2, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
|
|
static const uint8 kRupeesAbsorption[3] = {1, 5, 20};
|
|
const uint8 kAbsorptionSfx[15] = {0xb, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0x2f, 0x2f, 0xb};
|
|
static const uint8 kBombsAbsorption[3] = {1, 4, 8};
|
|
const uint8 kAbsorbBigKey[2] = {0x40, 0x20};
|
|
static int AllocOverlord();
|
|
static int Overworld_AllocSprite(uint8 type);
|
|
uint16 Sprite_GetX(int k) {
|
|
return sprite_x_lo[k] | sprite_x_hi[k] << 8;
|
|
}
|
|
|
|
uint16 Sprite_GetY(int k) {
|
|
return sprite_y_lo[k] | sprite_y_hi[k] << 8;
|
|
}
|
|
|
|
void Sprite_SetX(int k, uint16 x) {
|
|
sprite_x_lo[k] = x;
|
|
sprite_x_hi[k] = x >> 8;
|
|
}
|
|
|
|
void Sprite_SetY(int k, uint16 y) {
|
|
sprite_y_lo[k] = y;
|
|
sprite_y_hi[k] = y >> 8;
|
|
}
|
|
|
|
void Sprite_ApproachTargetSpeed(int k, uint8 x, uint8 y) {
|
|
if (sprite_x_vel[k] - x)
|
|
sprite_x_vel[k] += sign8(sprite_x_vel[k] - x) ? 1 : -1;
|
|
if (sprite_y_vel[k] - y)
|
|
sprite_y_vel[k] += sign8(sprite_y_vel[k] - y) ? 1 : -1;
|
|
}
|
|
|
|
void SpriteAddXY(int k, int xv, int yv) {
|
|
Sprite_SetX(k, Sprite_GetX(k) + xv);
|
|
Sprite_SetY(k, Sprite_GetY(k) + yv);
|
|
}
|
|
|
|
void Sprite_MoveXYZ(int k) {
|
|
Sprite_MoveZ(k);
|
|
Sprite_MoveX(k);
|
|
Sprite_MoveY(k);
|
|
}
|
|
|
|
void Sprite_Invert_XY_Speeds(int k) {
|
|
sprite_x_vel[k] = -sprite_x_vel[k];
|
|
sprite_y_vel[k] = -sprite_y_vel[k];
|
|
}
|
|
|
|
int Sprite_SpawnSimpleSparkleGarnishEx(int k, uint16 x, uint16 y, int limit) {
|
|
int j = GarnishAllocLimit(limit);
|
|
if (j >= 0) {
|
|
garnish_type[j] = 5;
|
|
garnish_active = 5;
|
|
Garnish_SetX(j, Sprite_GetX(k) + x);
|
|
Garnish_SetY(j, Sprite_GetY(k) + y - sprite_z[k] + 16);
|
|
garnish_countdown[j] = 31;
|
|
garnish_sprite[j] = k;
|
|
garnish_floor[j] = sprite_floor[k];
|
|
}
|
|
g_ram[15] = j;
|
|
return j;
|
|
}
|
|
|
|
static int AllocOverlord() {
|
|
int i = 7;
|
|
while (i >= 0 && overlord_type[i] != 0)
|
|
i--;
|
|
return i;
|
|
}
|
|
|
|
static int Overworld_AllocSprite(uint8 type) {
|
|
int i = (type == 0x58) ? 4 :
|
|
(type == 0xd0) ? 5 :
|
|
(type == 0xeb || type == 0x53 || type == 0xf3) ? 14 : 13;
|
|
for (; i >= 0; i--) {
|
|
if (sprite_state[i] == 0 || sprite_type[i] == 0x41 && sprite_C[i] != 0)
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
uint16 Garnish_GetX(int k) {
|
|
return garnish_x_lo[k] | garnish_x_hi[k] << 8;
|
|
}
|
|
|
|
uint16 Garnish_GetY(int k) {
|
|
return garnish_y_lo[k] | garnish_y_hi[k] << 8;
|
|
}
|
|
|
|
void Garnish_SparkleCommon(int k, uint8 shift) {
|
|
static const uint8 kGarnishSparkle_Char[4] = {0x83, 0xc7, 0x80, 0xb7};
|
|
uint8 t = garnish_countdown[k] >> shift;
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(oam, pt.x, pt.y, kGarnishSparkle_Char[t],
|
|
(sprite_oam_flags[j] | sprite_obj_prio[j]) & 0xf0 | 4, 0);
|
|
}
|
|
|
|
void Garnish_DustCommon(int k, uint8 shift) {
|
|
static const uint8 kRunningManDust_Char[3] = {0xdf, 0xcf, 0xa9};
|
|
tmp_counter = garnish_countdown[k] >> shift;
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
SetOamPlain(oam, pt.x, pt.y, kRunningManDust_Char[tmp_counter], 0x24, 0);
|
|
}
|
|
|
|
void SpriteModule_Explode(int k) {
|
|
static const DrawMultipleData kSpriteExplode_Dmd[32] = {
|
|
{ 0, 0, 0x0060, 2},
|
|
{ 0, 0, 0x0060, 2},
|
|
{ 0, 0, 0x0060, 2},
|
|
{ 0, 0, 0x0060, 2},
|
|
{-5, -5, 0x0062, 2},
|
|
{ 5, -5, 0x4062, 2},
|
|
{-5, 5, 0x8062, 2},
|
|
{ 5, 5, 0xc062, 2},
|
|
{-8, -8, 0x0062, 2},
|
|
{ 8, -8, 0x4062, 2},
|
|
{-8, 8, 0x8062, 2},
|
|
{ 8, 8, 0xc062, 2},
|
|
{-8, -8, 0x0064, 2},
|
|
{ 8, -8, 0x4064, 2},
|
|
{-8, 8, 0x8064, 2},
|
|
{ 8, 8, 0xc064, 2},
|
|
{-8, -8, 0x0066, 2},
|
|
{ 8, -8, 0x4066, 2},
|
|
{-8, 8, 0x8066, 2},
|
|
{ 8, 8, 0xc066, 2},
|
|
{-8, -8, 0x0068, 2},
|
|
{ 8, -8, 0x0068, 2},
|
|
{-8, 8, 0x0068, 2},
|
|
{ 8, 8, 0x0068, 2},
|
|
{-8, -8, 0x006a, 2},
|
|
{ 8, -8, 0x406a, 2},
|
|
{-8, 8, 0x806a, 2},
|
|
{ 8, 8, 0xc06a, 2},
|
|
{-8, -8, 0x004e, 2},
|
|
{ 8, -8, 0x404e, 2},
|
|
{-8, 8, 0x804e, 2},
|
|
{ 8, 8, 0xc04e, 2},
|
|
};
|
|
|
|
if (sprite_A[k]) {
|
|
if (!sprite_delay_main[k]) {
|
|
sprite_state[k] = 0;
|
|
for (int j = 15; j >= 0; j--) {
|
|
if (sprite_state[j] == 4)
|
|
return;
|
|
}
|
|
load_chr_halfslot_even_odd = 1;
|
|
if (!Sprite_CheckIfScreenIsClear())
|
|
flag_block_link_menu = 0;
|
|
} else {
|
|
Sprite_DrawMultiple(k, &kSpriteExplode_Dmd[((sprite_delay_main[k] >> 2) ^ 7) * 4], 4, NULL);
|
|
}
|
|
return;
|
|
}
|
|
sprite_floor[k] = 2;
|
|
|
|
if (sprite_delay_main[k] == 32) {
|
|
sprite_state[k] = 0;
|
|
flag_is_link_immobilized = 0;
|
|
if (player_near_pit_state != 2 && Sprite_CheckIfScreenIsClear()) {
|
|
if (sprite_type[k] >= 0xd6) {
|
|
music_control = 0x13;
|
|
} else if (sprite_type[k] == 0x7a) {
|
|
PrepareDungeonExitFromBossFight();
|
|
} else {
|
|
SpriteExplode_SpawnEA(k);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sprite_delay_main[k] >= 64 && (sprite_delay_main[k] >= 0x70 || !(sprite_delay_main[k] & 1)))
|
|
SpriteActive_Main(k);
|
|
|
|
uint8 type = sprite_type[k];
|
|
if (sprite_delay_main[k] >= 0xc0)
|
|
return;
|
|
if ((sprite_delay_main[k] & 3) == 0)
|
|
SpriteSfx_QueueSfx2WithPan(k, 0xc);
|
|
if (sprite_delay_main[k] & ((type == 0x92) ? 3 : 7))
|
|
return;
|
|
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamically(k, 0x1c, &info);
|
|
if (j >= 0) {
|
|
static const int8 kSpriteExplode_RandomXY[16] = {0, 4, 8, 12, -4, -8, -12, 0, 0, 8, 16, 24, -24, -16, -8, 0};
|
|
load_chr_halfslot_even_odd = 11;
|
|
sprite_state[j] = 4;
|
|
sprite_flags2[j] = 3;
|
|
sprite_oam_flags[j] = 0xc;
|
|
int xoff = kSpriteExplode_RandomXY[(GetRandomNumber() & 7) | ((type == 0x92) ? 8 : 0)];
|
|
int yoff = kSpriteExplode_RandomXY[(GetRandomNumber() & 7) | ((type == 0x92) ? 8 : 0)];
|
|
Sprite_SetX(j, info.r0_x + xoff);
|
|
Sprite_SetY(j, info.r2_y + yoff - info.r4_z);
|
|
sprite_delay_main[j] = 31;
|
|
sprite_A[j] = 31;
|
|
}
|
|
// endif_1
|
|
}
|
|
|
|
void SpriteDeath_MainEx(int k, bool second_entry) {
|
|
if (!second_entry) {
|
|
uint8 type = sprite_type[k];
|
|
if (type == 0xec) {
|
|
ThrowableScenery_ScatterIntoDebris(k);
|
|
return;
|
|
}
|
|
if (type == 0x53 || type == 0x54 || type == 0x92 || type == 0x4a && sprite_C[k] >= 2) {
|
|
SpriteActive_Main(k);
|
|
return;
|
|
}
|
|
if (sprite_delay_main[k] == 0) {
|
|
Sprite_DoTheDeath(k);
|
|
return;
|
|
}
|
|
}
|
|
if (sign8(sprite_flags3[k])) {
|
|
SpriteActive_Main(k);
|
|
return;
|
|
}
|
|
if (!((frame_counter & 3) | submodule_index | flag_unk1))
|
|
sprite_delay_main[k]++;
|
|
SpriteDeath_DrawPoof(k);
|
|
|
|
if (sprite_type[k] != 0x40 && sprite_delay_main[k] < 10)
|
|
return;
|
|
oam_cur_ptr += 16;
|
|
oam_ext_cur_ptr += 4;
|
|
uint8 bak = sprite_flags2[k];
|
|
sprite_flags2[k] -= 4;
|
|
SpriteActive_Main(k);
|
|
sprite_flags2[k] = bak;
|
|
}
|
|
|
|
void SpriteModule_Burn(int k) {
|
|
static const uint8 kFlame_Gfx[32] = {
|
|
5, 4, 3, 1, 2, 0, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0,
|
|
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0,
|
|
};
|
|
sprite_hit_timer[k] = 0;
|
|
int j = sprite_delay_main[k] - 1;
|
|
if (j == 0) {
|
|
Sprite_DoTheDeath(k);
|
|
return;
|
|
}
|
|
uint8 bak = sprite_graphics[k];
|
|
uint8 bak1 = sprite_oam_flags[k];
|
|
sprite_graphics[k] = kFlame_Gfx[j >> 3];
|
|
sprite_oam_flags[k] = 3;
|
|
Flame_Draw(k);
|
|
sprite_oam_flags[k] = bak1;
|
|
sprite_graphics[k] = bak;
|
|
|
|
oam_cur_ptr += 8;
|
|
oam_ext_cur_ptr += 2;
|
|
if (sprite_delay_main[k] >= 0x10) {
|
|
uint8 bak = sprite_flags2[k];
|
|
sprite_flags2[k] -= 2;
|
|
SpriteActive_Main(k);
|
|
sprite_flags2[k] = bak;
|
|
}
|
|
}
|
|
|
|
void Sprite_HitTimer31(int k) {
|
|
if (sprite_type[k] != 0x7a || is_in_dark_world)
|
|
return;
|
|
if (sprite_health[k] <= sprite_give_damage[k]) {
|
|
dialogue_message_index = 0x140;
|
|
Sprite_ShowMessageMinimal();
|
|
}
|
|
}
|
|
|
|
void SpriteStunned_MainEx(int k, bool second_entry) {
|
|
if (second_entry)
|
|
goto ThrownSprite_TileAndSpriteInteraction;
|
|
Sprite_DrawRippleIfInWater(k);
|
|
SpriteStunned_Main_Func1(k);
|
|
if (Sprite_ReturnIfPaused(k))
|
|
return;
|
|
if (sprite_F[k]) {
|
|
if (sign8(sprite_F[k]))
|
|
sprite_F[k] = 0;
|
|
sprite_x_vel[k] = sprite_y_vel[k] = 0;
|
|
}
|
|
if (sprite_delay_main[k] < 0x20)
|
|
Sprite_CheckDamageFromLink(k);
|
|
if (Sprite_ReturnIfRecoiling(k))
|
|
return;
|
|
Sprite_MoveXY(k);
|
|
if (!sprite_E[k]) {
|
|
Sprite_CheckTileCollision(k);
|
|
if (!sprite_state[k])
|
|
return;
|
|
ThrownSprite_TileAndSpriteInteraction:
|
|
if (sprite_wallcoll[k] & 0xf) {
|
|
Sprite_ApplyRicochet(k);
|
|
if (sprite_state[k] == 11)
|
|
SpriteSfx_QueueSfx2WithPan(k, 5);
|
|
}
|
|
}
|
|
Sprite_CheckTileProperty(k, 0x68);
|
|
|
|
if (kSpriteInit_Flags3[sprite_type[k]] & 0x10) {
|
|
sprite_flags3[k] |= 0x10;
|
|
if (sprite_tiletype == 32)
|
|
sprite_flags3[k] &= ~0x10;
|
|
}
|
|
Sprite_MoveZ(k);
|
|
sprite_z_vel[k] -= 2;
|
|
uint8 z = sprite_z[k] - 1;
|
|
if (z >= 0xf0) {
|
|
sprite_z[k] = 0;
|
|
if (sprite_type[k] == 0xe8 && sign8(sprite_z_vel[k] - 0xe8)) {
|
|
sprite_state[k] = 6;
|
|
sprite_delay_main[k] = 8;
|
|
sprite_flags2[k] = 3;
|
|
return;
|
|
}
|
|
ThrowableScenery_TransmuteIfValid(k);
|
|
uint8 a = sprite_tiletype;
|
|
if (sprite_tiletype == 32 && !(a = sprite_flags[k] >> 1, sprite_flags[k] & 1)) { // wtf
|
|
Sprite_Func8(k);
|
|
return;
|
|
}
|
|
if (a == 9) {
|
|
z = sprite_z_vel[k];
|
|
sprite_z_vel[k] = 0;
|
|
int j;
|
|
SpriteSpawnInfo info;
|
|
|
|
if (sign8(z - 0xf0) && (j = Sprite_SpawnDynamically(k, 0xec, &info)) >= 0) {
|
|
Sprite_SetSpawnedCoordinates(j, &info);
|
|
Sprite_Func22(j);
|
|
}
|
|
} else if (a == 8) {
|
|
if (sprite_type[k] == 0xd2 || (GetRandomNumber() & 1))
|
|
Sprite_SpawnLeapingFish(k);
|
|
Sprite_Func22(k);
|
|
return;
|
|
}
|
|
z = sprite_z_vel[k];
|
|
if (sign8(z)) {
|
|
z = (uint8)(-z) >> 1;
|
|
sprite_z_vel[k] = z < 9 ? 0 : z;
|
|
}
|
|
sprite_x_vel[k] = (int8)sprite_x_vel[k] >> 1;
|
|
if (sprite_x_vel[k] == 255)
|
|
sprite_x_vel[k] = 0;
|
|
sprite_y_vel[k] = (int8)sprite_y_vel[k] >> 1;
|
|
if (sprite_y_vel[k] == 255)
|
|
sprite_y_vel[k] = 0;
|
|
}
|
|
if (sprite_state[k] != 11 || sprite_unk5[k] != 0) {
|
|
if (Sprite_ReturnIfLifted(k))
|
|
return;
|
|
if (sprite_type[k] != 0x4a)
|
|
ThrownSprite_CheckDamageToSprites(k);
|
|
}
|
|
}
|
|
|
|
int Ancilla_SpawnFallingPrize(uint8 item) { // 85a51d
|
|
return AncillaAdd_FallingPrize(0x29, item, 4);
|
|
}
|
|
|
|
bool Sprite_CheckDamageToAndFromLink(int k) { // 85ab93
|
|
Sprite_CheckDamageFromLink(k);
|
|
return Sprite_CheckDamageToLink(k);
|
|
}
|
|
|
|
uint8 Sprite_CheckTileCollision(int k) { // 85b88d
|
|
Sprite_CheckTileCollision2(k);
|
|
return sprite_wallcoll[k];
|
|
}
|
|
|
|
bool Sprite_TrackBodyToHead(int k) { // 85dca2
|
|
if (sprite_head_dir[k] != sprite_D[k]) {
|
|
if (frame_counter & 0x1f)
|
|
return false;
|
|
if (!((sprite_head_dir[k] ^ sprite_D[k]) & 2)) {
|
|
sprite_D[k] = (((k ^ frame_counter) >> 5 | 2) & 3) ^ (sprite_head_dir[k] & 2);
|
|
return false;
|
|
}
|
|
}
|
|
sprite_D[k] = sprite_head_dir[k];
|
|
return true;
|
|
}
|
|
|
|
void Sprite_DrawMultiple(int k, const DrawMultipleData *src, int n, PrepOamCoordsRet *info) { // 85df6c
|
|
PrepOamCoordsRet info_buf;
|
|
if (!info)
|
|
info = &info_buf;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, info))
|
|
return;
|
|
word_7E0CFE = 0;
|
|
uint8 a = sprite_state[k];
|
|
if (a == 10)
|
|
a = sprite_unk4[k];
|
|
if (a == 11)
|
|
BYTE(word_7E0CFE) = sprite_unk5[k];
|
|
OamEnt *oam = GetOamCurPtr();
|
|
do {
|
|
uint16 d = src->char_flags ^ WORD(info->r4);
|
|
if (word_7E0CFE >= 1)
|
|
d = d & ~0xE00 | 0x400;
|
|
SetOamHelper0(oam, src->x + info->x, src->y + info->y, d, d >> 8, src->ext);
|
|
|
|
} while (src++, oam++, --n);
|
|
}
|
|
|
|
void Sprite_DrawMultiplePlayerDeferred(int k, const DrawMultipleData *src, int n, PrepOamCoordsRet *info) { // 85df75
|
|
Oam_AllocateDeferToPlayer(k);
|
|
Sprite_DrawMultiple(k, src, n, info);
|
|
}
|
|
|
|
int Sprite_ShowSolicitedMessage(int k, uint16 msg) { // 85e1a7
|
|
static const uint8 kShowMessageFacing_Tab0[4] = {4, 6, 0, 2};
|
|
dialogue_message_index = msg;
|
|
if (!Sprite_CheckDamageToLink_same_layer(k) ||
|
|
Sprite_CheckIfLinkIsBusy() ||
|
|
!(filtered_joypad_L & 0x80) ||
|
|
sprite_delay_aux4[k] || link_auxiliary_state == 2)
|
|
return sprite_D[k];
|
|
uint8 dir = Sprite_DirectionToFaceLink(k, NULL);
|
|
if (link_direction_facing != kShowMessageFacing_Tab0[dir])
|
|
return sprite_D[k];
|
|
Sprite_ShowMessageUnconditional(dialogue_message_index);
|
|
sprite_delay_aux4[k] = 64;
|
|
return dir ^ 0x103;
|
|
}
|
|
|
|
int Sprite_ShowMessageOnContact(int k, uint16 msg) { // 85e1f0
|
|
dialogue_message_index = msg;
|
|
if (!Sprite_CheckDamageToLink_same_layer(k) || link_auxiliary_state == 2)
|
|
return sprite_D[k];
|
|
Sprite_ShowMessageUnconditional(dialogue_message_index);
|
|
return Sprite_DirectionToFaceLink(k, NULL) ^ 0x103;
|
|
}
|
|
|
|
void Sprite_ShowMessageUnconditional(uint16 msg) { // 85e219
|
|
dialogue_message_index = msg;
|
|
byte_7E0223 = 0;
|
|
messaging_module = 0;
|
|
submodule_index = 2;
|
|
saved_module_for_menu = main_module_index;
|
|
main_module_index = 14;
|
|
Sprite_NullifyHookshotDrag();
|
|
link_speed_setting = 0;
|
|
Link_CancelDash();
|
|
link_auxiliary_state = 0;
|
|
link_incapacitated_timer = 0;
|
|
if (link_player_handler_state == kPlayerState_RecoilWall)
|
|
link_player_handler_state = kPlayerState_Ground;
|
|
}
|
|
|
|
bool Sprite_TutorialGuard_ShowMessageOnContact(int k, uint16 msg) { // 85fa59
|
|
dialogue_message_index = msg;
|
|
uint8 bak2 = sprite_flags2[k];
|
|
uint8 bak4 = sprite_flags4[k];
|
|
sprite_flags2[k] = 0x80;
|
|
sprite_flags4[k] = 0x07;
|
|
bool rv = Sprite_CheckDamageToLink_same_layer(k);
|
|
sprite_flags2[k] = bak2;
|
|
sprite_flags4[k] = bak4;
|
|
if (!rv)
|
|
return rv;
|
|
Sprite_NullifyHookshotDrag();
|
|
link_is_running = 0;
|
|
link_speed_setting = 0;
|
|
if (!link_auxiliary_state)
|
|
Sprite_ShowMessageMinimal();
|
|
return rv;
|
|
}
|
|
|
|
void Sprite_ShowMessageMinimal() { // 85fa8e
|
|
byte_7E0223 = 0;
|
|
messaging_module = 0;
|
|
submodule_index = 2;
|
|
saved_module_for_menu = main_module_index;
|
|
main_module_index = 14;
|
|
}
|
|
|
|
void Prepare_ApplyRumbleToSprites() { // 8680fa
|
|
static const int8 kApplyRumble_X[4] = { -32, -32, -32, 16 };
|
|
static const int8 kApplyRumble_Y[4] = { -32, 32, -24, -24 };
|
|
static const uint8 kApplyRumble_WH[6] = { 0x50, 0x50, 0x20, 0x20, 0x50, 0x50 };
|
|
int j = link_direction_facing >> 1;
|
|
SpriteHitBox hb;
|
|
uint16 x = link_x_coord + kApplyRumble_X[j];
|
|
uint16 y = link_y_coord + kApplyRumble_Y[j];
|
|
hb.r0_xlo = x;
|
|
hb.r8_xhi = x >> 8;
|
|
hb.r1_ylo = y;
|
|
hb.r9_yhi = y >> 8;
|
|
hb.r2 = kApplyRumble_WH[j];
|
|
hb.r3 = kApplyRumble_WH[j + 2];
|
|
Entity_ApplyRumbleToSprites(&hb);
|
|
}
|
|
|
|
void Sprite_SpawnImmediatelySmashedTerrain(uint8 what, uint16 x, uint16 y) { // 86812d
|
|
uint8 bak1 = flag_is_sprite_to_pick_up;
|
|
uint8 bak2 = byte_7E0FB2;
|
|
int k = Sprite_SpawnThrowableTerrain_silently(what, x, y);
|
|
if (k >= 0)
|
|
ThrowableScenery_TransmuteToDebris(k);
|
|
byte_7E0FB2 = bak2;
|
|
flag_is_sprite_to_pick_up = bak1;
|
|
}
|
|
|
|
void Sprite_SpawnThrowableTerrain(uint8 what, uint16 x, uint16 y) { // 86814b
|
|
sound_effect_1 = Link_CalculateSfxPan() | 29;
|
|
Sprite_SpawnThrowableTerrain_silently(what, x, y);
|
|
}
|
|
|
|
int Sprite_SpawnThrowableTerrain_silently(uint8 what, uint16 x, uint16 y) { // 868156
|
|
int k = 15;
|
|
for (; k >= 0 && sprite_state[k] != 0; k--);
|
|
if (k < 0)
|
|
return k;
|
|
sprite_state[k] = 10;
|
|
sprite_type[k] = 0xEC;
|
|
Sprite_SetX(k, x);
|
|
Sprite_SetY(k, y);
|
|
SpritePrep_LoadProperties(k);
|
|
sprite_floor[k] = link_is_on_lower_level;
|
|
sprite_C[k] = what;
|
|
if (what >= 6)
|
|
sprite_flags2[k] = 0xa6;
|
|
// oob read, this array has only 6 elements.
|
|
uint8 flags = kThrowableScenery_Flags[what];
|
|
if (what == 2) {
|
|
if (player_is_indoors)
|
|
sprite_oam_flags[k] = 0x80, flags = 0x50; // wtf
|
|
}
|
|
sprite_oam_flags[k] = flags;
|
|
sprite_unk4[k] = 9;
|
|
flag_is_sprite_to_pick_up = 2;
|
|
byte_7E0FB2 = 2;
|
|
sprite_delay_main[k] = 16;
|
|
sprite_floor[k] = link_is_on_lower_level;
|
|
sprite_graphics[k] = 0;
|
|
if (BYTE(dung_secrets_unk1) != 255) {
|
|
if (!(BYTE(dung_secrets_unk1) | player_is_indoors) && (uint8)(sprite_C[k] - 2) < 2)
|
|
Overworld_SubstituteAlternateSecret();
|
|
if (dung_secrets_unk1 & 0x80) {
|
|
sprite_graphics[k] = dung_secrets_unk1 & 0x7f;
|
|
BYTE(dung_secrets_unk1) = 0;
|
|
}
|
|
Sprite_SpawnSecret(k);
|
|
}
|
|
return k;
|
|
}
|
|
|
|
void Sprite_SpawnSecret(int k) { // 868264
|
|
if (!player_is_indoors && (GetRandomNumber() & 8))
|
|
return;
|
|
int b = BYTE(dung_secrets_unk1);
|
|
if (b == 0)
|
|
return;
|
|
if (b == 4)
|
|
b = 19 + (GetRandomNumber() & 3);
|
|
if (!kSpawnSecretItems[b - 1])
|
|
return;
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamically(k, kSpawnSecretItems[b - 1], &info);
|
|
if (j < 0)
|
|
return;
|
|
sprite_ai_state[j] = kSpawnSecretItem_SpawnFlag[b - 1];
|
|
sprite_ignore_projectile[j] = kSpawnSecretItem_IgnoreProj[b - 1];
|
|
sprite_z_vel[j] = kSpawnSecretItem_ZVel[b - 1];
|
|
Sprite_SetX(j, info.r0_x + kSpawnSecretItem_XLo[b - 1]);
|
|
Sprite_SetY(j, info.r2_y);
|
|
sprite_z[j] = info.r4_z;
|
|
sprite_graphics[j] = 0;
|
|
sprite_delay_aux4[j] = 32;
|
|
sprite_delay_aux2[j] = 48;
|
|
uint8 type = sprite_type[j];
|
|
if (type == 0xe4) {
|
|
SpritePrep_SmallKey(j);
|
|
sprite_stunned[j] = 255;
|
|
} else if (type == 0xb) {
|
|
sound_effect_1 = 0x30;
|
|
if (BYTE(dungeon_room_index2) == 1)
|
|
sprite_subtype[j] = 1;
|
|
sprite_stunned[j] = 255;
|
|
} else if (type == 0x41 || type == 0x42) {
|
|
sound_effect_2 = 4;
|
|
sprite_give_damage[j] = 0;
|
|
sprite_hit_timer[j] = 160;
|
|
} else if (type == 0x3e) {
|
|
sprite_oam_flags[j] = 9;
|
|
} else {
|
|
sprite_stunned[j] = 255;
|
|
if (type == 0x79)
|
|
sprite_A[j] = 32;
|
|
}
|
|
}
|
|
|
|
void Sprite_Main() { // 868328
|
|
if (!player_is_indoors) {
|
|
ancilla_floor[0] = 0;
|
|
ancilla_floor[1] = 0;
|
|
ancilla_floor[2] = 0;
|
|
ancilla_floor[3] = 0;
|
|
ancilla_floor[4] = 0;
|
|
Sprite_ProximityActivation();
|
|
}
|
|
is_in_dark_world = (savegame_is_darkworld != 0);
|
|
if (submodule_index == 0)
|
|
drag_player_x = drag_player_y = 0;
|
|
Oam_ResetRegionBases();
|
|
Garnish_ExecuteUpperSlots();
|
|
Follower_Main();
|
|
byte_7E0FB2 = flag_is_sprite_to_pick_up;
|
|
flag_is_sprite_to_pick_up = 0;
|
|
HIBYTE(dungmap_var8) = 0x80;
|
|
|
|
if (set_when_damaging_enemies & 0x7f)
|
|
set_when_damaging_enemies--;
|
|
else
|
|
set_when_damaging_enemies = 0;
|
|
byte_7E0379 = 0;
|
|
link_unk_master_sword = 0;
|
|
link_prevent_from_moving = 0;
|
|
if (sprite_alert_flag)
|
|
sprite_alert_flag--;
|
|
Ancilla_Main();
|
|
Overlord_Main();
|
|
archery_game_out_of_arrows = 0;
|
|
for (int i = 15; i >= 0; i--) {
|
|
cur_object_index = i;
|
|
Sprite_ExecuteSingle(i);
|
|
}
|
|
Garnish_ExecuteLowerSlots();
|
|
byte_7E069E[0] = byte_7E069E[1] = 0;
|
|
ExecuteCachedSprites();
|
|
if (load_chr_halfslot_even_odd)
|
|
byte_7E0FC6 = load_chr_halfslot_even_odd;
|
|
}
|
|
|
|
void Oam_ResetRegionBases() { // 8683d3
|
|
memcpy(oam_region_base, kOam_ResetRegionBases, 12);
|
|
}
|
|
|
|
void Sprite_TimersAndOam(int k) { // 8683f2
|
|
Sprite_Get16BitCoords(k);
|
|
|
|
uint8 num = ((sprite_flags2[k] & 0x1f) + 1) * 4;
|
|
|
|
if (sort_sprites_setting) {
|
|
if (sprite_floor[k])
|
|
Oam_AllocateFromRegionF(num);
|
|
else
|
|
Oam_AllocateFromRegionD(num);
|
|
} else {
|
|
Oam_AllocateFromRegionA(num);
|
|
}
|
|
|
|
if (!(submodule_index | flag_unk1)) {
|
|
if (sprite_delay_main[k])
|
|
sprite_delay_main[k]--;
|
|
if (sprite_delay_aux1[k])
|
|
sprite_delay_aux1[k]--;
|
|
if (sprite_delay_aux2[k])
|
|
sprite_delay_aux2[k]--;
|
|
if (sprite_delay_aux3[k])
|
|
sprite_delay_aux3[k]--;
|
|
|
|
uint8 timer = sprite_hit_timer[k] & 0x7f;
|
|
if (timer) {
|
|
if (sprite_state[k] >= 9) {
|
|
if (timer == 31) {
|
|
Sprite_HitTimer31(k);
|
|
} else if (timer == 24) {
|
|
Sprite_MiniMoldorm_Recoil(k);
|
|
}
|
|
}
|
|
if (sprite_give_damage[k] < 251)
|
|
sprite_obj_prio[k] = sprite_hit_timer[k] * 2 & 0xe;
|
|
sprite_hit_timer[k]--;
|
|
} else {
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_obj_prio[k] = 0;
|
|
}
|
|
if (sprite_delay_aux4[k])
|
|
sprite_delay_aux4[k]--;
|
|
}
|
|
|
|
static const uint8 kSpritePrios[4] = {0x20, 0x10, 0x30, 0x30};
|
|
int floor = link_is_on_lower_level;
|
|
if (floor != 3)
|
|
floor = sprite_floor[k];
|
|
sprite_obj_prio[k] = sprite_obj_prio[k] & 0xcf | kSpritePrios[floor];
|
|
}
|
|
|
|
void Sprite_Get16BitCoords(int k) { // 8684c1
|
|
cur_sprite_x = sprite_x_lo[k] | sprite_x_hi[k] << 8;
|
|
cur_sprite_y = sprite_y_lo[k] | sprite_y_hi[k] << 8;
|
|
}
|
|
|
|
void Sprite_ExecuteSingle(int k) { // 8684e2
|
|
uint8 st = sprite_state[k];
|
|
if (st != 0)
|
|
Sprite_TimersAndOam(k);
|
|
kSprite_ExecuteSingle[st](k);
|
|
}
|
|
|
|
void Sprite_inactiveSprite(int k) { // 868510
|
|
if (!player_is_indoors) {
|
|
sprite_N_word[k] = 0xffff;
|
|
} else {
|
|
sprite_N[k] = 0xff;
|
|
}
|
|
}
|
|
|
|
void SpriteModule_Fall1(int k) { // 86852e
|
|
if (!sprite_delay_main[k]) {
|
|
sprite_state[k] = 0;
|
|
Sprite_ManuallySetDeathFlagUW(k);
|
|
} else {
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
SpriteFall_Draw(k, &info);
|
|
}
|
|
}
|
|
|
|
void SpriteModule_Drown(int k) { // 86859c
|
|
static const DrawMultipleData kSpriteDrown_Dmd[8] = {
|
|
{-7, -7, 0x0480, 0},
|
|
{14, -6, 0x0483, 0},
|
|
{-6, -6, 0x04cf, 0},
|
|
{13, -5, 0x04df, 0},
|
|
{-4, -4, 0x04ae, 0},
|
|
{12, -4, 0x44af, 0},
|
|
{ 0, 0, 0x04e7, 2},
|
|
{ 0, 0, 0x04e7, 2},
|
|
};
|
|
static const uint8 kSpriteDrown_Oam_Flags[4] = {0, 0x40, 0xc0, 0x80};
|
|
static const uint8 kSpriteDrown_Oam_Char[11] = {0xc0, 0xc0, 0xc0, 0xc0, 0xcd, 0xcd, 0xcd, 0xcb, 0xcb, 0xcb, 0xcb};
|
|
|
|
if (sprite_ai_state[k]) {
|
|
if (sprite_A[k] == 6)
|
|
Oam_AllocateFromRegionC(8);
|
|
sprite_flags3[k] ^= 16;
|
|
SpriteDraw_SingleLarge(k);
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int j = sprite_delay_main[k];
|
|
if (j == 1)
|
|
sprite_state[k] = 0;
|
|
if (j != 0) {
|
|
assert((j >> 1) < 11);
|
|
oam->charnum = kSpriteDrown_Oam_Char[j >> 1];
|
|
oam->flags = 0x24;
|
|
return;
|
|
}
|
|
oam->charnum = 0x8a;
|
|
oam->flags = kSpriteDrown_Oam_Flags[sprite_subtype2[k] >> 2 & 3] | 0x24;
|
|
|
|
if (Sprite_ReturnIfPaused(k))
|
|
return;
|
|
sprite_subtype2[k]++;
|
|
Sprite_MoveXY(k);
|
|
Sprite_MoveZ(k);
|
|
sprite_z_vel[k] -= 2;
|
|
if (sign8(sprite_z[k])) {
|
|
sprite_z[k] = 0;
|
|
sprite_delay_main[k] = 18;
|
|
sprite_flags3[k] &= ~0x10;
|
|
}
|
|
} else {
|
|
if (Sprite_ReturnIfPaused(k))
|
|
return;
|
|
if (!(frame_counter & 1))
|
|
sprite_delay_main[k]++;
|
|
sprite_oam_flags[k] = 0;
|
|
sprite_hit_timer[k] = 0;
|
|
if (!sprite_delay_main[k])
|
|
sprite_state[k] = 0;
|
|
Sprite_DrawMultiple(k, &kSpriteDrown_Dmd[(sprite_delay_main[k] << 1 & 0xf8) >> 2], 2, NULL);
|
|
}
|
|
}
|
|
|
|
void Sprite_DrawDistress_custom(uint16 xin, uint16 yin, uint8 time) { // 86a733
|
|
Oam_AllocateFromRegionA(0x10);
|
|
if (!(time & 0x18))
|
|
return;
|
|
int i = 3;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
do {
|
|
SetOamHelper0(oam, xin + kSpriteDistress_X[i], yin + kSpriteDistress_Y[i],
|
|
0x83, 0x22, 0);
|
|
} while (oam++, --i >= 0);
|
|
}
|
|
|
|
void Sprite_CheckIfLifted_permissive(int k) { // 86aa0c
|
|
Sprite_ReturnIfLiftedPermissive(k);
|
|
}
|
|
|
|
void Entity_ApplyRumbleToSprites(SpriteHitBox *hb) { // 86ad03
|
|
for (int j = 15; j >= 0; j--) {
|
|
if (!(sprite_defl_bits[j] & 2) || sprite_E[j] == 0)
|
|
continue;
|
|
if (byte_7E0FC6 != 0xe) {
|
|
Sprite_SetupHitBox(j, hb);
|
|
if (!CheckIfHitBoxesOverlap(hb))
|
|
continue;
|
|
}
|
|
sprite_E[j] = 0;
|
|
sound_effect_2 = 0x30;
|
|
sprite_z_vel[j] = 0x30;
|
|
sprite_x_vel[j] = 0x10;
|
|
sprite_delay_aux3[j] = 0x30;
|
|
sprite_stunned[j] = 255;
|
|
if (sprite_type[j] == 0xd8)
|
|
Sprite_TransmuteToBomb(j);
|
|
}
|
|
}
|
|
|
|
void Sprite_ZeroVelocity_XY(int k) { // 86cf5d
|
|
sprite_x_vel[k] = sprite_y_vel[k] = 0;
|
|
}
|
|
|
|
bool Sprite_HandleDraggingByAncilla(int k) { // 86cf64
|
|
int j = sprite_B[k];
|
|
if (j-- == 0)
|
|
return false;
|
|
if (ancilla_type[j] == 0) {
|
|
Sprite_HandleAbsorptionByPlayer(k);
|
|
} else {
|
|
sprite_x_lo[k] = ancilla_x_lo[j];
|
|
sprite_x_hi[k] = ancilla_x_hi[j];
|
|
sprite_y_lo[k] = ancilla_y_lo[j];
|
|
sprite_y_hi[k] = ancilla_y_hi[j];
|
|
sprite_z[k] = 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Sprite_ReturnIfPhasingOut(int k) { // 86d0ed
|
|
if (!sprite_stunned[k] || (submodule_index | flag_unk1))
|
|
return false;
|
|
if (!(frame_counter & 1))
|
|
sprite_stunned[k]--;
|
|
uint8 a = sprite_stunned[k];
|
|
if (a == 0)
|
|
sprite_state[k] = 0;
|
|
else if (a >= 0x28 || (a & 1) != 0)
|
|
return false;
|
|
PrepOamCoordsRet info;
|
|
Sprite_PrepOamCoordOrDoubleRet(k, &info);
|
|
return true;
|
|
}
|
|
|
|
void Sprite_CheckAbsorptionByPlayer(int k) { // 86d116
|
|
if (!sprite_delay_aux4[k] && Sprite_CheckDamageToPlayer_1(k))
|
|
Sprite_HandleAbsorptionByPlayer(k);
|
|
}
|
|
|
|
void Sprite_HandleAbsorptionByPlayer(int k) { // 86d13c
|
|
sprite_state[k] = 0;
|
|
int t = sprite_type[k] - 0xd8;
|
|
SpriteSfx_QueueSfx3WithPan(k, kAbsorptionSfx[t]);
|
|
switch(t) {
|
|
case 0:
|
|
link_hearts_filler += 8;
|
|
break;
|
|
case 1: case 2: case 3:
|
|
link_rupees_goal += kRupeesAbsorption[t - 1];
|
|
break;
|
|
case 4: case 5: case 6:
|
|
link_bomb_filler += kBombsAbsorption[t - 4];
|
|
break;
|
|
case 7:
|
|
link_magic_filler += 0x10;
|
|
break;
|
|
case 8:
|
|
link_magic_filler = 0x80;
|
|
break;
|
|
case 9:
|
|
link_arrow_filler += (sprite_head_dir[k] == 0) ? 5 : sprite_head_dir[k];
|
|
break;
|
|
case 10:
|
|
link_arrow_filler += 10;
|
|
break;
|
|
case 11:
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x31);
|
|
link_hearts_filler += 56;
|
|
break;
|
|
case 12:
|
|
link_num_keys += 1;
|
|
goto after_getkey;
|
|
case 13:
|
|
item_receipt_method = 0;
|
|
Link_ReceiveItem(0x32, 0);
|
|
after_getkey:
|
|
sprite_N[k] = sprite_subtype[k];
|
|
dung_savegame_state_bits |= kAbsorbBigKey[sprite_die_action[k]] << 8;
|
|
Sprite_ManuallySetDeathFlagUW(k);
|
|
break;
|
|
case 14:
|
|
link_shield_type = sprite_subtype[k];
|
|
// Shield needs to have the right palette after pikit
|
|
if (enhanced_features0 & kFeatures0_MiscBugFixes)
|
|
Palette_Load_Shield();
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool SpriteDraw_AbsorbableTransient(int k, bool transient) { // 86d22f
|
|
if (transient && Sprite_ReturnIfPhasingOut(k))
|
|
return false;
|
|
if (sort_sprites_setting == 0 && player_is_indoors != 0)
|
|
sprite_obj_prio[k] = 0x30;
|
|
if (byte_7E0FC6 >= 3)
|
|
return false;
|
|
if (sprite_delay_aux2[k] != 0)
|
|
Oam_AllocateFromRegionC(12);
|
|
if (sprite_E[k] != 0) {
|
|
// This code runs when an absorbable is hidden under say a rock.
|
|
// sprite_B holds the sprite that grabbed us with a hookshot.
|
|
// Cancel the grab if we're hidden.
|
|
if (enhanced_features0 & kFeatures0_MiscBugFixes)
|
|
sprite_B[k] = 0;
|
|
return true;
|
|
}
|
|
uint8 j = sprite_type[k];
|
|
assert(j >= 0xd8 && j < 0xd8 + 19);
|
|
uint8 a = kAbsorbable_Tab2[j - 0xd8];
|
|
if (a != 0) {
|
|
Sprite_DrawNumberedAbsorbable(k, a);
|
|
return false;
|
|
}
|
|
uint8 t = kAbsorbable_Tab1[j - 0xd8];
|
|
if (t == 0) {
|
|
SpriteDraw_SingleSmall(k);
|
|
return false;
|
|
}
|
|
if (t == 2) {
|
|
if (sprite_type[k] == 0xe6) {
|
|
if (sprite_subtype[k] == 1)
|
|
goto draw_key;
|
|
sprite_graphics[k] = 1;
|
|
}
|
|
SpriteDraw_SingleLarge(k);
|
|
return false;
|
|
}
|
|
draw_key:
|
|
Sprite_DrawThinAndTall(k);
|
|
return false;
|
|
}
|
|
|
|
void Sprite_DrawNumberedAbsorbable(int k, int a) { // 86d2fa
|
|
a = (a - 1) * 3;
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int n = (sprite_head_dir[k] < 1) ? 2 : 1;
|
|
do {
|
|
int j = n + a;
|
|
SetOamHelper0(oam,
|
|
info.x + kNumberedAbsorbable_X[j], info.y + kNumberedAbsorbable_Y[j],
|
|
kNumberedAbsorbable_Char[j], info.flags,
|
|
kNumberedAbsorbable_Ext[j]);
|
|
} while (oam++, --n >= 0);
|
|
SpriteDraw_Shadow(k, &info);
|
|
}
|
|
|
|
void Sprite_BounceOffWall(int k) { // 86d9c0
|
|
if (sprite_wallcoll[k] & 3)
|
|
sprite_x_vel[k] = -sprite_x_vel[k];
|
|
if (sprite_wallcoll[k] & 12)
|
|
sprite_y_vel[k] = -sprite_y_vel[k];
|
|
}
|
|
|
|
void Sprite_InvertSpeed_XY(int k) { // 86d9d5
|
|
sprite_x_vel[k] = -sprite_x_vel[k];
|
|
sprite_y_vel[k] = -sprite_y_vel[k];
|
|
}
|
|
|
|
bool Sprite_ReturnIfInactive(int k) { // 86d9ec
|
|
return (sprite_state[k] != 9 || flag_unk1 || submodule_index || !(sprite_defl_bits[k] & 0x80) && sprite_pause[k]);
|
|
}
|
|
|
|
bool Sprite_ReturnIfPaused(int k) { // 86d9f3
|
|
return (flag_unk1 || submodule_index || !(sprite_defl_bits[k] & 0x80) && sprite_pause[k]);
|
|
}
|
|
|
|
void SpriteDraw_SingleLarge(int k) { // 86dc10
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
Sprite_PrepAndDrawSingleLargeNoPrep(k, &info);
|
|
}
|
|
|
|
void Sprite_PrepAndDrawSingleLargeNoPrep(int k, PrepOamCoordsRet *info) { // 86dc13
|
|
OamEnt *oam = GetOamCurPtr();
|
|
oam->x = info->x;
|
|
if ((uint16)(info->y + 0x10) < 0x100) {
|
|
oam->y = info->y;
|
|
oam->charnum = kSprite_PrepAndDrawSingleLarge_Tab2[kSprite_PrepAndDrawSingleLarge_Tab1[sprite_type[k]] + sprite_graphics[k]];
|
|
oam->flags = info->flags;
|
|
}
|
|
bytewise_extended_oam[oam - oam_buf] = 2 | ((info->x >= 256) ? 1: 0);
|
|
if (sprite_flags3[k] & 0x10)
|
|
SpriteDraw_Shadow(k, info);
|
|
}
|
|
|
|
void SpriteDraw_Shadow_custom(int k, PrepOamCoordsRet *info, uint8 a) { // 86dc5c
|
|
uint16 y = Sprite_GetY(k) + a;
|
|
info->y = y;
|
|
if (sprite_pause[k] || sprite_state[k] == 10 && sprite_unk3[k] == 3)
|
|
return;
|
|
y -= BG2VOFS_copy2;
|
|
info->y = y;
|
|
if ((uint16)(y + 0x10) >= 0x100)
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr() + (sprite_flags2[k] & 0x1f);
|
|
if (sprite_flags3[k] & 0x20) {
|
|
SetOamHelper1(oam, info->x, y + 1, 0x38, (info->flags & 0x30) | 8, 0);
|
|
} else {
|
|
SetOamHelper1(oam, info->x, y, 0x6c, (info->flags & 0x30) | 8, 2);
|
|
}
|
|
}
|
|
|
|
void SpriteDraw_Shadow(int k, PrepOamCoordsRet *oam) { // 86dc64
|
|
SpriteDraw_Shadow_custom(k, oam, 10);
|
|
}
|
|
|
|
void SpriteDraw_SingleSmall(int k) { // 86dcef
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
oam->x = info.x;
|
|
if ((uint16)(info.y + 0x10) < 0x100) {
|
|
oam->y = info.y;
|
|
oam->charnum = kSprite_PrepAndDrawSingleLarge_Tab2[kSprite_PrepAndDrawSingleLarge_Tab1[sprite_type[k]] + sprite_graphics[k]];
|
|
oam->flags = info.flags;
|
|
}
|
|
bytewise_extended_oam[oam - oam_buf] = 0 | (info.x >= 256);
|
|
if (sprite_flags3[k] & 0x10)
|
|
SpriteDraw_Shadow_custom(k, &info, 2);
|
|
}
|
|
|
|
void Sprite_DrawThinAndTall(int k) { // 86dd40
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
uint8 a = kSprite_PrepAndDrawSingleLarge_Tab2[kSprite_PrepAndDrawSingleLarge_Tab1[sprite_type[k]] + sprite_graphics[k]];
|
|
SetOamHelper0(oam + 0, info.x, info.y + 0, a + 0x00, info.flags, 0);
|
|
SetOamHelper0(oam + 1, info.x, info.y + 8, a + 0x10, info.flags, 0);
|
|
if (sprite_flags3[k] & 0x10)
|
|
SpriteDraw_Shadow(k, &info);
|
|
}
|
|
|
|
void SpriteModule_Carried(int k) { // 86de83
|
|
|
|
|
|
static const uint8 kSpriteHeld_ZForFrame[6] = {3, 2, 1, 3, 2, 1};
|
|
static const int8 kSpriteHeld_X[16] = {0, 0, 0, 0, 0, 0, 0, 0, -13, -10, -5, 0, 13, 10, 5, 0};
|
|
static const uint8 kSpriteHeld_Z[16] = {13, 14, 15, 16, 0, 10, 22, 16, 8, 11, 14, 16, 8, 11, 14, 16};
|
|
sprite_room[k] = overworld_area_index;
|
|
if (sprite_unk3[k] != 3) {
|
|
if (sprite_delay_main[k] == 0) {
|
|
sprite_delay_main[k] = (sprite_C[k] == 6) ? 8 : 4;
|
|
sprite_unk3[k]++;
|
|
}
|
|
} else {
|
|
sprite_flags3[k] &= ~0x10;
|
|
}
|
|
|
|
uint8 t = sprite_delay_aux4[k] - 1;
|
|
uint8 r0 = t < 63 && (t & 2);
|
|
int j = link_direction_facing * 2 + sprite_unk3[k];
|
|
|
|
int t0 = (uint8)link_x_coord + (uint8)kSpriteHeld_X[j];
|
|
int t1 = (uint8)t0 + (t0 >> 8 & 1) + r0;
|
|
int t2 = HIBYTE(link_x_coord) + (t1 >> 8 & 1) + (t0 >> 8 & 1) + (uint8)(kSpriteHeld_X[j]>>8);
|
|
sprite_x_lo[k] = t1;
|
|
sprite_x_hi[k] = t2;
|
|
|
|
// Sprite_SetX(k, link_x_coord + kSpriteHeld_X[j] + r0);
|
|
sprite_z[k] = kSpriteHeld_Z[j];
|
|
int an = link_animation_steps < 6 ? link_animation_steps : 0;
|
|
uint16 z = link_z_coord + 1 + kSpriteHeld_ZForFrame[an];
|
|
Sprite_SetY(k, link_y_coord + 8 - z);
|
|
sprite_floor[k] = link_is_on_lower_level & 1;
|
|
CarriedSprite_CheckForThrow(k);
|
|
Sprite_Get16BitCoords(k);
|
|
if (sprite_unk4[k] != 11) {
|
|
SpriteActive_Main(k);
|
|
if (sprite_delay_aux4[k] == 1) {
|
|
sprite_state[k] = 9;
|
|
sprite_B[k] = 0;
|
|
sprite_delay_aux4[k] = 96;
|
|
sprite_z_vel[k] = 32;
|
|
sprite_flags3[k] |= 0x10;
|
|
link_picking_throw_state = 2;
|
|
}
|
|
} else {
|
|
SpriteStunned_Main_Func1(k);
|
|
}
|
|
}
|
|
|
|
void CarriedSprite_CheckForThrow(int k) { // 86df6d
|
|
static const int8 kSpriteHeld_Throw_Xvel[4] = {0, 0, -62, 63};
|
|
static const int8 kSpriteHeld_Throw_Yvel[4] = {-62, 63, 0, 0};
|
|
static const uint8 kSpriteHeld_Throw_Zvel[4] = {4, 4, 4, 4};
|
|
|
|
if (main_module_index == 14)
|
|
return;
|
|
|
|
if (player_near_pit_state != 2) {
|
|
uint8 t = (link_auxiliary_state & 1) | link_is_in_deep_water | link_is_bunny_mirror |
|
|
link_pose_for_item | (link_disable_sprite_damage ? 0 : link_incapacitated_timer);
|
|
if (!t) {
|
|
if (sprite_unk3[k] != 3 || !((filtered_joypad_H | filtered_joypad_L) & 0x80))
|
|
return;
|
|
filtered_joypad_L &= 0x7f;
|
|
}
|
|
}
|
|
|
|
SpriteSfx_QueueSfx3WithPan(k, 0x13);
|
|
link_picking_throw_state = 2;
|
|
sprite_state[k] = sprite_unk4[k];
|
|
sprite_z_vel[k] = 0;
|
|
sprite_unk3[k] = 0;
|
|
sprite_flags3[k] = sprite_flags3[k] & ~0x10 | kSpriteInit_Flags3[sprite_type[k]] & 0x10;
|
|
int j = link_direction_facing >> 1;
|
|
sprite_x_vel[k] = kSpriteHeld_Throw_Xvel[j];
|
|
sprite_y_vel[k] = kSpriteHeld_Throw_Yvel[j];
|
|
sprite_z_vel[k] = kSpriteHeld_Throw_Zvel[j];
|
|
sprite_delay_aux4[k] = 0;
|
|
}
|
|
|
|
void SpriteModule_Stunned(int k) { // 86dffa
|
|
SpriteStunned_MainEx(k, false);
|
|
}
|
|
|
|
void ThrownSprite_TileAndSpriteInteraction(int k) { // 86e02a
|
|
SpriteStunned_MainEx(k, true);
|
|
}
|
|
|
|
void Sprite_Func8(int k) { // 86e0ab
|
|
sprite_state[k] = 1;
|
|
sprite_delay_main[k] = 0x1f;
|
|
sound_effect_1 = 0;
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x20);
|
|
}
|
|
|
|
void Sprite_Func22(int k) { // 86e0f6
|
|
sound_effect_1 = Sprite_CalculateSfxPan(k) | 0x28;
|
|
sprite_state[k] = 3;
|
|
sprite_delay_main[k] = 15;
|
|
sprite_ai_state[k] = 0;
|
|
GetRandomNumber(); // wtf
|
|
sprite_flags2[k] = 3;
|
|
}
|
|
|
|
void ThrowableScenery_InteractWithSpritesAndTiles(int k) { // 86e164
|
|
Sprite_MoveXY(k);
|
|
if (!sprite_E[k])
|
|
Sprite_CheckTileCollision(k);
|
|
ThrownSprite_TileAndSpriteInteraction(k);
|
|
}
|
|
|
|
void ThrownSprite_CheckDamageToSprites(int k) { // 86e172
|
|
if (sprite_delay_aux4[k] || !(sprite_x_vel[k] | sprite_y_vel[k]))
|
|
return;
|
|
for (int i = 15; i >= 0; i--) {
|
|
if (i != cur_object_index && sprite_type[k] != 0xd2 && sprite_state[i] >= 9 &&
|
|
((i ^ frame_counter) & 3 | sprite_ignore_projectile[i] | sprite_hit_timer[i]) == 0 && sprite_floor[k] == sprite_floor[i])
|
|
ThrownSprite_CheckDamageToSingleSprite(k, i);
|
|
}
|
|
}
|
|
|
|
void ThrownSprite_CheckDamageToSingleSprite(int k, int j) { // 86e1b2
|
|
SpriteHitBox hb;
|
|
hb.r0_xlo = sprite_x_lo[k];
|
|
hb.r8_xhi = sprite_x_hi[k];
|
|
hb.r2 = 15;
|
|
int t = sprite_y_lo[k] - sprite_z[k];
|
|
int u = (t & 0xff) + 8;
|
|
hb.r1_ylo = u;
|
|
hb.r9_yhi = sprite_y_hi[k] + (u >> 8) - (t < 0);
|
|
hb.r3 = 8;
|
|
Sprite_SetupHitBox(j, &hb);
|
|
if (!CheckIfHitBoxesOverlap(&hb))
|
|
return;
|
|
if (sprite_type[j] == 0x3f) {
|
|
Sprite_PlaceWeaponTink(k);
|
|
} else {
|
|
uint8 a = (sprite_type[k] == 0xec && sprite_C[k] == 2 && !player_is_indoors) ? 1 : 3;
|
|
Ancilla_CheckDamageToSprite_preset(j, a);
|
|
|
|
sprite_x_recoil[j] = sprite_x_vel[k] * 2;
|
|
sprite_y_recoil[j] = sprite_y_vel[k] * 2;
|
|
sprite_delay_aux4[k] = 16;
|
|
}
|
|
Sprite_ApplyRicochet(k);
|
|
}
|
|
|
|
void Sprite_ApplyRicochet(int k) { // 86e229
|
|
Sprite_InvertSpeed_XY(k);
|
|
Sprite_HalveSpeed_XY(k);
|
|
ThrowableScenery_TransmuteIfValid(k);
|
|
}
|
|
|
|
void ThrowableScenery_TransmuteIfValid(int k) { // 86e22f
|
|
if (sprite_type[k] != 0xec)
|
|
return;
|
|
repulsespark_timer = 0;
|
|
ThrowableScenery_TransmuteToDebris(k);
|
|
}
|
|
|
|
void ThrowableScenery_TransmuteToDebris(int k) { // 86e239
|
|
uint8 a = sprite_graphics[k];
|
|
if (a != 0) {
|
|
BYTE(dung_secrets_unk1) = a;
|
|
Sprite_SpawnSecret(k);
|
|
BYTE(dung_secrets_unk1) = 0;
|
|
}
|
|
a = player_is_indoors ? 0 : sprite_C[k];
|
|
sound_effect_1 = 0;
|
|
SpriteSfx_QueueSfx2WithPan(k, kSprite_Func21_Sfx[a]);
|
|
Sprite_ScheduleForBreakage(k);
|
|
}
|
|
|
|
void Sprite_ScheduleForBreakage(int k) { // 86e25a
|
|
sprite_delay_main[k] = 31;
|
|
sprite_state[k] = 6;
|
|
sprite_flags2[k] += 4;
|
|
}
|
|
|
|
void Sprite_HalveSpeed_XY(int k) { // 86e26e
|
|
sprite_x_vel[k] = (int8)sprite_x_vel[k] >> 1;
|
|
sprite_y_vel[k] = (int8)sprite_y_vel[k] >> 1;
|
|
}
|
|
|
|
void Sprite_SpawnLeapingFish(int k) { // 86e286
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamically(k, 0xd2, &info);
|
|
if (j < 0)
|
|
return;
|
|
Sprite_SetSpawnedCoordinates(j, &info);
|
|
sprite_ai_state[j] = 2;
|
|
sprite_delay_main[j] = 48;
|
|
if (sprite_type[k] == 0xd2)
|
|
sprite_A[j] = 0xd2;
|
|
}
|
|
|
|
void SpriteStunned_Main_Func1(int k) { // 86e2ba
|
|
SpriteActive_Main(k);
|
|
if (sprite_unk5[k]) {
|
|
if (sprite_delay_main[k] < 32)
|
|
sprite_oam_flags[k] = sprite_oam_flags[k] & 0xf1 | 4;
|
|
uint8 t = ((k << 4) ^ frame_counter) | submodule_index;
|
|
if (t & kSpriteStunned_Main_Func1_Masks[sprite_delay_main[k] >> 4])
|
|
return;
|
|
uint16 x = kSparkleGarnish_XY[GetRandomNumber() & 3];
|
|
uint16 y = kSparkleGarnish_XY[GetRandomNumber() & 3];
|
|
Sprite_GarnishSpawn_Sparkle(k, x, y);
|
|
} else {
|
|
if ((frame_counter & 1) | submodule_index | flag_unk1)
|
|
return;
|
|
uint8 t = sprite_stunned[k];
|
|
if (t) {
|
|
sprite_stunned[k]--;
|
|
if (t < 0x38) {
|
|
sprite_x_vel[k] = (t & 1) ? -8 : 8;
|
|
Sprite_MoveX(k);
|
|
}
|
|
return;
|
|
}
|
|
sprite_state[k] = 9;
|
|
sprite_x_recoil[k] = 0;
|
|
sprite_y_recoil[k] = 0;
|
|
}
|
|
}
|
|
|
|
void SpriteModule_Poof(int k) { // 86e393
|
|
static const int8 kSpritePoof_X[16] = {-6, 10, 1, 13, -6, 10, 1, 13, -7, 4, -5, 6, -1, 1, -2, 0};
|
|
static const int8 kSpritePoof_Y[16] = {-6, -4, 10, 9, -6, -4, 10, 9, -8, -10, 4, 3, -1, -2, 0, 1};
|
|
static const uint8 kSpritePoof_Char[16] = {0x9b, 0x9b, 0x9b, 0x9b, 0xb3, 0xb3, 0xb3, 0xb3, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a};
|
|
static const uint8 kSpritePoof_Flags[16] = {0x24, 0xa4, 0x24, 0xa4, 0xe4, 0x64, 0xa4, 0x24, 0x24, 0xe4, 0xe4, 0xe4, 0x24, 0xe4, 0xe4, 0xe4};
|
|
static const uint8 kSpritePoof_Ext[16] = {0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2};
|
|
// Frozen sprite pulverized by hammer
|
|
if (sprite_delay_main[k] == 0) {
|
|
if (sprite_type[k] == 0xd && sprite_head_dir[k] != 0) {
|
|
// buzz blob?
|
|
int bakx = Sprite_GetX(k);
|
|
PrepareEnemyDrop(k, 0xd);
|
|
Sprite_SetX(k, bakx);
|
|
sprite_z_vel[k] = 0;
|
|
sprite_ignore_projectile[k] = 0;
|
|
} else {
|
|
if (sprite_die_action[k] == 0) {
|
|
ForcePrizeDrop(k, 2, 2);
|
|
} else {
|
|
Sprite_DoTheDeath(k);
|
|
}
|
|
}
|
|
} else {
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int j = ((sprite_delay_main[k] >> 1) & ~3) + 3;
|
|
for (int i = 3; i >= 0; i--, j--, oam++) {
|
|
SetOamPlain(oam, kSpritePoof_X[j] + BYTE(dungmap_var7), kSpritePoof_Y[j] + HIBYTE(dungmap_var7),
|
|
kSpritePoof_Char[j], kSpritePoof_Flags[j], kSpritePoof_Ext[j]);
|
|
}
|
|
Sprite_CorrectOamEntries(k, 3, 0xff);
|
|
}
|
|
}
|
|
|
|
void Sprite_PrepOamCoord(int k, PrepOamCoordsRet *ret) { // 86e416
|
|
Sprite_PrepOamCoordOrDoubleRet(k, ret);
|
|
}
|
|
|
|
bool Sprite_PrepOamCoordOrDoubleRet(int k, PrepOamCoordsRet *ret) { // 86e41e
|
|
sprite_pause[k] = 0;
|
|
uint16 x = cur_sprite_x - BG2HOFS_copy2;
|
|
uint16 y = cur_sprite_y - BG2VOFS_copy2;
|
|
bool out_of_bounds = false;
|
|
R0 = x;
|
|
R2 = y - sprite_z[k];
|
|
ret->flags = sprite_oam_flags[k] ^ sprite_obj_prio[k];
|
|
ret->r4 = 0;
|
|
int xt = (enhanced_features0 & kFeatures0_ExtendScreen64) ? 0x40 : 0;
|
|
|
|
if ((uint16)(x + 0x40 + xt) >= (0x170 + xt * 2) ||
|
|
(uint16)(y + 0x40) >= 0x170 && !(sprite_flags4[k] & 0x20)) {
|
|
sprite_pause[k]++;
|
|
if (!(sprite_defl_bits[k] & 0x80))
|
|
Sprite_KillSelf(k);
|
|
out_of_bounds = true;
|
|
}
|
|
ret->x = R0;
|
|
ret->y = R2;
|
|
BYTE(dungmap_var7) = ret->x;
|
|
HIBYTE(dungmap_var7) = ret->y;
|
|
return out_of_bounds;
|
|
}
|
|
|
|
void Sprite_CheckTileCollision2(int k) { // 86e4ab
|
|
sprite_wallcoll[k] = 0;
|
|
if (sign8(sprite_flags4[k]) || !dung_hdr_collision) {
|
|
Sprite_CheckTileCollisionSingleLayer(k);
|
|
return;
|
|
}
|
|
byte_7E0FB6 = sprite_floor[k];
|
|
sprite_floor[k] = 1;
|
|
Sprite_CheckTileCollisionSingleLayer(k);
|
|
if (dung_hdr_collision == 4) {
|
|
sprite_floor[k] = byte_7E0FB6;
|
|
return;
|
|
}
|
|
sprite_floor[k] = 0;
|
|
Sprite_CheckTileCollisionSingleLayer(k);
|
|
byte_7FFABC[k] = sprite_tiletype;
|
|
}
|
|
|
|
void Sprite_CheckTileCollisionSingleLayer(int k) { // 86e4db
|
|
if (sprite_flags2[k] & 0x20) {
|
|
if (Sprite_CheckTileProperty(k, 0x6a))
|
|
sprite_wallcoll[k]++;
|
|
return;
|
|
}
|
|
|
|
if (sign8(sprite_flags4[k]) || dung_hdr_collision == 0) {
|
|
if (sprite_y_vel[k])
|
|
Sprite_CheckForTileInDirection_vertical(k, sign8(sprite_y_vel[k]) ? 0 : 1);
|
|
if (sprite_x_vel[k])
|
|
Sprite_CheckForTileInDirection_horizontal(k, sign8(sprite_x_vel[k]) ? 2 : 3);
|
|
} else {
|
|
Sprite_CheckForTileInDirection_vertical(k, 1);
|
|
Sprite_CheckForTileInDirection_vertical(k, 0);
|
|
Sprite_CheckForTileInDirection_horizontal(k, 3);
|
|
Sprite_CheckForTileInDirection_horizontal(k, 2);
|
|
}
|
|
|
|
if (sign8(sprite_flags5[k]) || sprite_z[k])
|
|
return;
|
|
|
|
Sprite_CheckTileProperty(k, 0x68);
|
|
sprite_I[k] = sprite_tiletype;
|
|
if (sprite_tiletype == 0x1c) {
|
|
if (sort_sprites_setting && sprite_state[k] == 11)
|
|
sprite_floor[k] = 1;
|
|
} else if (sprite_tiletype == 0x20) {
|
|
if (sprite_flags[k] & 1) {
|
|
if (!player_is_indoors) {
|
|
Sprite_Func8(k);
|
|
} else {
|
|
sprite_state[k] = 5;
|
|
if (sprite_type[k] == 0x13 || sprite_type[k] == 0x26) {
|
|
sprite_oam_flags[k] &= ~1;
|
|
sprite_delay_main[k] = 63;
|
|
} else {
|
|
sprite_delay_main[k] = 95;
|
|
}
|
|
}
|
|
}
|
|
} else if (sprite_tiletype == 0xc) {
|
|
if (byte_7FFABC[k] == 0x1c) {
|
|
SpriteFall_AdjustPosition(k);
|
|
sprite_wallcoll[k] |= 0x20;
|
|
}
|
|
} else if (sprite_tiletype >= 0x68 && sprite_tiletype < 0x6c) {
|
|
Sprite_ApplyConveyor(k, sprite_tiletype);
|
|
} else if (sprite_tiletype == 8) {
|
|
if (dung_hdr_collision == 4)
|
|
Sprite_ApplyConveyor(k, 0x6a);
|
|
}
|
|
}
|
|
|
|
void Sprite_CheckForTileInDirection_horizontal(int k, int yy) { // 86e5b8
|
|
if (!Sprite_CheckTileInDirection(k, yy))
|
|
return;
|
|
sprite_wallcoll[k] |= kSprite_Func7_Tab[yy];
|
|
if ((sprite_subtype[k] & 7) < 5) {
|
|
int8 n = sprite_F[k] ? 3 : 1;
|
|
SpriteAddXY(k, (yy & 1) ? -n : n, 0);
|
|
}
|
|
}
|
|
|
|
void Sprite_CheckForTileInDirection_vertical(int k, int yy) { // 86e5ee
|
|
if (!Sprite_CheckTileInDirection(k, yy))
|
|
return;
|
|
sprite_wallcoll[k] |= kSprite_Func7_Tab[yy];
|
|
if ((sprite_subtype[k] & 7) < 5) {
|
|
int8 n = sprite_F[k] ? 3 : 1;
|
|
SpriteAddXY(k, 0, (yy & 1) ? -n : n);
|
|
}
|
|
}
|
|
|
|
void SpriteFall_AdjustPosition(int k) { // 86e624
|
|
SpriteAddXY(k, dung_floor_x_vel, dung_floor_y_vel);
|
|
}
|
|
|
|
bool Sprite_CheckTileInDirection(int k, int yy) { // 86e72f
|
|
uint8 t = (sprite_flags[k] & 0xf0);
|
|
yy = 2 * ((t >> 2) + yy);
|
|
return Sprite_CheckTileProperty(k, yy);
|
|
}
|
|
|
|
bool Sprite_CheckTileProperty(int k, int j) { // 86e73c
|
|
uint16 x, y;
|
|
bool in_bounds;
|
|
j >>= 1;
|
|
|
|
if (player_is_indoors) {
|
|
x = (cur_sprite_x + 8 & 0x1ff) + kSprite_Func5_X[j] - 8;
|
|
y = (cur_sprite_y + 8 & 0x1ff) + kSprite_Func5_Y[j] - 8;
|
|
in_bounds = (x < 0x200) && (y < 0x200);
|
|
} else {
|
|
x = cur_sprite_x + kSprite_Func5_X[j];
|
|
y = cur_sprite_y + kSprite_Func5_Y[j];
|
|
in_bounds = (uint16)(x - sprcoll_x_base) < sprcoll_x_size &&
|
|
(uint16)(y - sprcoll_y_base) < sprcoll_y_size;
|
|
}
|
|
if (!in_bounds) {
|
|
if (sprite_flags2[k] & 0x40) {
|
|
sprite_state[k] = 0;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
int b = Sprite_GetTileAttribute(k, &x, y);
|
|
|
|
if (sprite_defl_bits[k] & 8) {
|
|
uint8 a = kSprite_SimplifiedTileAttr[b];
|
|
if (a == 4) {
|
|
if (!player_is_indoors)
|
|
sprite_E[k] = 4;
|
|
} else if (a >= 1) {
|
|
return (sprite_tiletype >= 0x10 && sprite_tiletype < 0x14) ? Entity_CheckSlopedTileCollision(x, y) : true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (sprite_flags5[k] & 0x40) {
|
|
uint8 type = sprite_type[k];
|
|
if ((type == 0xd2 || type == 0x8a) && b == 9)
|
|
return false;
|
|
if (type == 0x94 && !sprite_E[k] || type == 0xe3 || type == 0x8c || type == 0x9a || type == 0x81)
|
|
return (b != 8) && (b != 9);
|
|
}
|
|
|
|
if (kSprite_Func5_Tab3[b] == 0)
|
|
return false;
|
|
|
|
if (sprite_tiletype >= 0x10 && sprite_tiletype < 0x14)
|
|
return Entity_CheckSlopedTileCollision(x, y);
|
|
|
|
if (sprite_tiletype == 0x44) {
|
|
if (sprite_F[k] && !sign8(sprite_give_damage[k])) {
|
|
|
|
// Some mothula bug fix because we changed damage class 4.
|
|
if (sprite_type[k] == 0x88 && (enhanced_features0 & kFeatures0_MiscBugFixes)) {
|
|
if (sprite_hit_timer[k] == 0)
|
|
Ancilla_CheckDamageToSprite_preset(k, 6);
|
|
} else {
|
|
Ancilla_CheckDamageToSprite_preset(k, 4);
|
|
}
|
|
if (sprite_hit_timer[k]) {
|
|
sprite_hit_timer[k] = 153;
|
|
sprite_F[k] = 0;
|
|
}
|
|
}
|
|
} else if (sprite_tiletype == 0x20) {
|
|
return !(sprite_flags[k] & 1) || !sprite_F[k];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
uint8 GetTileAttribute(uint8 floor, uint16 *x, uint16 y) { // 86e87b
|
|
uint8 tiletype;
|
|
if (player_is_indoors) {
|
|
int t = (floor >= 1) ? 0x1000 : 0;
|
|
t += (*x & 0x1f8) >> 3;
|
|
t += (y & 0x1f8) << 3;
|
|
tiletype = dung_bg2_attr_table[t];
|
|
} else {
|
|
tiletype = Overworld_GetTileAttributeAtLocation(*x >>= 3, y);
|
|
}
|
|
sprite_tiletype = tiletype;
|
|
return tiletype;
|
|
}
|
|
|
|
uint8 Sprite_GetTileAttribute(int k, uint16 *x, uint16 y) { // 86e883
|
|
return GetTileAttribute(sprite_floor[k], x, y);
|
|
}
|
|
|
|
bool Entity_CheckSlopedTileCollision(uint16 x, uint16 y) { // 86e8fe
|
|
uint8 a = y & 7;
|
|
uint8 r6 = sprite_tiletype - 0x10;
|
|
uint8 b = kSlopedTile[r6 * 8 + (x & 7)];
|
|
return (r6 < 2) ? (b >= a) : (a >= b);
|
|
}
|
|
|
|
void Sprite_MoveXY(int k) { // 86e92c
|
|
Sprite_MoveX(k);
|
|
Sprite_MoveY(k);
|
|
}
|
|
|
|
void Sprite_MoveX(int k) { // 86e932
|
|
if (sprite_x_vel[k] != 0) {
|
|
uint32 t = sprite_x_subpixel[k] + (sprite_x_lo[k] << 8) + (sprite_x_hi[k] << 16) + ((int8)sprite_x_vel[k] << 4);
|
|
sprite_x_subpixel[k] = t, sprite_x_lo[k] = t >> 8, sprite_x_hi[k] = t >> 16;
|
|
}
|
|
}
|
|
|
|
void Sprite_MoveY(int k) { // 86e93e
|
|
if (sprite_y_vel[k] != 0) {
|
|
uint32 t = sprite_y_subpixel[k] + (sprite_y_lo[k] << 8) + (sprite_y_hi[k] << 16) + ((int8)sprite_y_vel[k] << 4);
|
|
sprite_y_subpixel[k] = t, sprite_y_lo[k] = t >> 8, sprite_y_hi[k] = t >> 16;
|
|
}
|
|
}
|
|
|
|
void Sprite_MoveZ(int k) { // 86e96c
|
|
uint16 z = (sprite_z[k] << 8 | sprite_z_subpos[k]) + ((int8)sprite_z_vel[k] << 4);
|
|
sprite_z_subpos[k] = z;
|
|
sprite_z[k] = z >> 8;
|
|
}
|
|
|
|
ProjectSpeedRet Sprite_ProjectSpeedTowardsLink(int k, uint8 vel) { // 86e991
|
|
if (vel == 0) {
|
|
ProjectSpeedRet rv = { 0, 0, 0, 0 };
|
|
return rv;
|
|
}
|
|
PairU8 below = Sprite_IsBelowLink(k);
|
|
uint8 r12 = sign8(below.b) ? -below.b : below.b;
|
|
|
|
PairU8 right = Sprite_IsRightOfLink(k);
|
|
uint8 r13 = sign8(right.b) ? -right.b : right.b;
|
|
uint8 t;
|
|
bool swapped = false;
|
|
if (r13 < r12) {
|
|
swapped = true;
|
|
t = r12, r12 = r13, r13 = t;
|
|
}
|
|
uint8 xvel = vel, yvel = 0;
|
|
t = 0;
|
|
do {
|
|
t += r12;
|
|
if (t >= r13)
|
|
t -= r13, yvel++;
|
|
} while (--vel);
|
|
if (swapped)
|
|
t = xvel, xvel = yvel, yvel = t;
|
|
ProjectSpeedRet rv = {
|
|
(uint8)(right.a ? -xvel : xvel),
|
|
(uint8)(below.a ? -yvel : yvel),
|
|
right.b,
|
|
below.b
|
|
|
|
};
|
|
return rv;
|
|
}
|
|
|
|
void Sprite_ApplySpeedTowardsLink(int k, uint8 vel) { // 86ea04
|
|
ProjectSpeedRet pt = Sprite_ProjectSpeedTowardsLink(k, vel);
|
|
sprite_x_vel[k] = pt.x;
|
|
sprite_y_vel[k] = pt.y;
|
|
}
|
|
|
|
ProjectSpeedRet Sprite_ProjectSpeedTowardsLocation(int k, uint16 x, uint16 y, uint8 vel) { // 86ea2d
|
|
if (vel == 0) {
|
|
ProjectSpeedRet rv = { 0, 0, 0, 0 };
|
|
return rv;
|
|
}
|
|
PairU8 below = Sprite_IsBelowLocation(k, y);
|
|
uint8 r12 = sign8(below.b) ? -below.b : below.b;
|
|
|
|
PairU8 right = Sprite_IsRightOfLocation(k, x);
|
|
uint8 r13 = sign8(right.b) ? -right.b : right.b;
|
|
uint8 t;
|
|
bool swapped = false;
|
|
if (r13 < r12) {
|
|
swapped = true;
|
|
t = r12, r12 = r13, r13 = t;
|
|
}
|
|
uint8 xvel = vel, yvel = 0;
|
|
t = 0;
|
|
do {
|
|
t += r12;
|
|
if (t >= r13)
|
|
t -= r13, yvel++;
|
|
} while (--vel);
|
|
if (swapped)
|
|
t = xvel, xvel = yvel, yvel = t;
|
|
ProjectSpeedRet rv = {
|
|
(uint8)(right.a ? -xvel : xvel),
|
|
(uint8)(below.a ? -yvel : yvel),
|
|
right.b,
|
|
below.b
|
|
};
|
|
return rv;
|
|
}
|
|
|
|
uint8 Sprite_DirectionToFaceLink(int k, PointU8 *coords_out) { // 86eaa4
|
|
PairU8 below = Sprite_IsBelowLink(k);
|
|
PairU8 right = Sprite_IsRightOfLink(k);
|
|
uint8 ym = sign8(below.b) ? -below.b : below.b;
|
|
tmp_counter = ym;
|
|
uint8 xm = sign8(right.b) ? -right.b : right.b;
|
|
if (coords_out)
|
|
coords_out->x = right.b, coords_out->y = below.b;
|
|
return (xm >= ym) ? right.a : below.a + 2;
|
|
}
|
|
|
|
PairU8 Sprite_IsRightOfLink(int k) { // 86ead1
|
|
uint16 x = link_x_coord - Sprite_GetX(k);
|
|
PairU8 rv = { (uint8)(sign16(x) ? 1 : 0), (uint8)x };
|
|
return rv;
|
|
}
|
|
|
|
PairU8 Sprite_IsBelowLink(int k) { // 86eae8
|
|
int t = BYTE(link_y_coord) + 8;
|
|
int u = (t & 0xff) + sprite_z[k];
|
|
int v = (u & 0xff) - sprite_y_lo[k];
|
|
int w = HIBYTE(link_y_coord) - sprite_y_hi[k] - (v < 0);
|
|
uint8 y = (w & 0xff) + (t >> 8) + (u >> 8);
|
|
PairU8 rv = { (uint8)(sign8(y) ? 1 : 0), (uint8)v };
|
|
return rv;
|
|
}
|
|
|
|
PairU8 Sprite_IsRightOfLocation(int k, uint16 x) { // 86eb0a
|
|
uint16 xv = x - Sprite_GetX(k);
|
|
PairU8 rv = { (uint8)(sign16(xv) ? 1 : 0), (uint8)xv };
|
|
return rv;
|
|
}
|
|
|
|
PairU8 Sprite_IsBelowLocation(int k, uint16 y) { // 86eb1d
|
|
uint16 yv = y - Sprite_GetY(k);
|
|
PairU8 rv = { (uint8)(sign16(yv) ? 1 : 0), (uint8)yv };
|
|
return rv;
|
|
}
|
|
|
|
uint8 Sprite_DirectionToFaceLocation(int k, uint16 x, uint16 y) { // 86eb30
|
|
PairU8 below = Sprite_IsBelowLocation(k, y);
|
|
PairU8 right = Sprite_IsRightOfLocation(k, x);
|
|
uint8 ym = sign8(below.b) ? -below.b : below.b;
|
|
tmp_counter = ym;
|
|
uint8 xm = sign8(right.b) ? -right.b : right.b;
|
|
return (xm >= ym) ? right.a : below.a + 2;
|
|
}
|
|
|
|
void Guard_ParrySwordAttacks(int k) { // 86eb5e
|
|
if (link_is_on_lower_level != sprite_floor[k] || link_incapacitated_timer | link_auxiliary_state || sign8(sprite_hit_timer[k]))
|
|
return;
|
|
SpriteHitBox hb;
|
|
Sprite_DoHitBoxesFast(k, &hb);
|
|
if (link_position_mode & 0x10 || player_oam_y_offset == 0x80) {
|
|
Sprite_AttemptDamageToLinkWithCollisionCheck(k);
|
|
return;
|
|
}
|
|
Player_SetupActionHitBox(&hb);
|
|
if (sign8(button_b_frames) || !CheckIfHitBoxesOverlap(&hb)) {
|
|
Sprite_SetupHitBox(k, &hb);
|
|
if (!CheckIfHitBoxesOverlap(&hb))
|
|
Sprite_AttemptDamageToLinkWithCollisionCheck(k);
|
|
else
|
|
Sprite_AttemptZapDamage(k);
|
|
return;
|
|
}
|
|
if (sprite_type[k] != 0x6a)
|
|
sprite_F[k] = kSprite_Func1_Tab[GetRandomNumber() & 7];
|
|
link_incapacitated_timer = kSprite_Func1_Tab2[GetRandomNumber() & 7];
|
|
ProjectSpeedRet pt = Sprite_ProjectSpeedTowardsLink(k, sign8(button_b_frames - 9) ? 32 : 24);
|
|
sprite_x_recoil[k] = -pt.x;
|
|
sprite_y_recoil[k] = -pt.y;
|
|
Sprite_ApplyRecoilToLink(k, sign8(button_b_frames - 9) ? 8 : 16);
|
|
Link_PlaceWeaponTink();
|
|
set_when_damaging_enemies = 0x90;
|
|
}
|
|
|
|
void Sprite_AttemptZapDamage(int k) { // 86ec02
|
|
uint8 a = sprite_type[k];
|
|
if ((a == 0x7a || a == 0xd && (a = link_sword_type) < 4 || (a == 0x24 || a == 0x23) && sprite_delay_main[k] != 0) && sprite_state[k] == 9) {
|
|
if (!countdown_for_blink) {
|
|
sprite_delay_aux1[k] = 64;
|
|
link_electrocute_on_touch = 64;
|
|
Sprite_AttemptDamageToLinkPlusRecoil(k);
|
|
}
|
|
} else {
|
|
ProjectSpeedRet pt = Sprite_ProjectSpeedTowardsLink(k, sign8(button_b_frames - 9) ? 0x50 : 0x40);
|
|
sprite_x_recoil[k] = -pt.x;
|
|
sprite_y_recoil[k] = -pt.y;
|
|
Sprite_CalculateSwordDamage(k);
|
|
}
|
|
}
|
|
|
|
void Ancilla_CheckDamageToSprite_preset(int k, int a) { // 86ece0
|
|
if (a == 15 && sprite_z[k] != 0)
|
|
return;
|
|
|
|
if (a != 0 && a != 7) {
|
|
Sprite_Func15(k, a);
|
|
return;
|
|
}
|
|
Sprite_Func15(k, a);
|
|
if (sprite_give_damage[k] || repulsespark_timer)
|
|
return;
|
|
// Called when hitting enemy which is frozen
|
|
repulsespark_timer = 5;
|
|
int j = byte_7E0FB6;
|
|
repulsespark_x_lo = ancilla_x_lo[j] + 4;
|
|
repulsespark_y_lo = ancilla_y_lo[j];
|
|
repulsespark_floor_status = link_is_on_lower_level;
|
|
sound_effect_1 = 0;
|
|
SpriteSfx_QueueSfx2WithPan(k, 5);
|
|
}
|
|
|
|
void Sprite_Func15(int k, int a) { // 86ed25
|
|
damage_type_determiner = a;
|
|
Sprite_ApplyCalculatedDamage(k, a == 8 ? 0x35 : 0x20);
|
|
}
|
|
|
|
void Sprite_CalculateSwordDamage(int k) { // 86ed3f
|
|
if (sprite_flags3[k] & 0x40)
|
|
return;
|
|
sprite_unk1[k] = link_is_running;
|
|
uint8 a = link_sword_type - 1;
|
|
if (!link_is_running)
|
|
a |= sign8(button_b_frames) ? 4 : sign8(button_b_frames - 9) ? 0 : 8;
|
|
damage_type_determiner = kSprite_Func14_Damage[a];
|
|
if (link_item_in_hand & 10)
|
|
damage_type_determiner = 3;
|
|
link_sword_delay_timer = 4;
|
|
set_when_damaging_enemies = 16;
|
|
Sprite_ApplyCalculatedDamage(k, 0x9d);
|
|
}
|
|
|
|
void Sprite_ApplyCalculatedDamage(int k, int a) { // 86ed89
|
|
if ((sprite_flags3[k] & 0x40) || sprite_type[k] >= 0xD8)
|
|
return;
|
|
uint8 dmg = kEnemyDamages[damage_type_determiner * 8 | enemy_damage_data[sprite_type[k] * 16 | damage_type_determiner]];
|
|
Sprite_GiveDamage(k, dmg, a);
|
|
}
|
|
|
|
void Sprite_GiveDamage(int k, uint8 dmg, uint8 r0_hit_timer) { // 86edc5
|
|
if (dmg == 249) {
|
|
Sprite_Func18(k, 0xe3);
|
|
return;
|
|
}
|
|
if (dmg == 250) {
|
|
Sprite_Func18(k, 0x8f);
|
|
sprite_ai_state[k] = 2;
|
|
sprite_z_vel[k] = 32;
|
|
sprite_oam_flags[k] = 8;
|
|
sprite_F[k] = 0;
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_health[k] = 0;
|
|
sprite_bump_damage[k] = 1;
|
|
sprite_flags5[k] = 1;
|
|
return;
|
|
}
|
|
if (dmg >= sprite_give_damage[k])
|
|
sprite_give_damage[k] = dmg;
|
|
if (dmg == 0) {
|
|
if (damage_type_determiner != 10) {
|
|
if (sprite_flags[k] & 4)
|
|
goto flag4;
|
|
link_sword_delay_timer = 0;
|
|
}
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_give_damage[k] = 0;
|
|
return;
|
|
}
|
|
if (dmg >= 254 && sprite_state[k] == 11) {
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_give_damage[k] = 0;
|
|
return;
|
|
}
|
|
if (sprite_type[k] == 0x9a && sprite_give_damage[k] < 0xf0) {
|
|
sprite_state[k] = 9;
|
|
sprite_ai_state[k] = 4;
|
|
sprite_delay_main[k] = 15;
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x28);
|
|
return;
|
|
}
|
|
if (sprite_type[k] == 0x1b) {
|
|
SpriteSfx_QueueSfx2WithPan(k, 5);
|
|
Sprite_ScheduleForBreakage(k);
|
|
Sprite_PlaceWeaponTink(k);
|
|
return;
|
|
}
|
|
sprite_hit_timer[k] = r0_hit_timer;
|
|
if (sprite_type[k] != 0x92 || sprite_C[k] >= 3) {
|
|
uint8 sfx = sprite_flags[k] & 2 ? 0x21 :
|
|
sprite_flags5[k] & 0x10 ? 0x1c : 8;
|
|
sound_effect_2 = sfx | Sprite_CalculateSfxPan(k);
|
|
}
|
|
uint8 type;
|
|
flag4:
|
|
type = sprite_type[k];
|
|
sprite_F[k] = (damage_type_determiner >= 13) ? 0 :
|
|
(type == 9) ? 20 :
|
|
(type == 0x53 || type == 0x18) ? 11 : 15;
|
|
}
|
|
|
|
void Sprite_Func18(int k, uint8 new_type) { // 86edcb
|
|
sprite_type[k] = new_type;
|
|
SpritePrep_LoadProperties(k);
|
|
Sprite_SpawnPoofGarnish(k);
|
|
sound_effect_2 = 0;
|
|
SpriteSfx_QueueSfx3WithPan(k, 0x32);
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_give_damage[k] = 0;
|
|
}
|
|
|
|
void Sprite_MiniMoldorm_Recoil(int k) { // 86eec8
|
|
if (sprite_state[k] < 9)
|
|
return;
|
|
tmp_counter = sprite_state[k];
|
|
|
|
uint8 dmg = sprite_give_damage[k];
|
|
if (dmg == 253) {
|
|
sprite_give_damage[k] = 0;
|
|
SpriteSfx_QueueSfx3WithPan(k, 9);
|
|
sprite_state[k] = 7;
|
|
sprite_delay_main[k] = 0x70;
|
|
sprite_flags2[k] += 2;
|
|
sprite_give_damage[k] = 0;
|
|
return;
|
|
}
|
|
|
|
if (dmg >= 251) {
|
|
sprite_give_damage[k] = 0;
|
|
if (sprite_state[k] == 11)
|
|
return;
|
|
sprite_unk5[k] = (dmg == 254);
|
|
if (sprite_unk5[k]) {
|
|
sprite_defl_bits[k] |= 8;
|
|
sprite_flags5[k] &= ~0x80;
|
|
SpriteSfx_QueueSfx2WithPan(k, 15);
|
|
sprite_z_vel[k] = 24;
|
|
sprite_bump_damage[k] &= ~0x80;
|
|
Sprite_ZeroVelocity_XY(k);
|
|
}
|
|
sprite_state[k] = 11;
|
|
sprite_delay_main[k] = 64;
|
|
static const uint8 kHitTimer24StunValues[5] = {0x20, 0x80, 0, 0, 0xff};
|
|
sprite_stunned[k] = kHitTimer24StunValues[(uint8)(dmg + 5)];
|
|
if (sprite_type[k] == 0x23)
|
|
sprite_type[k] = 0x24;
|
|
return;
|
|
}
|
|
|
|
int t = sprite_health[k] - sprite_give_damage[k];
|
|
sprite_health[k] = t;
|
|
sprite_give_damage[k] = 0;
|
|
if (t > 0)
|
|
return;
|
|
|
|
if (sprite_die_action[k] == 0) {
|
|
if (sprite_state[k] == 11)
|
|
sprite_die_action[k] = 3;
|
|
if (sprite_unk1[k] != 0) {
|
|
sprite_unk1[k] = 0;
|
|
sprite_flags5[k] = 0;
|
|
}
|
|
}
|
|
|
|
uint8 type = sprite_type[k];
|
|
if (type != 0x1b)
|
|
SpriteSfx_QueueSfx3WithPan(k, 9);
|
|
|
|
if (type == 0x40)
|
|
save_ow_event_info[BYTE(overworld_screen_index)] |= 0x40;
|
|
else if (type == 0xec) {
|
|
if (sprite_C[k] == 2)
|
|
ThrowableScenery_TransmuteToDebris(k);
|
|
return;
|
|
}
|
|
|
|
if (sprite_state[k] == 10) {
|
|
link_state_bits = 0;
|
|
link_picking_throw_state = 0;
|
|
}
|
|
sprite_state[k] = 6;
|
|
|
|
if (type == 0xc) {
|
|
Sprite_Func3(k);
|
|
} else if (type == 0x92) {
|
|
Sprite_KillFriends();
|
|
sprite_delay_main[k] = 255;
|
|
goto out_common;
|
|
} else if (type == 0xcb) {
|
|
sprite_ai_state[k] = 128;
|
|
sprite_delay_main[k] = 128;
|
|
sprite_state[k] = 9;
|
|
goto out_common;
|
|
} else if (type == 0xcc || type == 0xcd) {
|
|
sprite_ai_state[k] = 128;
|
|
sprite_delay_main[k] = 96;
|
|
sprite_state[k] = 9;
|
|
goto out_common;
|
|
} else if (type == 0x53) {
|
|
sprite_delay_main[k] = 35;
|
|
sprite_hit_timer[k] = 0;
|
|
goto out_common2;
|
|
} else if (type == 0x54) {
|
|
sprite_ai_state[k] = 5;
|
|
sprite_delay_main[k] = 0xc0;
|
|
sprite_hit_timer[k] = 0xc0;
|
|
goto out_common;
|
|
} else if (type == 0x9) {
|
|
sprite_ai_state[k] = 3;
|
|
sprite_delay_aux4[k] = 160;
|
|
sprite_state[k] = 9;
|
|
goto out_common;
|
|
} else if (type == 0x7a) {
|
|
Sprite_KillFriends();
|
|
sprite_state[k] = 9;
|
|
sprite_ignore_projectile[k] = 9;
|
|
if (is_in_dark_world == 0) {
|
|
sprite_ai_state[k] = 10;
|
|
sprite_delay_main[k] = 255;
|
|
sprite_z_vel[k] = 32;
|
|
} else {
|
|
sprite_delay_main[k] = 255;
|
|
sprite_ai_state[k] = 8;
|
|
sprite_ai_state[1] = 9;
|
|
sprite_ai_state[2] = 9;
|
|
sprite_graphics[1] = 0;
|
|
sprite_graphics[2] = 0;
|
|
}
|
|
goto out_common;
|
|
} else if (type == 0x23 && sprite_C[k] == 0) {
|
|
sprite_ai_state[k] = 2;
|
|
sprite_delay_main[k] = 32;
|
|
sprite_state[k] = 9;
|
|
sprite_hit_timer[k] = 0;
|
|
} else if (type == 0xf) {
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_delay_main[k] = 15;
|
|
} else if (!(sprite_flags[k] & 2)) {
|
|
sprite_delay_main[k] = sprite_hit_timer[k] & 0x80 ? 31 : 15;
|
|
sprite_flags2[k] += 4;
|
|
if (tmp_counter == 11)
|
|
sprite_flags5[k] = 1;
|
|
} else {
|
|
if (type != 0xa2)
|
|
Sprite_KillFriends();
|
|
sprite_state[k] = 4;
|
|
sprite_A[k] = 0;
|
|
sprite_delay_main[k] = 255;
|
|
sprite_hit_timer[k] = 255;
|
|
out_common:
|
|
flag_block_link_menu++;
|
|
out_common2:
|
|
sound_effect_2 = 0;
|
|
SpriteSfx_QueueSfx3WithPan(k, 0x22);
|
|
}
|
|
}
|
|
|
|
void Sprite_Func3(int k) { // 86efda
|
|
sprite_state[k] = 6;
|
|
sprite_delay_main[k] = 31;
|
|
sprite_flags2[k] = 3;
|
|
}
|
|
|
|
bool Sprite_CheckDamageToLink(int k) { // 86f145
|
|
if (link_disable_sprite_damage)
|
|
return false;
|
|
return Sprite_CheckDamageToPlayer_1(k);
|
|
}
|
|
|
|
bool Sprite_CheckDamageToPlayer_1(int k) { // 86f14a
|
|
if ((k ^ frame_counter) & 3 | sprite_hit_timer[k])
|
|
return false;
|
|
return Sprite_CheckDamageToLink_same_layer(k);
|
|
}
|
|
|
|
bool Sprite_CheckDamageToLink_same_layer(int k) { // 86f154
|
|
if (link_is_on_lower_level != sprite_floor[k])
|
|
return false;
|
|
return Sprite_CheckDamageToLink_ignore_layer(k);
|
|
}
|
|
|
|
bool Sprite_CheckDamageToLink_ignore_layer(int k) { // 86f15c
|
|
uint8 carry, t;
|
|
if (sprite_flags4[k]) {
|
|
SpriteHitBox hitbox;
|
|
Link_SetupHitBox(&hitbox);
|
|
|
|
// Set hitbox to the sword hitbox if the item type is an absorbable
|
|
if (sprite_type[k] >= 0xd8 && sprite_type[k] <= 0xe6 && (enhanced_features0 & kFeatures0_CollectItemsWithSword))
|
|
Link_UpdateHitBoxWithSword(&hitbox);
|
|
|
|
Sprite_SetupHitBox(k, &hitbox);
|
|
carry = CheckIfHitBoxesOverlap(&hitbox);
|
|
} else {
|
|
carry = Sprite_SetupHitBox00(k);
|
|
}
|
|
|
|
if (sign8(sprite_flags2[k]))
|
|
return carry;
|
|
|
|
if (!carry || link_auxiliary_state)
|
|
return false;
|
|
|
|
if (link_is_bunny_mirror || sign8(link_state_bits) || !(sprite_flags5[k] & 0x20) || !link_shield_type)
|
|
goto if_3;
|
|
sprite_state[k] = 0;
|
|
|
|
t = button_b_frames ? kSpriteDamage_Tab2[link_direction_facing >> 1] : link_direction_facing;
|
|
if (t != kSpriteDamage_Tab3[sprite_D[k]]) {
|
|
if_3:
|
|
Sprite_AttemptDamageToLinkPlusRecoil(k);
|
|
if (sprite_type[k] == 0xc)
|
|
Sprite_Func3(k);
|
|
return true;
|
|
}
|
|
SpriteSfx_QueueSfx2WithPan(k, 6);
|
|
Sprite_PlaceRupulseSpark_2(k);
|
|
if (sprite_type[k] == 0x95) {
|
|
SpriteSfx_QueueSfx3WithPan(k, 0x26);
|
|
return false;
|
|
} else if (sprite_type[k] == 0x9B) {
|
|
Sprite_Invert_XY_Speeds(k);
|
|
sprite_D[k] ^= 1;
|
|
sprite_ai_state[k]++;
|
|
sprite_state[k] = 9;
|
|
return false;
|
|
} else if (sprite_type[k] == 0x1B) { // arrow
|
|
Sprite_ScheduleForBreakage(k);
|
|
return false; // unk ret val
|
|
} else if (sprite_type[k] == 0xc) {
|
|
Sprite_Func3(k);
|
|
return true;
|
|
} else {
|
|
return false; // unk ret val
|
|
}
|
|
}
|
|
|
|
bool Sprite_SetupHitBox00(int k) { // 86f1f6
|
|
return (uint16)(link_x_coord - cur_sprite_x + 11) < 23 &&
|
|
(uint16)(link_y_coord - cur_sprite_y + sprite_z[k] + 16) < 24;
|
|
}
|
|
|
|
bool Sprite_ReturnIfLifted(int k) { // 86f228
|
|
if (submodule_index | button_b_frames | flag_unk1 || sprite_floor[k] != link_is_on_lower_level)
|
|
return false;
|
|
for (int j = 15; j >= 0; j--)
|
|
if (sprite_state[j] == 10)
|
|
return false;
|
|
if (sprite_type[k] != 0xb && sprite_type[k] != 0x4a && (sprite_x_vel[k] | sprite_y_vel[k]) != 0)
|
|
return false;
|
|
if (link_is_running)
|
|
return false;
|
|
return Sprite_ReturnIfLiftedPermissive(k);
|
|
}
|
|
|
|
bool Sprite_ReturnIfLiftedPermissive(int k) { // 86f257
|
|
if (link_is_running)
|
|
return false;
|
|
if ((uint8)(flag_is_sprite_to_pick_up_cached - 1) != cur_object_index) {
|
|
SpriteHitBox hb;
|
|
Link_SetupHitBox_conditional(&hb);
|
|
Sprite_SetupHitBox(k, &hb);
|
|
if (CheckIfHitBoxesOverlap(&hb))
|
|
byte_7E0FB2 = flag_is_sprite_to_pick_up = k + 1;
|
|
return false;
|
|
} else {
|
|
BYTE(filtered_joypad_L) = 0;
|
|
sprite_E[k] = 0;
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x1d);
|
|
sprite_unk4[k] = sprite_state[k];
|
|
sprite_state[k] = 10;
|
|
sprite_delay_main[k] = 16;
|
|
sprite_unk3[k] = 0;
|
|
sprite_I[k] = 0;
|
|
link_direction_facing = kSprite_ReturnIfLifted_Dirs[Sprite_DirectionToFaceLink(k, NULL)];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
uint8 Sprite_CheckDamageFromLink(int k) { // 86f2b4
|
|
if (sprite_hit_timer[k] & 0x80 || sprite_floor[k] != link_is_on_lower_level || player_oam_y_offset == 0x80)
|
|
return 0;
|
|
|
|
SpriteHitBox hb;
|
|
Player_SetupActionHitBox(&hb);
|
|
Sprite_SetupHitBox(k, &hb);
|
|
if (!CheckIfHitBoxesOverlap(&hb))
|
|
return 0;
|
|
|
|
set_when_damaging_enemies = 0;
|
|
if (link_position_mode & 0x10)
|
|
return kCheckDamageFromPlayer_Carry | kCheckDamageFromPlayer_Ne;
|
|
|
|
if (link_item_in_hand & 10) {
|
|
if (sprite_type[k] >= 0xd6)
|
|
return 0;
|
|
if (sprite_state[k] == 11 && sprite_unk5[k] != 0) {
|
|
sprite_state[k] = 2;
|
|
sprite_delay_main[k] = 32;
|
|
sprite_flags2[k] = (sprite_flags2[k] & 0xe0) | 3;
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x1f);
|
|
return kCheckDamageFromPlayer_Carry | kCheckDamageFromPlayer_Ne;
|
|
}
|
|
}
|
|
uint8 type = sprite_type[k];
|
|
if (type == 0x7b) {
|
|
if (!sign8(button_b_frames - 9))
|
|
return 0;
|
|
} else if (type == 9) {
|
|
if (!sprite_A[k]) {
|
|
Sprite_ApplyRecoilToLink(k, 48);
|
|
set_when_damaging_enemies = 144;
|
|
link_incapacitated_timer = 16;
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x21);
|
|
sprite_delay_aux1[k] = 48;
|
|
sound_effect_2 = Sprite_CalculateSfxPan(k) | (enhanced_features0 & kFeatures0_MiscBugFixes ? 0x32 : 0);
|
|
Link_PlaceWeaponTink();
|
|
return kCheckDamageFromPlayer_Carry;
|
|
}
|
|
} else if (type == 0x92) {
|
|
if (sprite_C[k] >= 3)
|
|
goto is_many;
|
|
goto getting_out;
|
|
} else if (type == 0x26 || type == 0x13 || type == 2) {
|
|
bool cond = (type == 0x13 && kSpriteDamage_Tab3[sprite_D[k]] == link_direction_facing) || (type == 2);
|
|
Sprite_AttemptZapDamage(k);
|
|
Sprite_ApplyRecoilToLink(k, 32);
|
|
set_when_damaging_enemies = 16;
|
|
link_incapacitated_timer = 16;
|
|
if (cond) {
|
|
sprite_hit_timer[k] = 0;
|
|
Link_PlaceWeaponTink();
|
|
}
|
|
return 0; // what return value?
|
|
} else if (type == 0xcb || type == 0xcd || type == 0xcc || type == 0xd6 || type == 0xd7 || type == 0xce || type == 0x54) {
|
|
is_many:
|
|
Sprite_ApplyRecoilToLink(k, 32);
|
|
set_when_damaging_enemies = 144;
|
|
link_incapacitated_timer = 16;
|
|
}
|
|
if (!(sprite_defl_bits[k] & 4)) {
|
|
Sprite_AttemptZapDamage(k);
|
|
return kCheckDamageFromPlayer_Carry;
|
|
}
|
|
getting_out:
|
|
if (!set_when_damaging_enemies) {
|
|
Sprite_ApplyRecoilToLink(k, 4);
|
|
link_incapacitated_timer = 16;
|
|
set_when_damaging_enemies = 16;
|
|
}
|
|
Link_PlaceWeaponTink();
|
|
return kCheckDamageFromPlayer_Carry;
|
|
}
|
|
|
|
void Sprite_AttemptDamageToLinkWithCollisionCheck(int k) { // 86f3ca
|
|
if ((k ^ frame_counter) & 1)
|
|
return;
|
|
SpriteHitBox hb;
|
|
Sprite_DoHitBoxesFast(k, &hb);
|
|
Link_SetupHitBox_conditional(&hb);
|
|
if (CheckIfHitBoxesOverlap(&hb))
|
|
Sprite_AttemptDamageToLinkPlusRecoil(k);
|
|
}
|
|
|
|
void Sprite_AttemptDamageToLinkPlusRecoil(int k) { // 86f3db
|
|
if (countdown_for_blink | link_disable_sprite_damage)
|
|
return;
|
|
link_incapacitated_timer = 19;
|
|
Sprite_ApplyRecoilToLink(k, 24);
|
|
link_auxiliary_state = 1;
|
|
link_give_damage = kPlayerDamages[3 * (sprite_bump_damage[k] & 0xf) + link_armor];
|
|
if (sprite_type[k] == 0x61 && sprite_C[k]) {
|
|
link_actual_vel_x = sprite_x_vel[k] * 2;
|
|
link_actual_vel_y = sprite_y_vel[k] * 2;
|
|
}
|
|
}
|
|
|
|
void Player_SetupActionHitBox(SpriteHitBox *hb) { // 86f5e0
|
|
if (link_is_running) {
|
|
int j = link_direction_facing >> 1;
|
|
int x = link_x_coord + (kPlayerActionBoxRun_XLo[j] | kPlayerActionBoxRun_XHi[j] << 8);
|
|
int y = link_y_coord + (kPlayerActionBoxRun_YLo[j] | kPlayerActionBoxRun_YHi[j] << 8);
|
|
hb->r0_xlo = x;
|
|
hb->r8_xhi = x >> 8;
|
|
hb->r1_ylo = y;
|
|
hb->r9_yhi = y >> 8;
|
|
hb->r2 = hb->r3 = 16;
|
|
} else {
|
|
int t = 0;
|
|
if (!(link_item_in_hand & 10) && !(link_position_mode & 0x10)) {
|
|
if (sign8(button_b_frames)) {
|
|
int x = link_x_coord - 14;
|
|
int y = link_y_coord - 10;
|
|
hb->r0_xlo = x;
|
|
hb->r8_xhi = x >> 8;
|
|
hb->r1_ylo = y;
|
|
hb->r9_yhi = y >> 8;
|
|
hb->r2 = 44;
|
|
hb->r3 = 45;
|
|
return;
|
|
} else if (kPlayer_SetupActionHitBox_Tab4[button_b_frames]) {
|
|
hb->r8_xhi = 0x80;
|
|
return;
|
|
}
|
|
t = link_direction_facing * 8 + button_b_frames + 1;
|
|
}
|
|
int x = link_x_coord + (int8)(kPlayer_SetupActionHitBox_X[t] + player_oam_x_offset);
|
|
int y = link_y_coord + (int8)(kPlayer_SetupActionHitBox_Y[t] + player_oam_y_offset);
|
|
hb->r0_xlo = x;
|
|
hb->r8_xhi = x >> 8;
|
|
hb->r1_ylo = y;
|
|
hb->r9_yhi = y >> 8;
|
|
hb->r2 = kPlayer_SetupActionHitBox_W[t];
|
|
hb->r3 = kPlayer_SetupActionHitBox_H[t];
|
|
}
|
|
}
|
|
|
|
void Link_UpdateHitBoxWithSword(SpriteHitBox *hb) { // new
|
|
if (link_spin_attack_step_counter != 0 || sign8(button_b_frames) ||
|
|
kPlayer_SetupActionHitBox_Tab4[button_b_frames])
|
|
return;
|
|
int t = link_direction_facing * 8 + button_b_frames + 1, r;
|
|
int x = link_x_coord + (int8)(kPlayer_SetupActionHitBox_X[t] + player_oam_x_offset);
|
|
int y = link_y_coord + (int8)(kPlayer_SetupActionHitBox_Y[t] + player_oam_y_offset);
|
|
// Reduce size of hitbox if 'too' big.
|
|
hb->r2 = kPlayer_SetupActionHitBox_W[t];
|
|
if (hb->r2 - 2 >= 0)
|
|
r = IntMin(6, hb->r2 - 2), hb->r2 -= r, x += r >> 1;
|
|
hb->r3 = kPlayer_SetupActionHitBox_H[t];
|
|
if (hb->r3 - 2 >= 0)
|
|
r = IntMin(6, hb->r3 - 2), hb->r3 -= r, y += r >> 1;
|
|
hb->r0_xlo = x;
|
|
hb->r8_xhi = x >> 8;
|
|
hb->r1_ylo = y;
|
|
hb->r9_yhi = y >> 8;
|
|
}
|
|
|
|
void Sprite_DoHitBoxesFast(int k, SpriteHitBox *hb) { // 86f645
|
|
if (HIBYTE(dungmap_var8) == 0x80) {
|
|
hb->r10_spr_xhi = 0x80;
|
|
return;
|
|
}
|
|
int t;
|
|
t = Sprite_GetX(k) + (int8)HIBYTE(dungmap_var8);
|
|
hb->r4_spr_xlo = t;
|
|
hb->r10_spr_xhi = t >> 8;
|
|
t = Sprite_GetY(k) + (int8)BYTE(dungmap_var8);
|
|
hb->r5_spr_ylo = t;
|
|
hb->r11_spr_yhi = t >> 8;
|
|
hb->r6_spr_xsize = hb->r7_spr_ysize = (sprite_type[k] == 0x6a) ? 16 : 3;
|
|
}
|
|
|
|
void Sprite_ApplyRecoilToLink(int k, uint8 vel) { // 86f688
|
|
ProjectSpeedRet pt = Sprite_ProjectSpeedTowardsLink(k, vel);
|
|
link_actual_vel_x = pt.x;
|
|
link_actual_vel_y = pt.y;
|
|
g_ram[0xc7] = link_actual_vel_z = vel >> 1;
|
|
link_z_coord = 0;
|
|
}
|
|
|
|
void Link_PlaceWeaponTink() { // 86f69f
|
|
if (repulsespark_timer)
|
|
return;
|
|
repulsespark_timer = 5;
|
|
int t = (uint8)link_x_coord + player_oam_x_offset;
|
|
repulsespark_x_lo = t;
|
|
t = (uint8)link_y_coord + player_oam_y_offset + (t >> 8); // carry wtf
|
|
repulsespark_y_lo = t;
|
|
repulsespark_floor_status = link_is_on_lower_level;
|
|
sound_effect_1 = Link_CalculateSfxPan() | 5;
|
|
}
|
|
|
|
void Sprite_PlaceWeaponTink(int k) { // 86f6ca
|
|
if (repulsespark_timer)
|
|
return;
|
|
SpriteSfx_QueueSfx2WithPan(k, 5);
|
|
Sprite_PlaceRupulseSpark_2(k);
|
|
}
|
|
|
|
void Sprite_PlaceRupulseSpark_2(int k) { // 86f6d5
|
|
uint16 x = Sprite_GetX(k) - BG2HOFS_copy2;
|
|
uint16 y = Sprite_GetY(k) - BG2VOFS_copy2;
|
|
if (x & ~0xff || y & ~0xff)
|
|
return;
|
|
repulsespark_x_lo = sprite_x_lo[k];
|
|
repulsespark_y_lo = sprite_y_lo[k];
|
|
repulsespark_timer = 5;
|
|
repulsespark_floor_status = sprite_floor[k];
|
|
}
|
|
|
|
void Link_SetupHitBox_conditional(SpriteHitBox *hb) { // 86f705
|
|
if (link_disable_sprite_damage)
|
|
hb->r9_yhi = 0x80;
|
|
else
|
|
Link_SetupHitBox(hb);
|
|
}
|
|
|
|
void Link_SetupHitBox(SpriteHitBox *hb) { // 86f70a
|
|
hb->r3 = hb->r2 = 8;
|
|
uint16 x = link_x_coord + 4;
|
|
hb->r0_xlo = x;
|
|
hb->r8_xhi = x >> 8;
|
|
uint16 y = link_y_coord + 8;
|
|
hb->r1_ylo = y;
|
|
hb->r9_yhi = y >> 8;
|
|
}
|
|
|
|
void Sprite_SetupHitBox(int k, SpriteHitBox *hb) { // 86f7ef
|
|
if (sign8(sprite_z[k])) {
|
|
hb->r10_spr_xhi = 0x80;
|
|
return;
|
|
}
|
|
int i = sprite_flags4[k] & 0x1f;
|
|
int t, u;
|
|
|
|
t = sprite_x_lo[k] + (uint8)kSpriteHitbox_XLo[i];
|
|
hb->r4_spr_xlo = t;
|
|
t = sprite_x_hi[k] + (uint8)kSpriteHitbox_XHi[i] + (t >> 8);
|
|
hb->r10_spr_xhi = t;
|
|
|
|
t = sprite_y_lo[k] + (uint8)kSpriteHitbox_YLo[i];
|
|
u = t >> 8;
|
|
t = (t & 0xff) - sprite_z[k];
|
|
hb->r5_spr_ylo = t;
|
|
t = sprite_y_hi[k] - (t < 0);
|
|
hb->r11_spr_yhi = t + u + (uint8)kSpriteHitbox_YHi[i];
|
|
|
|
hb->r6_spr_xsize = kSpriteHitbox_XSize[i];
|
|
hb->r7_spr_ysize = kSpriteHitbox_YSize[i];
|
|
}
|
|
|
|
// Returns the carry flag
|
|
bool CheckIfHitBoxesOverlap(SpriteHitBox *hb) { // 86f836
|
|
int t;
|
|
uint8 r15, r12;
|
|
|
|
if (hb->r8_xhi == 0x80 || hb->r10_spr_xhi == 0x80)
|
|
return false;
|
|
|
|
t = hb->r5_spr_ylo - hb->r1_ylo;
|
|
r15 = t + hb->r7_spr_ysize;
|
|
r12 = hb->r11_spr_yhi - hb->r9_yhi - (t < 0);
|
|
t = r12 + (((t & 0xff) + 0x80) >> 8);
|
|
if (t & 0xff)
|
|
return (t >= 0x100);
|
|
if ((uint8)(hb->r3 + hb->r7_spr_ysize) < r15)
|
|
return false;
|
|
|
|
t = hb->r4_spr_xlo - hb->r0_xlo;
|
|
r15 = t + hb->r6_spr_xsize;
|
|
r12 = hb->r10_spr_xhi - hb->r8_xhi - (t < 0);
|
|
t = r12 + (((t & 0xff) + 0x80) >> 8);
|
|
if (t & 0xff)
|
|
return (t >= 0x100);
|
|
if ((uint8)(hb->r2 + hb->r6_spr_xsize) < r15)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void Oam_AllocateDeferToPlayer(int k) { // 86f86c
|
|
if (sprite_floor[k] != link_is_on_lower_level)
|
|
return;
|
|
PairU8 right = Sprite_IsRightOfLink(k);
|
|
if ((uint8)(right.b + 0x10) >= 0x20)
|
|
return;
|
|
PairU8 below = Sprite_IsBelowLink(k);
|
|
if ((uint8)(below.b + 0x20) >= 0x48)
|
|
return;
|
|
uint8 nslots = ((sprite_flags2[k] & 0x1f) + 1) << 2;
|
|
if (below.a)
|
|
Oam_AllocateFromRegionC(nslots);
|
|
else
|
|
Oam_AllocateFromRegionB(nslots);
|
|
}
|
|
|
|
void SpriteModule_Die(int k) { // 86f8a2
|
|
SpriteDeath_MainEx(k, false);
|
|
}
|
|
|
|
void Sprite_DoTheDeath(int k) { // 86f923
|
|
uint8 type = sprite_type[k];
|
|
// This is how Vitreous knows whether to come out of his slime pool
|
|
if (type == 0xBE)
|
|
sprite_G[0]--;
|
|
|
|
if (type == 0xaa && sprite_E[k] != 0) {
|
|
uint8 bak = sprite_subtype[k];
|
|
PrepareEnemyDrop(k, kPikitDropItems[sprite_E[k] - 1]);
|
|
sprite_subtype[k] = bak;
|
|
if (bak == 1) {
|
|
sprite_oam_flags[k] = 9;
|
|
sprite_flags3[k] = 0xf0;
|
|
}
|
|
sprite_head_dir[k]++;
|
|
return;
|
|
}
|
|
|
|
// Resets the music in the village when the crazy green guards are killed.
|
|
if (type == 0x45 && sram_progress_indicator == 2 && BYTE(overworld_area_index) == 0x18)
|
|
music_control = 7;
|
|
|
|
uint8 drop_item = sprite_die_action[k];
|
|
if (drop_item != 0) {
|
|
sprite_subtype[k] = sprite_N[k];
|
|
sprite_N[k] = 255;
|
|
uint8 arg = (drop_item == 1) ? 0xe4 : // small key, big key or rupee
|
|
(drop_item == 3) ? 0xd9 : 0xe5;
|
|
PrepareEnemyDrop(k, arg);
|
|
return;
|
|
}
|
|
|
|
uint8 prize = sprite_flags5[k] & 0xf;
|
|
if (prize-- != 0) {
|
|
uint8 luck = item_drop_luck;
|
|
if (luck != 0) {
|
|
if (++luck_kill_counter >= 10)
|
|
item_drop_luck = 0;
|
|
if (luck == 1) {
|
|
ForcePrizeDrop(k, prize, 1);
|
|
return;
|
|
}
|
|
} else {
|
|
if (!(GetRandomNumber() & kPrizeMasks[prize])) {
|
|
ForcePrizeDrop(k, prize, prize);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
sprite_state[k] = 0;
|
|
SpriteDeath_Func4(k);
|
|
}
|
|
|
|
void ForcePrizeDrop(int k, uint8 prize, uint8 slot) { // 86f9bc
|
|
prize = prize * 8 | prizes_arr1[slot];
|
|
prizes_arr1[slot] = (prizes_arr1[slot] + 1) & 7;
|
|
PrepareEnemyDrop(k, kPrizeItems[prize]);
|
|
}
|
|
|
|
void PrepareEnemyDrop(int k, uint8 item) { // 86f9d1
|
|
sprite_type[k] = item;
|
|
if (item == 0xe5)
|
|
SpritePrep_BigKey_load_graphics(k);
|
|
else if (item == 0xe4)
|
|
SpritePrep_KeySetItemDrop(k);
|
|
|
|
sprite_state[k] = 9;
|
|
uint8 zbak = sprite_z[k];
|
|
SpritePrep_LoadProperties(k);
|
|
sprite_ignore_projectile[k]++;
|
|
|
|
uint8 pz = kPrizeZ[sprite_type[k] - 0xd8];
|
|
sprite_z_vel[k] = pz & 0xf0;
|
|
Sprite_SetX(k, Sprite_GetX(k) + (pz & 0xf));
|
|
sprite_z[k] = zbak;
|
|
sprite_delay_aux4[k] = 21;
|
|
sprite_stunned[k] = 255;
|
|
SpriteDeath_Func4(k);
|
|
}
|
|
|
|
void SpriteDeath_Func4(int k) { // 86fa25
|
|
if (sprite_type[k] == 0xa2 && Sprite_CheckIfScreenIsClear())
|
|
Ancilla_SpawnFallingPrize(4);
|
|
Sprite_ManuallySetDeathFlagUW(k);
|
|
num_sprites_killed++;
|
|
if (sprite_type[k] == 0x40) {
|
|
// evil barrier
|
|
sprite_state[k] = 9;
|
|
sprite_graphics[k] = 4;
|
|
SpriteDeath_MainEx(k, true);
|
|
}
|
|
}
|
|
|
|
void SpriteDeath_DrawPoof(int k) { // 86fb2a
|
|
if (dung_hdr_collision == 4)
|
|
sprite_obj_prio[k] = 0x30;
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
uint8 r12 = (sprite_flags3[k] & 0x20) >> 3;
|
|
int i = ((sprite_delay_main[k] & 0x1c) ^ 0x1c) + 3, n = 3;
|
|
do {
|
|
if (kPerishOverlay_Char[i]) {
|
|
oam->charnum = kPerishOverlay_Char[i];
|
|
oam->y = HIBYTE(dungmap_var7) - r12 + kPerishOverlay_Y[i];
|
|
oam->x = BYTE(dungmap_var7) - r12 + kPerishOverlay_X[i];
|
|
oam->flags = (info.flags & 0x30) | kPerishOverlay_Flags[i];
|
|
}
|
|
} while (oam++, i--, --n >= 0);
|
|
Sprite_CorrectOamEntries(k, 3, 0);
|
|
}
|
|
|
|
void SpriteModule_Fall2(int k) { // 86fbea
|
|
uint8 delay = sprite_delay_main[k];
|
|
if (!delay) {
|
|
sprite_state[k] = 0;
|
|
Sprite_ManuallySetDeathFlagUW(k);
|
|
return;
|
|
}
|
|
|
|
if (delay >= 0x40) {
|
|
if (sprite_oam_flags[k] != 5) {
|
|
if (!(delay & 7 | submodule_index | flag_unk1))
|
|
SpriteSfx_QueueSfx3WithPan(k, 0x31);
|
|
SpriteActive_Main(k);
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
Sprite_DrawDistress_custom(info.x, info.y - 8, delay + 20);
|
|
return;
|
|
}
|
|
sprite_delay_main[k] = delay = 63;
|
|
}
|
|
|
|
if (delay == 61)
|
|
SpriteSfx_QueueSfx2WithPan(k, 0x20);
|
|
|
|
int j = delay >> 1;
|
|
|
|
if (sprite_type[k] == 0x26 || sprite_type[k] == 0x13) {
|
|
sprite_graphics[k] = kSpriteFall_Tab2[j];
|
|
SpriteDraw_FallingHelmaBeetle(k);
|
|
} else {
|
|
uint8 t = kSpriteFall_Tab1[j];
|
|
if (t < 12)
|
|
t += kSpriteFall_Tab4[sprite_D[k]];
|
|
sprite_graphics[k] = t;
|
|
SpriteDraw_FallingHumanoid(k);
|
|
}
|
|
if (frame_counter & kSpriteFall_Tab3[sprite_delay_main[k] >> 3] | submodule_index)
|
|
return;
|
|
Sprite_CheckTileProperty(k, 0x68);
|
|
if (sprite_tiletype != 0x20) {
|
|
sprite_y_recoil[k] = 0;
|
|
sprite_x_recoil[k] = 0;
|
|
}
|
|
sprite_y_vel[k] = (int8)sprite_y_recoil[k] >> 2;
|
|
sprite_x_vel[k] = (int8)sprite_x_recoil[k] >> 2;
|
|
Sprite_MoveXY(k);
|
|
}
|
|
|
|
void SpriteDraw_FallingHelmaBeetle(int k) { // 86fd17
|
|
PrepOamCoordsRet info;
|
|
const DrawMultipleData *src = kSpriteDrawFall0Data + sprite_graphics[k];
|
|
if (sprite_type[k] == 0x13)
|
|
src += 6;
|
|
Sprite_DrawMultiple(k, src, 1, &info);
|
|
}
|
|
|
|
void SpriteDraw_FallingHumanoid(int k) { // 86fe5b
|
|
PrepOamCoordsRet info;
|
|
if (Sprite_PrepOamCoordOrDoubleRet(k, &info))
|
|
return;
|
|
|
|
int q = sprite_graphics[k];
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int n = (q < 12 && (q & 3) == 0) ? 3 : 0, nn = n;
|
|
do {
|
|
int i = q * 4 + n;
|
|
SetOamPlain(oam, info.x + kSpriteDrawFall1_X[i], info.y + kSpriteDrawFall1_Y[i],
|
|
kSpriteDrawFall1_Char[i], info.flags ^ kSpriteDrawFall1_Flags[i], kSpriteDrawFall1_Ext[i]);
|
|
} while (oam++, --n >= 0);
|
|
Sprite_CorrectOamEntries(k, nn, 0xff);
|
|
}
|
|
|
|
void Sprite_CorrectOamEntries(int k, int n, uint8 islarge) { // 86febc
|
|
OamEnt *oam = GetOamCurPtr();
|
|
uint8 *extp = &g_ram[oam_ext_cur_ptr];
|
|
uint16 spr_x = Sprite_GetX(k);
|
|
uint16 spr_y = Sprite_GetY(k);
|
|
uint8 scrollx = spr_x - BG2HOFS_copy2;
|
|
uint8 scrolly = spr_y - BG2VOFS_copy2;
|
|
do {
|
|
uint16 x = spr_x + (int8)(oam->x - scrollx);
|
|
uint16 y = spr_y + (int8)(oam->y - scrolly);
|
|
uint8 ext = sign8(islarge) ? (*extp & 2) : islarge;
|
|
*extp = ext + ((uint16)(x - BG2HOFS_copy2) >= 0x100);
|
|
if ((uint16)(y + 0x10 - BG2VOFS_copy2) >= 0x100)
|
|
oam->y = 0xf0;
|
|
} while (oam++, extp++, --n >= 0);
|
|
}
|
|
|
|
bool Sprite_ReturnIfRecoiling(int k) { // 86ff78
|
|
if (!sprite_F[k])
|
|
return false;
|
|
if (!(sprite_F[k] & 0x7f)) {
|
|
sprite_F[k] = 0;
|
|
return false;
|
|
}
|
|
uint8 yvbak = sprite_y_vel[k];
|
|
uint8 xvbak = sprite_x_vel[k];
|
|
if (!--sprite_F[k] && ((uint8)(sprite_x_recoil[k] + 0x20) >= 0x40 || (uint8)(sprite_y_recoil[k] + 0x20) >= 0x40))
|
|
sprite_F[k] = 144;
|
|
|
|
int i = sprite_F[k];
|
|
uint8 t;
|
|
if (!sign8(i) && !(frame_counter & kSprite2_ReturnIfRecoiling_Masks[i>>2])) {
|
|
sprite_y_vel[k] = sprite_y_recoil[k];
|
|
sprite_x_vel[k] = sprite_x_recoil[k];
|
|
if (!sign8(sprite_bump_damage[k]) && (t = (Sprite_CheckTileCollision(k) & 0xf))) {
|
|
if (t < 4)
|
|
sprite_x_recoil[k] = sprite_x_vel[k] = 0;
|
|
else
|
|
sprite_y_recoil[k] = sprite_y_vel[k] = 0;
|
|
} else {
|
|
Sprite_MoveXY(k);
|
|
}
|
|
}
|
|
sprite_y_vel[k] = yvbak;
|
|
sprite_x_vel[k] = xvbak;
|
|
return sprite_type[k] != 0x7a;
|
|
}
|
|
|
|
bool Sprite_CheckIfLinkIsBusy() { // 87f4d0
|
|
if (link_auxiliary_state | link_pose_for_item | (link_state_bits & 0x80))
|
|
return true;
|
|
for (int i = 4; i >= 0; i--) {
|
|
if (ancilla_type[i] == 0x27)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Sprite_SetSpawnedCoordinates(int k, SpriteSpawnInfo *info) { // 89ae64
|
|
sprite_x_lo[k] = info->r0_x;
|
|
sprite_x_hi[k] = info->r0_x >> 8;
|
|
sprite_y_lo[k] = info->r2_y;
|
|
sprite_y_hi[k] = info->r2_y >> 8;
|
|
sprite_z[k] = info->r4_z;
|
|
}
|
|
|
|
bool Sprite_CheckIfScreenIsClear() { // 89af32
|
|
for (int i = 15; i >= 0; i--) {
|
|
if (sprite_state[i] && !(sprite_flags4[i] & 0x40)) {
|
|
uint16 x = Sprite_GetX(i) - BG2HOFS_copy2;
|
|
uint16 y = Sprite_GetY(i) - BG2VOFS_copy2;
|
|
if (x < 256 && y < 256)
|
|
return false;
|
|
}
|
|
}
|
|
return Sprite_CheckIfOverlordsClear();
|
|
}
|
|
|
|
bool Sprite_CheckIfRoomIsClear() { // 89af61
|
|
for (int i = 15; i >= 0; i--) {
|
|
if (sprite_state[i] && !(sprite_flags4[i] & 0x40))
|
|
return false;
|
|
}
|
|
return Sprite_CheckIfOverlordsClear();
|
|
}
|
|
|
|
bool Sprite_CheckIfOverlordsClear() { // 89af76
|
|
for (int i = 7; i >= 0; i--) {
|
|
if (overlord_type[i] == 0x14 || overlord_type[i] == 0x18)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Sprite_InitializeMirrorPortal() { // 89af89
|
|
for (int k = 15; k >= 0; k--) {
|
|
if (sprite_state[k] && sprite_type[k] == 0x6c)
|
|
sprite_state[k] = 0;
|
|
}
|
|
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamically(0xff, 0x6c, &info);
|
|
if (j < 0)
|
|
j = 0;
|
|
|
|
Sprite_SetX(j, bird_travel_x_hi[15] << 8 | bird_travel_x_lo[15]);
|
|
Sprite_SetY(j, (bird_travel_y_hi[15] << 8 | bird_travel_y_lo[15]) + 8);
|
|
|
|
sprite_floor[j] = 0;
|
|
sprite_ignore_projectile[j] = 1;
|
|
}
|
|
|
|
void Sprite_InitializeSlots() { // 89afd6
|
|
for (int k = 15; k >= 0; k--) {
|
|
uint8 st = sprite_state[k], ty = sprite_type[k];
|
|
if (st != 0) {
|
|
if (st == 10) {
|
|
if (ty != 0xec && ty != 0xd2) {
|
|
link_picking_throw_state = 0;
|
|
link_state_bits = 0;
|
|
sprite_state[k] = 0;
|
|
}
|
|
} else {
|
|
if (ty != 0x6c && sprite_room[k] != BYTE(overworld_area_index))
|
|
sprite_state[k] = 0;
|
|
}
|
|
}
|
|
}
|
|
for (int k = 7; k >= 0; k--) {
|
|
if (overlord_type[k] && overlord_spawned_in_area[k] != BYTE(overworld_area_index))
|
|
overlord_type[k] = 0;
|
|
}
|
|
}
|
|
|
|
void Garnish_ExecuteUpperSlots() { // 89b08c
|
|
HandleScreenFlash();
|
|
|
|
if (garnish_active) {
|
|
for (int i = 29; i >= 15; i--)
|
|
Garnish_ExecuteSingle(i);
|
|
}
|
|
}
|
|
|
|
void Garnish_ExecuteLowerSlots() { // 89b097
|
|
if (garnish_active) {
|
|
for (int i = 14; i >= 0; i--)
|
|
Garnish_ExecuteSingle(i);
|
|
}
|
|
}
|
|
|
|
void Garnish_ExecuteSingle(int k) { // 89b0b6
|
|
cur_object_index = k;
|
|
uint8 type = garnish_type[k];
|
|
if (type == 0)
|
|
return;
|
|
if ((type == 5 || (submodule_index | flag_unk1) == 0) && garnish_countdown[k] != 0 && --garnish_countdown[k] == 0) {
|
|
garnish_type[k] = 0;
|
|
return;
|
|
}
|
|
uint8 sprsize = kGarnish_OamMemSize[garnish_type[k]];
|
|
if (sort_sprites_setting) {
|
|
if (garnish_floor[k])
|
|
Oam_AllocateFromRegionF(sprsize);
|
|
else
|
|
Oam_AllocateFromRegionD(sprsize);
|
|
} else {
|
|
Oam_AllocateFromRegionA(sprsize);
|
|
}
|
|
kGarnish_Funcs[garnish_type[k] - 1](k);
|
|
}
|
|
|
|
void Garnish15_ArrghusSplash(int k) { // 89b178
|
|
static const int8 kArrghusSplash_X[8] = {-12, 20, -10, 10, -8, 8, -4, 4};
|
|
static const int8 kArrghusSplash_Y[8] = {-4, -4, -2, -2, 0, 0, 0, 0};
|
|
static const uint8 kArrghusSplash_Char[8] = {0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xac, 0xac};
|
|
static const uint8 kArrghusSplash_Flags[8] = {0x34, 0x74, 0x34, 0x74, 0x34, 0x74, 0x34, 0x74};
|
|
static const uint8 kArrghusSplash_Ext[8] = {0, 0, 2, 2, 2, 2, 2, 2};
|
|
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int g = (garnish_countdown[k] >> 1) & 6;
|
|
for (int i = 1; i >= 0; i--, oam++) {
|
|
int j = i + g;
|
|
SetOamPlain(oam, pt.x + kArrghusSplash_X[j], pt.y + kArrghusSplash_Y[j], kArrghusSplash_Char[j], kArrghusSplash_Flags[j], kArrghusSplash_Ext[j]);
|
|
}
|
|
}
|
|
|
|
void Garnish13_PyramidDebris(int k) { // 89b216
|
|
OamEnt *oam = GetOamCurPtr();
|
|
|
|
int y = (garnish_y_lo[k] << 8) + garnish_y_subpixel[k] + ((int8)garnish_y_vel[k] << 4);
|
|
garnish_y_subpixel[k] = y;
|
|
garnish_y_lo[k] = y >> 8;
|
|
|
|
int x = (garnish_x_lo[k] << 8) + garnish_x_subpixel[k] + ((int8)garnish_x_vel[k] << 4);
|
|
garnish_x_subpixel[k] = x;
|
|
garnish_x_lo[k] = x >> 8;
|
|
|
|
garnish_y_vel[k] = garnish_y_vel[k] + 3;
|
|
uint8 t;
|
|
if ((t = garnish_x_lo[k] - BG2HOFS_copy2) >= 248) {
|
|
garnish_type[k] = 0;
|
|
return;
|
|
}
|
|
oam->x = t;
|
|
if ((t = garnish_y_lo[k] - BG2VOFS_copy2) >= 240) {
|
|
garnish_type[k] = 0;
|
|
return;
|
|
}
|
|
oam->y = t;
|
|
oam->charnum = 0x5c;
|
|
oam->flags = (frame_counter << 3) & 0xc0 | 0x34;
|
|
bytewise_extended_oam[oam - oam_buf] = 0;
|
|
}
|
|
|
|
void Garnish11_WitheringGanonBatFlame(int k) { // 89b2b2
|
|
if ((submodule_index | flag_unk1) == 0) {
|
|
Garnish_SetY(k, Garnish_GetY(k) - 1);
|
|
}
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
OamEnt *oam = GetOamCurPtr();
|
|
SetOamPlain(oam + 0, pt.x + 0, pt.y, 0xa4, 0x22, 0);
|
|
SetOamPlain(oam + 1, pt.x + 8, pt.y, 0xa5, 0x22, 0);
|
|
}
|
|
|
|
void Garnish10_GanonBatFlame(int k) { // 89b306
|
|
static const uint8 kGanonBatFlame_Idx[32] = {
|
|
7, 6, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
|
|
5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
|
|
};
|
|
static const uint8 kGanonBatFlame_Char[7] = {0xac, 0xac, 0x66, 0x66, 0x8e, 0xa0, 0xa2};
|
|
static const uint8 kGanonBatFlame_Flags[7] = {1, 0x41, 1, 0x41, 0, 0, 0};
|
|
|
|
if (garnish_countdown[k] == 8)
|
|
garnish_type[k] = 0x11;
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = kGanonBatFlame_Idx[garnish_countdown[k] >> 3];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kGanonBatFlame_Char[j], kGanonBatFlame_Flags[j] | 0x22, 2);
|
|
Garnish_CheckPlayerCollision(k, pt.x, pt.y);
|
|
}
|
|
|
|
void Garnish0C_TrinexxIceBreath(int k) { // 89b34f
|
|
static const uint8 kTrinexxIce_Char[12] = {0xe8, 0xe8, 0xe6, 0xe6, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4};
|
|
static const uint8 kTrinexxIce_Flags[4] = {0, 0x40, 0xc0, 0x80};
|
|
|
|
if (garnish_countdown[k] == 0x50 && (submodule_index | flag_unk1) == 0) {
|
|
Dungeon_UpdateTileMapWithCommonTile(Garnish_GetX(k), Garnish_GetY(k) - 16, 18);
|
|
}
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kTrinexxIce_Char[garnish_countdown[k] >> 4],
|
|
kTrinexxIce_Flags[(garnish_countdown[k] >> 2) & 3] | 0x35, 2);
|
|
}
|
|
|
|
void Garnish14_KakKidDashDust(int k) { // 89b3bc
|
|
Garnish_DustCommon(k, 2);
|
|
}
|
|
|
|
void Garnish_WaterTrail(int k) { // 89b3c2
|
|
Garnish_DustCommon(k, 3);
|
|
}
|
|
|
|
void Garnish0A_CannonSmoke(int k) { // 89b3ee
|
|
static const uint8 kGarnish_CannonPoof_Char[2] = { 0x8a, 0x86 };
|
|
static const uint8 kGarnish_CannonPoof_Flags[4] = { 0x20, 0x10, 0x30, 0x30 };
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kGarnish_CannonPoof_Char[garnish_countdown[k] >> 3], kGarnish_CannonPoof_Flags[j] | 4, 2);
|
|
}
|
|
|
|
void Garnish09_LightningTrail(int k) { // 89b429
|
|
static const uint8 kLightningTrail_Char[8] = {0xcc, 0xec, 0xce, 0xee, 0xcc, 0xec, 0xce, 0xee};
|
|
static const uint8 kLightningTrail_Flags[8] = {0x31, 0x31, 0x31, 0x31, 0x71, 0x71, 0x71, 0x71};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y,
|
|
kLightningTrail_Char[j] - (BYTE(dungeon_room_index2) == 0x20 ? 0x80 : 0),
|
|
(frame_counter << 1) & 0xe | kLightningTrail_Flags[j], 2);
|
|
Garnish_CheckPlayerCollision(k, pt.x, pt.y);
|
|
}
|
|
|
|
void Garnish_CheckPlayerCollision(int k, int x, int y) { // 89b459
|
|
if ((k ^ frame_counter) & 7 | countdown_for_blink | link_disable_sprite_damage)
|
|
return;
|
|
|
|
if ((uint8)(link_x_coord - BG2HOFS_copy2 - x + 12) < 24 &&
|
|
(uint8)(link_y_coord - BG2VOFS_copy2 - y + 22) < 28) {
|
|
link_auxiliary_state = 1;
|
|
link_incapacitated_timer = 16;
|
|
link_give_damage = 16;
|
|
link_actual_vel_x ^= 255;
|
|
link_actual_vel_y ^= 255;
|
|
}
|
|
}
|
|
|
|
void Garnish07_BabasuFlash(int k) { // 89b49e
|
|
static const uint8 kBabusuFlash_Char[4] = {0xa8, 0x8a, 0x86, 0x86};
|
|
static const uint8 kBabusuFlash_Flags[4] = {0x2d, 0x2c, 0x2c, 0x2c};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_countdown[k] >> 3;
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kBabusuFlash_Char[j], kBabusuFlash_Flags[j], 2);
|
|
}
|
|
|
|
void Garnish08_KholdstareTrail(int k) { // 89b4c6
|
|
static const int8 kGarnish_Nebule_XY[3] = { -1, -1, 0 };
|
|
static const uint8 kGarnish_Nebule_Char[3] = { 0x9c, 0x9d, 0x8d };
|
|
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int i = garnish_countdown[k] >> 2;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x + kGarnish_Nebule_XY[i], pt.y + kGarnish_Nebule_XY[i], kGarnish_Nebule_Char[i],
|
|
(sprite_oam_flags[j] | sprite_obj_prio[j]) & ~1, 0);
|
|
}
|
|
|
|
void Garnish06_ZoroTrail(int k) { // 89b4fb
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, 0x75, sprite_oam_flags[j] | sprite_obj_prio[j], 0);
|
|
}
|
|
|
|
void Garnish12_Sparkle(int k) { // 89b520
|
|
Garnish_SparkleCommon(k, 2);
|
|
}
|
|
|
|
void Garnish_SimpleSparkle(int k) { // 89b526
|
|
Garnish_SparkleCommon(k, 3);
|
|
}
|
|
|
|
void Garnish0E_TrinexxFireBreath(int k) { // 89b55d
|
|
static const uint8 kTrinexxLavaBubble_Char[4] = {0x83, 0xc7, 0x80, 0x9d};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kTrinexxLavaBubble_Char[garnish_countdown[k] >> 3],
|
|
(sprite_oam_flags[j] | sprite_obj_prio[j]) & 0xf0 | 0xe, 0);
|
|
}
|
|
|
|
void Garnish0F_BlindLaserTrail(int k) { // 89b591
|
|
static const uint8 kBlindLaserTrail_Char[4] = {0x61, 0x71, 0x70, 0x60};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kBlindLaserTrail_Char[garnish_oam_flags[k] - 7], sprite_oam_flags[j] | sprite_obj_prio[j], 0);
|
|
}
|
|
|
|
void Garnish04_LaserTrail(int k) { // 89b5bb
|
|
static const uint8 kLaserBeamTrail_Char[2] = {0xd2, 0xf3};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, kLaserBeamTrail_Char[garnish_oam_flags[k]], 0x25, 0);
|
|
}
|
|
|
|
bool Garnish_ReturnIfPrepFails(int k, Point16U *pt) { // 89b5de
|
|
uint16 x = Garnish_GetX(k) - BG2HOFS_copy2;
|
|
uint16 y = Garnish_GetY(k) - BG2VOFS_copy2;
|
|
|
|
if (x >= 256 || y >= 256) {
|
|
garnish_type[k] = 0;
|
|
return true;
|
|
}
|
|
pt->x = x;
|
|
pt->y = y - 16;
|
|
return false;
|
|
}
|
|
|
|
void Garnish03_FallingTile(int k) { // 89b627
|
|
static const uint8 kCrumbleTile_XY[5] = {4, 0, 0, 0, 0};
|
|
static const uint8 kCrumbleTile_Char[5] = {0x80, 0xcc, 0xcc, 0xea, 0xca};
|
|
static const uint8 kCrumbleTile_Flags[5] = {0x30, 0x31, 0x31, 0x31, 0x31};
|
|
static const uint8 kCrumbleTile_Ext[5] = {0, 2, 2, 2, 2};
|
|
|
|
int j;
|
|
if ((j = garnish_countdown[k]) == 0x1e && (j = (submodule_index | flag_unk1)) == 0)
|
|
Dungeon_UpdateTileMapWithCommonTile(Garnish_GetX(k), Garnish_GetY(k) - 16, 4);
|
|
j >>= 3;
|
|
uint16 x = Garnish_GetX(k) + kCrumbleTile_XY[j] - BG2HOFS_copy2;
|
|
uint16 y = Garnish_GetY(k) + kCrumbleTile_XY[j] - BG2VOFS_copy2;
|
|
if (x < 256 && y < 256)
|
|
SetOamPlain(GetOamCurPtr(), x, y - 16, kCrumbleTile_Char[j], kCrumbleTile_Flags[j], kCrumbleTile_Ext[j]);
|
|
}
|
|
|
|
void Garnish01_FireSnakeTail(int k) { // 89b6c0
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), pt.x, pt.y, 0x28, sprite_oam_flags[j] | sprite_obj_prio[j], 2);
|
|
}
|
|
|
|
void Garnish02_MothulaBeamTrail(int k) { // 89b6e1
|
|
int j = garnish_sprite[k];
|
|
SetOamPlain(GetOamCurPtr(), garnish_x_lo[k] - BG2HOFS_copy2, garnish_y_lo[k] - BG2VOFS_copy2, 0xaa,
|
|
sprite_oam_flags[j] | sprite_obj_prio[j], 2);
|
|
}
|
|
|
|
void Dungeon_ResetSprites() { // 89c114
|
|
Dungeon_CacheTransSprites();
|
|
link_picking_throw_state = 0;
|
|
link_state_bits = 0;
|
|
Sprite_DisableAll();
|
|
sprcoll_x_size = sprcoll_y_size = 0xffff;
|
|
int j = FindInWordArray(dungeon_room_history, dungeon_room_index2, 4);
|
|
if (j < 0) {
|
|
uint16 blk = dungeon_room_history[3];
|
|
dungeon_room_history[3] = dungeon_room_history[2];
|
|
dungeon_room_history[2] = dungeon_room_history[1];
|
|
dungeon_room_history[1] = dungeon_room_history[0];
|
|
dungeon_room_history[0] = dungeon_room_index2;
|
|
if (blk != 0xffff)
|
|
sprite_where_in_room[blk] = 0;
|
|
}
|
|
Dungeon_LoadSprites();
|
|
}
|
|
|
|
void Dungeon_CacheTransSprites() { // 89c176
|
|
if (!player_is_indoors)
|
|
return;
|
|
alt_sprites_flag = player_is_indoors;
|
|
for (int k = 15; k >= 0; k--) {
|
|
alt_sprite_state[k] = 0;
|
|
alt_sprite_type[k] = sprite_type[k];
|
|
alt_sprite_x_lo[k] = sprite_x_lo[k];
|
|
alt_sprite_graphics[k] = sprite_graphics[k];
|
|
alt_sprite_x_hi[k] = sprite_x_hi[k];
|
|
alt_sprite_y_lo[k] = sprite_y_lo[k];
|
|
alt_sprite_y_hi[k] = sprite_y_hi[k];
|
|
if (sprite_pause[k] != 0 || sprite_state[k] == 4 || sprite_state[k] == 10)
|
|
continue;
|
|
alt_sprite_state[k] = sprite_state[k];
|
|
alt_sprite_A[k] = sprite_A[k];
|
|
alt_sprite_head_dir[k] = sprite_head_dir[k];
|
|
alt_sprite_oam_flags[k] = sprite_oam_flags[k];
|
|
alt_sprite_obj_prio[k] = sprite_obj_prio[k];
|
|
alt_sprite_D[k] = sprite_D[k];
|
|
alt_sprite_flags2[k] = sprite_flags2[k];
|
|
alt_sprite_floor[k] = sprite_floor[k];
|
|
alt_sprite_spawned_flag[k] = sprite_ai_state[k];
|
|
alt_sprite_flags3[k] = sprite_flags3[k];
|
|
alt_sprite_B[k] = sprite_B[k];
|
|
alt_sprite_C[k] = sprite_C[k];
|
|
alt_sprite_E[k] = sprite_E[k];
|
|
alt_sprite_subtype2[k] = sprite_subtype2[k];
|
|
alt_sprite_height_above_shadow[k] = sprite_z[k];
|
|
alt_sprite_delay_main[k] = sprite_delay_main[k];
|
|
alt_sprite_I[k] = sprite_I[k];
|
|
alt_sprite_maybe_ignore_projectile[k] = sprite_ignore_projectile[k];
|
|
}
|
|
}
|
|
|
|
void Sprite_DisableAll() { // 89c22f
|
|
for (int k = 15; k >= 0; k--) {
|
|
if (sprite_state[k] && (player_is_indoors || sprite_type[k] != 0x6c))
|
|
sprite_state[k] = 0;
|
|
}
|
|
for (int k = 9; k >= 0; k--)
|
|
ancilla_type[k] = 0;
|
|
flag_is_ancilla_to_pick_up = 0;
|
|
sprite_limit_instance = 0;
|
|
byte_7E0B9B = 0;
|
|
byte_7E0B88 = 0;
|
|
archery_game_arrows_left = 0;
|
|
garnish_active = 0;
|
|
byte_7E0B9E = 0;
|
|
activate_bomb_trap_overlord = 0;
|
|
intro_times_pal_flash = 0;
|
|
byte_7E0FF8 = 0;
|
|
byte_7E0FFB = 0;
|
|
flag_block_link_menu = 0;
|
|
byte_7E0FFD = 0;
|
|
byte_7E0FC6 = 0;
|
|
is_archer_or_shovel_game = 0;
|
|
for (int k = 7; k >= 0; k--)
|
|
overlord_type[k] = 0;
|
|
for (int k = 29; k >= 0; k--)
|
|
garnish_type[k] = 0;
|
|
}
|
|
|
|
void Dungeon_LoadSprites() { // 89c290
|
|
const uint8 *src = kDungeonSprites + kDungeonSpriteOffs[dungeon_room_index2];
|
|
byte_7E0FB1 = dungeon_room_index2 >> 3 & 0xfe;
|
|
byte_7E0FB0 = (dungeon_room_index2 & 0xf) << 1;
|
|
sort_sprites_setting = *src++;
|
|
for (int k = 0; *src != 0xff; src += 3)
|
|
k = Dungeon_LoadSingleSprite(k, src) + 1;
|
|
}
|
|
|
|
void Sprite_ManuallySetDeathFlagUW(int k) { // 89c2f5
|
|
if (!player_is_indoors || sprite_defl_bits[k] & 1 || sign8(sprite_N[k]))
|
|
return;
|
|
sprite_where_in_room[dungeon_room_index2] |= 1 << sprite_N[k];
|
|
}
|
|
|
|
int Dungeon_LoadSingleSprite(int k, const uint8 *src) { // 89c327
|
|
uint8 y = src[0], x = src[1], type = src[2];
|
|
if (type == 0xe4) {
|
|
if (y == 0xfe || y == 0xfd) {
|
|
sprite_die_action[k - 1] = (y == 0xfe) ? 1 : 2;
|
|
return k - 1;
|
|
}
|
|
} else if (x >= 0xe0) {
|
|
Dungeon_LoadSingleOverlord(src);
|
|
return k - 1;
|
|
}
|
|
if (!(kSpriteInit_DeflBits[type] & 1) && (sprite_where_in_room[dungeon_room_index2] & (1 << k)))
|
|
return k;
|
|
sprite_state[k] = 8;
|
|
tmp_counter = y;
|
|
sprite_floor[k] = (y >> 7);
|
|
Sprite_SetY(k, ((y << 4) & 0x1ff) + (byte_7E0FB1 << 8));
|
|
byte_7E0FB6 = x;
|
|
Sprite_SetX(k, ((x << 4) & 0x1ff) + (byte_7E0FB0 << 8));
|
|
sprite_type[k] = type;
|
|
tmp_counter = (tmp_counter & 0x60) >> 2;
|
|
sprite_subtype[k] = tmp_counter | byte_7E0FB6 >> 5;
|
|
sprite_N[k] = k;
|
|
sprite_die_action[k] = 0;
|
|
return k;
|
|
}
|
|
|
|
void Dungeon_LoadSingleOverlord(const uint8 *src) { // 89c3e8
|
|
int k = AllocOverlord();
|
|
if (k < 0)
|
|
return;
|
|
uint8 y = src[0], x = src[1], type = src[2];
|
|
overlord_type[k] = type;
|
|
overlord_floor[k] = (y >> 7);
|
|
int t = ((y << 4) & 0x1ff) + (byte_7E0FB1 << 8);
|
|
overlord_y_lo[k] = t;
|
|
overlord_y_hi[k] = t >> 8;
|
|
t = ((x << 4) & 0x1ff) + (byte_7E0FB0 << 8);
|
|
overlord_x_lo[k] = t;
|
|
overlord_x_hi[k] = t >> 8;
|
|
overlord_spawned_in_area[k] = overworld_area_index;
|
|
overlord_gen2[k] = 0;
|
|
overlord_gen1[k] = 0;
|
|
overlord_gen3[k] = 0;
|
|
if (overlord_type[k] == 10 || overlord_type[k] == 11) {
|
|
overlord_gen2[k] = 160;
|
|
} else if (overlord_type[k] == 3) {
|
|
overlord_gen2[k] = 255;
|
|
overlord_x_lo[k] -= 8;
|
|
}
|
|
}
|
|
|
|
void Sprite_ResetAll() { // 89c44e
|
|
Sprite_DisableAll();
|
|
Sprite_ResetAll_noDisable();
|
|
}
|
|
|
|
void Sprite_ResetAll_noDisable() { // 89c452
|
|
byte_7E0FDD = 0;
|
|
sprite_alert_flag = 0;
|
|
byte_7E0FFD = 0;
|
|
byte_7E02F0 = 0;
|
|
byte_7E0FC6 = 0;
|
|
sprite_limit_instance = 0;
|
|
sort_sprites_setting = 0;
|
|
if (follower_indicator != 13)
|
|
super_bomb_indicator_unk2 = 0xfe;
|
|
memset(sprite_where_in_room, 0, 0x1000);
|
|
memset(overworld_sprite_was_loaded, 0, 0x200);
|
|
memset(dungeon_room_history, 0xff, 8);
|
|
}
|
|
|
|
void Sprite_ReloadAll_Overworld() { // 89c499
|
|
Sprite_DisableAll();
|
|
Sprite_OverworldReloadAll_justLoad();
|
|
}
|
|
|
|
void Sprite_OverworldReloadAll_justLoad() { // 89c49d
|
|
Sprite_ResetAll_noDisable();
|
|
Overworld_LoadSprites();
|
|
Sprite_ActivateAllProxima();
|
|
}
|
|
|
|
void Overworld_LoadSprites() { // 89c4ac
|
|
sprcoll_x_base = (overworld_area_index & 7) << 9;
|
|
sprcoll_y_base = ((overworld_area_index & 0x3f) >> 2 & 0xe) << 8;
|
|
sprcoll_x_size = sprcoll_y_size = kOverworldAreaSprcollSizes[BYTE(overworld_area_index)] << 8;
|
|
const uint8 *src = GetOverworldSpritePtr(overworld_area_index);
|
|
uint8 b;
|
|
|
|
for (; (b = src[0]) != 0xff; src += 3) {
|
|
if (src[2] == 0xf4) {
|
|
byte_7E0FFD++;
|
|
continue;
|
|
}
|
|
uint8 r2 = (src[0] >> 4) << 2;
|
|
uint8 r6 = (src[1] >> 4) + r2;
|
|
uint8 r5 = src[1] & 0xf | src[0] << 4;
|
|
sprite_where_in_overworld[r5 | r6 << 8] = src[2] + 1;
|
|
}
|
|
}
|
|
|
|
void Sprite_ActivateAllProxima() { // 89c55e
|
|
uint16 bak0 = BG2HOFS_copy2;
|
|
uint8 bak1 = byte_7E069E[1];
|
|
byte_7E069E[1] = 0xff;
|
|
|
|
int xt = (enhanced_features0 & kFeatures0_ExtendScreen64) ? 0x40 : 0;
|
|
BG2HOFS_copy2 -= xt;
|
|
for (int i = 21 + (xt >> 3); i >= 0; i--) {
|
|
Sprite_ActivateWhenProximal();
|
|
BG2HOFS_copy2 += 16;
|
|
}
|
|
byte_7E069E[1] = bak1;
|
|
BG2HOFS_copy2 = bak0;
|
|
}
|
|
|
|
void Sprite_ProximityActivation() { // 89c58f
|
|
if (submodule_index != 0) {
|
|
Sprite_ActivateWhenProximal();
|
|
Sprite_ActivateWhenProximalBig();
|
|
} else {
|
|
if (!(spr_ranged_based_toggler & 1))
|
|
Sprite_ActivateWhenProximal();
|
|
if (spr_ranged_based_toggler & 1)
|
|
Sprite_ActivateWhenProximalBig();
|
|
spr_ranged_based_toggler++;
|
|
}
|
|
}
|
|
|
|
void Sprite_ActivateWhenProximal() { // 89c5bb
|
|
if (byte_7E069E[1]) {
|
|
int xt = (enhanced_features0 & kFeatures0_ExtendScreen64) ? 0x40 : 0;
|
|
uint16 x = BG2HOFS_copy2 + (sign8(byte_7E069E[1]) ? -0x10 - xt : 0x110 + xt);
|
|
uint16 y = BG2VOFS_copy2 - 0x30;
|
|
for (int i = 21; i >= 0; i--, y += 16)
|
|
Sprite_Overworld_ProximityMotivatedLoad(x, y);
|
|
}
|
|
}
|
|
|
|
void Sprite_ActivateWhenProximalBig() { // 89c5fa
|
|
if (byte_7E069E[0]) {
|
|
int xt = (enhanced_features0 & kFeatures0_ExtendScreen64) ? 0x40 : 0;
|
|
uint16 x = BG2HOFS_copy2 - 0x30 - xt;
|
|
uint16 y = BG2VOFS_copy2 + (sign8(byte_7E069E[0]) ? -0x10 : 0x110);
|
|
for (int i = 21 + (xt >> 3); i >= 0; i--, x += 16)
|
|
Sprite_Overworld_ProximityMotivatedLoad(x, y);
|
|
}
|
|
}
|
|
|
|
void Sprite_Overworld_ProximityMotivatedLoad(uint16 x, uint16 y) { // 89c6f5
|
|
uint16 xt = (uint16)(x - sprcoll_x_base);
|
|
uint16 yt = (uint16)(y - sprcoll_y_base);
|
|
if (xt >= sprcoll_x_size || yt >= sprcoll_y_size)
|
|
return;
|
|
|
|
uint8 r1 = (yt >> 8) * 4 | (xt >> 8);
|
|
uint8 r0 = y & 0xf0 | x >> 4 & 0xf;
|
|
Overworld_LoadProximaSpriteIfAlive(r1 << 8 | r0);
|
|
}
|
|
|
|
void Overworld_LoadProximaSpriteIfAlive(uint16 blk) { // 89c739
|
|
uint8 *p5 = sprite_where_in_overworld + blk;
|
|
uint8 sprite_to_spawn = *p5;
|
|
if (!sprite_to_spawn)
|
|
return;
|
|
|
|
uint8 loadedmask = (0x80 >> (blk & 7));
|
|
uint8 *loadedp = &overworld_sprite_was_loaded[blk >> 3];
|
|
|
|
if (*loadedp & loadedmask)
|
|
return;
|
|
|
|
if (sprite_to_spawn >= 0xf4) {
|
|
// load overlord
|
|
int k = AllocOverlord();
|
|
if (k < 0)
|
|
return;
|
|
*loadedp |= loadedmask;
|
|
overlord_offset_sprite_pos[k] = blk;
|
|
overlord_type[k] = sprite_to_spawn - 0xf3;
|
|
overlord_x_lo[k] = (blk << 4 & 0xf0) + (overlord_type[k] == 1 ? 8 : 0);
|
|
overlord_y_lo[k] = blk & 0xf0;
|
|
overlord_x_hi[k] = (blk >> 8 & 3) + HIBYTE(sprcoll_x_base);
|
|
overlord_y_hi[k] = (blk >> 10) + HIBYTE(sprcoll_y_base);
|
|
overlord_floor[k] = 0;
|
|
overlord_spawned_in_area[k] = overworld_area_index;
|
|
overlord_gen2[k] = 0;
|
|
overlord_gen1[k] = 0;
|
|
overlord_gen3[k] = 0;
|
|
} else {
|
|
// load regular sprite
|
|
int k = Overworld_AllocSprite(sprite_to_spawn);
|
|
if (k < 0)
|
|
return;
|
|
*loadedp |= loadedmask;
|
|
|
|
sprite_N_word[k] = blk;
|
|
sprite_type[k] = sprite_to_spawn - 1;
|
|
sprite_state[k] = 8;
|
|
sprite_x_lo[k] = blk << 4 & 0xf0;
|
|
sprite_y_lo[k] = blk & 0xf0;
|
|
sprite_x_hi[k] = (blk >> 8 & 3) + HIBYTE(sprcoll_x_base);
|
|
sprite_y_hi[k] = (blk >> 10) + HIBYTE(sprcoll_y_base);
|
|
sprite_floor[k] = 0;
|
|
sprite_subtype[k] = 0;
|
|
sprite_die_action[k] = 0;
|
|
}
|
|
}
|
|
|
|
void SpriteExplode_SpawnEA(int k) { // 89ee4c
|
|
tmp_counter = sprite_type[k];
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamicallyEx(k, 0xea, &info, 14);
|
|
Sprite_SetSpawnedCoordinates(j, &info);
|
|
sprite_z_vel[j] = 32;
|
|
sprite_floor[j] = link_is_on_lower_level;
|
|
sprite_A[j] = (j == 9) ? 2 : 6;
|
|
Sprite_SetY(j, info.r2_y + 3);
|
|
if (tmp_counter == 0xce) {
|
|
Sprite_SetY(j, info.r2_y + 16);
|
|
return;
|
|
}
|
|
if (tmp_counter == 0xcb) {
|
|
sprite_y_lo[j] = sprite_x_lo[j] = 0x78;
|
|
sprite_x_hi[j] = HIBYTE(link_x_coord);
|
|
sprite_y_hi[j] = HIBYTE(link_y_coord);
|
|
}
|
|
}
|
|
|
|
void Sprite_KillFriends() { // 89ef56
|
|
for(int j = 15; j >= 0; j--) {
|
|
if (j != cur_object_index && sprite_state[j] && !(sprite_defl_bits[j] & 2) && sprite_type[j] != 0x7a) {
|
|
sprite_state[j] = 6;
|
|
sprite_delay_main[j] = 15;
|
|
sprite_flags3[j] = 0;
|
|
sprite_flags5[j] = 0;
|
|
sprite_flags2[j] = 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Garnish16_ThrownItemDebris(int k) { // 89f0cb
|
|
static const int16 kScatterDebris_Draw_X[64] = {
|
|
0, 8, 0, 8, -2, 9, -1, 9, -4, 9, -1, 10, -6, 9, -1, 12,
|
|
-7, 9, -2, 13, -9, 9, -3, 14, -4, -4, 9, 15, -3, -3, -3, 9,
|
|
-4, 4, 6, 10, -1, 4, 6, 7, 0, 2, 4, 7, 1, 1, 5, 7,
|
|
0, -2, 8, 9, -1, -6, 9, 10, -2, -7, 12, 11, -3, -9, 4, 6,
|
|
};
|
|
static const int8 kScatterDebris_Draw_Y[64] = {
|
|
0, 0, 8, 8, 0, -1, 10, 10, 0, -3, 11, 7, 1, -4, 12, 8,
|
|
1, -4, 13, 9, 2, -4, 16, 10, 14, 14, -4, 11, 16, 16, 16, -1,
|
|
2, -5, 5, 1, 3, -7, 8, 2, 4, -8, 4, 10, -9, 4, 4, 12,
|
|
-10, 4, 8, 14, -12, 4, 8, 15, -15, 3, 8, 17, -17, 1, 18, 15,
|
|
};
|
|
static const int8 kScatterDebris_Draw_Char[64] = {
|
|
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
|
|
0x48, 0x58, 0x58, 0x58, 0x48, 0x58, 0x58, 0x48, 0x48, 0x48, 0x58, 0x48, 0x48, 0x48, 0x48, 0x48,
|
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,
|
|
0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,
|
|
};
|
|
static const uint8 kScatterDebris_Draw_Flags[64] = {
|
|
0x80, 0, 0x80, 0x40, 0x80, 0x40, 0x80, 0, 0, 0xc0, 0, 0x80, 0x80, 0x40, 0x80, 0,
|
|
0x80, 0xc0, 0, 0x80, 0, 0, 0x80, 0, 0x80, 0x80, 0x80, 0x80, 0, 0, 0, 0,
|
|
0x40, 0x40, 0x40, 0, 0x40, 0x40, 0x40, 0, 0x40, 0x40, 0, 0, 0x80, 0, 0x40, 0x40,
|
|
0x40, 0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0, 0, 0x40, 0, 0, 0,
|
|
};
|
|
Point16U pt;
|
|
if (Garnish_ReturnIfPrepFails(k, &pt))
|
|
return;
|
|
uint8 r5 = garnish_oam_flags[k];
|
|
if (byte_7E0FC6 >= 3)
|
|
return;
|
|
if (garnish_sprite[k] == 3) {
|
|
ScatterDebris_Draw(k, pt);
|
|
return;
|
|
}
|
|
OamEnt *oam = GetOamCurPtr();
|
|
tmp_counter = garnish_sprite[k];
|
|
uint8 base = ((garnish_countdown[k] >> 2) ^ 7) << 2;
|
|
if (tmp_counter == 4 || tmp_counter == 2 && !player_is_indoors)
|
|
base += 0x20;
|
|
for (int i = 3; i >= 0; i--, oam++) {
|
|
int j = i + base;
|
|
SetOamHelper1(oam, pt.x + kScatterDebris_Draw_X[j], pt.y + kScatterDebris_Draw_Y[j],
|
|
(tmp_counter == 0) ? 0x4E : (tmp_counter >= 0x80) ? 0xF2 : kScatterDebris_Draw_Char[j],
|
|
kScatterDebris_Draw_Flags[j] | r5, 0);
|
|
}
|
|
}
|
|
|
|
void ScatterDebris_Draw(int k, Point16U pt) { // 89f198
|
|
static const int8 kScatterDebris_Draw_X2[12] = {-8, 8, 16, -5, 8, 15, -1, 7, 11, 1, 3, 8};
|
|
static const int8 kScatterDebris_Draw_Y2[12] = {7, 2, 12, 9, 2, 10, 11, 2, 11, 7, 3, 8};
|
|
static const uint8 kScatterDebris_Draw_Char2[12] = {0xe2, 0xe2, 0xe2, 0xe2, 0xf2, 0xf2, 0xf2, 0xe2, 0xe2, 0xf2, 0xe2, 0xe2};
|
|
static const uint8 kScatterDebris_Draw_Flags2[12] = {0, 0, 0, 0, 0x80, 0x40, 0, 0x80, 0x40, 0, 0, 0};
|
|
|
|
if (garnish_countdown[k] == 16)
|
|
garnish_type[k] = 0;
|
|
|
|
OamEnt *oam = GetOamCurPtr();
|
|
int base = ((garnish_countdown[k] & 0xf) >> 2) * 3;
|
|
|
|
for (int i = 2; i >= 0; i--, oam++) {
|
|
int j = i + base;
|
|
SetOamHelper1(oam, pt.x + kScatterDebris_Draw_X2[j], pt.y + kScatterDebris_Draw_Y2[j],
|
|
kScatterDebris_Draw_Char2[j], kScatterDebris_Draw_Flags2[j] | 0x22, 0);
|
|
}
|
|
}
|
|
|
|
void Sprite_KillSelf(int k) { // 89f1f8
|
|
if (!(sprite_defl_bits[k] & 0x40) && player_is_indoors)
|
|
return;
|
|
sprite_state[k] = 0;
|
|
uint16 blk = sprite_N_word[k];
|
|
g_ram[0] = blk; // Sprite_PrepOamCoordOrDoubleRet reads this!
|
|
WORD(g_ram[1]) = (blk >> 3) + 0xef80; // Sprite_PrepOamCoordOrDoubleRet reads this!
|
|
uint8 loadedmask = (0x80 >> (blk & 7));
|
|
uint16 addr = 0xEF80 + (blk >> 3); // warning: blk may be bad, seen with cannon balls in 2nd dungeon
|
|
|
|
uint8 *loadedp = &g_ram[addr + 0x10000];
|
|
|
|
if (blk < 0xffff)
|
|
*loadedp &= ~loadedmask;
|
|
if (!player_is_indoors)
|
|
sprite_N_word[k] = 0xffff;
|
|
else
|
|
sprite_N[k] = 0xff;
|
|
}
|
|
|
|
void SpritePrep_LoadProperties(int k) { // 8db818
|
|
SpritePrep_ResetProperties(k);
|
|
int j = sprite_type[k];
|
|
sprite_flags2[k] = kSpriteInit_Flags2[j];
|
|
sprite_health[k] = kSpriteInit_Health[j];
|
|
sprite_flags4[k] = kSpriteInit_Flags4[j];
|
|
sprite_flags5[k] = kSpriteInit_Flags5[j];
|
|
sprite_defl_bits[k] = kSpriteInit_DeflBits[j];
|
|
sprite_bump_damage[k] = kSpriteInit_BumpDamage[j];
|
|
sprite_flags[k] = kSpriteInit_Flags[j];
|
|
sprite_room[k] = player_is_indoors ? dungeon_room_index2 : overworld_area_index;
|
|
sprite_flags3[k] = kSpriteInit_Flags3[j];
|
|
sprite_oam_flags[k] = kSpriteInit_Flags3[j] & 0xf;
|
|
}
|
|
|
|
void SpritePrep_LoadPalette(int k) { // 8db85c
|
|
int f = kSpriteInit_Flags3[sprite_type[k]];
|
|
sprite_flags3[k] = f;
|
|
sprite_oam_flags[k] = f & 15;
|
|
}
|
|
|
|
void SpritePrep_ResetProperties(int k) { // 8db871
|
|
sprite_pause[k] = 0;
|
|
sprite_E[k] = 0;
|
|
sprite_x_vel[k] = 0;
|
|
sprite_y_vel[k] = 0;
|
|
sprite_z_vel[k] = 0;
|
|
sprite_x_subpixel[k] = 0;
|
|
sprite_y_subpixel[k] = 0;
|
|
sprite_z_subpos[k] = 0;
|
|
sprite_ai_state[k] = 0;
|
|
sprite_graphics[k] = 0;
|
|
sprite_D[k] = 0;
|
|
sprite_delay_main[k] = 0;
|
|
sprite_delay_aux1[k] = 0;
|
|
sprite_delay_aux2[k] = 0;
|
|
sprite_delay_aux4[k] = 0;
|
|
sprite_head_dir[k] = 0;
|
|
sprite_anim_clock[k] = 0;
|
|
sprite_G[k] = 0;
|
|
sprite_hit_timer[k] = 0;
|
|
sprite_wallcoll[k] = 0;
|
|
sprite_z[k] = 0;
|
|
sprite_health[k] = 0;
|
|
sprite_F[k] = 0;
|
|
sprite_x_recoil[k] = 0;
|
|
sprite_y_recoil[k] = 0;
|
|
sprite_A[k] = 0;
|
|
sprite_B[k] = 0;
|
|
sprite_C[k] = 0;
|
|
sprite_unk2[k] = 0;
|
|
sprite_subtype2[k] = 0;
|
|
sprite_ignore_projectile[k] = 0;
|
|
sprite_obj_prio[k] = 0;
|
|
sprite_oam_flags[k] = 0;
|
|
sprite_stunned[k] = 0;
|
|
sprite_give_damage[k] = 0;
|
|
sprite_unk3[k] = 0;
|
|
sprite_unk4[k] = 0;
|
|
sprite_unk5[k] = 0;
|
|
sprite_unk1[k] = 0;
|
|
sprite_I[k] = 0;
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionA(uint8 num) { // 8dba80
|
|
return Oam_GetBufferPosition(num, 0);
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionB(uint8 num) { // 8dba84
|
|
return Oam_GetBufferPosition(num, 2);
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionC(uint8 num) { // 8dba88
|
|
return Oam_GetBufferPosition(num, 4);
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionD(uint8 num) { // 8dba8c
|
|
return Oam_GetBufferPosition(num, 6);
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionE(uint8 num) { // 8dba90
|
|
return Oam_GetBufferPosition(num, 8);
|
|
}
|
|
|
|
uint8 Oam_AllocateFromRegionF(uint8 num) { // 8dba94
|
|
return Oam_GetBufferPosition(num, 10);
|
|
}
|
|
|
|
uint8 Oam_GetBufferPosition(uint8 num, uint8 y) { // 8dbb0a
|
|
y >>= 1;
|
|
uint16 p = oam_region_base[y], pstart = p;
|
|
p += num;
|
|
if (p >= kOamGetBufferPos_Tab0[y]) {
|
|
int j = oam_alloc_arr1[y]++ & 7;
|
|
pstart = kOamGetBufferPos_Tab1[y * 8 + j];
|
|
} else {
|
|
oam_region_base[y] = p;
|
|
}
|
|
oam_ext_cur_ptr = 0xa20 + (pstart >> 2);
|
|
oam_cur_ptr = 0x800 + pstart;
|
|
return oam_cur_ptr;
|
|
}
|
|
|
|
void Sprite_NullifyHookshotDrag() { // 8ff540
|
|
for (int i = 4; i >= 0; i--) {
|
|
if (!(ancilla_type[i] & 0x1f) && related_to_hookshot) {
|
|
related_to_hookshot = 0;
|
|
break;
|
|
}
|
|
}
|
|
link_x_coord_safe_return_hi = link_x_coord >> 8;
|
|
link_y_coord_safe_return_hi = link_y_coord >> 8;
|
|
link_x_coord = link_x_coord_prev;
|
|
link_y_coord = link_y_coord_prev;
|
|
HandleIndoorCameraAndDoors();
|
|
}
|
|
|
|
void Overworld_SubstituteAlternateSecret() { // 9afbdb
|
|
static const uint8 kSecretSubst_Tab0[64] = {
|
|
0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
4, 4, 6, 4, 4, 6, 0, 0, 15, 15, 4, 5, 5, 4, 6, 6,
|
|
15, 15, 4, 5, 5, 7, 6, 6, 31, 31, 4, 7, 7, 4, 6, 6,
|
|
6, 7, 2, 0, 0, 0, 0, 0, 6, 6, 2, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint8 kSecretSubst_Tab2[16] = { 1, 1, 1, 1, 15, 1, 1, 18, 16, 1, 1, 1, 17, 1, 1, 3 };
|
|
static const uint8 kSecretSubst_Tab1[16] = { 0, 0, 0, 0, 2, 0, 0, 8, 16, 0, 0, 0, 1, 0, 0, 0 };
|
|
if (GetRandomNumber() & 1)
|
|
return;
|
|
int n = 0;
|
|
for (int j = 15; j >= 0; j--) {
|
|
if (sprite_state[j] && sprite_type[j] != 0x6c)
|
|
n++;
|
|
}
|
|
if (n >= 4 || sram_progress_indicator < 2)
|
|
return;
|
|
int j = (overworld_secret_subst_ctr++ & 7) + (is_in_dark_world ? 8 : 0);
|
|
if (!(kSecretSubst_Tab0[BYTE(overworld_area_index) & 0x3f] & kSecretSubst_Tab1[j]))
|
|
BYTE(dung_secrets_unk1) = kSecretSubst_Tab2[j];
|
|
}
|
|
|
|
void Sprite_ApplyConveyor(int k, int j) { // 9d8010
|
|
if (!(frame_counter & 1))
|
|
return;
|
|
static const int8 kConveyorAdjustment_X[] = {0, 0, -1, 1};
|
|
static const int8 kConveyorAdjustment_Y[] = {-1, 1, 0, 0};
|
|
Sprite_SetX(k, Sprite_GetX(k) + kConveyorAdjustment_X[j - 0x68]);
|
|
Sprite_SetY(k, Sprite_GetY(k) + kConveyorAdjustment_Y[j - 0x68]);
|
|
}
|
|
|
|
uint8 Sprite_BounceFromTileCollision(int k) { // 9dc751
|
|
int j = Sprite_CheckTileCollision(k);
|
|
if (j & 3) {
|
|
sprite_x_vel[k] = -sprite_x_vel[k];
|
|
sprite_G[k]++;
|
|
}
|
|
if (j & 12) {
|
|
sprite_y_vel[k] = -sprite_y_vel[k];
|
|
sprite_G[k]++;
|
|
return sprite_G[k]; // wtf
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ExecuteCachedSprites() { // 9de9da
|
|
if (!player_is_indoors || submodule_index == 0 || submodule_index == 14 || alt_sprites_flag == 0) {
|
|
alt_sprites_flag = 0;
|
|
return;
|
|
}
|
|
for (int i = 15; i >= 0; i--) {
|
|
cur_object_index = i;
|
|
if (alt_sprite_state[i])
|
|
UncacheAndExecuteSprite(i);
|
|
}
|
|
}
|
|
|
|
void UncacheAndExecuteSprite(int k) { // 9dea00
|
|
uint8 bak0 = sprite_state[k];
|
|
uint8 bak1 = sprite_type[k];
|
|
uint8 bak2 = sprite_x_lo[k];
|
|
uint8 bak3 = sprite_x_hi[k];
|
|
uint8 bak4 = sprite_y_lo[k];
|
|
uint8 bak5 = sprite_y_hi[k];
|
|
uint8 bak6 = sprite_graphics[k];
|
|
uint8 bak7 = sprite_A[k];
|
|
uint8 bak8 = sprite_head_dir[k];
|
|
uint8 bak9 = sprite_oam_flags[k];
|
|
uint8 bak10 = sprite_obj_prio[k];
|
|
uint8 bak11 = sprite_D[k];
|
|
uint8 bak12 = sprite_flags2[k];
|
|
uint8 bak13 = sprite_floor[k];
|
|
uint8 bak14 = sprite_ai_state[k];
|
|
uint8 bak15 = sprite_flags3[k];
|
|
uint8 bak16 = sprite_B[k];
|
|
uint8 bak17 = sprite_C[k];
|
|
uint8 bak18 = sprite_E[k];
|
|
uint8 bak19 = sprite_subtype2[k];
|
|
uint8 bak20 = sprite_z[k];
|
|
uint8 bak21 = sprite_delay_main[k];
|
|
uint8 bak22 = sprite_I[k];
|
|
uint8 bak23 = sprite_ignore_projectile[k];
|
|
sprite_state[k] = alt_sprite_state[k];
|
|
sprite_type[k] = alt_sprite_type[k];
|
|
sprite_x_lo[k] = alt_sprite_x_lo[k];
|
|
sprite_x_hi[k] = alt_sprite_x_hi[k];
|
|
sprite_y_lo[k] = alt_sprite_y_lo[k];
|
|
sprite_y_hi[k] = alt_sprite_y_hi[k];
|
|
sprite_graphics[k] = alt_sprite_graphics[k];
|
|
sprite_A[k] = alt_sprite_A[k];
|
|
sprite_head_dir[k] = alt_sprite_head_dir[k];
|
|
sprite_oam_flags[k] = alt_sprite_oam_flags[k];
|
|
sprite_obj_prio[k] = alt_sprite_obj_prio[k];
|
|
sprite_D[k] = alt_sprite_D[k];
|
|
sprite_flags2[k] = alt_sprite_flags2[k];
|
|
sprite_floor[k] = alt_sprite_floor[k];
|
|
sprite_ai_state[k] = alt_sprite_spawned_flag[k];
|
|
sprite_flags3[k] = alt_sprite_flags3[k];
|
|
sprite_B[k] = alt_sprite_B[k];
|
|
sprite_C[k] = alt_sprite_C[k];
|
|
sprite_E[k] = alt_sprite_E[k];
|
|
sprite_subtype2[k] = alt_sprite_subtype2[k];
|
|
sprite_z[k] = alt_sprite_height_above_shadow[k];
|
|
sprite_delay_main[k] = alt_sprite_delay_main[k];
|
|
sprite_I[k] = alt_sprite_I[k];
|
|
sprite_ignore_projectile[k] = alt_sprite_maybe_ignore_projectile[k];
|
|
Sprite_ExecuteSingle(k);
|
|
if (sprite_pause[k] != 0)
|
|
alt_sprite_state[k] = 0;
|
|
sprite_ignore_projectile[k] = bak23;
|
|
sprite_I[k] = bak22;
|
|
sprite_delay_main[k] = bak21;
|
|
sprite_z[k] = bak20;
|
|
sprite_subtype2[k] = bak19;
|
|
sprite_E[k] = bak18;
|
|
sprite_C[k] = bak17;
|
|
sprite_B[k] = bak16;
|
|
sprite_flags3[k] = bak15;
|
|
sprite_ai_state[k] = bak14;
|
|
sprite_floor[k] = bak13;
|
|
sprite_flags2[k] = bak12;
|
|
sprite_D[k] = bak11;
|
|
sprite_obj_prio[k] = bak10;
|
|
sprite_oam_flags[k] = bak9;
|
|
sprite_head_dir[k] = bak8;
|
|
sprite_A[k] = bak7;
|
|
sprite_graphics[k] = bak6;
|
|
sprite_y_hi[k] = bak5;
|
|
sprite_y_lo[k] = bak4;
|
|
sprite_x_hi[k] = bak3;
|
|
sprite_x_lo[k] = bak2;
|
|
sprite_type[k] = bak1;
|
|
sprite_state[k] = bak0;
|
|
|
|
}
|
|
|
|
uint8 Sprite_ConvertVelocityToAngle(uint8 x, uint8 y) { // 9df614
|
|
static const uint8 kConvertVelocityToAngle_Tab0[32] = {
|
|
0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 15, 15, 15, 14, 14, 14,
|
|
8, 8, 7, 7, 7, 6, 6, 6, 8, 8, 9, 9, 9, 10, 10, 10,
|
|
};
|
|
static const uint8 kConvertVelocityToAngle_Tab1[32] = {
|
|
4, 4, 3, 3, 3, 2, 2, 2, 12, 12, 13, 13, 13, 14, 14, 14,
|
|
4, 4, 5, 5, 5, 6, 6, 6, 12, 12, 11, 11, 11, 10, 10, 10,
|
|
};
|
|
int s = ((y >> 7) + (x >> 7) * 2) * 8;
|
|
if (sign8(x)) x = -x;
|
|
if (sign8(y)) y = -y;
|
|
if (x >= y) {
|
|
return kConvertVelocityToAngle_Tab0[(y >> 2) + s];
|
|
} else {
|
|
return kConvertVelocityToAngle_Tab1[(x >> 2) + s];
|
|
}
|
|
}
|
|
|
|
int Sprite_SpawnDynamically(int k, uint8 what, SpriteSpawnInfo *info) { // 9df65d
|
|
return Sprite_SpawnDynamicallyEx(k, what, info, 15);
|
|
}
|
|
|
|
int Sprite_SpawnDynamicallyEx(int k, uint8 what, SpriteSpawnInfo *info, int j) { // 9df65f
|
|
do {
|
|
if (sprite_state[j] == 0) {
|
|
sprite_type[j] = what;
|
|
sprite_state[j] = 9;
|
|
info->r0_x = Sprite_GetX(k);
|
|
info->r2_y = Sprite_GetY(k);
|
|
info->r4_z = sprite_z[k];
|
|
info->r5_overlord_x = overlord_x_lo[k] | overlord_x_hi[k] << 8;
|
|
info->r7_overlord_y = overlord_y_lo[k] | overlord_y_hi[k] << 8;
|
|
SpritePrep_LoadProperties(j);
|
|
if (!player_is_indoors) {
|
|
sprite_N_word[j] = 0xffff;
|
|
} else {
|
|
sprite_N[j] = 0xff;
|
|
}
|
|
sprite_floor[j] = sprite_floor[k];
|
|
sprite_D[j] = sprite_D[k];
|
|
sprite_die_action[j] = 0;
|
|
sprite_subtype[j] = 0;
|
|
break;
|
|
}
|
|
} while (--j >= 0);
|
|
return j;
|
|
}
|
|
|
|
void SpriteFall_Draw(int k, PrepOamCoordsRet *info) { // 9dffc5
|
|
static const uint8 kSpriteFall_Char[8] = {0x83, 0x83, 0x83, 0x80, 0x80, 0x80, 0xb7, 0xb7};
|
|
OamEnt *oam = GetOamCurPtr();
|
|
oam->x = info->x + 4;
|
|
oam->y = info->y + 4;
|
|
oam->charnum = kSpriteFall_Char[sprite_delay_main[k] >> 2];
|
|
oam->flags = info->flags & 0x30 | 0x04;
|
|
Sprite_CorrectOamEntries(k, 0, 0);
|
|
}
|
|
|
|
void Sprite_GarnishSpawn_Sparkle_limited(int k, uint16 x, uint16 y) { // 9ea001
|
|
Sprite_SpawnSimpleSparkleGarnishEx(k, x, y, 14);
|
|
}
|
|
|
|
int Sprite_GarnishSpawn_Sparkle(int k, uint16 x, uint16 y) { // 9ea007
|
|
return Sprite_SpawnSimpleSparkleGarnishEx(k, x, y, 29);
|
|
}
|
|
|
|
void Sprite_BehaveAsBarrier(int k) { // 9ef4f3
|
|
uint8 bak = sprite_flags4[k];
|
|
sprite_flags4[k] = 0;
|
|
if (Sprite_CheckDamageToLink_same_layer(k))
|
|
Sprite_HaltAllMovement();
|
|
sprite_flags4[k] = bak;
|
|
}
|
|
|
|
void Sprite_HaltAllMovement() { // 9ef508
|
|
Sprite_NullifyHookshotDrag();
|
|
link_speed_setting = 0;
|
|
Link_CancelDash();
|
|
}
|
|
|
|
int ReleaseFairy() { // 9efe33
|
|
SpriteSpawnInfo info;
|
|
int j = Sprite_SpawnDynamically(0, 0xe3, &info);
|
|
if (j >= 0) {
|
|
sprite_floor[j] = link_is_on_lower_level;
|
|
Sprite_SetX(j, link_x_coord + 8);
|
|
Sprite_SetY(j, link_y_coord + 16);
|
|
sprite_D[j] = 0;
|
|
sprite_delay_aux4[j] = 96;
|
|
}
|
|
return j;
|
|
}
|
|
|
|
void Sprite_DrawRippleIfInWater(int k) { // 9eff8d
|
|
if (sprite_I[k] != 8 && sprite_I[k] != 9)
|
|
return;
|
|
|
|
if (sprite_flags3[k] & 0x20) {
|
|
cur_sprite_x -= 4;
|
|
if (sprite_type[k] == 0xdf)
|
|
cur_sprite_y -= 7;
|
|
}
|
|
SpriteDraw_WaterRipple(k);
|
|
Sprite_Get16BitCoords(k);
|
|
Oam_AllocateFromRegionA(((sprite_flags2[k] & 0x1f) + 1) * 4);
|
|
}
|
|
|