summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPikalaxALT <PikalaxALT@users.noreply.github.com>2019-10-03 20:57:28 -0400
committerGitHub <noreply@github.com>2019-10-03 20:57:28 -0400
commit0cf4c9f25c2fe165c53a0c24f93a31a27ea42d6a (patch)
treeb88f7cf114f3f0c79ba6816255f27cda21f335d7 /src
parentd9ab841b0d72a52676131846447de26e59e7a16d (diff)
parentaa0ac46b7145951f1d6f65e7af005a3fe561ff63 (diff)
Merge pull request #108 from PikalaxALT/itemfinder
Itemfinder
Diffstat (limited to 'src')
-rw-r--r--src/fieldmap.c2
-rw-r--r--src/item_use.c2
-rw-r--r--src/itemfinder.c659
3 files changed, 661 insertions, 2 deletions
diff --git a/src/fieldmap.c b/src/fieldmap.c
index 2683eaf62..000b8105b 100644
--- a/src/fieldmap.c
+++ b/src/fieldmap.c
@@ -833,7 +833,7 @@ s32 sub_80596FC(struct MapConnection *connection, s32 x, s32 y)
return FALSE;
}
-struct MapConnection *sub_805973C(s16 x, s16 y)
+struct MapConnection *GetMapConnectionAtPos(s16 x, s16 y)
{
s32 count;
struct MapConnection *connection;
diff --git a/src/item_use.c b/src/item_use.c
index 5fa9390c1..c472960bd 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -274,7 +274,7 @@ void ItemUseOnFieldCB_Rod(u8 taskId)
void ItemUseOutOfBattle_Itemfinder(u8 taskId)
{
IncrementGameStat(GAME_STAT_USED_ITEMFINDER);
- sItemUseOnFieldCB = sub_813EC8C;
+ sItemUseOnFieldCB = ItemUseOnFieldCB_Itemfinder;
sub_80A103C(taskId);
}
diff --git a/src/itemfinder.c b/src/itemfinder.c
new file mode 100644
index 000000000..4e723ac03
--- /dev/null
+++ b/src/itemfinder.c
@@ -0,0 +1,659 @@
+#include "global.h"
+#include "task.h"
+#include "new_menu_helpers.h"
+#include "strings.h"
+#include "event_scripts.h"
+#include "map_obj_lock.h"
+#include "script.h"
+#include "sound.h"
+#include "event_data.h"
+#include "field_player_avatar.h"
+#include "field_specials.h"
+#include "fieldmap.h"
+#include "itemfinder.h"
+#include "constants/songs.h"
+
+static void Task_NoResponse_CleanUp(u8 taskId);
+static void Task_ItemfinderResponseSoundsAndAnims(u8 taskId);
+static void Task_ItemfinderUnderfootSoundsAndAnims(u8 taskId);
+static bool8 HiddenItemIsWithinRangeOfPlayer(struct MapEvents * events, u8 taskId);
+static void SetUnderfootHiddenItem(u8 taskId, struct HiddenItemStruct hiddenItem);
+static void SetNormalHiddenItem(u8 taskId);
+static void FindHiddenItemsInConnectedMaps(u8 taskId);
+static void RegisterHiddenItemRelativeCoordsIfCloser(u8 taskId, s16 dx, s16 dy);
+static u8 GetPlayerDirectionTowardsHiddenItem(s16 itemX, s16 itemY);
+static void Task_ItemfinderResponsePrintMessage(u8 taskId);
+static void Task_ItemfinderResponseCleanUp(u8 taskId);
+static void Task_ItemfinderUnderfootPrintMessage(u8 taskId);
+static void Task_ItemfinderUnderfootDigUpItem(u8 taskId);
+static void DestroyArrowAndStarTiles(void);
+static void LoadArrowAndStarTiles(void);
+static void CreateArrowSprite(u8 animNum, u8 direction);
+static void SpriteCallback_Arrow(struct Sprite * sprite);
+static void SpriteCallback_DestroyArrow(struct Sprite * sprite);
+static u8 CreateStarSprite(void);
+static void SpriteCallback_Star(struct Sprite * sprite);
+static void SpriteCallback_DestroyStar(struct Sprite * sprite);
+
+#define ARROW_TILE_TAG 2000
+
+static const u16 sArrowAndStarSpriteTiles[] = INCBIN_U16("data/itemfinder/spr_tiles.4bpp");
+
+static const union AnimCmd sArrowAnim0[] = {
+ ANIMCMD_FRAME( 0, 10),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sArrowAnim1[] = {
+ ANIMCMD_FRAME( 4, 10),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sArrowAnim2[] = {
+ ANIMCMD_FRAME( 8, 10),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sArrowAnim3[] = {
+ ANIMCMD_FRAME(12, 10),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sStarAnim[] = {
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sArrowAndStarSpriteAnimTable[] = {
+ sArrowAnim0,
+ sArrowAnim1,
+ sArrowAnim2,
+ sArrowAnim3,
+ sStarAnim
+};
+
+static const struct OamData sArrowAndStarSpriteOamData = {
+ .affineMode = ST_OAM_AFFINE_NORMAL,
+ .shape = ST_OAM_SQUARE,
+ .size = ST_OAM_SIZE_1
+};
+
+static const union AffineAnimCmd sAffineAnim_Left[] = {
+ AFFINEANIMCMD_FRAME(0, 0, 0x00, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sAffineAnim_Down[] = {
+ AFFINEANIMCMD_FRAME(0, 0, 0x40, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sAffineAnim_Right[] = {
+ AFFINEANIMCMD_FRAME(0, 0, 0x80, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sAffineAnim_Up[] = {
+ AFFINEANIMCMD_FRAME(0, 0, 0xc0, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sArrowAndStarSpriteAffineAnimTable[] = {
+ sAffineAnim_Left,
+ sAffineAnim_Down,
+ sAffineAnim_Right,
+ sAffineAnim_Up
+};
+
+static const struct SpriteTemplate gUnknown_84647E4 = {
+ .tileTag = ARROW_TILE_TAG,
+ .paletteTag = 0xFFFF,
+ .oam = &sArrowAndStarSpriteOamData,
+ .anims = sArrowAndStarSpriteAnimTable,
+ .affineAnims = sArrowAndStarSpriteAffineAnimTable,
+ .callback = SpriteCallback_Arrow
+};
+
+static const struct SpriteSheet sArrowAndStarSpriteSheet = {
+ .data = sArrowAndStarSpriteTiles,
+ .size = sizeof(sArrowAndStarSpriteTiles),
+ .tag = ARROW_TILE_TAG
+};
+
+#define tItemX data[0]
+#define tItemY data[1]
+#define tHiddenItemFound data[2]
+#define tDingTimer data[3]
+#define tNumDingsRemaining data[4]
+#define tDingNum data[5]
+#define tUnderfoot data[6]
+#define tStartSpriteId data[7]
+
+void ItemUseOnFieldCB_Itemfinder(u8 taskId)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ gTasks[taskId].data[i] = 0;
+ if (HiddenItemIsWithinRangeOfPlayer(gMapHeader.events, taskId) == TRUE)
+ {
+ LoadArrowAndStarTiles();
+ if (gTasks[taskId].tUnderfoot == TRUE)
+ gTasks[taskId].func = Task_ItemfinderUnderfootSoundsAndAnims;
+ else
+ gTasks[taskId].func = Task_ItemfinderResponseSoundsAndAnims;
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, 2, gText_NopeTheresNoResponse, Task_NoResponse_CleanUp);
+ }
+}
+
+static void Task_NoResponse_CleanUp(u8 taskId)
+{
+ ClearDialogWindowAndFrame(0, TRUE);
+ sub_80696C0();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+}
+
+static void Task_ItemfinderResponseSoundsAndAnims(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ u8 direction;
+ if (tDingTimer % 25 == 0)
+ {
+ direction = GetPlayerDirectionTowardsHiddenItem(tItemX, tItemY);
+ if (tNumDingsRemaining == 0)
+ {
+ gTasks[taskId].func = Task_ItemfinderResponsePrintMessage;
+ return;
+ }
+ else
+ {
+ PlaySE(SE_TOY_F);
+ CreateArrowSprite(tDingNum, direction);
+ tDingNum++;
+ tNumDingsRemaining--;
+ }
+ }
+ tDingTimer++;
+}
+
+static void Task_ItemfinderUnderfootSoundsAndAnims(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (tDingTimer % 25 == 0)
+ {
+ if (tNumDingsRemaining == 0)
+ {
+ gTasks[taskId].func = Task_ItemfinderUnderfootPrintMessage;
+ return;
+ }
+ else
+ {
+ PlaySE(SE_TOY_F);
+ tStartSpriteId = CreateStarSprite();
+ tDingNum++;
+ tNumDingsRemaining--;
+ }
+ }
+ tDingTimer++;
+}
+
+static bool8 HiddenItemIsWithinRangeOfPlayer(struct MapEvents * events, u8 taskId)
+{
+ s16 x, y, i, dx, dy;
+ PlayerGetDestCoords(&x, &y);
+ gTasks[taskId].tHiddenItemFound = FALSE;
+ for (i = 0; i < events->bgEventCount; i++)
+ {
+ if (events->bgEvents[i].kind == 7 && !FlagGet(GetHiddenItemAttr(events->bgEvents[i].bgUnion.hiddenItem, HIDDEN_ITEM_FLAG)))
+ {
+ dx = events->bgEvents[i].x + 7 - x;
+ dy = events->bgEvents[i].y + 7 - y;
+ if (GetHiddenItemAttr(events->bgEvents[i].bgUnion.hiddenItem, HIDDEN_ITEM_UNDERFOOT) == TRUE)
+ {
+ if (dx == 0 && dy == 0)
+ {
+ SetUnderfootHiddenItem(taskId, events->bgEvents[i].bgUnion.hiddenItem);
+ return TRUE;
+ }
+ }
+ else if (
+ dx >= -7
+ && dx <= 7
+ && dy >= -5
+ && dy <= 5
+ )
+ {
+ RegisterHiddenItemRelativeCoordsIfCloser(taskId, dx, dy);
+ }
+ }
+ }
+ FindHiddenItemsInConnectedMaps(taskId);
+ if (gTasks[taskId].tHiddenItemFound == TRUE)
+ {
+ SetNormalHiddenItem(taskId);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void SetUnderfootHiddenItem(u8 taskId, struct HiddenItemStruct hiddenItem)
+{
+ s16 *data = gTasks[taskId].data;
+ gSpecialVar_0x8004 = GetHiddenItemAttr(hiddenItem, HIDDEN_ITEM_FLAG);
+ gSpecialVar_0x8005 = GetHiddenItemAttr(hiddenItem, HIDDEN_ITEM_ID);
+ gSpecialVar_0x8006 = 1;
+ TV_PrintIntToStringVar(0, gSpecialVar_0x8005);
+ tHiddenItemFound = TRUE;
+ tItemX = 0;
+ tItemY = 0;
+ tNumDingsRemaining = 3;
+ tUnderfoot = TRUE;
+}
+
+static void SetNormalHiddenItem(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 absY = tItemY;
+ s16 absX = tItemX;
+
+ // The strength of the response increases inversely with distance to the item.
+ if (tItemX == 0 && tItemY == 0)
+ tNumDingsRemaining = 4;
+ else
+ {
+ if (tItemX < 0)
+ absX = tItemX * -1;
+ if (tItemY < 0)
+ absY = tItemY * -1;
+ if (absX > absY)
+ {
+ if (absX > 3)
+ tNumDingsRemaining = 2;
+ else
+ tNumDingsRemaining = 4;
+ }
+ else
+ {
+ if (absY > 3)
+ tNumDingsRemaining = 2;
+ else
+ tNumDingsRemaining = 4;
+ }
+ }
+}
+
+static bool8 HiddenItemAtPos(struct MapEvents * events, s16 x, s16 y)
+{
+ u8 bgEventCount = events->bgEventCount;
+ struct BgEvent * bgEvents = events->bgEvents;
+ u16 eventFlag;
+ int i;
+
+ for (i = 0; i < bgEventCount; i++)
+ {
+ if (
+ bgEvents[i].kind == 7
+ && x == bgEvents[i].x
+ && y == bgEvents[i].y
+ )
+ {
+ eventFlag = GetHiddenItemAttr(bgEvents[i].bgUnion.hiddenItem, HIDDEN_ITEM_FLAG);
+ if (GetHiddenItemAttr(bgEvents[i].bgUnion.hiddenItem, HIDDEN_ITEM_UNDERFOOT) != TRUE && !FlagGet(eventFlag))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+static bool8 HiddenItemInConnectedMapAtPos(struct MapConnection * connection, s32 x, s32 y)
+{
+ const struct MapHeader * mapHeader;
+ u16 localX, localY;
+ u32 localOffset;
+ s32 localLength;
+
+ mapHeader = mapconnection_get_mapheader(connection);
+
+ switch (connection->direction)
+ {
+ // same weird temp variable behavior seen in HiddenItemAtPos
+ case 2:
+ localOffset = connection->offset + 7;
+ localX = x - localOffset;
+ localLength = mapHeader->mapData->height - 7;
+ localY = localLength + y; // additions are reversed for some reason
+ break;
+ case 1:
+ localOffset = connection->offset + 7;
+ localX = x - localOffset;
+ localLength = gMapHeader.mapData->height + 7;
+ localY = y - localLength;
+ break;
+ case 3:
+ localLength = mapHeader->mapData->width - 7;
+ localX = localLength + x; // additions are reversed for some reason
+ localOffset = connection->offset + 7;
+ localY = y - localOffset;
+ break;
+ case 4:
+ localLength = gMapHeader.mapData->width + 7;
+ localX = x - localLength;
+ localOffset = connection->offset + 7;
+ localY = y - localOffset;
+ break;
+ default:
+ return FALSE;
+ }
+ return HiddenItemAtPos(mapHeader->events, localX, localY);
+}
+
+static void FindHiddenItemsInConnectedMaps(u8 taskId)
+{
+ s16 x, y;
+ s16 curX, curY;
+ s16 width = gMapHeader.mapData->width + 7;
+ s16 height = gMapHeader.mapData->height + 7;
+
+ s16 var1 = 7;
+ s16 var2 = 7;
+
+ PlayerGetDestCoords(&x, &y);
+
+ for (curX = x - 7; curX <= x + 7; curX++)
+ {
+ for (curY = y - 5; curY <= y + 5; curY++)
+ {
+ if (var1 > curX
+ || curX >= width
+ || var2 > curY
+ || curY >= height)
+ {
+ struct MapConnection * conn = GetMapConnectionAtPos(curX, curY);
+ if (conn != NULL && HiddenItemInConnectedMapAtPos(conn, curX, curY) == TRUE)
+ RegisterHiddenItemRelativeCoordsIfCloser(taskId, curX - x, curY - y);
+ }
+ }
+ }
+}
+
+static void RegisterHiddenItemRelativeCoordsIfCloser(u8 taskId, s16 dx, s16 dy)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 dx2, dy2, dx3, dy3;
+
+ if (tHiddenItemFound == FALSE)
+ {
+ tItemX = dx;
+ tItemY = dy;
+ tHiddenItemFound = TRUE;
+ }
+ else
+ {
+ // tItemX and tItemY contain the player's coordinates.
+ // dx and dy contain the item's coordinates.
+ if (tItemX < 0)
+ dx2 = tItemX * -1; // item is to the left
+ else
+ dx2 = tItemX; // item is to the right
+
+ if (tItemY < 0)
+ dy2 = tItemY * -1; // item is to the north
+ else
+ dy2 = tItemY; // item is to the south
+
+ if (dx < 0)
+ dx3 = dx * -1;
+ else
+ dx3 = dx;
+
+ if (dy < 0)
+ dy3 = dy * -1;
+ else
+ dy3 = dy;
+
+ if (dx2 + dy2 > dx3 + dy3)
+ {
+ tItemX = dx;
+ tItemY = dy;
+ }
+ else
+ {
+ if (dx2 + dy2 == dx3 + dy3 && (dy2 > dy3 || (dy2 == dy3 && tItemY < dy)))
+ {
+ tItemX = dx;
+ tItemY = dy;
+ }
+ }
+ }
+}
+
+static u8 GetPlayerDirectionTowardsHiddenItem(s16 itemX, s16 itemY)
+{
+ s16 abX, abY;
+
+ if (itemX == 0 && itemY == 0)
+ return DIR_NONE; // player is standing on the item.
+
+ // get absolute X distance.
+ if (itemX < 0)
+ abX = itemX * -1;
+ else
+ abX = itemX;
+
+ // get absolute Y distance.
+ if (itemY < 0)
+ abY = itemY * -1;
+ else
+ abY = itemY;
+
+ if (abX > abY)
+ {
+ if (itemX < 0)
+ return DIR_EAST;
+ else
+ return DIR_NORTH;
+ }
+ else
+ {
+ if (abX < abY)
+ {
+ if (itemY < 0)
+ return DIR_SOUTH;
+ else
+ return DIR_WEST;
+ }
+ if (abX == abY)
+ {
+ if (itemY < 0)
+ return DIR_SOUTH;
+ else
+ return DIR_WEST;
+ }
+ return DIR_NONE; // should never get here. return something so it doesnt crash.
+ }
+}
+
+static void Task_ItemfinderResponsePrintMessage(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, 2, gText_ItemfinderResponding, Task_ItemfinderResponseCleanUp);
+}
+
+static void Task_ItemfinderResponseCleanUp(u8 taskId)
+{
+ DestroyArrowAndStarTiles();
+ ClearDialogWindowAndFrame(0, TRUE);
+ sub_80696C0();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+}
+
+static void Task_ItemfinderUnderfootPrintMessage(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, 2, gText_ItemfinderShakingWildly, Task_ItemfinderUnderfootDigUpItem);
+}
+
+static void Task_ItemfinderUnderfootDigUpItem(u8 taskId)
+{
+ DestroyArrowAndStarTiles();
+ DestroyTask(taskId);
+ ScriptContext1_SetupScript(EventScript_ItemfinderDigUpUnderfootItem);
+ ScriptContext2_Enable();
+}
+
+#undef tStartSpriteId
+#undef tUnderfoot
+#undef tDingNum
+#undef tNumDingsRemaining
+#undef tDingTimer
+#undef tHiddenItemFound
+#undef tItemY
+#undef tItemX
+
+#define spData0 data[0]
+#define spDeltaX data[1]
+#define spDeltaY data[2]
+#define spCurX data[3]
+#define spCurY data[4]
+#define spCenterX data[5]
+#define spCenterY data[6]
+#define spAnimNum data[7]
+
+static void LoadArrowAndStarTiles(void)
+{
+ LoadSpriteSheet(&sArrowAndStarSpriteSheet);
+}
+
+static void DestroyArrowAndStarTiles(void)
+{
+ FreeSpriteTilesByTag(ARROW_TILE_TAG);
+}
+
+static void CreateArrowSprite(u8 animNum, u8 direction)
+{
+ u8 spriteId = CreateSprite(&gUnknown_84647E4, 120, 76, 0);
+ gSprites[spriteId].oam.paletteNum = 0;
+ StartSpriteAnim(&gSprites[spriteId], animNum);
+ gSprites[spriteId].spAnimNum = animNum;
+ gSprites[spriteId].spData0 = 0;
+ gSprites[spriteId].spCurX = 0;
+ gSprites[spriteId].spCurY = 0;
+ gSprites[spriteId].spCenterX = 120;
+ gSprites[spriteId].spCenterY = 76;
+ switch (direction)
+ {
+ case DIR_NONE:
+ switch (GetPlayerFacingDirection())
+ {
+ case DIR_WEST:
+ gSprites[spriteId].spDeltaX = -100;
+ gSprites[spriteId].spDeltaY = 0;
+ StartSpriteAffineAnim(&gSprites[spriteId], 0);
+ break;
+ case DIR_NORTH:
+ gSprites[spriteId].spDeltaX = 0;
+ gSprites[spriteId].spDeltaY = -100;
+ StartSpriteAffineAnim(&gSprites[spriteId], 3);
+ break;
+ case DIR_EAST:
+ gSprites[spriteId].spDeltaX = 100;
+ gSprites[spriteId].spDeltaY = 0;
+ StartSpriteAffineAnim(&gSprites[spriteId], 2);
+ break;
+ case DIR_SOUTH:
+ gSprites[spriteId].spDeltaX = 0;
+ gSprites[spriteId].spDeltaY = 100;
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+ break;
+ }
+ break;
+ case DIR_SOUTH:
+ gSprites[spriteId].spDeltaX = 0;
+ gSprites[spriteId].spDeltaY = -100;
+ StartSpriteAffineAnim(&gSprites[spriteId], 3);
+ break;
+ case DIR_NORTH:
+ gSprites[spriteId].spDeltaX = 100;
+ gSprites[spriteId].spDeltaY = 0;
+ StartSpriteAffineAnim(&gSprites[spriteId], 2);
+ break;
+ case DIR_WEST:
+ gSprites[spriteId].spDeltaX = 0;
+ gSprites[spriteId].spDeltaY = 100;
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+ break;
+ case DIR_EAST:
+ gSprites[spriteId].spDeltaX = -100;
+ gSprites[spriteId].spDeltaY = 0;
+ break;
+ }
+}
+
+static void SpriteCallback_Arrow(struct Sprite * sprite)
+{
+ s16 x, y;
+ sprite->spCurX += sprite->spDeltaX;
+ sprite->spCurY += sprite->spDeltaY;
+ sprite->pos1.x = sprite->spCenterX + (sprite->spCurX >> 8);
+ sprite->pos1.y = sprite->spCenterY + (sprite->spCurY >> 8);
+ if (sprite->pos1.x <= 104
+ || sprite->pos1.x > 132
+ || sprite->pos1.y <= 60
+ || sprite->pos1.y > 88)
+ sprite->callback = SpriteCallback_DestroyArrow;
+}
+
+static void SpriteCallback_DestroyArrow(struct Sprite * sprite)
+{
+ FreeSpriteOamMatrix(sprite);
+ DestroySprite(sprite);
+}
+
+static u8 CreateStarSprite(void)
+{
+ u8 spriteId = CreateSprite(&gUnknown_84647E4, 120, 76, 0);
+ gSprites[spriteId].oam.paletteNum = 0;
+ gSprites[spriteId].callback = SpriteCallback_Star;
+ StartSpriteAnim(&gSprites[spriteId], 4);
+ gSprites[spriteId].spAnimNum = 0;
+ gSprites[spriteId].spData0 = 0;
+ gSprites[spriteId].spCurX = 0;
+ gSprites[spriteId].spCurY = 0;
+ gSprites[spriteId].spCenterX = 120;
+ gSprites[spriteId].spCenterY = 76;
+ gSprites[spriteId].spDeltaX = 0;
+ gSprites[spriteId].spDeltaY = -100;
+ return spriteId;
+}
+
+static void SpriteCallback_Star(struct Sprite * sprite)
+{
+ s16 x, y;
+ sprite->spCurX += sprite->spDeltaX;
+ sprite->spCurY += sprite->spDeltaY;
+ sprite->pos1.x = sprite->spCenterX + (sprite->spCurX >> 8);
+ sprite->pos1.y = sprite->spCenterY + (sprite->spCurY >> 8);
+ if (sprite->pos1.x <= 104
+ || sprite->pos1.x > 132
+ || sprite->pos1.y <= 60
+ || sprite->pos1.y > 88)
+ sprite->callback = SpriteCallback_DestroyStar;
+}
+
+static void SpriteCallback_DestroyStar(struct Sprite * sprite)
+{
+ DestroySprite(sprite);
+}
+
+#undef spAnimNum
+#undef spCenterY
+#undef spCenterX
+#undef spCurY
+#undef spCurX
+#undef spDeltaY
+#undef spDeltaX
+#undef spData0