diff --git a/config/symbols.us.borbo5.txt b/config/symbols.us.borbo5.txt index 04c50ba714..58db41dee1 100644 --- a/config/symbols.us.borbo5.txt +++ b/config/symbols.us.borbo5.txt @@ -2,7 +2,6 @@ D_800AD57C = 0x80181834; g_DopAnimationFrames = 0x801840B0; g_SpriteSheet = 0x80184434; g_PlOvlDopBatSpritesheet = 0x801AAE4C; -D_us_801B2D0C = 0x801B2D0C; g_Dop = 0x801D3FF0; // size:0x3D0 g_Dop_padPressed = 0x801D4308; g_Dop_padTapped = 0x801D430C; diff --git a/config/symbols.us.stno4.txt b/config/symbols.us.stno4.txt index 381b532afd..d28f2e0ed4 100644 --- a/config/symbols.us.stno4.txt +++ b/config/symbols.us.stno4.txt @@ -4,7 +4,6 @@ g_WaterSounds = 0x80180EE4; g_WaterXTbl = 0x80180EE8; NO4_PrizeDrops = 0x80181928; cutscene_data_ferryman_right = 0x801853B7; // used:true -D_801B0934 = 0x801C0D3C; Update = 0x801CA620; UpdateStageEntities = 0x801CA91C; HitDetection = 0x801CAA24; diff --git a/config/symbols.us.stnz1.txt b/config/symbols.us.stnz1.txt index 733d2a2129..c61f3b4fa2 100644 --- a/config/symbols.us.stnz1.txt +++ b/config/symbols.us.stnz1.txt @@ -10,17 +10,11 @@ g_EInitCommon = 0x80180B7C; g_EInitEnvironment = 0x80180B94; g_EInitHarpyFlame = 0x80180BD0; NZ1_BackgroundBlockInit = 0x80180D08; -entityLockCameraHitbox = 0x80180DA0; -entityLockCameraData = 0x80180DA4; -entityLockCameraTilemapProps = 0x80180DA8; g_WaterSounds = 0x801810CC; g_WaterXTbl = 0x801810D0; NZ1_PrizeDrops = 0x8018111C; g_HarpyFlameAnim = 0x80181F74; NZ1_rooms = 0x8018233C; -PlayerIsWithinHitbox = 0x801A5E18; -NZ1_EntityLockCamera = 0x801A5E9C; // source=match -EntityBridgeBackgroundPiece = 0x801A7118; EntityClouds = 0x801A7970; EntityBreakableWall = 0x801A9154; EntityBreakableWallPartial = 0x801A94CC; @@ -57,11 +51,9 @@ EntitySplashWater = 0x801B8414; // source=match EntitySurfacingWater = 0x801B8D20; // source=match EntitySideWaterSplash = 0x801B920C; // source=match EntitySmallWaterDrop = 0x801B95A0; // source=match -EntityWaterDrop = 0x801B97FC; // source=match EntitySkullLord = 0x801B9AA0; // source=match EntitySkullLordOutline = 0x801BA250; // source=match EntitySkullLordFlames = 0x801BA52C; // source=match -EntitySkullLordPieces = 0x801BA7F8; // source=match EntityHarpyDagger = 0x801BB628; EntityHarpyFlame = 0x801BB7C0; EntityHarpyKick = 0x801BB9E8; diff --git a/src/st/nz1/e_red_door.c b/src/st/nz1/e_red_door.c index c5a9c00dd0..3cd56e1a06 100644 --- a/src/st/nz1/e_red_door.c +++ b/src/st/nz1/e_red_door.c @@ -1,6 +1,32 @@ // SPDX-License-Identifier: AGPL-3.0-or-later #include "nz1.h" -INCLUDE_ASM("st/nz1/nonmatchings/e_red_door", EntityIsNearPlayer); +extern u16 PLAYER_posX_i_hi; +extern u16 PLAYER_posY_i_hi; + +static bool EntityIsNearPlayer(Entity* self) { + s16 distanceX; + s16 diffX; + s16 distanceY; + s16 diffY; + + diffX = PLAYER.posX.i.hi - self->posX.i.hi; + distanceX = abs(diffX); +#ifdef STAGE_IS_NO1 + if (distanceX > 24) { +#else + if (distanceX > 16) { +#endif + return false; + } + + diffY = PLAYER.posY.i.hi - self->posY.i.hi; + distanceY = abs(diffY); + if (distanceY > 32) { + return false; + } + + return true; +} INCLUDE_ASM("st/nz1/nonmatchings/e_red_door", NZ1_EntityRedDoor); diff --git a/src/st/nz1/e_skull_lord.c b/src/st/nz1/e_skull_lord.c index 6def59efc9..9b2c9594de 100644 --- a/src/st/nz1/e_skull_lord.c +++ b/src/st/nz1/e_skull_lord.c @@ -7,4 +7,40 @@ INCLUDE_ASM("st/nz1/nonmatchings/e_skull_lord", EntitySkullLordOutline); INCLUDE_ASM("st/nz1/nonmatchings/e_skull_lord", EntitySkullLordFlames); -INCLUDE_ASM("st/nz1/nonmatchings/e_skull_lord", EntitySkullLordPieces); +extern EInit g_EInitSkullLord; +extern EInit D_us_80180BAC; + +void EntitySkullLordPieces(Entity* self) { + s32 rand; + s16 angle; + s32 step = (s32)self->step; + + switch (step) { + case 0: + InitializeEntity(D_us_80180BAC); + self->flags |= FLAG_DESTROY_IF_OUT_OF_CAMERA; + rand = Random() & 3; + if (rand == 3) { + rand = 2; + } + self->animCurFrame = rand + 9; + angle = self->ext.skullLord.unk82; + rand = (Random() & 0xF) + 2; + self->velocityX = rand * rcos(angle); + rand = 0x20 - (Random() & 0x1F); + self->velocityY = -rand * rsin(angle); + self->drawMode = DRAW_TPAGE2 | DRAW_TPAGE; + self->drawFlags = FLAG_DRAW_ROTATE; + break; + + case 1: + MoveEntity(); + self->velocityY += FIX(0.125); + if (self->velocityX > 0) { + self->rotate += 0x80; + } else { + self->rotate -= 0x80; + } + break; + } +} diff --git a/src/st/nz1/e_vandal_sword.c b/src/st/nz1/e_vandal_sword.c index b238290445..fa1f8ffef5 100644 --- a/src/st/nz1/e_vandal_sword.c +++ b/src/st/nz1/e_vandal_sword.c @@ -3,9 +3,42 @@ INCLUDE_ASM("st/nz1/nonmatchings/e_vandal_sword", VandalSwordDrawAlastor); -INCLUDE_ASM("st/nz1/nonmatchings/e_vandal_sword", VandalSwordTargetPlayer); +extern Entity g_Entities_224; +extern int g_Timer; +extern Entity* g_CurrentEntity; -INCLUDE_ASM("st/nz1/nonmatchings/e_vandal_sword", VandalSwordTrail); +void VandalSwordTargetPlayer(void) { + Entity* temp_v0 = NULL; + + if (g_Timer & 7) + goto done; + + temp_v0 = AllocEntity( + &g_Entities_224, (Entity*)((char*)&g_Entities_224 + 0x1780)); + if (temp_v0 == NULL) + goto done; + + CreateEntityFromEntity(E_VANDAL_SWORD_DEATH, g_CurrentEntity, temp_v0); + temp_v0->rotate = (s16)(u16)g_CurrentEntity->rotate; + temp_v0->facingLeft = g_CurrentEntity->facingLeft; + +done: + return; +} + +bool VandalSwordTrail(s16* val, s16 target, s16 step) { + if (abs(*val - target) < step) { + *val = target; + return true; + } + if (*val > target) { + *val -= step; + } + if (*val < target) { + *val += step; + } + return false; +} INCLUDE_ASM("st/nz1/nonmatchings/e_vandal_sword", EntityVandalSword); diff --git a/src/st/nz1/water_effects.c b/src/st/nz1/water_effects.c index bffc3b45fd..1dc3e59c62 100644 --- a/src/st/nz1/water_effects.c +++ b/src/st/nz1/water_effects.c @@ -13,4 +13,86 @@ INCLUDE_ASM("st/nz1/nonmatchings/water_effects", EntitySideWaterSplash); INCLUDE_ASM("st/nz1/nonmatchings/water_effects", EntitySmallWaterDrop); -INCLUDE_ASM("st/nz1/nonmatchings/water_effects", EntityWaterDrop); +extern EInit g_EInitCommon; +extern s16 (*g_api_func_800EDB58)(s32 kind, s32 count); + +void EntityWaterDrop(Entity* self) { + s16 x = self->posX.i.hi; + s16 y = self->posY.i.hi; + FakePrim* prim; + s32 primIndex; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitCommon); + primIndex = g_api_func_800EDB58(PRIM_TILE_ALT, 0x21); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + self->flags |= FLAG_HAS_PRIMS; + self->primIndex = primIndex; + self->ext.timer.t = 0x2F; + prim = (FakePrim*)&g_PrimBuf[primIndex]; + + while (1) { + prim->drawMode = DRAW_UNK_40 | DRAW_TPAGE2 | DRAW_TPAGE | + DRAW_UNK02 | DRAW_TRANSP; + prim->priority = self->zPriority + 2; + + if (prim->next == NULL) { + prim->drawMode &= ~DRAW_HIDE; + prim->y0 = prim->x0 = prim->w = 0; + break; + } + + prim->posX.i.lo = prim->posY.i.lo = 0; + prim->velocityY.val = (rand() & PSP_RANDMASK) * 8 + self->velocityY; + prim->posY.i.hi = y + (rand() & 15); + prim->posX.i.hi = x + (rand() & 31) - 16; + prim->delay = (rand() & 15) + 32; + prim->x0 = prim->posX.i.hi; + prim->y0 = prim->posY.i.hi; + prim->r0 = 255; + prim->g0 = 255; + prim->b0 = 255; + prim->w = 2; + prim->h = 2; + prim = prim->next; + } + break; + + case 1: + if (--self->ext.timer.t == 0) { + DestroyEntity(self); + return; + } + + prim = (FakePrim*)&g_PrimBuf[self->primIndex]; + + while (1) { + if (prim->next == NULL) { + prim->drawMode &= ~DRAW_HIDE; + prim->y0 = prim->x0 = prim->w = 0; + return; + } + prim->posX.i.hi = prim->x0; + prim->posY.i.hi = prim->y0; + if (!--prim->delay) { + prim->drawMode |= DRAW_HIDE; + } + prim->posY.val += prim->velocityY.val; + if (prim->velocityY.val > FIX(0.5)) { + prim->r0 -= 4; + prim->g0 -= 4; + prim->b0 -= 4; + } else { + prim->velocityY.val += FIX(28.0 / 128); + } + prim->x0 = prim->posX.i.hi; + prim->y0 = prim->posY.i.hi; + prim = prim->next; + } + break; + } +}