diff --git a/config/splat.us.stnz0.yaml b/config/splat.us.stnz0.yaml index 4b31807e1e..e8d2a982ee 100644 --- a/config/splat.us.stnz0.yaml +++ b/config/splat.us.stnz0.yaml @@ -37,20 +37,27 @@ segments: - [0x164, .data, header] # layers - [0x47C, data] - [0x8EC, .data, e_laydef] # layout entries header - - [0xA94, data] + - [0xA94, .data, e_init] + - [0xDBC, data] + - [0xDE4, .data, e_breakable] + - [0xE54, data] + - [0x1574, .data, st_update] - [0x15A0, .data, collision] - [0x1960, .data, e_red_door] - - [0x1978, data] + - [0x1978, .data, st_common] - [0x1B78, .data, e_collect] - [0x1E68, .data, entity_relic_orb] - [0x1ECC, data] - [0x1F80, .data, e_particles] - [0x2000, .data, e_room_fg] - - [0x208C, data] - - [0x20B0, data] - - [0x2220, data] - - [0x2600, data] - - [0x2710, data] + - [0x208C, .data, e_bone_scimitar] + - [0x2180, .data, e_axe_knight] + - [0x22D4, .data, e_bloody_zombie] + - [0x23DC, .data, e_skeleton] + - [0x24CC, data] # spittle bone + - [0x2584, data] # subweapon container + - [0x2610, data] # bloody skeleton + - [0x26B8, data] # magically sealed door - [0x272C, .data, rooms] - [0x2830, data, D_80182830] - [0x2884, .data, e_layout] # layout entries data @@ -59,46 +66,47 @@ segments: - [0x20A5C, .data, tile_data] # tile definitions - [0x26E8C, .data, sprites] - [0x3058C, rodata] - - [0x305A4, .rodata, 30958] # func_801B3C38 + - [0x305A4, .rodata, 311C0] # EntityWargExplosionPuffOpaque - [0x305B8, .rodata, bossfight] # EntityBossFightManager - [0x305E8, .rodata, bossfight] # EntityBossRoomBlock - [0x305FC, .rodata, slogra] # EntitySlogra - [0x30618, .rodata, gaibon] # EntityGaibon .rodata, 33FCC - - [0x3063C, .rodata, 36DE4] # func_801B7034 + - [0x3063C, .rodata, e_elevator] # func_801B7034 - [0x3064C, rodata] - [0x30664, .rodata, mariacutscene] - [0x306E8, .rodata, maria] - - [0x30728, .rodata, e_red_door] # EntityRedDoor + - [0x30728, .rodata, e_red_door] - [0x30740, .rodata, e_collect] # CollectGold text - [0x30790, .rodata, e_collect] # EntityPrizeDrop - [0x307B0, .rodata, e_collect] # EntityEquipItemDrop - [0x307C8, .rodata, entity_relic_orb] - [0x30800, .rodata, entity_message_box] - - [0x30814, .rodata, 43708] # EntityBoneScimitar - - [0x30834, .rodata, 43F9C] # EntityAxeKnight - - [0x30858, .rodata, 44EAC] # EntityBloodyZombie - - [0x30880, .rodata, 45F2C] # EntitySkeleton - - [0x3089C, .rodata, 4672C] # EntitySpittleBone - - [0x308C8, .rodata, 47048] # EntitySubWeaponContainer - - [0x308D4, .rodata, 47958] # EntityBloodSkeleton - - [0x308E8, .rodata, 47CF0] # EntityMagicallySealedDoor - - [0x30900, .rodata, e_stage_name] # EntityStageNamePopup + - [0x30814, .rodata, e_bone_scimitar] + - [0x30834, .rodata, e_axe_knight] + - [0x30858, .rodata, e_bloody_zombie] + - [0x30880, .rodata, e_skeleton] + - [0x3089C, .rodata, e_spittle_bone] + - [0x308C8, .rodata, e_subweapon_container] + - [0x308D4, .rodata, e_bloody_skeleton] + - [0x308E8, .rodata, e_magically_sealed_door] + - [0x30900, .rodata, e_stage_name] - [0x30934, .rodata, prim_helpers] - [0x3093C, .rodata, lifeupspawn] - [0x30958, c] + - [0x30EEC, c, e_breakable] + - [0x311C0, c] - [0x33FCC, c, bossfight] # Slogra & Gaibon Boss - [0x34690, c, slogra] - [0x35778, c, gaibon] - [0x36DE4, c] + - [0x37034, c, e_elevator] - [0x374CC, c, mariacutscene] - [0x38E0C, c, maria] - - [0x394D4, c, random] - - [0x39504, c, update] - - [0x39800, c, update_stage_entities] + - [0x394D4, c, st_update] - [0x39908, c, collision] - [0x3B0C4, c, create_entity] - [0x3BC3C, c, e_red_door] - - [0x3C8EC, c, 3C8EC] + - [0x3C8EC, c, st_common] - [0x3D848, c, e_collect] - [0x3F308, c, blit_char] - [0x3F5B8, c, entity_relic_orb] @@ -108,15 +116,15 @@ segments: - [0x42AA8, c, e_particles] - [0x432EC, c, e_room_fg] - [0x433d8, c, popup] - - [0x43708, c] # EntityBoneScimitar - - [0x43F9C, c] # EntityAxeKnight - - [0x44EAC, c] # EntityBloodyZombie - - [0x45F2C, c] # EntitySkeleton - - [0x4672C, c] # EntitySpittleBone - - [0x47048, c] # EntitySubWeaponContainer - - [0x47958, c] # EntityBloodSkeleton - - [0x47CF0, c] # EntityMagicallySealedDoor - - [0x48ADC, c, e_stage_name] # EntityStageNamePopup + - [0x43708, c, e_bone_scimitar] + - [0x43F9C, c, e_axe_knight] + - [0x44EAC, c, e_bloody_zombie] + - [0x45F2C, c, e_skeleton] + - [0x4672C, c, e_spittle_bone] + - [0x47048, c, e_subweapon_container] + - [0x47958, c, e_bloody_skeleton] + - [0x47CF0, c, e_magically_sealed_door] + - [0x48ADC, c, e_stage_name] - [0x49930, c, prim_helpers] - [0x4A160, c, lifeupspawn] - [0x4AA14, .bss, bss] diff --git a/config/symbols.us.stnz0.txt b/config/symbols.us.stnz0.txt index 36df17b187..dab06d72f4 100644 --- a/config/symbols.us.stnz0.txt +++ b/config/symbols.us.stnz0.txt @@ -1,17 +1,8 @@ g_EntityGfxs = 0x80180888; -PfnEntityUpdates = 0x80180A94; -g_InitializeData0 = 0x80180BD4; -g_InitializeEntityData0 = 0x80180BE0; -g_EInitGeneric = 0x80180BF8; -g_InitDataEnt13 = 0x80180C04; -g_eInitGeneric2 = 0x80180C1C; -g_eDamageDisplayInit = 0x80180C28; -g_eRedDoorTiles = 0x80180D8C; g_CallElevator = 0x80180EEC; g_BossFlag = 0x80181010; g_ElevatorTarget = 0x801813A4; g_ElevatorTargetPos = 0x801813A8; -UNK_Invincibility0 = 0x80181574; g_eUnk14SpawnRots = 0x80181ECC; unk15_rot = 0x80181EDC; unk15_yVel = 0x80181EEC; @@ -23,59 +14,10 @@ g_UnkRecursPrimVecOrder = 0x80181F40; g_UnkRecursPrim2Inds = 0x80181F60; g_eBlueDoorUV = 0x801826B8; g_eBlueDoorTiles = 0x801826D0; -EntityBreakable = 0x801B0EEC; -EntityRedEyeBust = 0x801B11C0; -EntityPurpleBrickScrollingBackground = 0x801B12E8; -EntityLeftSecretRoomWall = 0x801B14C4; -EntityBottomSecretRoomFloor = 0x801B1770; -EntityMoveableBox = 0x801B20CC; -EntityCannonLever = 0x801B23B4; -EntityCannon = 0x801B25C4; -EntityCannonShot = 0x801B2874; -EntityCannonWall = 0x801B2978; -EntityElevator2 = 0x801B2D08; -EntityFloorSpikes = 0x801B3294; -EntityTableWithGlobe = 0x801B3534; EntityWargExplosionPuffOpaque = 0x801B3C38; EntityBossFightManager = 0x801B3FCC; EntityBossRoomBlock = 0x801B4518; EntitySlogra = 0x801B4778; -EntitySlograSpear = 0x801B54A8; -EntitySlograSpearProjectile = 0x801B5654; EntityGaibon = 0x801B5778; -EntitySmallGaibonProjectile = 0x801B6AAC; -EntityLargeGaibonProjectile = 0x801B6BBC; -EntityElevator = 0x801B7034; -EntityMariaCutscene = 0x801B7D58; -EntityMaria = 0x801B8F94; -EntityDamageDisplay = 0x801BAA20; -EntityRedDoor = 0x801BBCB4; -EntityDummy = 0x801BD6F8; EntityPrizeDrop = 0x801BE30C; -EntityExplosion = 0x801BEB80; EntityEquipItemDrop = 0x801BED20; -EntityRelicOrb = 0x801BF5B8; -EntityHeartDrop = 0x801C0088; -EntityMessageBox = 0x801C01B0; -EntityUnkId13 = 0x801C07FC; -EntityUnkId14 = 0x801C0B24; -EntityUnkId15 = 0x801C0C14; -EntityIntenseExplosion = 0x801C15B4; -EntitySoulStealOrb = 0x801C2AA8; -EntityEnemyBlood = 0x801C2E3C; -EntityRoomForeground = 0x801C32EC; -EntityBoneScimitar = 0x801C37E4; -EntityBoneScimitarParts = 0x801C3E94; -EntityAxeKnight = 0x801C45BC; -EntityAxeKnightThrowingAxe = 0x801C4D18; -EntityBloodSplatter = 0x801C4EAC; -EntityBloodyZombie = 0x801C5568; -EntitySkeleton = 0x801C5FC4; -EntitySpittleBone = 0x801C672C; -EntityRotateSpittlebone = 0x801C6B24; -EntitySpittleBoneSpit = 0x801C6C6C; -EntitySubWeaponContainer = 0x801C7048; -EntityBloodSkeleton = 0x801C7958; -EntityMagicallySealedDoor = 0x801C7D68; -EntityStageNamePopup = 0x801C8CAC; -EntityLifeUpSpawn = 0x801CA160; diff --git a/src/st/cen/14264.c b/src/st/cen/14264.c index bc2c7e3871..92a4b4b486 100644 --- a/src/st/cen/14264.c +++ b/src/st/cen/14264.c @@ -1,8 +1,11 @@ #include "cen.h" - -#include "../entity.h" #include "sfx.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" + u8 func_8019444C(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; u8* var_s1 = &frames[animFrameStart]; diff --git a/src/st/cen/entity.c b/src/st/cen/entity.c index 04a0cb81c2..7049181025 100644 --- a/src/st/cen/entity.c +++ b/src/st/cen/entity.c @@ -147,37 +147,10 @@ ObjInit2 D_80180490 = { .unk10 = &D_8018048C, }; -u16 g_eRedDoorTiles[3][8] = { - { - 0x039C, - 0x039B, - 0x039C, - 0x039B, - 0x010D, - 0x010B, - 0x010D, - 0x010B, - }, - { - 0x03A3, - 0x03A4, - 0x03A5, - 0x03A6, - 0x02F4, - 0x0309, - 0x0305, - 0x0307, - }, - { - 0x03A3, - 0x03A7, - 0x03A8, - 0x03A3, - 0x02F4, - 0x030F, - 0x0310, - 0x02F4, - }, +u16 g_eRedDoorTiles[][8] = { + {0x039C, 0x039B, 0x039C, 0x039B, 0x010D, 0x010B, 0x010D, 0x010B}, + {0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x02F4, 0x0309, 0x0305, 0x0307}, + {0x03A3, 0x03A7, 0x03A8, 0x03A3, 0x02F4, 0x030F, 0x0310, 0x02F4}, }; u8 D_801804D4[] = {32, 32, 32, 32, 32, 32, 80, 32}; diff --git a/src/st/dre/1A3A8.c b/src/st/dre/1A3A8.c index 6c4ec8be33..2a309fdb30 100644 --- a/src/st/dre/1A3A8.c +++ b/src/st/dre/1A3A8.c @@ -1,8 +1,11 @@ #include "dre.h" - -#include "../entity.h" #include "sfx.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" + u8 func_8019A590(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; u8* var_s1 = &frames[animFrameStart]; diff --git a/src/st/e_breakable.h b/src/st/e_breakable.h index fee5e32338..e59c88b92b 100644 --- a/src/st/e_breakable.h +++ b/src/st/e_breakable.h @@ -4,23 +4,17 @@ static u8 D_801805A8[] = {4, 1, 4, 2, 0, 0, 0, 0}; static u8 D_801805B0[] = {4, 0, 4, 0, 0, 0, 0, 0}; static u8* g_eBreakableAnimations[] = { - D_801805A8, D_801805B0, NULL, NULL, NULL, NULL, NULL, NULL, -}; -static u8 g_eBreakableHitboxes[] = { - 8, 8, 0, 0, 0, 0, 0, 0, -}; + D_801805A8, D_801805B0, NULL, NULL, NULL, NULL, NULL, NULL}; +static u8 g_eBreakableHitboxes[] = {8, 8, 0, 0, 0, 0, 0, 0}; #ifndef VERSION_PSP // on PSP this is in the BSS section, not data -static u8 g_eBreakableExplosionTypes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, -}; +static u8 g_eBreakableExplosionTypes[] = {0, 0, 0, 0, 0, 0, 0, 0}; #else extern u8 g_eBreakableExplosionTypes[]; #endif static u16 g_eBreakableanimSets[] = { - 3, 3, 0, 0, 0, 0, 0, 0, -}; + ANIMSET_DRA(3), ANIMSET_DRA(3), 0, 0, 0, 0, 0, 0}; static u8 g_eBreakableDrawModes[] = { DRAW_TPAGE | DRAW_TPAGE2 | DRAW_UNK_40, DRAW_TPAGE | DRAW_TPAGE2, @@ -29,8 +23,7 @@ static u8 g_eBreakableDrawModes[] = { DRAW_DEFAULT, DRAW_DEFAULT, DRAW_DEFAULT, - DRAW_DEFAULT, -}; + DRAW_DEFAULT}; #ifndef VERSION_PSP // on PSP this might be either optimised out to BSS or completely removed @@ -60,7 +53,7 @@ void EntityBreakable(Entity* entity) { } } else { InitializeEntity(g_eBreakableInit); - entity->zPriority = g_unkGraphicsStruct.g_zEntityCenter.unk - 0x14; + entity->zPriority = g_unkGraphicsStruct.g_zEntityCenter.unk - 20; entity->drawMode = g_eBreakableDrawModes[breakableType]; entity->hitboxHeight = g_eBreakableHitboxes[breakableType]; entity->animSet = g_eBreakableanimSets[breakableType]; diff --git a/src/st/entity.h b/src/st/entity.h deleted file mode 100644 index 4976b969b1..0000000000 --- a/src/st/entity.h +++ /dev/null @@ -1,5 +0,0 @@ -// an implementation of entity.c -#include "../destroy_entity.h" -#include "../destroy_entities_from_index.h" -#include "prevent_entity_from_respawning.h" -#include "animate_entity.h" diff --git a/src/st/mad/11D3C.c b/src/st/mad/11D3C.c index 34466c93f2..8a76630536 100644 --- a/src/st/mad/11D3C.c +++ b/src/st/mad/11D3C.c @@ -1,8 +1,11 @@ #include "mad.h" - -#include "../entity.h" #include "sfx.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" + u8 func_80191F24(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; u8* var_s1 = &frames[animFrameStart]; diff --git a/src/st/no3/44C64.c b/src/st/no3/44C64.c index 154de7cd7e..a7d224f01b 100644 --- a/src/st/no3/44C64.c +++ b/src/st/no3/44C64.c @@ -1,8 +1,11 @@ #include "no3.h" - -#include "../entity.h" #include "sfx.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" + u8 func_801C4E4C(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; u8* var_s1 = &frames[animFrameStart]; diff --git a/src/st/np3/e_init.c b/src/st/np3/e_init.c index dbc3ec57fc..4203cdb163 100644 --- a/src/st/np3/e_init.c +++ b/src/st/np3/e_init.c @@ -256,7 +256,7 @@ ObjInit2 D_80180C10[] = { {0x8001, 0x0039, 0x0000, 0x0000, 0x00, 0x00, 0x00000000, D_80180C04}, }; -u16 g_eRedDoorTiles[2][8] = { +u16 g_eRedDoorTiles[][8] = { {0x06C7, 0x04FA, 0x04FA, 0x04FA, 0x030F, 0x0000, 0x0000, 0x0000}, {0x04FA, 0x04FA, 0x04FA, 0x04FA, 0x0000, 0x0000, 0x0000, 0x0000}, }; diff --git a/src/st/np3/st_common.c b/src/st/np3/st_common.c index e7ebff55cc..bc65f94712 100644 --- a/src/st/np3/st_common.c +++ b/src/st/np3/st_common.c @@ -1,6 +1,9 @@ #include "np3.h" -#include "../entity.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" u8 func_801BC6BC(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; diff --git a/src/st/nz0/30958.c b/src/st/nz0/30958.c index 96e7403974..0e86621802 100644 --- a/src/st/nz0/30958.c +++ b/src/st/nz0/30958.c @@ -168,1489 +168,3 @@ void func_801B0AA4(Entity* self) { } } } - -void EntityBreakable(Entity* self) { - u16 params = self->params >> 0xC; - s16 top, bottom, left, right; - Entity* newEntity; - Primitive* prim; - - if (self->step != 0) { - AnimateEntity((u8*)D_80180E04[params], self); - if (params == 2) { - prim = &g_PrimBuf[self->primIndex]; - if (g_Timer & 2) { - prim->clut = 0x21B; - } else { - prim->clut = 0x21C; - } - } - - if (self->unk44 != 0) { - if (params == 2) { - g_api.FreePrimitives(self->primIndex); - self->flags &= ~FLAG_HAS_PRIMS; - } - g_api.PlaySfx(SFX_CANDLE_HIT); - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromCurrentEntity(E_EXPLOSION, newEntity); - newEntity->params = D_80180E2C[params]; - } - ReplaceBreakableWithItemDrop(self); - } - } else { - InitializeEntity(D_80180BC8); - self->zPriority = g_unkGraphicsStruct.g_zEntityCenter.unk - 20; - self->drawMode = D_80180E44[params]; - self->hitboxHeight = D_80180E24[params]; - self->animSet = D_80180E34[params]; - if (params == 2) { - self->unk5A = 0x4B; - self->palette = 0x219; - self->primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (self->primIndex == -1) { - DestroyEntity(self); - return; - } - self->flags |= FLAG_HAS_PRIMS; - prim = &g_PrimBuf[self->primIndex]; - prim->tpage = 0x12; - prim->u0 = prim->u2 = 0xC8; - prim->u1 = prim->u3 = 0xF8; - prim->v0 = prim->v1 = 0x80; - prim->v2 = prim->v3 = 0xA0; - left = self->posX.i.hi - 23; - right = self->posX.i.hi + 25; - prim->x0 = prim->x2 = left; - prim->x1 = prim->x3 = right; - top = self->posY.i.hi - 23; - bottom = self->posY.i.hi + 9; - prim->y0 = prim->y1 = top; - prim->y2 = prim->y3 = bottom; - prim->priority = self->zPriority; - prim->drawMode = 0x73; - } - } -} - -// bust with red eyes that can have a candle on it -void EntityRedEyeBust(Entity* self) { - switch (self->step) { - case 0: - InitializeEntity(D_80180C34); - self->animCurFrame = 7; - self->zPriority = 0x70; - break; - - case 1: - break; - - case 2: - FntPrint(&D_801B058C, self->animCurFrame); // "charal %x\n" - if (g_pads[1].pressed & PAD_SQUARE) { - if (self->params == 0) { - self->animCurFrame++; - self->params |= 1; - } else - break; - } else { - self->params = 0; - } - - if (g_pads[1].pressed & PAD_CIRCLE) { - if (self->step_s == 0) { - self->animCurFrame--; - self->step_s |= 1; - } - } else { - self->step_s = 0; - } - break; - } -} - -// A purplish-red brick background that scrolls behind the foreground layer -void EntityPurpleBrickScrollingBackground(Entity* self) { - Primitive* prim; - s16 primIndex; - s32 tempPosX; - s32 tempPosY; - s32 x, y; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->posX.i.hi = 0; - self->posY.i.hi = 0; - self->unk68 = 0x80; - // Composed of 15 primitives - primIndex = g_api.AllocPrimitives(PRIM_GT4, 15); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - prim = &g_PrimBuf[primIndex]; - self->primIndex = (s32)primIndex; - *(s32*)&self->ext.generic.unk7C = prim; - self->flags |= FLAG_HAS_PRIMS; - while (prim != NULL) { - prim->tpage = 0xF; - prim->clut = 4; - prim->u0 = prim->u2 = 0x80; - prim->u1 = prim->u3 = 0xFF; - prim->v0 = prim->v1 = 0x80; - prim->v2 = prim->v3 = 0xBF; - prim->priority = 0x20; - prim->drawMode = 2; - prim = prim->next; - } - - case 1: - // Add a scrolling effect - tempPosX = self->posX.i.hi; - tempPosX = tempPosX & 0x7F; - tempPosX = tempPosX - 0x80; - tempPosY = self->posY.i.hi; - tempPosY = (tempPosY & 0x3F) - 0x40; - prim = *((s32*)(&self->ext.generic.unk7C)); - // Primitives are laid out in a 5-tall by 3-wide grid - for (y = 0; y < 5; y++) { - for (x = 0; x < 3; x++) { - prim->x0 = prim->x2 = tempPosX + (x * 0x80); - prim->x1 = prim->x3 = prim->x0 + 0x80; - prim->y0 = prim->y1 = tempPosY + (y * 0x40); - prim->y2 = prim->y3 = prim->y0 + 0x40; - prim->drawMode = DRAW_DEFAULT; - prim = prim->next; - } - } - - while (prim != NULL) { - prim->drawMode = DRAW_HIDE; - prim = prim->next; - } - } -} - -void EntityLeftSecretRoomWall(Entity* self, u16* tileLayoutPtr, s32 tilePos) { - Entity* newEntity; - s32 cond; - s32 i; - - switch (self->step) { - case LEFT_SECRET_ROOM_WALL_INIT: - InitializeEntity(g_EInitGeneric); - self->hitboxWidth = 16; - self->hitboxHeight = 32; - self->hitboxState = 2; - - cond = g_CastleFlags[129] != 0; - tileLayoutPtr = &D_80180E54 + (-cond & 0xC); - - tilePos = 0x260; - for (i = 0; i < 4; i++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); - tilePos += 0x10; - tileLayoutPtr += 2; - } - - if (g_CastleFlags[129] != 0) { - DestroyEntity(self); - break; - } - - case LEFT_SECRET_ROOM_WALL_IDLE: - if (self->hitFlags != 0) { - func_801C29B0(SFX_WALL_DEBRIS_B); - self->step++; - } - break; - - case LEFT_SECRET_ROOM_WALL_BREAK: - self->ext.generic.unk84.unk++; - tileLayoutPtr = &D_80180E54 + (self->ext.generic.unk84.unk * 0x4); - - tilePos = 0x260; - for (i = 0; i < 4; i++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); - tileLayoutPtr += 2; - tilePos += 0x10; - } - - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 0x13; - } - self->ext.generic.unk80.modeS32 = 32; - self->step++; - - if (self->ext.generic.unk84.unk == 3) { - g_CastleFlags[129] = 1; - g_api.func_800F1FC4(0x81); - - for (i = 0; i < 8; i++) { - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(0x22, self, newEntity); - newEntity->posX.i.hi += (Random() & 0xF); - newEntity->posY.i.hi -= 0x20 - (Random() & 0x3F); - } - } - DestroyEntity(self); - } - break; - - case LEFT_SECRET_ROOM_WALL_CHECK: - if (--self->ext.generic.unk80.modeS32 == 0) { - self->step = LEFT_SECRET_ROOM_WALL_IDLE; - } - break; - } -} - -void EntityBottomSecretRoomFloor( - Entity* self, u16* tileLayoutPtr, s32 tilePos) { - Entity* newEntity; - s32 flag; - s32 i; - - switch (self->step) { - case BOTTOM_SECRET_ROOM_FLOOR_INIT: - InitializeEntity(g_EInitGeneric); - self->hitboxWidth = 16; - self->hitboxHeight = 16; - self->hitboxState = 2; - flag = (g_CastleFlags[130] != 0); - tileLayoutPtr = &D_80180E94 + (-flag & 0x6); - - tilePos = 0x2E7; - for (i = 0; i < 2; i++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); - tileLayoutPtr += 2; - tilePos += 0x10; - } - - if (g_CastleFlags[130] != 0) { - DestroyEntity(self); - break; - } - - case BOTTOM_SECRET_ROOM_FLOOR_IDLE: - if (self->hitFlags != 0) { - func_801C29B0(SFX_WALL_DEBRIS_B); - self->step++; - } - return; - - case BOTTOM_SECRET_ROOM_FLOOR_BREAK: - self->ext.generic.unk84.unk++; - tileLayoutPtr = &D_80180E94 + (self->ext.generic.unk84.unk * 2); - - tilePos = 0x2E7; - for (i = 0; i < 2; i++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); - tileLayoutPtr += 2; - tilePos += 0x10; - } - - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 0x11; - } - self->ext.generic.unk80.modeS32 = 32; - self->step++; - - if (self->ext.generic.unk84.unk == 3) { - g_CastleFlags[130] = 1; - g_api.func_800F1FC4(0x82); - DestroyEntity(self); - } - break; - - case BOTTOM_SECRET_ROOM_FLOOR_CHECK: - if (--self->ext.generic.unk80.modeS32 == 0) { - self->step = BOTTOM_SECRET_ROOM_FLOOR_IDLE; - } - break; - } -} - -void func_801B19A0(Entity* self) { - Collider collider; - Entity* newEntity; - s32 rnd; - s16 rnd2; - s32 i; - - switch (self->step) { - case 0: - InitializeEntity(D_80180C34); - self->drawFlags = FLAG_DRAW_ROTZ; - - if (Random() & 1) { - self->animCurFrame = 1; - } else { - self->animCurFrame = 2; - } - - rnd = (Random() & 0x1F) + 16; - rnd2 = ((Random() & 0x3F) * 16) | 0xC00; - if (self->params != 0) { - self->animCurFrame = 3; - rnd = (Random() & 0x1F) + 16; - rnd2 = (Random() * 6) + 0x900; - } - - self->velocityX = rnd * rcos(rnd2); - self->velocityY = rnd * rsin(rnd2); - if (self->velocityX < 0) { - self->facingLeft = 1; - } - - case 1: - MoveEntity(); - self->rotZ += 0x20; - if (self->params != 0) { - self->rotZ += 0x20; - } - - self->velocityY += FIX(0.125); - g_api.CheckCollision( - self->posX.i.hi, self->posY.i.hi + 6, &collider, 0); - if (collider.effects & EFFECT_SOLID) { - self->posY.i.hi += collider.unk18; - if (self->params == 0) { - func_801C29B0(SFX_WALL_DEBRIS_B); - for (i = 0; i < 2; i++) { - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(0x22, self, newEntity); - newEntity->params = 0x1; - } - } - DestroyEntity(self); - break; - } - if (self->velocityY < FIX(0.5)) { - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity( - E_INTENSE_EXPLOSION, self, newEntity); - newEntity->params = 0x10; - } - DestroyEntity(self); - break; - } - self->velocityY = -self->velocityY; - self->velocityY *= 2; - self->velocityY /= 3; - } - } -} - -void func_801B1C18(Entity* self) { - s32 temp_s1 = GetPlayerCollisionWith(self, 8, 8, 4); - s16 primIndex; - POLY_GT4* poly; - Entity* player; - s32 temp; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - poly = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *((s32*)(&self->ext.generic.unk7C)) = poly; - self->flags |= FLAG_HAS_PRIMS; - poly->code = 6; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 72; - poly->v0 = 200; - poly->u1 = 16; - poly->v1 = 16; - poly->pad2 = 0x5F; - poly->pad3 = 2; - - case 1: - if (temp_s1 != 0) { - player = &PLAYER; - player->posY.i.hi++; - self->posY.val += FIX(1.0); - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp > 468) { - self->posY.i.hi = 468 - g_Tilemap.scrollY.i.hi; - D_80180EB4 ^= self->params; - self->step++; - } - } - break; - - case 2: - if (temp_s1 == 0) { - self->step++; - } - break; - - case 3: - self->posY.val += 0xFFFF0000; - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp < 464) { - self->posY.i.hi = 464 - g_Tilemap.scrollY.i.hi; - self->step = 1; - } - break; - } - poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); - poly->x0 = self->posX.i.hi - 8; - poly->y0 = self->posY.i.hi - 8; -} - -void func_801B1E54(Entity* self, s16 primIndex) { - POLY_GT4* poly; - s8 var_v1; - s32 temp; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->hitboxWidth = 12; - self->hitboxHeight = 12; - self->attackElement = 1; - self->attack = 7; - self->hitboxState = 1; - - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - poly = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *((s32*)(&self->ext.generic.unk7C)) = poly; - self->flags |= FLAG_HAS_PRIMS; - poly->code = 6; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 40; - poly->v0 = 200; - poly->u1 = 32; - poly->v1 = 32; - poly->pad2 = 0x5F; - poly->pad3 = 2; - - if (self->params & D_80180EB4) { - self->posY.i.hi = 480 - g_Tilemap.scrollY.i.hi; - self->ext.generic.unk88.S8.unk0 = 1; - } else { - self->posY.i.hi = 452 - g_Tilemap.scrollY.i.hi; - self->ext.generic.unk88.S8.unk0 = 0; - } - - case 1: - if (self->params & D_80180EB4) { - self->posY.val += FIX(1.0); - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp > 480) { - self->posY.i.hi = 480 - g_Tilemap.scrollY.i.hi; - } - var_v1 = 1; - } else { - self->posY.val += 0xFFFF0000; - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp < 452) { - self->posY.i.hi = 452 - g_Tilemap.scrollY.i.hi; - self->step = 1; - } - var_v1 = 0; - } - - if (self->ext.generic.unk88.U8.unk0 != var_v1) { - self->ext.generic.unk88.U8.unk0 = var_v1; - func_801C29B0(0x69D); - } - } - - poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); - poly->x0 = self->posX.i.hi - 16; - poly->y0 = self->posY.i.hi - 16; - temp = 480 - (g_Tilemap.scrollY.i.hi + self->posY.i.hi); - D_801CB736[self->params] = temp; -} - -// moveable box for spike/switch areas -void EntityMoveableBox(Entity* self) { - Entity* player; - POLY_GT4* poly; - s32 temp_s1 = GetPlayerCollisionWith(self, 0x10, 0x10, 5); - s32 var_s1 = temp_s1; - s16 primIndex; - s32 temp_v0_2; - s32 new_var; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - poly = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *((s32*)(&self->ext.generic.unk7C.s)) = poly; - self->flags |= FLAG_HAS_PRIMS; - poly->code = 6; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 8; - poly->v0 = 200; - poly->u1 = 32; - poly->v1 = 32; - poly->pad2 = 112; - poly->pad3 = 2; - - case 1: - player = &PLAYER; - self->velocityX = 0; - self->velocityY = 0; - - if (var_s1 & 1) { - temp_s1 = GetSideToPlayer(); - if (temp_s1 & 1 && player->velocityX > 0) { - if (!(g_Timer & 7)) { - g_api.PlaySfx(SFX_STONE_MOVE_B); - } - self->velocityX = FIX(0.5); - } - temp_s1 = GetSideToPlayer(); - if (!(primIndex = (temp_s1 & 1)) && (player->velocityX < 0)) { - if (!(g_Timer & 7)) { - g_api.PlaySfx(SFX_STONE_MOVE_B); - } - self->velocityX = FIX(-0.5); - } - } - - func_801BCF74(&D_80180EB8); - - if (self->params == 0) { - temp_v0_2 = self->posX.i.hi + g_Tilemap.scrollX.i.hi; - if (abs(temp_v0_2 - 192) < 24) { - var_s1 = 1; - } else { - var_s1 = 0; - } - if (abs(temp_v0_2 - 256) < 24) { - var_s1 = 2; - } - if ((self->ext.generic.unk84.unk == 0) && - ((s16)D_801CB736[var_s1] != 0)) { - var_s1 = 0; - self->posX.val -= self->velocityX; - } - self->ext.generic.unk84.unk = var_s1; - if (var_s1 != 0) { - self->posY.i.hi = - (448 - D_801CB736[var_s1]) - g_Tilemap.scrollY.i.hi; - } - } - break; - } - poly = (POLY_GT4*)(*(s32*)(&self->ext.generic.unk7C.s)); - new_var = ((u16)self->posX.i.hi) - 16; - poly->x0 = new_var; - poly->y0 = ((u16)self->posY.i.hi) - 16; -} - -// lever to operate cannon -void EntityCannonLever(Entity* self) { - /** TODO: !FAKE - * self->ext.generic.unk7C should be a POLY_G4* - */ - POLY_GT4* poly; - s16 primIndex; - s32 temp_v0_2; - s32 temp_v1_2; - s32 var_v0; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->hitboxWidth = 4; - self->hitboxHeight = 20; - self->hitboxState = 2; - - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - poly = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *(s32*)&self->ext.generic.unk7C = poly; - - self->flags |= FLAG_HAS_PRIMS; - poly->code = 6; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 0x68; - poly->v0 = 0x80; - poly->u1 = 8; - poly->v1 = 0x28; - poly->pad2 = 0x70; - poly->pad3 = 2; - - if (PLAYER.posX.i.hi < 128) { - self->hitboxState = 0; - } - break; - - case 1: - if (self->hitFlags != 0) { - self->velocityX = FIX(-4); - self->step++; - } - break; - - case 2: - MoveEntity(); - temp_v1_2 = self->velocityX; - if (temp_v1_2 < 0) { - var_v0 = temp_v1_2 + 0xF; - } else { - var_v0 = temp_v1_2; - } - temp_v0_2 = temp_v1_2 - (var_v0 >> 4); - self->velocityX = temp_v0_2; - if (temp_v0_2 < 0x2000) { - self->step++; - } - break; - - case 3: - D_80180ED0[0] = 1; - break; - } - - if (D_8003BE6F[0] != 0) { - self->hitboxState = 0; - } - poly = (POLY_GT4*)*(s32*)&self->ext.generic.unk7C.s; - poly->x0 = self->posX.i.hi - 4; - poly->y0 = self->posY.i.hi - 20; -} - -// cannon for shortcut -void EntityCannon(Entity* self) { - s16 primIndex; - Entity* newEntity; - Primitive* prim; - s32 var_v0; - s32 temp; - s32 temp2; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - primIndex = g_api.AllocPrimitives(PRIM_GT4, 2); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - - self->primIndex = primIndex; - prim = &g_PrimBuf[primIndex]; - *(s32*)&self->ext.generic.unk7C = prim; - self->flags |= FLAG_HAS_PRIMS; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0x28; - prim->v0 = 0xA8; - prim->u1 = 0x38; - prim->v1 = 0x20; - prim->priority = 0x70; - prim->drawMode = 2; - - prim = prim->next; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0x28; - prim->v0 = 0x80; - prim->u1 = 0x40; - prim->v1 = 0x28; - prim->x0 = self->posX.i.hi - 8; - prim->y0 = 120 - g_Tilemap.scrollY.i.hi; - prim->priority = 0x78; - prim->drawMode = 2; - - if (D_8003BE6F[0] != 0) { - self->step = 3; - } - break; - - case 1: - if (D_80180ED0[0] != 0) { - g_api.func_80102CD8(1); - g_api.PlaySfx(0x6AC); - self->velocityX = FIX(8); - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != 0) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 0x13; - } - CreateEntityFromEntity(0x1E, self, &self[1]); - self->step++; - } - break; - - case 2: - prim = *(s32*)&self->ext.generic.unk7C; - prim = prim->next; - self->posX.i.hi = prim->x0 + 8; - self->posX.i.lo = 0; - MoveEntity(); - - temp = self->velocityX; - if (temp < 0) { - var_v0 = temp + 7; - } else { - var_v0 = temp; - } - - temp2 = temp - (var_v0 >> 3); - self->velocityX = temp - (var_v0 >> 3); - - if (temp2 < 0x2000) { - self->step++; - } - break; - } - - prim = *(s32*)&self->ext.generic.unk7C; - prim->x0 = self->posX.i.hi - 24; - prim->y0 = self->posY.i.hi - 16; -} - -// projectile shot by cannon -void EntityCannonShot(Entity* self) { - Entity* newEntity; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->animSet = ANIMSET_DRA(2); - self->animCurFrame = 1; - self->palette = 0x81AF; - self->zPriority = 0x6F; - self->velocityX = FIX(-8); - - case 1: - MoveEntity(); - if ((self->posX.i.hi + g_Tilemap.scrollX.i.hi) < 112) { - g_api.func_80102CD8(1); - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 3; - } - D_8003BE6F[0] = 1; - DestroyEntity(self); - } - break; - } -} - -void EntityCannonWall(Entity* self) { - u16* tileLayoutPtr; - s32 tilePos; - s32 cond; - s32 i; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - - cond = g_CastleFlags[131] != 0; - tileLayoutPtr = (-cond & 6) + &D_80180ED4[0]; - for (tilePos = 0x46, i = 0; i < 6; i++, tileLayoutPtr++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - tilePos += 0x10; - } - - if (g_CastleFlags[131] != 0) { - DestroyEntity(self); - } - break; - - case 1: - i = g_CastleFlags[131] != 0; // TODO: !FAKE: - if (i) { - self->step++; - } - break; - - case 2: - g_api.PlaySfx(SFX_WALL_DEBRIS_B); - - tileLayoutPtr = &D_80180EE0; - for (tilePos = 0x46, i = 0; i < 6; i++, tileLayoutPtr++) { - g_Tilemap.fg[tilePos] = *tileLayoutPtr; - tilePos += 0x10; - } - DestroyEntity(self); - } -} - -void func_801B2AD8(Entity* self) { - POLY_GT4* poly; - s16 primIndex; - s32 var_a0; - s32 temp; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->hitboxHeight = 8; - self->hitboxOffY = -22; - self->hitboxWidth = 6; - self->hitboxState = 1; - CreateEntityFromEntity(0x26, self, &self[-1]); - self[-1].posY.i.hi = 344 - g_Tilemap.scrollY.i.hi; - - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - poly = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *(s32*)&self->ext.generic.unk7C = poly; - self->flags |= FLAG_HAS_PRIMS; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 72; - poly->v0 = 200; - poly->u1 = 16; - poly->v1 = 16; - poly->pad2 = 0x5F; - poly->code = 6; - poly->pad3 = 2; - - case 1: - var_a0 = self->hitFlags; - - if (abs(self->posX.i.hi - self[-1].posX.i.hi) < 8) { - var_a0 |= 0x8000; - } - - if (var_a0) { - self->posY.val += FIX(1.0); - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp > 376) { - self->posY.i.hi = 376 - g_Tilemap.scrollY.i.hi; - } - g_CallElevator = true; - } else { - self->posY.val += 0xFFFF0000; - temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (temp < 372) { - self->posY.i.hi = 372 - g_Tilemap.scrollY.i.hi; - } - g_CallElevator = false; - } - - default: - poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); - poly->x0 = self->posX.i.hi - 8; - poly->y0 = self->posY.i.hi - 8; - } -} - -void EntityElevator2(Entity* self) { - s32 temp = GetPlayerCollisionWith(self, 16, 5, 4); - volatile int pad[3]; - Primitive* prim; - s16 primIndex; - s32 player; - s32 camY; - s32 i; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->hitboxOffX = 0; - self->hitboxOffY = 68; - g_CallElevator = false; - - primIndex = g_api.AllocPrimitives(PRIM_GT4, 3); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - prim = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - self->ext.prim = prim; - self->flags |= FLAG_HAS_PRIMS; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 8; - prim->v0 = 0x80; - prim->u1 = 0x20; - prim->v1 = 0x48; - prim->priority = 0x72; - prim->drawMode = 2; - - prim = prim->next; - for (i = 0; i < 2; i++) { - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0; - prim->v0 = 0x80; - prim->u1 = 8; - prim->v1 = 0x40; - prim->priority = 0x5F; - prim->drawMode = 2; - prim = prim->next; - } - - case 1: - //! FAKE: - player = PLAYER_CHARACTER; - if (g_CallElevator) { - self->posY.i.hi--; - camY = g_Tilemap.scrollY.i.hi; - if ((self->posY.i.hi + camY) < 96) { - self->posY.i.hi = 96 - camY; - } else if (temp != 0) { - g_Entities[player].posY.i.hi--; - D_80097488.y.i.hi--; - } - } else { - self->posY.i.hi++; - camY = g_Tilemap.scrollY.i.hi; - if ((self->posY.i.hi + camY) > 216) { - self->posY.i.hi = 216 - camY; - } else if (temp != 0) { - g_Entities[player].posY.i.hi++; - D_80097488.y.i.hi++; - } - } - } - prim = self->ext.prim; - prim->x0 = self->posX.i.hi - 16; - prim->y0 = self->posY.i.hi; - - prim = prim->next; - prim->x0 = self->posX.i.hi - 3; - prim->y0 = self->posY.i.hi - 56; - - prim = prim->next; - prim->x0 = self->posX.i.hi - 3; - prim->y0 = self->posY.i.hi - 120; -} - -void func_801B2FD8(Entity* self) { - s32 temp = GetPlayerCollisionWith(self, 8, 8, 4); - Primitive* prim; - Entity* player; - s16 primIndex; - s32 posX, posY; - s32 camY; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->ext.generic.unk80.modeS32 = - self->posY.i.hi + g_Tilemap.scrollY.i.hi; - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - prim = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - self->ext.prim = prim; - self->flags |= FLAG_HAS_PRIMS; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0x48; - prim->v0 = 0xC8; - prim->v1 = prim->u1 = 0x10; - prim->priority = 0x5F; - prim->drawMode = 2; - - posX = self->posX.i.hi; - posX += g_Tilemap.scrollX.i.hi; - posX >>= 4; - - // TODO: !FAKE - camY = self->posY.i.hi; - posY = camY += 4; - posY = camY += g_Tilemap.scrollY.i.hi; - - camY = (camY >> 4) * g_Tilemap.hSize * 16; - g_Tilemap.fg[posX + camY] = 0x5AF; - - case 1: - if (temp != 0) { - player = &PLAYER; - player->posY.i.hi++; - self->posY.val += FIX(1.0); - posY = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if ((self->ext.generic.unk80.modeS32 + 4) < posY) { - self->posY.i.hi = (self->ext.generic.unk80.modeS16.unk0 + 4) - - g_Tilemap.scrollY.i.hi; - self[1].ext.stub[0xC] = 1; - self->step++; - LOW(self[1].ext.stub[0x8]) ^= 1; - } - } - - default: - prim = self->ext.prim; - prim->x0 = self->posX.i.hi - 8; - prim->y0 = self->posY.i.hi - 8; - break; - - case 2: - if (temp == 0) { - self->posY.val += ~0xFFFF; - posY = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - if (posY < self->ext.generic.unk80.modeS32) { - self->posY.i.hi = self->ext.generic.unk80.modeS16.unk0 - - g_Tilemap.scrollY.i.hi; - self->step = 1; - } - } - prim = self->ext.prim; - prim->x0 = self->posX.i.hi - 8; - prim->y0 = self->posY.i.hi - 8; - break; - } -} - -void EntityFloorSpikes(Entity* self) { - Primitive* prim; - s16 primIndex; - s32 var_v1; - s32 tilePos; - s32 new_var; - u8 temp; // !FAKE - volatile int pad[3]; - - switch (self->step) { - case 0: - InitializeEntity(g_EInitGeneric); - self->hitboxWidth = 12; - self->hitboxHeight = 12; - self->attackElement = 1; - self->attack = 7; - self->hitboxState = 1; - self->ext.generic.unk80.modeS32 = - self->posY.i.hi + g_Tilemap.scrollY.i.hi; - - temp = 4; - new_var = self->posY.i.hi - 4; - new_var += g_Tilemap.scrollY.i.hi; - tilePos = ((self->posX.i.hi - temp + g_Tilemap.scrollX.i.hi) >> 4) + - (((new_var >> 4) * g_Tilemap.hSize) * 16); - - g_Tilemap.fg[tilePos] = 0x102; - g_Tilemap.fg[tilePos + 1] = 0x103; - primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - prim = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - *((s32*)(&self->ext.generic.unk7C)) = prim; - self->flags |= FLAG_HAS_PRIMS; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0x28; - prim->v0 = 0xC8; - prim->v1 = prim->u1 = 0x20; - prim->priority = 0x5F; - prim->drawMode = 2; - self->posY.i.hi -= 28; - - case 1: - self->hitboxState = 1; - if (self->ext.generic.unk84.unk != 0) { - self->posY.val += FIX(1.0); - new_var = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - var_v1 = g_Tilemap.scrollY.i.hi; - if (new_var > self->ext.generic.unk80.modeS32) { - self->hitboxState = 0; - self->posY.i.hi = self->ext.generic.unk80.modeS16.unk0 - var_v1; - } - } else { - self->posY.val += 0xFFFF0000; - new_var = g_Tilemap.scrollY.i.hi + self->posY.i.hi; - var_v1 = g_Tilemap.scrollY.i.hi; - if (new_var < (self->ext.generic.unk80.modeS32 - 28)) { - self->posY.i.hi = - self->ext.generic.unk80.modeS16.unk0 - 28 - var_v1; - } - } - } - if (self->ext.generic.unk88.U8.unk0 != 0) { - func_801C29B0(0x69D); - self->ext.generic.unk88.S8.unk0 = 0; - } - prim = *((s32*)(&self->ext.generic.unk7C)); - prim->x0 = self->posX.i.hi - 16; - prim->y0 = self->posY.i.hi - 16; -} - -// table with globe on it that can be broken -void EntityTableWithGlobe(Entity* self) { - switch (self->step) { - case 0: - InitializeEntity(D_80180CC4); - self->zPriority = 0x6A; - self->hitboxWidth = 8; - self->hitboxHeight = 12; - self->hitboxOffY = -0xA; - self->hitboxOffX = 0; - self->hitboxState = 2; - - case 1: - AnimateEntity(D_80180EF0, self); - if (self->hitFlags != 0) { - func_801C29B0(SFX_GLASS_BREAK_E); - self->hitboxState = 0; - CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); - self[1].params = D_80180F10[self->params]; - SetStep(2); - } - break; - - case 2: - AnimateEntity(D_80180EF8, self); - break; - } -} - -void func_801B3648(Entity* self) { - Entity* newEntity; - - switch (self->step) { - case 0: - InitializeEntity(D_80180CD0); - self->zPriority = 0x6A; - self->hitboxWidth = 8; - self->hitboxHeight = 12; - self->hitboxOffY = -0xA; - self->hitboxOffX = 0; - self->hitboxState = 2; - - case 1: - AnimateEntity(D_80180F1C, self); - if (self->hitFlags != 0) { - func_801C29B0(SFX_GLASS_BREAK_A); - self->hitboxState = 0; - SetStep(2); - } - break; - - case 2: - if (AnimateEntity(D_80180F30, self) == 0) { - CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); - self[1].params = D_80180F4C[self->params]; - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 2; - newEntity->posY.i.hi -= 8; - } - self->step++; - } - break; - - case 3: - newEntity = self; - newEntity->animCurFrame = 20; - break; - } -} - -void func_801B37C0(Entity* self) { - Entity* newEntity; - - switch (self->step) { - case 0: - InitializeEntity(D_80180CDC); - if (self->params & 0x100) { - self->drawMode = 0x30; - } else { - self->zPriority = 0x6A; - self->hitboxWidth = 8; - self->hitboxHeight = 12; - self->hitboxOffY = -0xA; - self->hitboxOffX = 0; - self->hitboxState = 2; - CreateEntityFromEntity(0x37, self, &self[1]); - self[1].params = 0x100; - } - - case 1: - if (self->params & 0x100) { - AnimateEntity(D_80180F74, self); - break; - } - AnimateEntity(D_80180F50, self); - if (self->hitFlags != 0) { - self->hitboxState = 0; - SetStep(2); - } - break; - - case 2: - if (self->params > 0x1) { - CreateEntityFromEntity(E_RELIC_ORB, self, &self[1]); - } else { - CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); - } - - self[1].params = D_80180F9C[self->params]; - do { // !FAKE - } while (0); - newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (newEntity != NULL) { - CreateEntityFromEntity(E_EXPLOSION, self, newEntity); - newEntity->params = 2; - newEntity->posY.i.hi -= 8; - } - func_801C29B0(SFX_GLASS_BREAK_E); - self->step++; - - case 3: - self->animCurFrame = 4; - break; - - case 255: - FntPrint(&D_801B0598, self->animCurFrame); // "charal %x\n" - if (g_pads[1].pressed & PAD_SQUARE) { - if (self->params != 0) { - break; - } - self->animCurFrame++; - self->params |= 1; - } else { - self->params = 0; - } - if (g_pads[1].pressed & PAD_CIRCLE) { - if (self->step_s == 0) { - self->animCurFrame--; - self->step_s |= 1; - } - } else { - newEntity = self; - newEntity->step_s = 0; - } - break; - } -} - -void func_801B3A50(Entity* self) { - switch (self->step) { - case 0: - InitializeEntity(D_80180CDC); - self->zPriority = 0x6A; - self->hitboxWidth = 8; - self->hitboxHeight = 16; - self->hitboxOffY = -0xA; - self->hitboxOffX = 0; - self->hitboxState = 2; - - case 1: - AnimateEntity(D_80180F88, self); - if (self->hitFlags != 0) { - g_api.PlaySfx(SFX_CANDLE_HIT); - self->hitboxState = 0; - SetStep(2); - } - break; - - case 2: - CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); - self[1].params = D_80180F9C[self->params]; - self->step++; - - case 3: - self->animCurFrame = 18; - break; - } -} - -void func_801B3B78() { - Entity* entity; - s8 temp_s4 = Random() & 3; - s16 temp_s3 = ((Random() & 0xF) << 8) - 0x800; - s32 i; - - for (i = 0; i < 6; i++) { - entity = AllocEntity(&g_Entities[224], &g_Entities[256]); - if (entity != NULL) { - CreateEntityFromEntity(0x38, g_CurrentEntity, entity); - entity->params = 2; - entity->ext.generic.unk88.S8.unk1 = 6 - i; - entity->ext.generic.unk84.S16.unk0 = temp_s3; - entity->ext.generic.unk88.S8.unk0 = temp_s4; - } - } -} - -// Id 0x38 -void EntityWargExplosionPuffOpaque(Entity* self) { - Unkstruct_80180FE0* obj; - s32 velocityX; - s32 velocityY; - s32 params; - s32 temp_s0; - s32 adjVelocityX; - s32 adjVelocityY; - u32 temp_v0; - s32 rnd; - - switch (self->step) { - case 0: - InitializeEntity(g_InitializeEntityData0); - params = self->params & 0xF; - obj = &D_80180FE0[params]; - self->palette = obj->palette + 0x2E0; - self->drawMode = obj->drawMode; - self->animSet = obj->animSet; - self->unk5A = obj->unk2; - self->ext.et38.unk80 = obj->unk8; - self->step = params + 1; - - temp_v0 = self->params & 0xFF00; - if (temp_v0 != 0) { - self->zPriority = temp_v0 >> 8; - } - - if (self->params & 0xF0) { - self->palette = 0x819F; - self->drawMode = DRAW_TPAGE; - self->facingLeft = 1; - } - break; - - case 1: - MoveEntity(); - self->velocityY = FIX(-1); - if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { - DestroyEntity(self); - } - break; - - case 2: - if (AnimateEntity((u8*)self->ext.et38.unk80, self) != 0) { - switch (self->step_s) { - case 0: - self->drawFlags = FLAG_DRAW_UNK8; - self->unk6C = 0x80; - self->step_s++; - break; - - case 1: - if (self->animFrameIdx == 5) { - self->step_s++; - } - break; - - case 2: - self->unk6C += 0xFC; - return; - } - } else { - DestroyEntity(self); - } - break; - - case 3: - if (self->step_s == 0) { - self->drawFlags |= 4; - switch (self->ext.et38.unk88) { - case 1: - if (self->ext.et38.unk89 >= 0x4) { - self->ext.et38.unk89 += 0xFD; - self->ext.et38.unk84 -= 0x800; - } - break; - - case 2: - self->ext.et38.unk84 = (u16)self->ext.et38.unk84 + - ((u8)self->ext.et38.unk89 * 0xC0); - break; - } - self->ext.et38.unk84 = self->ext.et38.unk84 & 0xFFF; - self->rotZ = self->ext.generic.unk84.S16.unk0 & 0xFFF; - temp_s0 = self->ext.generic.unk88.U8.unk1 * 0x140; - temp_s0 /= 28; - self->velocityX = temp_s0 * rsin(self->ext.et38.unk84); - self->velocityY = -(temp_s0 * rcos(self->ext.et38.unk84)); - self->step_s++; - } - - if (self->animFrameIdx >= 13) { - velocityX = self->velocityX; - if (velocityX < 0) { - adjVelocityX = velocityX + 3; - } else { - adjVelocityX = velocityX; - } - self->velocityX = velocityX - (adjVelocityX >> 2); - - velocityY = self->velocityY; - if (velocityY < 0) { - adjVelocityY = velocityY + 3; - } else { - adjVelocityY = velocityY; - } - self->velocityY = velocityY - (adjVelocityY >> 2); - } - MoveEntity(); - if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { - DestroyEntity(self); - } - break; - - case 4: - if (self->step_s == 0) { - rnd = Random(); - self->velocityY = FIX(-0.75); - self->facingLeft = rnd & 1; - self->rotX = 0xC0; - self->drawFlags |= 1; - self->step_s++; - } - MoveEntity(); - if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { - DestroyEntity(self); - } - break; - } -} diff --git a/src/st/nz0/311C0.c b/src/st/nz0/311C0.c new file mode 100644 index 0000000000..f477e432af --- /dev/null +++ b/src/st/nz0/311C0.c @@ -0,0 +1,1422 @@ +#include "nz0.h" + +// bust with red eyes that can have a candle on it +void EntityRedEyeBust(Entity* self) { + switch (self->step) { + case 0: + InitializeEntity(D_80180C34); + self->animCurFrame = 7; + self->zPriority = 0x70; + break; + + case 1: + break; + + case 2: + FntPrint(&D_801B058C, self->animCurFrame); // "charal %x\n" + if (g_pads[1].pressed & PAD_SQUARE) { + if (self->params == 0) { + self->animCurFrame++; + self->params |= 1; + } else + break; + } else { + self->params = 0; + } + + if (g_pads[1].pressed & PAD_CIRCLE) { + if (self->step_s == 0) { + self->animCurFrame--; + self->step_s |= 1; + } + } else { + self->step_s = 0; + } + break; + } +} + +// A purplish-red brick background that scrolls behind the foreground layer +void EntityPurpleBrickScrollingBackground(Entity* self) { + Primitive* prim; + s16 primIndex; + s32 tempPosX; + s32 tempPosY; + s32 x, y; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->posX.i.hi = 0; + self->posY.i.hi = 0; + self->unk68 = 0x80; + // Composed of 15 primitives + primIndex = g_api.AllocPrimitives(PRIM_GT4, 15); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + prim = &g_PrimBuf[primIndex]; + self->primIndex = (s32)primIndex; + *(s32*)&self->ext.generic.unk7C = prim; + self->flags |= FLAG_HAS_PRIMS; + while (prim != NULL) { + prim->tpage = 0xF; + prim->clut = 4; + prim->u0 = prim->u2 = 0x80; + prim->u1 = prim->u3 = 0xFF; + prim->v0 = prim->v1 = 0x80; + prim->v2 = prim->v3 = 0xBF; + prim->priority = 0x20; + prim->drawMode = 2; + prim = prim->next; + } + + case 1: + // Add a scrolling effect + tempPosX = self->posX.i.hi; + tempPosX = tempPosX & 0x7F; + tempPosX = tempPosX - 0x80; + tempPosY = self->posY.i.hi; + tempPosY = (tempPosY & 0x3F) - 0x40; + prim = *((s32*)(&self->ext.generic.unk7C)); + // Primitives are laid out in a 5-tall by 3-wide grid + for (y = 0; y < 5; y++) { + for (x = 0; x < 3; x++) { + prim->x0 = prim->x2 = tempPosX + (x * 0x80); + prim->x1 = prim->x3 = prim->x0 + 0x80; + prim->y0 = prim->y1 = tempPosY + (y * 0x40); + prim->y2 = prim->y3 = prim->y0 + 0x40; + prim->drawMode = DRAW_DEFAULT; + prim = prim->next; + } + } + + while (prim != NULL) { + prim->drawMode = DRAW_HIDE; + prim = prim->next; + } + } +} + +void EntityLeftSecretRoomWall(Entity* self, u16* tileLayoutPtr, s32 tilePos) { + Entity* newEntity; + s32 cond; + s32 i; + + switch (self->step) { + case LEFT_SECRET_ROOM_WALL_INIT: + InitializeEntity(g_EInitGeneric); + self->hitboxWidth = 16; + self->hitboxHeight = 32; + self->hitboxState = 2; + + cond = g_CastleFlags[129] != 0; + tileLayoutPtr = &D_80180E54 + (-cond & 0xC); + + tilePos = 0x260; + for (i = 0; i < 4; i++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); + tilePos += 0x10; + tileLayoutPtr += 2; + } + + if (g_CastleFlags[129] != 0) { + DestroyEntity(self); + break; + } + + case LEFT_SECRET_ROOM_WALL_IDLE: + if (self->hitFlags != 0) { + func_801C29B0(SFX_WALL_DEBRIS_B); + self->step++; + } + break; + + case LEFT_SECRET_ROOM_WALL_BREAK: + self->ext.generic.unk84.unk++; + tileLayoutPtr = &D_80180E54 + (self->ext.generic.unk84.unk * 0x4); + + tilePos = 0x260; + for (i = 0; i < 4; i++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); + tileLayoutPtr += 2; + tilePos += 0x10; + } + + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 0x13; + } + self->ext.generic.unk80.modeS32 = 32; + self->step++; + + if (self->ext.generic.unk84.unk == 3) { + g_CastleFlags[129] = 1; + g_api.func_800F1FC4(0x81); + + for (i = 0; i < 8; i++) { + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(0x22, self, newEntity); + newEntity->posX.i.hi += (Random() & 0xF); + newEntity->posY.i.hi -= 0x20 - (Random() & 0x3F); + } + } + DestroyEntity(self); + } + break; + + case LEFT_SECRET_ROOM_WALL_CHECK: + if (--self->ext.generic.unk80.modeS32 == 0) { + self->step = LEFT_SECRET_ROOM_WALL_IDLE; + } + break; + } +} + +void EntityBottomSecretRoomFloor( + Entity* self, u16* tileLayoutPtr, s32 tilePos) { + Entity* newEntity; + s32 flag; + s32 i; + + switch (self->step) { + case BOTTOM_SECRET_ROOM_FLOOR_INIT: + InitializeEntity(g_EInitGeneric); + self->hitboxWidth = 16; + self->hitboxHeight = 16; + self->hitboxState = 2; + flag = (g_CastleFlags[130] != 0); + tileLayoutPtr = &D_80180E94 + (-flag & 0x6); + + tilePos = 0x2E7; + for (i = 0; i < 2; i++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); + tileLayoutPtr += 2; + tilePos += 0x10; + } + + if (g_CastleFlags[130] != 0) { + DestroyEntity(self); + break; + } + + case BOTTOM_SECRET_ROOM_FLOOR_IDLE: + if (self->hitFlags != 0) { + func_801C29B0(SFX_WALL_DEBRIS_B); + self->step++; + } + return; + + case BOTTOM_SECRET_ROOM_FLOOR_BREAK: + self->ext.generic.unk84.unk++; + tileLayoutPtr = &D_80180E94 + (self->ext.generic.unk84.unk * 2); + + tilePos = 0x2E7; + for (i = 0; i < 2; i++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + g_Tilemap.fg[tilePos + 1] = *(tileLayoutPtr + 1); + tileLayoutPtr += 2; + tilePos += 0x10; + } + + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 0x11; + } + self->ext.generic.unk80.modeS32 = 32; + self->step++; + + if (self->ext.generic.unk84.unk == 3) { + g_CastleFlags[130] = 1; + g_api.func_800F1FC4(0x82); + DestroyEntity(self); + } + break; + + case BOTTOM_SECRET_ROOM_FLOOR_CHECK: + if (--self->ext.generic.unk80.modeS32 == 0) { + self->step = BOTTOM_SECRET_ROOM_FLOOR_IDLE; + } + break; + } +} + +void func_801B19A0(Entity* self) { + Collider collider; + Entity* newEntity; + s32 rnd; + s16 rnd2; + s32 i; + + switch (self->step) { + case 0: + InitializeEntity(D_80180C34); + self->drawFlags = FLAG_DRAW_ROTZ; + + if (Random() & 1) { + self->animCurFrame = 1; + } else { + self->animCurFrame = 2; + } + + rnd = (Random() & 0x1F) + 16; + rnd2 = ((Random() & 0x3F) * 16) | 0xC00; + if (self->params != 0) { + self->animCurFrame = 3; + rnd = (Random() & 0x1F) + 16; + rnd2 = (Random() * 6) + 0x900; + } + + self->velocityX = rnd * rcos(rnd2); + self->velocityY = rnd * rsin(rnd2); + if (self->velocityX < 0) { + self->facingLeft = 1; + } + + case 1: + MoveEntity(); + self->rotZ += 0x20; + if (self->params != 0) { + self->rotZ += 0x20; + } + + self->velocityY += FIX(0.125); + g_api.CheckCollision( + self->posX.i.hi, self->posY.i.hi + 6, &collider, 0); + if (collider.effects & EFFECT_SOLID) { + self->posY.i.hi += collider.unk18; + if (self->params == 0) { + func_801C29B0(SFX_WALL_DEBRIS_B); + for (i = 0; i < 2; i++) { + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(0x22, self, newEntity); + newEntity->params = 0x1; + } + } + DestroyEntity(self); + break; + } + if (self->velocityY < FIX(0.5)) { + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity( + E_INTENSE_EXPLOSION, self, newEntity); + newEntity->params = 0x10; + } + DestroyEntity(self); + break; + } + self->velocityY = -self->velocityY; + self->velocityY *= 2; + self->velocityY /= 3; + } + } +} + +void func_801B1C18(Entity* self) { + s32 temp_s1 = GetPlayerCollisionWith(self, 8, 8, 4); + s16 primIndex; + POLY_GT4* poly; + Entity* player; + s32 temp; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + poly = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *((s32*)(&self->ext.generic.unk7C)) = poly; + self->flags |= FLAG_HAS_PRIMS; + poly->code = 6; + poly->tpage = 0xF; + poly->clut = 9; + poly->u0 = 72; + poly->v0 = 200; + poly->u1 = 16; + poly->v1 = 16; + poly->pad2 = 0x5F; + poly->pad3 = 2; + + case 1: + if (temp_s1 != 0) { + player = &PLAYER; + player->posY.i.hi++; + self->posY.val += FIX(1.0); + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp > 468) { + self->posY.i.hi = 468 - g_Tilemap.scrollY.i.hi; + D_80180EB4 ^= self->params; + self->step++; + } + } + break; + + case 2: + if (temp_s1 == 0) { + self->step++; + } + break; + + case 3: + self->posY.val += 0xFFFF0000; + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp < 464) { + self->posY.i.hi = 464 - g_Tilemap.scrollY.i.hi; + self->step = 1; + } + break; + } + poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); + poly->x0 = self->posX.i.hi - 8; + poly->y0 = self->posY.i.hi - 8; +} + +void func_801B1E54(Entity* self, s16 primIndex) { + POLY_GT4* poly; + s8 var_v1; + s32 temp; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->hitboxWidth = 12; + self->hitboxHeight = 12; + self->attackElement = 1; + self->attack = 7; + self->hitboxState = 1; + + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + poly = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *((s32*)(&self->ext.generic.unk7C)) = poly; + self->flags |= FLAG_HAS_PRIMS; + poly->code = 6; + poly->tpage = 0xF; + poly->clut = 9; + poly->u0 = 40; + poly->v0 = 200; + poly->u1 = 32; + poly->v1 = 32; + poly->pad2 = 0x5F; + poly->pad3 = 2; + + if (self->params & D_80180EB4) { + self->posY.i.hi = 480 - g_Tilemap.scrollY.i.hi; + self->ext.generic.unk88.S8.unk0 = 1; + } else { + self->posY.i.hi = 452 - g_Tilemap.scrollY.i.hi; + self->ext.generic.unk88.S8.unk0 = 0; + } + + case 1: + if (self->params & D_80180EB4) { + self->posY.val += FIX(1.0); + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp > 480) { + self->posY.i.hi = 480 - g_Tilemap.scrollY.i.hi; + } + var_v1 = 1; + } else { + self->posY.val += 0xFFFF0000; + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp < 452) { + self->posY.i.hi = 452 - g_Tilemap.scrollY.i.hi; + self->step = 1; + } + var_v1 = 0; + } + + if (self->ext.generic.unk88.U8.unk0 != var_v1) { + self->ext.generic.unk88.U8.unk0 = var_v1; + func_801C29B0(0x69D); + } + } + + poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); + poly->x0 = self->posX.i.hi - 16; + poly->y0 = self->posY.i.hi - 16; + temp = 480 - (g_Tilemap.scrollY.i.hi + self->posY.i.hi); + D_801CB736[self->params] = temp; +} + +// moveable box for spike/switch areas +void EntityMoveableBox(Entity* self) { + Entity* player; + POLY_GT4* poly; + s32 temp_s1 = GetPlayerCollisionWith(self, 0x10, 0x10, 5); + s32 var_s1 = temp_s1; + s16 primIndex; + s32 temp_v0_2; + s32 new_var; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + poly = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *((s32*)(&self->ext.generic.unk7C.s)) = poly; + self->flags |= FLAG_HAS_PRIMS; + poly->code = 6; + poly->tpage = 0xF; + poly->clut = 9; + poly->u0 = 8; + poly->v0 = 200; + poly->u1 = 32; + poly->v1 = 32; + poly->pad2 = 112; + poly->pad3 = 2; + + case 1: + player = &PLAYER; + self->velocityX = 0; + self->velocityY = 0; + + if (var_s1 & 1) { + temp_s1 = GetSideToPlayer(); + if (temp_s1 & 1 && player->velocityX > 0) { + if (!(g_Timer & 7)) { + g_api.PlaySfx(SFX_STONE_MOVE_B); + } + self->velocityX = FIX(0.5); + } + temp_s1 = GetSideToPlayer(); + if (!(primIndex = (temp_s1 & 1)) && (player->velocityX < 0)) { + if (!(g_Timer & 7)) { + g_api.PlaySfx(SFX_STONE_MOVE_B); + } + self->velocityX = FIX(-0.5); + } + } + + func_801BCF74(&D_80180EB8); + + if (self->params == 0) { + temp_v0_2 = self->posX.i.hi + g_Tilemap.scrollX.i.hi; + if (abs(temp_v0_2 - 192) < 24) { + var_s1 = 1; + } else { + var_s1 = 0; + } + if (abs(temp_v0_2 - 256) < 24) { + var_s1 = 2; + } + if ((self->ext.generic.unk84.unk == 0) && + ((s16)D_801CB736[var_s1] != 0)) { + var_s1 = 0; + self->posX.val -= self->velocityX; + } + self->ext.generic.unk84.unk = var_s1; + if (var_s1 != 0) { + self->posY.i.hi = + (448 - D_801CB736[var_s1]) - g_Tilemap.scrollY.i.hi; + } + } + break; + } + poly = (POLY_GT4*)(*(s32*)(&self->ext.generic.unk7C.s)); + new_var = ((u16)self->posX.i.hi) - 16; + poly->x0 = new_var; + poly->y0 = ((u16)self->posY.i.hi) - 16; +} + +// lever to operate cannon +void EntityCannonLever(Entity* self) { + /** TODO: !FAKE + * self->ext.generic.unk7C should be a POLY_G4* + */ + POLY_GT4* poly; + s16 primIndex; + s32 temp_v0_2; + s32 temp_v1_2; + s32 var_v0; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->hitboxWidth = 4; + self->hitboxHeight = 20; + self->hitboxState = 2; + + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + poly = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *(s32*)&self->ext.generic.unk7C = poly; + + self->flags |= FLAG_HAS_PRIMS; + poly->code = 6; + poly->tpage = 0xF; + poly->clut = 9; + poly->u0 = 0x68; + poly->v0 = 0x80; + poly->u1 = 8; + poly->v1 = 0x28; + poly->pad2 = 0x70; + poly->pad3 = 2; + + if (PLAYER.posX.i.hi < 128) { + self->hitboxState = 0; + } + break; + + case 1: + if (self->hitFlags != 0) { + self->velocityX = FIX(-4); + self->step++; + } + break; + + case 2: + MoveEntity(); + temp_v1_2 = self->velocityX; + if (temp_v1_2 < 0) { + var_v0 = temp_v1_2 + 0xF; + } else { + var_v0 = temp_v1_2; + } + temp_v0_2 = temp_v1_2 - (var_v0 >> 4); + self->velocityX = temp_v0_2; + if (temp_v0_2 < 0x2000) { + self->step++; + } + break; + + case 3: + D_80180ED0[0] = 1; + break; + } + + if (D_8003BE6F[0] != 0) { + self->hitboxState = 0; + } + poly = (POLY_GT4*)*(s32*)&self->ext.generic.unk7C.s; + poly->x0 = self->posX.i.hi - 4; + poly->y0 = self->posY.i.hi - 20; +} + +// cannon for shortcut +void EntityCannon(Entity* self) { + s16 primIndex; + Entity* newEntity; + Primitive* prim; + s32 var_v0; + s32 temp; + s32 temp2; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + primIndex = g_api.AllocPrimitives(PRIM_GT4, 2); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + + self->primIndex = primIndex; + prim = &g_PrimBuf[primIndex]; + *(s32*)&self->ext.generic.unk7C = prim; + self->flags |= FLAG_HAS_PRIMS; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0x28; + prim->v0 = 0xA8; + prim->u1 = 0x38; + prim->v1 = 0x20; + prim->priority = 0x70; + prim->drawMode = 2; + + prim = prim->next; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0x28; + prim->v0 = 0x80; + prim->u1 = 0x40; + prim->v1 = 0x28; + prim->x0 = self->posX.i.hi - 8; + prim->y0 = 120 - g_Tilemap.scrollY.i.hi; + prim->priority = 0x78; + prim->drawMode = 2; + + if (D_8003BE6F[0] != 0) { + self->step = 3; + } + break; + + case 1: + if (D_80180ED0[0] != 0) { + g_api.func_80102CD8(1); + g_api.PlaySfx(0x6AC); + self->velocityX = FIX(8); + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != 0) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 0x13; + } + CreateEntityFromEntity(0x1E, self, &self[1]); + self->step++; + } + break; + + case 2: + prim = *(s32*)&self->ext.generic.unk7C; + prim = prim->next; + self->posX.i.hi = prim->x0 + 8; + self->posX.i.lo = 0; + MoveEntity(); + + temp = self->velocityX; + if (temp < 0) { + var_v0 = temp + 7; + } else { + var_v0 = temp; + } + + temp2 = temp - (var_v0 >> 3); + self->velocityX = temp - (var_v0 >> 3); + + if (temp2 < 0x2000) { + self->step++; + } + break; + } + + prim = *(s32*)&self->ext.generic.unk7C; + prim->x0 = self->posX.i.hi - 24; + prim->y0 = self->posY.i.hi - 16; +} + +// projectile shot by cannon +void EntityCannonShot(Entity* self) { + Entity* newEntity; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->animSet = ANIMSET_DRA(2); + self->animCurFrame = 1; + self->palette = 0x81AF; + self->zPriority = 0x6F; + self->velocityX = FIX(-8); + + case 1: + MoveEntity(); + if ((self->posX.i.hi + g_Tilemap.scrollX.i.hi) < 112) { + g_api.func_80102CD8(1); + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 3; + } + D_8003BE6F[0] = 1; + DestroyEntity(self); + } + break; + } +} + +void EntityCannonWall(Entity* self) { + u16* tileLayoutPtr; + s32 tilePos; + s32 cond; + s32 i; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + + cond = g_CastleFlags[131] != 0; + tileLayoutPtr = (-cond & 6) + &D_80180ED4[0]; + for (tilePos = 0x46, i = 0; i < 6; i++, tileLayoutPtr++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + tilePos += 0x10; + } + + if (g_CastleFlags[131] != 0) { + DestroyEntity(self); + } + break; + + case 1: + i = g_CastleFlags[131] != 0; // TODO: !FAKE: + if (i) { + self->step++; + } + break; + + case 2: + g_api.PlaySfx(SFX_WALL_DEBRIS_B); + + tileLayoutPtr = &D_80180EE0; + for (tilePos = 0x46, i = 0; i < 6; i++, tileLayoutPtr++) { + g_Tilemap.fg[tilePos] = *tileLayoutPtr; + tilePos += 0x10; + } + DestroyEntity(self); + } +} + +void func_801B2AD8(Entity* self) { + POLY_GT4* poly; + s16 primIndex; + s32 var_a0; + s32 temp; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->hitboxHeight = 8; + self->hitboxOffY = -22; + self->hitboxWidth = 6; + self->hitboxState = 1; + CreateEntityFromEntity(0x26, self, &self[-1]); + self[-1].posY.i.hi = 344 - g_Tilemap.scrollY.i.hi; + + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + poly = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *(s32*)&self->ext.generic.unk7C = poly; + self->flags |= FLAG_HAS_PRIMS; + poly->tpage = 0xF; + poly->clut = 9; + poly->u0 = 72; + poly->v0 = 200; + poly->u1 = 16; + poly->v1 = 16; + poly->pad2 = 0x5F; + poly->code = 6; + poly->pad3 = 2; + + case 1: + var_a0 = self->hitFlags; + + if (abs(self->posX.i.hi - self[-1].posX.i.hi) < 8) { + var_a0 |= 0x8000; + } + + if (var_a0) { + self->posY.val += FIX(1.0); + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp > 376) { + self->posY.i.hi = 376 - g_Tilemap.scrollY.i.hi; + } + g_CallElevator = true; + } else { + self->posY.val += 0xFFFF0000; + temp = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (temp < 372) { + self->posY.i.hi = 372 - g_Tilemap.scrollY.i.hi; + } + g_CallElevator = false; + } + + default: + poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); + poly->x0 = self->posX.i.hi - 8; + poly->y0 = self->posY.i.hi - 8; + } +} + +void EntityElevator2(Entity* self) { + s32 temp = GetPlayerCollisionWith(self, 16, 5, 4); + volatile int pad[3]; + Primitive* prim; + s16 primIndex; + s32 player; + s32 camY; + s32 i; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->hitboxOffX = 0; + self->hitboxOffY = 68; + g_CallElevator = false; + + primIndex = g_api.AllocPrimitives(PRIM_GT4, 3); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + prim = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + self->ext.prim = prim; + self->flags |= FLAG_HAS_PRIMS; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 8; + prim->v0 = 0x80; + prim->u1 = 0x20; + prim->v1 = 0x48; + prim->priority = 0x72; + prim->drawMode = 2; + + prim = prim->next; + for (i = 0; i < 2; i++) { + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0; + prim->v0 = 0x80; + prim->u1 = 8; + prim->v1 = 0x40; + prim->priority = 0x5F; + prim->drawMode = 2; + prim = prim->next; + } + + case 1: + //! FAKE: + player = PLAYER_CHARACTER; + if (g_CallElevator) { + self->posY.i.hi--; + camY = g_Tilemap.scrollY.i.hi; + if ((self->posY.i.hi + camY) < 96) { + self->posY.i.hi = 96 - camY; + } else if (temp != 0) { + g_Entities[player].posY.i.hi--; + D_80097488.y.i.hi--; + } + } else { + self->posY.i.hi++; + camY = g_Tilemap.scrollY.i.hi; + if ((self->posY.i.hi + camY) > 216) { + self->posY.i.hi = 216 - camY; + } else if (temp != 0) { + g_Entities[player].posY.i.hi++; + D_80097488.y.i.hi++; + } + } + } + prim = self->ext.prim; + prim->x0 = self->posX.i.hi - 16; + prim->y0 = self->posY.i.hi; + + prim = prim->next; + prim->x0 = self->posX.i.hi - 3; + prim->y0 = self->posY.i.hi - 56; + + prim = prim->next; + prim->x0 = self->posX.i.hi - 3; + prim->y0 = self->posY.i.hi - 120; +} + +void func_801B2FD8(Entity* self) { + s32 temp = GetPlayerCollisionWith(self, 8, 8, 4); + Primitive* prim; + Entity* player; + s16 primIndex; + s32 posX, posY; + s32 camY; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->ext.generic.unk80.modeS32 = + self->posY.i.hi + g_Tilemap.scrollY.i.hi; + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + prim = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + self->ext.prim = prim; + self->flags |= FLAG_HAS_PRIMS; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0x48; + prim->v0 = 0xC8; + prim->v1 = prim->u1 = 0x10; + prim->priority = 0x5F; + prim->drawMode = 2; + + posX = self->posX.i.hi; + posX += g_Tilemap.scrollX.i.hi; + posX >>= 4; + + // TODO: !FAKE + camY = self->posY.i.hi; + posY = camY += 4; + posY = camY += g_Tilemap.scrollY.i.hi; + + camY = (camY >> 4) * g_Tilemap.hSize * 16; + g_Tilemap.fg[posX + camY] = 0x5AF; + + case 1: + if (temp != 0) { + player = &PLAYER; + player->posY.i.hi++; + self->posY.val += FIX(1.0); + posY = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if ((self->ext.generic.unk80.modeS32 + 4) < posY) { + self->posY.i.hi = (self->ext.generic.unk80.modeS16.unk0 + 4) - + g_Tilemap.scrollY.i.hi; + self[1].ext.stub[0xC] = 1; + self->step++; + LOW(self[1].ext.stub[0x8]) ^= 1; + } + } + + default: + prim = self->ext.prim; + prim->x0 = self->posX.i.hi - 8; + prim->y0 = self->posY.i.hi - 8; + break; + + case 2: + if (temp == 0) { + self->posY.val += ~0xFFFF; + posY = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + if (posY < self->ext.generic.unk80.modeS32) { + self->posY.i.hi = self->ext.generic.unk80.modeS16.unk0 - + g_Tilemap.scrollY.i.hi; + self->step = 1; + } + } + prim = self->ext.prim; + prim->x0 = self->posX.i.hi - 8; + prim->y0 = self->posY.i.hi - 8; + break; + } +} + +void EntityFloorSpikes(Entity* self) { + Primitive* prim; + s16 primIndex; + s32 var_v1; + s32 tilePos; + s32 new_var; + u8 temp; // !FAKE + volatile int pad[3]; + + switch (self->step) { + case 0: + InitializeEntity(g_EInitGeneric); + self->hitboxWidth = 12; + self->hitboxHeight = 12; + self->attackElement = 1; + self->attack = 7; + self->hitboxState = 1; + self->ext.generic.unk80.modeS32 = + self->posY.i.hi + g_Tilemap.scrollY.i.hi; + + temp = 4; + new_var = self->posY.i.hi - 4; + new_var += g_Tilemap.scrollY.i.hi; + tilePos = ((self->posX.i.hi - temp + g_Tilemap.scrollX.i.hi) >> 4) + + (((new_var >> 4) * g_Tilemap.hSize) * 16); + + g_Tilemap.fg[tilePos] = 0x102; + g_Tilemap.fg[tilePos + 1] = 0x103; + primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + prim = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + *((s32*)(&self->ext.generic.unk7C)) = prim; + self->flags |= FLAG_HAS_PRIMS; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0x28; + prim->v0 = 0xC8; + prim->v1 = prim->u1 = 0x20; + prim->priority = 0x5F; + prim->drawMode = 2; + self->posY.i.hi -= 28; + + case 1: + self->hitboxState = 1; + if (self->ext.generic.unk84.unk != 0) { + self->posY.val += FIX(1.0); + new_var = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + var_v1 = g_Tilemap.scrollY.i.hi; + if (new_var > self->ext.generic.unk80.modeS32) { + self->hitboxState = 0; + self->posY.i.hi = self->ext.generic.unk80.modeS16.unk0 - var_v1; + } + } else { + self->posY.val += 0xFFFF0000; + new_var = g_Tilemap.scrollY.i.hi + self->posY.i.hi; + var_v1 = g_Tilemap.scrollY.i.hi; + if (new_var < (self->ext.generic.unk80.modeS32 - 28)) { + self->posY.i.hi = + self->ext.generic.unk80.modeS16.unk0 - 28 - var_v1; + } + } + } + if (self->ext.generic.unk88.U8.unk0 != 0) { + func_801C29B0(0x69D); + self->ext.generic.unk88.S8.unk0 = 0; + } + prim = *((s32*)(&self->ext.generic.unk7C)); + prim->x0 = self->posX.i.hi - 16; + prim->y0 = self->posY.i.hi - 16; +} + +// table with globe on it that can be broken +void EntityTableWithGlobe(Entity* self) { + switch (self->step) { + case 0: + InitializeEntity(D_80180CC4); + self->zPriority = 0x6A; + self->hitboxWidth = 8; + self->hitboxHeight = 12; + self->hitboxOffY = -0xA; + self->hitboxOffX = 0; + self->hitboxState = 2; + + case 1: + AnimateEntity(D_80180EF0, self); + if (self->hitFlags != 0) { + func_801C29B0(SFX_GLASS_BREAK_E); + self->hitboxState = 0; + CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); + self[1].params = D_80180F10[self->params]; + SetStep(2); + } + break; + + case 2: + AnimateEntity(D_80180EF8, self); + break; + } +} + +void func_801B3648(Entity* self) { + Entity* newEntity; + + switch (self->step) { + case 0: + InitializeEntity(D_80180CD0); + self->zPriority = 0x6A; + self->hitboxWidth = 8; + self->hitboxHeight = 12; + self->hitboxOffY = -0xA; + self->hitboxOffX = 0; + self->hitboxState = 2; + + case 1: + AnimateEntity(D_80180F1C, self); + if (self->hitFlags != 0) { + func_801C29B0(SFX_GLASS_BREAK_A); + self->hitboxState = 0; + SetStep(2); + } + break; + + case 2: + if (AnimateEntity(D_80180F30, self) == 0) { + CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); + self[1].params = D_80180F4C[self->params]; + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 2; + newEntity->posY.i.hi -= 8; + } + self->step++; + } + break; + + case 3: + newEntity = self; + newEntity->animCurFrame = 20; + break; + } +} + +void func_801B37C0(Entity* self) { + Entity* newEntity; + + switch (self->step) { + case 0: + InitializeEntity(D_80180CDC); + if (self->params & 0x100) { + self->drawMode = 0x30; + } else { + self->zPriority = 0x6A; + self->hitboxWidth = 8; + self->hitboxHeight = 12; + self->hitboxOffY = -0xA; + self->hitboxOffX = 0; + self->hitboxState = 2; + CreateEntityFromEntity(0x37, self, &self[1]); + self[1].params = 0x100; + } + + case 1: + if (self->params & 0x100) { + AnimateEntity(D_80180F74, self); + break; + } + AnimateEntity(D_80180F50, self); + if (self->hitFlags != 0) { + self->hitboxState = 0; + SetStep(2); + } + break; + + case 2: + if (self->params > 0x1) { + CreateEntityFromEntity(E_RELIC_ORB, self, &self[1]); + } else { + CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); + } + + self[1].params = D_80180F9C[self->params]; + do { // !FAKE + } while (0); + newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (newEntity != NULL) { + CreateEntityFromEntity(E_EXPLOSION, self, newEntity); + newEntity->params = 2; + newEntity->posY.i.hi -= 8; + } + func_801C29B0(SFX_GLASS_BREAK_E); + self->step++; + + case 3: + self->animCurFrame = 4; + break; + + case 255: + FntPrint(&D_801B0598, self->animCurFrame); // "charal %x\n" + if (g_pads[1].pressed & PAD_SQUARE) { + if (self->params != 0) { + break; + } + self->animCurFrame++; + self->params |= 1; + } else { + self->params = 0; + } + if (g_pads[1].pressed & PAD_CIRCLE) { + if (self->step_s == 0) { + self->animCurFrame--; + self->step_s |= 1; + } + } else { + newEntity = self; + newEntity->step_s = 0; + } + break; + } +} + +void func_801B3A50(Entity* self) { + switch (self->step) { + case 0: + InitializeEntity(D_80180CDC); + self->zPriority = 0x6A; + self->hitboxWidth = 8; + self->hitboxHeight = 16; + self->hitboxOffY = -0xA; + self->hitboxOffX = 0; + self->hitboxState = 2; + + case 1: + AnimateEntity(D_80180F88, self); + if (self->hitFlags != 0) { + g_api.PlaySfx(SFX_CANDLE_HIT); + self->hitboxState = 0; + SetStep(2); + } + break; + + case 2: + CreateEntityFromEntity(E_HEART_DROP, self, &self[1]); + self[1].params = D_80180F9C[self->params]; + self->step++; + + case 3: + self->animCurFrame = 18; + break; + } +} + +void func_801B3B78() { + Entity* entity; + s8 temp_s4 = Random() & 3; + s16 temp_s3 = ((Random() & 0xF) << 8) - 0x800; + s32 i; + + for (i = 0; i < 6; i++) { + entity = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (entity != NULL) { + CreateEntityFromEntity(0x38, g_CurrentEntity, entity); + entity->params = 2; + entity->ext.generic.unk88.S8.unk1 = 6 - i; + entity->ext.generic.unk84.S16.unk0 = temp_s3; + entity->ext.generic.unk88.S8.unk0 = temp_s4; + } + } +} + +// Id 0x38 +void EntityWargExplosionPuffOpaque(Entity* self) { + Unkstruct_80180FE0* obj; + s32 velocityX; + s32 velocityY; + s32 params; + s32 temp_s0; + s32 adjVelocityX; + s32 adjVelocityY; + u32 temp_v0; + s32 rnd; + + switch (self->step) { + case 0: + InitializeEntity(g_InitializeEntityData0); + params = self->params & 0xF; + obj = &D_80180FE0[params]; + self->palette = obj->palette + 0x2E0; + self->drawMode = obj->drawMode; + self->animSet = obj->animSet; + self->unk5A = obj->unk2; + self->ext.et38.unk80 = obj->unk8; + self->step = params + 1; + + temp_v0 = self->params & 0xFF00; + if (temp_v0 != 0) { + self->zPriority = temp_v0 >> 8; + } + + if (self->params & 0xF0) { + self->palette = 0x819F; + self->drawMode = DRAW_TPAGE; + self->facingLeft = 1; + } + break; + + case 1: + MoveEntity(); + self->velocityY = FIX(-1); + if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { + DestroyEntity(self); + } + break; + + case 2: + if (AnimateEntity((u8*)self->ext.et38.unk80, self) != 0) { + switch (self->step_s) { + case 0: + self->drawFlags = FLAG_DRAW_UNK8; + self->unk6C = 0x80; + self->step_s++; + break; + + case 1: + if (self->animFrameIdx == 5) { + self->step_s++; + } + break; + + case 2: + self->unk6C += 0xFC; + return; + } + } else { + DestroyEntity(self); + } + break; + + case 3: + if (self->step_s == 0) { + self->drawFlags |= 4; + switch (self->ext.et38.unk88) { + case 1: + if (self->ext.et38.unk89 >= 0x4) { + self->ext.et38.unk89 += 0xFD; + self->ext.et38.unk84 -= 0x800; + } + break; + + case 2: + self->ext.et38.unk84 = (u16)self->ext.et38.unk84 + + ((u8)self->ext.et38.unk89 * 0xC0); + break; + } + self->ext.et38.unk84 = self->ext.et38.unk84 & 0xFFF; + self->rotZ = self->ext.generic.unk84.S16.unk0 & 0xFFF; + temp_s0 = self->ext.generic.unk88.U8.unk1 * 0x140; + temp_s0 /= 28; + self->velocityX = temp_s0 * rsin(self->ext.et38.unk84); + self->velocityY = -(temp_s0 * rcos(self->ext.et38.unk84)); + self->step_s++; + } + + if (self->animFrameIdx >= 13) { + velocityX = self->velocityX; + if (velocityX < 0) { + adjVelocityX = velocityX + 3; + } else { + adjVelocityX = velocityX; + } + self->velocityX = velocityX - (adjVelocityX >> 2); + + velocityY = self->velocityY; + if (velocityY < 0) { + adjVelocityY = velocityY + 3; + } else { + adjVelocityY = velocityY; + } + self->velocityY = velocityY - (adjVelocityY >> 2); + } + MoveEntity(); + if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { + DestroyEntity(self); + } + break; + + case 4: + if (self->step_s == 0) { + rnd = Random(); + self->velocityY = FIX(-0.75); + self->facingLeft = rnd & 1; + self->rotX = 0xC0; + self->drawFlags |= 1; + self->step_s++; + } + MoveEntity(); + if (AnimateEntity((u8*)self->ext.et38.unk80, self) == 0) { + DestroyEntity(self); + } + break; + } +} diff --git a/src/st/nz0/36DE4.c b/src/st/nz0/36DE4.c index 30d1093a0e..a6a0cc5e84 100644 --- a/src/st/nz0/36DE4.c +++ b/src/st/nz0/36DE4.c @@ -1,11 +1,12 @@ #include "nz0.h" void func_801B6DE4(Entity* self) { - s32 temp_s1 = self->hitFlags; + s32 temp_s1; s16 primIndex; - POLY_GT4* poly; + Primitive* prim; s32 y; + temp_s1 = self->hitFlags; switch (self->step) { case 0: InitializeEntity(g_EInitGeneric); @@ -21,23 +22,21 @@ void func_801B6DE4(Entity* self) { DestroyEntity(self); return; } - poly = &g_PrimBuf[primIndex]; + prim = &g_PrimBuf[primIndex]; self->primIndex = primIndex; - self->ext.prim = poly; - + self->ext.prim = prim; self->flags |= FLAG_HAS_PRIMS; - poly->tpage = 0xF; - poly->clut = 9; - poly->u0 = 72; - poly->v0 = 200; - poly->u1 = 16; - poly->v1 = 16; - poly->pad2 = 0x5F; - poly->code = 6; - poly->pad3 = 2; - + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 72; + prim->v0 = 200; + prim->u1 = 16; + prim->v1 = 16; + prim->priority = 0x5F; + prim->type = PRIM_SPRT; + prim->drawMode = DRAW_UNK02; case 1: - if (temp_s1 != 0) { + if (temp_s1) { self->posY.val += FIX(1.0); y = g_Tilemap.scrollY.i.hi + self->posY.i.hi; if ((self->ext.generic.unk80.modeS32 + 4) < y) { @@ -49,9 +48,8 @@ void func_801B6DE4(Entity* self) { } } break; - case 2: - if (temp_s1 == 0) { + if (!temp_s1) { self->posY.val += 0xFFFF0000; y = g_Tilemap.scrollY.i.hi + self->posY.i.hi; if (y < self->ext.generic.unk80.modeS32) { @@ -62,158 +60,8 @@ void func_801B6DE4(Entity* self) { } break; } - - poly = (POLY_GT4*)(*((s32*)(&self->ext.generic.unk7C))); - poly->x0 = self->posX.i.hi - 8; - poly->y0 = self->posY.i.hi; - poly->y0 = poly->y0 - 8; -} - -typedef enum ElevatorSubSteps { - /* 0 */ ELEVATOR_INIT, - /* 1 */ ELEVATOR_IDLE, - /* 2 */ ELEVATOR_ASCEND, - /* 3 */ ELEVATOR_DESCEND, -} ElevatorSubSteps; - -void EntityElevator(Entity* self) { - Primitive* prim; - s16 primIndex; - s32 player; - s32 x, y; - s32 temp; - - FntPrint("elevator:%x\n", g_ElevatorTarget); - - if (g_Player.unk0C & 3) { - temp = 0; - } else { - temp = GetPlayerCollisionWith(self, 16, 5, 4); - } - - //! FAKE: - player = PLAYER_CHARACTER; - - switch (self->step) { - case ELEVATOR_INIT: - InitializeEntity(g_EInitGeneric); - self->hitboxOffX = 0; - self->hitboxOffY = 68; - self->hitboxWidth = 16; - self->hitboxHeight = 5; - self->hitboxState = 1; - - if (g_ElevatorTarget != 0) { - y = g_ElevatorTargetPos[g_ElevatorTarget]; - self->posY.i.hi = y - g_Tilemap.scrollY.i.hi; - } else { - g_ElevatorTarget = self->params; - } - - primIndex = g_api.AllocPrimitives(PRIM_GT4, 32); - if (primIndex == -1) { - DestroyEntity(self); - return; - } - prim = &g_PrimBuf[primIndex]; - self->primIndex = primIndex; - self->ext.elevator.prim = prim; - self->flags |= FLAG_HAS_PRIMS; - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 8; - prim->v0 = 0x80; - prim->u1 = 0x20; - prim->v1 = 0x48; - prim->priority = 0x72; - prim->drawMode = 2; - prim = prim->next; - while (prim != NULL) { - prim->type = PRIM_SPRT; - prim->tpage = 0xF; - prim->clut = 9; - prim->u0 = 0; - prim->v0 = 0x80; - prim->u1 = 8; - prim->v1 = 0x40; - prim->priority = 0x5F; - prim->drawMode = 2; - prim = prim->next; - } - self->ext.elevator.elevatorTarget = g_ElevatorTarget; - - case ELEVATOR_IDLE: - if (temp != 0) { - if (g_pads[0].pressed & PAD_UP) { - if (--g_ElevatorTarget < 1) { - g_ElevatorTarget = 1; - } - } - if (g_pads[0].pressed & PAD_DOWN) { - if (++g_ElevatorTarget > 3) { - g_ElevatorTarget = 3; - } - } - } - - if (g_ElevatorTarget != self->ext.elevator.elevatorTarget) { - y = g_ElevatorTargetPos[g_ElevatorTarget]; - y -= g_Tilemap.scrollY.i.hi; - if (y >= self->posY.i.hi) { - self->step = ELEVATOR_DESCEND; - } else { - self->step = ELEVATOR_ASCEND; - } - func_801C29B0(0x6E6); - } - self->ext.elevator.elevatorTarget = g_ElevatorTarget; - break; - - case ELEVATOR_ASCEND: - self->posY.i.hi--; - y = g_ElevatorTargetPos[self->ext.elevator.elevatorTarget] - - g_Tilemap.scrollY.i.hi; - if (self->posY.i.hi >= y) { - if (temp != 0) { - g_api.func_8010DFF0(0, 1); - g_Entities[player].posY.i.hi--; - D_80097488.y.i.hi--; - } - } else { - self->posY.i.hi = y; - self->step = ELEVATOR_IDLE; - } - break; - - case ELEVATOR_DESCEND: - self->posY.i.hi++; - y = g_ElevatorTargetPos[self->ext.elevator.elevatorTarget] - - g_Tilemap.scrollY.i.hi; - if (y < self->posY.i.hi) { - self->posY.i.hi = y; - self->step = ELEVATOR_IDLE; - break; - } - if (temp != 0) { - g_api.func_8010DFF0(0, 1); - g_Entities[player].posY.i.hi++; - D_80097488.y.i.hi++; - } - break; - } prim = self->ext.prim; - prim->x0 = self->posX.i.hi - 16; + prim->x0 = self->posX.i.hi - 8; prim->y0 = self->posY.i.hi; - - prim = prim->next; - x = self->posX.i.hi; - y = self->posY.i.hi - 56; - x -= 3; - while (prim != NULL) { - prim->x0 = x; - prim->y0 = y; - prim = prim->next; - y -= 0x40; - } + prim->y0 = prim->y0 - 8; } diff --git a/src/st/nz0/43F9C.c b/src/st/nz0/e_axe_knight.c similarity index 82% rename from src/st/nz0/43F9C.c rename to src/st/nz0/e_axe_knight.c index c9b0c3d029..5f09416177 100644 --- a/src/st/nz0/43F9C.c +++ b/src/st/nz0/e_axe_knight.c @@ -7,6 +7,57 @@ #include "nz0.h" #include "sfx.h" +typedef enum { + AXE_KNIGHT_INIT, + AXE_KNIGHT_IDLE, + AXE_KNIGHT_WALK_TOWARDS_PLAYER, + AXE_KNIGHT_WALK_AWAY_FROM_PLAYER, + AXE_KNIGHT_STANDING_THROW, + AXE_KNIGHT_DUCKING_THROW, + AXE_KNIGHT_UNUSED, // Charge Attack missing step from the blue AxeKnight + AXE_KNIGHT_ARCING_THROW, // Unused, present in the blue AxeKnight + AXE_KNIGHT_DYING, +} EntityAxeKnightSteps; + +extern u16 g_EAxeKnightInit[]; +static s16 sensors_move[] = {0, 32, 8, 0}; +static s16 sensors_ground[4][2] = {{0, 32}, {0, 4}, {8, -4}, {-16, 0}}; +static s16 dead_particle_pos[][2] = { + {-8, -4}, {8, -6}, {-2, 4}, {-1, -7}, {2, 8}, {11, -7}, {4, 6}, {-3, 0}}; +static u16 unused[] = { + 0x0114, 0x020A, 0x030A, 0x0414, 0x030A, 0x020A, 0x0000, 0x0000, 0x0508, + 0x0608, 0x0708, 0x0D08, 0x0E08, 0x0F02, 0x1402, 0x1502, 0x1620, 0x1708, + 0x0000, 0x0000, 0x0508, 0x0608, 0x0708, 0x0808, 0x090A, 0x0A04, 0x0B04, + 0x0C04, 0x0000, 0x0000, 0x0E04, 0x0F04, 0x1004, 0x1104, 0x0000, 0x0000, + 0x0D08, 0x0E08, 0x0F01, 0x1001, 0x1101, 0x1220, 0x1308, 0x0000}; +static u8 anim_walk[] = {0x1A, 0x18, 0x0A, 0x19, 0x0A, 0x1A, 0x1A, + 0x1B, 0x0A, 0x1A, 0x0A, 0x19, 0x00}; +static u8 anim_throw_duck[] = { + 0x08, 0x1C, 0x08, 0x1D, 0x08, 0x1E, 0x08, 0x1F, 0x0A, 0x20, 0x04, 0x21, + 0x04, 0x22, 0x04, 0x23, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x08, 0x25, + 0x02, 0x26, 0x02, 0x27, 0x02, 0x28, 0x20, 0x29, 0x08, 0x2A, 0x00}; +static u8 anim_throw_stand[] = { + 0x08, 0x1C, 0x08, 0x1D, 0x08, 0x1E, 0x08, 0x24, 0x08, 0x25, 0x02, + 0x26, 0x02, 0x2B, 0x02, 0x2C, 0x20, 0x2D, 0x08, 0x2E, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, 0x28, 0x00}; +static u8 anim_die[] = { + 0x08, 0x20, 0x08, 0x21, 0x08, 0x22, 0x08, 0x23, 0xFF, 0x00}; +static u8 hitboxes[][4] = { + {0, 0, 0, 0}, + {0, 6, 8, 26}, + {0, 11, 8, 21}, + {0, 12, 8, 20}, +}; +static u8 hitbox_lookup[] = { + 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 1, 0}; +static u8 steps[] = {AXE_KNIGHT_STANDING_THROW, AXE_KNIGHT_DUCKING_THROW, + AXE_KNIGHT_STANDING_THROW, AXE_KNIGHT_DUCKING_THROW, + AXE_KNIGHT_STANDING_THROW, AXE_KNIGHT_DUCKING_THROW, + AXE_KNIGHT_STANDING_THROW, AXE_KNIGHT_DUCKING_THROW}; +static u32 init_velocity_x[] = {FIX(2), FIX(2), FIX(1)}; +static u32 init_velocity_y[] = {FIX(0), FIX(0), FIX(-4)}; + // Weirdly, this function ONLY acts on prim->next, it does not act on prim. // However, it does call functions on prim. void func_801C3F9C(AxePrim* prim) { @@ -64,7 +115,7 @@ s32 func_801C4198(Entity* axeKnight) { switch (axeKnight->step_s) { case 0: - clutBase = D_80180C6A; + clutBase = g_EAxeKnightInit[3]; dataPtr = sprites_nz0_3[axeKnight->animCurFrame]; primIndex = g_api.AllocPrimitives(PRIM_GT4, *dataPtr * 2); if (primIndex != -1) { @@ -148,23 +199,11 @@ void func_801C4550(void) { if (g_CurrentEntity->ext.generic.unk80.modeS16.unk2 > 0) { g_CurrentEntity->ext.generic.unk80.modeS16.unk2 -= 3; } else { - SetStep(D_801822B4[(Random() & 7)]); + SetStep(steps[(Random() & 7)]); g_CurrentEntity->ext.generic.unk80.modeS16.unk2 = 256; } } -typedef enum { - AXE_KNIGHT_INIT, - AXE_KNIGHT_IDLE, - AXE_KNIGHT_WALK_TOWARDS_PLAYER, - AXE_KNIGHT_WALK_AWAY_FROM_PLAYER, - AXE_KNIGHT_STANDING_THROW, - AXE_KNIGHT_DUCKING_THROW, - AXE_KNIGHT_UNUSED, // Charge Attack missing step from the blue AxeKnight - AXE_KNIGHT_ARCING_THROW, // Unused, present in the blue AxeKnight - AXE_KNIGHT_DYING, -} EntityAxeKnightSteps; - // green knight that throws axes void EntityAxeKnight(Entity* self) { Entity* newEntity; @@ -185,14 +224,14 @@ void EntityAxeKnight(Entity* self) { switch (self->step) { case AXE_KNIGHT_INIT: - InitializeEntity(D_80180C64); + InitializeEntity(g_EAxeKnightInit); self->facingLeft = (GetSideToPlayer() & 1) ^ 1; self->hitboxOffY = 10; self->ext.generic.unk7C.S8.unk1 = 0; self->ext.generic.unk80.modeS16.unk2 = 512; case AXE_KNIGHT_IDLE: - if (func_801BCCFC(&D_80182188) & 1) { + if (func_801BCCFC(sensors_ground) & 1) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; SetStep(AXE_KNIGHT_WALK_TOWARDS_PLAYER); } @@ -208,7 +247,7 @@ void EntityAxeKnight(Entity* self) { self->step_s++; } - animStatus = AnimateEntity(D_80182210, self); + animStatus = AnimateEntity(anim_walk, self); if (self->animFrameDuration == 0) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; } @@ -237,7 +276,7 @@ void EntityAxeKnight(Entity* self) { self->velocityX += 0x300; } - if (func_801BCF74(&D_80182180) & 0x60) { + if (func_801BCF74(sensors_move) & 0x60) { self->posX.val -= self->velocityX; self->velocityX = 0; } @@ -254,7 +293,7 @@ void EntityAxeKnight(Entity* self) { self->step_s++; } - animStatus = AnimateEntity(D_80182210, self); + animStatus = AnimateEntity(anim_walk, self); if (self->animFrameDuration == 0) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; } @@ -283,7 +322,7 @@ void EntityAxeKnight(Entity* self) { self->velocityX -= 0x200; } - if (func_801BCF74(&D_80182180) & 0x60) { + if (func_801BCF74(sensors_move) & 0x60) { self->posX.val -= self->velocityX; self->velocityX = 0; } @@ -291,7 +330,7 @@ void EntityAxeKnight(Entity* self) { break; case AXE_KNIGHT_STANDING_THROW: - animStatus = AnimateEntity(D_80182244, self); + animStatus = AnimateEntity(anim_throw_stand, self); if (animStatus == 0) { label: if (GetDistanceToPlayerX() < 89) { @@ -318,7 +357,7 @@ void EntityAxeKnight(Entity* self) { break; case AXE_KNIGHT_DUCKING_THROW: - animStatus = AnimateEntity(D_80182220, self); + animStatus = AnimateEntity(anim_throw_duck, self); if (animStatus != 0) { if ((animStatus & 0x80) && (self->animFrameIdx == 6)) { func_801C29B0(NA_SE_VO_AXE_KNIGHT_THROW); @@ -341,7 +380,7 @@ void EntityAxeKnight(Entity* self) { break; case AXE_KNIGHT_ARCING_THROW: // unused - animStatus = AnimateEntity(D_80182244, self); + animStatus = AnimateEntity(anim_throw_stand, self); if (animStatus == 0) { if (GetDistanceToPlayerX() > 88) { SetStep(AXE_KNIGHT_WALK_TOWARDS_PLAYER); @@ -379,13 +418,13 @@ void EntityAxeKnight(Entity* self) { CreateEntityFromEntity(E_EXPLOSION, self, newEntity); temp >>= 3; newEntity->params = 2; - newEntity->posX.i.hi += D_80182198[temp]; - newEntity->posY.i.hi += D_8018219A[temp]; + newEntity->posX.i.hi += dead_particle_pos[temp][0]; + newEntity->posY.i.hi += dead_particle_pos[temp][1]; } } } - if (AnimateEntity(D_80182268, self) == 0) { + if (AnimateEntity(anim_die, self) == 0) { if (func_801C4198(self) != 0) { DestroyEntity(self); return; @@ -396,9 +435,8 @@ void EntityAxeKnight(Entity* self) { } break; } - hitbox = &D_80182284[self->animCurFrame][D_80182274]; - hitbox++; - hitbox--; + hitbox = hitboxes; + hitbox += hitbox_lookup[self->animCurFrame] * 4; self->hitboxOffX = *hitbox++; self->hitboxOffY = *hitbox++; self->hitboxWidth = hitbox[0]; @@ -428,8 +466,8 @@ void EntityAxeKnightThrowingAxe(Entity* entity) { case 0: InitializeEntity(D_80180C70); entity->drawFlags = FLAG_DRAW_ROTZ; - entity->velocityY = D_801822C8[entity->params]; - velocityX = D_801822BC[entity->params]; + entity->velocityY = init_velocity_y[entity->params]; + velocityX = init_velocity_x[entity->params]; if (entity->facingLeft == 0) { entity->velocityX = -velocityX; diff --git a/src/st/nz0/47958.c b/src/st/nz0/e_bloody_skeleton.c similarity index 100% rename from src/st/nz0/47958.c rename to src/st/nz0/e_bloody_skeleton.c diff --git a/src/st/nz0/44EAC.c b/src/st/nz0/e_bloody_zombie.c similarity index 85% rename from src/st/nz0/44EAC.c rename to src/st/nz0/e_bloody_zombie.c index e28d344bbf..d2247d65ba 100644 --- a/src/st/nz0/44EAC.c +++ b/src/st/nz0/e_bloody_zombie.c @@ -17,6 +17,38 @@ typedef enum { BLOODY_ZOMBIE_DESTROY } EntityBloodyZombieSteps; +extern u16 g_EBloodyZombieInit[]; +static s16 sensors_ground[4][2] = {{0, 28}, {0, 4}, {8, -4}, {-16, 0}}; +static u16 sensors_move[][2] = {{0, 28}, {8, 0}}; +static u8 anim_walk[] = {0x04, 0x02, 0x0D, 0x03, 0x0A, 0x02, 0x0A, 0x01, + 0x0D, 0x04, 0x0A, 0x01, 0x06, 0x02, 0x00, 0x00}; +static u8 anim_attack[] = { + 0x04, 0x05, 0x04, 0x06, 0x03, 0x07, 0x02, 0x08, 0x02, 0x09, 0x04, 0x08, + 0x02, 0x0A, 0x02, 0x0B, 0x02, 0x0C, 0x02, 0x0D, 0x02, 0x0E, 0x02, 0x0F, + 0x0C, 0x10, 0x02, 0x11, 0x02, 0x12, 0x02, 0x13, 0xFF, 0x00}; +static u8 anim_hit[] = { + 0x01, 0x16, 0x01, 0x14, 0x01, 0x15, 0x01, 0x14, 0x02, 0x15, + 0x03, 0x14, 0x04, 0x15, 0x08, 0x14, 0x02, 0x16, 0xFF, 0x00}; +static u8 anim_die[] = { + 0x01, 0x16, 0x01, 0x14, 0x01, 0x15, 0x01, 0x14, 0x02, 0x15, 0x03, 0x14, + 0x04, 0x15, 0x28, 0x14, 0x06, 0x17, 0x05, 0x18, 0x05, 0x19, 0x05, 0x1A, + 0x05, 0x1B, 0x02, 0x1C, 0x02, 0x1D, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, + 0x02, 0x1F, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, + 0x02, 0x1F, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, + 0x02, 0x1F, 0x02, 0x1E, 0x02, 0x1F, 0x02, 0x1E, 0xFF, 0x00}; +static u8 anim_chase[] = {0x02, 0x02, 0x06, 0x03, 0x04, 0x02, 0x04, 0x01, + 0x06, 0x04, 0x04, 0x01, 0x02, 0x02, 0x00, 0x00}; +static u8 D_8018238C[] = { + 0x08, 0x40, 0x20, 0x0F, 0x0F, 0x08, 0x50, 0x20, 0x0F, 0x0F, 0x08, + 0x60, 0x20, 0x0F, 0x0F, 0x08, 0x70, 0x20, 0x0F, 0x0F, 0xFF, 0x00}; +static u8 D_801823A4[] = { + 0x04, 0x20, 0x00, 0x1F, 0x1F, 0x04, 0x40, 0x00, 0x1F, 0x1F, 0x04, + 0x60, 0x00, 0x1F, 0x1F, 0x04, 0x00, 0x20, 0x1F, 0x1F, 0x04, 0x20, + 0x20, 0x1F, 0x0F, 0x04, 0x20, 0x30, 0x1F, 0x0F, 0xFF, 0x00}; +static s16 D_801823C4[][2] = {{0x0000, 0x0000}, {0x00FF, 0x0000}}; +static u8 unused[] = {0x06, 0x01, 0x04, 0x01, 0x04, 0x02, 0x06, 0x03, + 0x05, 0x04, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00}; + void EntityBloodSplatter(Entity* self) { Primitive *prim, *prim2, *prim3; s16 primIndex; @@ -132,7 +164,7 @@ void EntityBloodSplatter(Entity* self) { prim3 = prim->next; prim3->b3 += 254; - if (UpdateAnimation(&D_8018238C, prim) == 0) { + if (UpdateAnimation(D_8018238C, prim) == 0) { UnkPolyFunc0(prim); } @@ -152,7 +184,7 @@ void EntityBloodSplatter(Entity* self) { prim3->b3 = 0; } - if (UpdateAnimation(&D_801823A4, prim) == 0) { + if (UpdateAnimation(D_801823A4, prim) == 0) { UnkPolyFunc0(prim); } @@ -163,7 +195,7 @@ void EntityBloodSplatter(Entity* self) { } } -void func_801C53AC(Primitive* prim) { +static void func_801C53AC(Primitive* prim) { switch (prim->next->u2) { case 0: prim->tpage = 0x12; @@ -230,14 +262,14 @@ void EntityBloodyZombie(Entity* self) { switch (self->step) { case BLOODY_ZOMBIE_INIT: - InitializeEntity(D_80180C7C); + InitializeEntity(g_EBloodyZombieInit); self->hitboxOffX = 1; self->hitboxOffY = 4; SetStep(BLOODY_ZOMBIE_UNK_2); break; case BLOODY_ZOMBIE_UNK_2: - if (func_801BCCFC(D_801822D4) & 1) { + if (func_801BCCFC(sensors_ground) & 1) { SetStep(BLOODY_ZOMBIE_WALK); } break; @@ -248,8 +280,8 @@ void EntityBloodyZombie(Entity* self) { self->step_s++; } - AnimateEntity(D_801822EC, self); - func_801BCF74(D_801822E4); + AnimateEntity(anim_walk, self); + func_801BCF74(sensors_move); if (self->facingLeft == 0) { self->velocityX = FIX(-0.375); @@ -282,10 +314,10 @@ void EntityBloodyZombie(Entity* self) { break; case BLOODY_ZOMBIE_CHASE: - if (AnimateEntity(D_8018237C, self) == 0) { + if (AnimateEntity(anim_chase, self) == 0) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; } - func_801BCF74(D_801822E4); + func_801BCF74(sensors_move); if (self->facingLeft != 0) { self->velocityX = FIX(0.75); @@ -312,7 +344,7 @@ void EntityBloodyZombie(Entity* self) { break; case BLOODY_ZOMBIE_ATTACK: - animStatus = AnimateEntity(D_801822FC, self); + animStatus = AnimateEntity(anim_attack, self); if (animStatus & 0x80 && self->animFrameIdx == 10) { func_801C29B0(SFX_WEAPON_SWISH_B); } @@ -332,7 +364,7 @@ void EntityBloodyZombie(Entity* self) { self->step_s++; } - if (AnimateEntity(D_80182320, self) == 0) { + if (AnimateEntity(anim_hit, self) == 0) { SetStep(BLOODY_ZOMBIE_WALK); self->step_s++; } @@ -395,7 +427,7 @@ void EntityBloodyZombie(Entity* self) { } } - if (AnimateEntity(D_80182334, self) == 0) { + if (AnimateEntity(anim_die, self) == 0) { newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); if (newEntity != NULL) { CreateEntityFromEntity(E_EXPLOSION, self, newEntity); diff --git a/src/st/nz0/43708.c b/src/st/nz0/e_bone_scimitar.c similarity index 72% rename from src/st/nz0/43708.c rename to src/st/nz0/e_bone_scimitar.c index 0624ddf301..16000e1623 100644 --- a/src/st/nz0/43708.c +++ b/src/st/nz0/e_bone_scimitar.c @@ -28,9 +28,40 @@ typedef enum { BONE_SCIMITAR_WALK_LEFT } BoneScimitarSpecialSubSteps; +extern u16 g_BoneScimitarInit[]; +static s32 D_8018208C = 0; // Flag for special bone scimitar to appear or not +static u8 anim_walk[] = {0x06, 0x01, 0x04, 0x02, 0x04, 0x03, 0x06, + 0x04, 0x05, 0x05, 0x05, 0x06, 0x00}; +static u8 anim_walk_backwards[] = {0x06, 0x01, 0x05, 0x06, 0x05, 0x05, 0x06, + 0x04, 0x04, 0x03, 0x04, 0x02, 0x00}; +static u8 anim_swing_sword[] = { + 0x05, 0x01, 0x05, 0x02, 0x05, 0x07, 0x06, 0x08, 0x05, + 0x09, 0x05, 0x0A, 0x05, 0x0B, 0x01, 0x0C, 0x1E, 0x0D, + 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0xFF, 0x00}; +static u8 anim_jump[] = { + 0x01, 0x01, 0x04, 0x0E, 0x04, 0x0F, 0x01, 0x01, 0xFF, 0x00}; +static u8 anim_land[] = { + 0x01, 0x01, 0x04, 0x0E, 0x06, 0x0F, 0x04, 0x0E, 0x01, 0x01, 0xFF, 0x00}; +static s16 anim_bone_rot[] = { + 0x0100, 0x0080, 0x0048, 0x0020, 0x0040, 0x0010, 0x0018, 0x0000}; +static s8 dead_parts_selector[] = {0x30, 0x20, 0x14, 0x0C, 0x18, 0x10, 0x14}; +static s32 dead_parts_velocity_x[] = { + FIX(.75), FIX(1.75), FIX(1.5), FIX(1), FIX(2), FIX(1.75), FIX(0.75)}; +static s32 dead_parts_velocity_y[] = { + FIX(-5), FIX(-3), FIX(-2), FIX(-3), FIX(-4), FIX(-.875), FIX(-4)}; +static s16 dead_parts_pos_x[] = {-4, 0, 4, -4, -4, 4, 0}; +static s16 dead_parts_pos_y[] = {-16, -8, -4, -4, 9, 9, 0}; +static u8 attack_timer_cycles[2][4] = { + {0x80, 0x08, 0x08, 0x40}, // skeleton type 0, attacks in quick succession + {0xF0, 0xC0, 0xA0, 0x80}, // type 1, attacks slowly +}; +static u16 sensors_ground[][2] = {{0, 20}, {0, 4}, {8, -4}, {-16, 0}}; +static s16 D_8018216C[] = {0, 20, 12, 0}; +static u16 sensor_move[][2] = {{-12, 16}, {0, -16}, {0, -16}}; + void func_801C3708(void) { - s32 temp = func_801BCF74(&D_8018216C); - s32 temp2 = func_801BD720(&D_80182174, 3); + s32 temp = func_801BCF74(D_8018216C); + s32 temp2 = func_801BD720(sensor_move, LEN(sensor_move)); if ((temp == 128) || (temp2 & 2)) { SetStep(BONE_SCIMITAR_JUMP); @@ -59,7 +90,7 @@ void EntityBoneScimitar(Entity* self) { switch (self->step) { case BONE_SCIMITAR_INIT: - InitializeEntity(D_80180C4C); + InitializeEntity(g_BoneScimitarInit); if (self->params != 0) { self->palette += self->params; self->flags &= ~(FLAG_DESTROY_IF_BARELY_OUT_OF_CAMERA | @@ -76,7 +107,7 @@ void EntityBoneScimitar(Entity* self) { break; case BONE_SCIMITAR_IDLE: - if (func_801BCCFC(&D_8018215C) != 0) { + if (func_801BCCFC(sensors_ground) != 0) { self->step++; if (self->params != 0) { SetStep(BONE_SCIMITAR_SPECIAL); @@ -85,7 +116,7 @@ void EntityBoneScimitar(Entity* self) { break; case BONE_SCIMITAR_WALK_TOWARDS_PLAYER: - if (AnimateEntity(D_80182090, self) == 0) { + if (AnimateEntity(anim_walk, self) == 0) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; } self->ext.generic.unk80.modeS8.unk0 = self->facingLeft; @@ -103,7 +134,7 @@ void EntityBoneScimitar(Entity* self) { break; case BONE_SCIMITAR_WALK_AWAY_FROM_PLAYER: - if (AnimateEntity(D_801820A0, self) == 0) { + if (AnimateEntity(anim_walk_backwards, self) == 0) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; } self->ext.generic.unk80.modeS8.unk0 = self->facingLeft ^ 1; @@ -121,7 +152,7 @@ void EntityBoneScimitar(Entity* self) { break; case BONE_SCIMITAR_ATTACK: - animStatus = AnimateEntity(D_801820B0, self); + animStatus = AnimateEntity(anim_swing_sword, self); if (self->animCurFrame == 12) { self->hitboxWidth = 20; self->hitboxHeight = 17; @@ -141,8 +172,8 @@ void EntityBoneScimitar(Entity* self) { if (animStatus == 0) { SetStep(BONE_SCIMITAR_WALK_AWAY_FROM_PLAYER); self->ext.generic.unk7C.S8.unk0 = - D_80182154[self->params % 2] - [(++self->ext.generic.unk84.S8.unk0) & 3]; + attack_timer_cycles[self->params % 2] + [(++self->ext.generic.unk84.S8.unk0) & 3]; if (self->params != 0) { SetStep(BONE_SCIMITAR_SPECIAL); } @@ -152,7 +183,7 @@ void EntityBoneScimitar(Entity* self) { case BONE_SCIMITAR_JUMP: switch (self->step_s) { case BONE_SCIMITAR_JUMPING: - if (!(AnimateEntity(D_801820CC, self) & 1)) { + if (!(AnimateEntity(anim_jump, self) & 1)) { u8 facing_ = self->ext.generic.unk80.modeS8.unk0; s32 facing; @@ -176,14 +207,14 @@ void EntityBoneScimitar(Entity* self) { break; case BONE_SCIMITAR_IN_AIR: - if (func_801BCCFC(&D_8018215C) != 0) { + if (func_801BCCFC(sensors_ground) != 0) { self->step_s++; } - CheckFieldCollision(&D_80182174, 2); + CheckFieldCollision(sensor_move, 2); break; case BONE_SCIMITAR_LAND: - if (AnimateEntity(D_801820D8, self) == 0) { + if (AnimateEntity(anim_land, self) == 0) { SetStep(BONE_SCIMITAR_WALK_AWAY_FROM_PLAYER); } } @@ -193,9 +224,9 @@ void EntityBoneScimitar(Entity* self) { self->facingLeft = (GetSideToPlayer() & 1) ^ 1; func_801BCF74(&D_8018216C); if (((((u32)self->velocityX) >> 0x1F) ^ self->facingLeft) != 0) { - AnimateEntity(D_80182090, self); + AnimateEntity(anim_walk, self); } else { - AnimateEntity(D_801820A0, self); + AnimateEntity(anim_walk_backwards, self); } switch (self->step_s) { @@ -228,7 +259,7 @@ void EntityBoneScimitar(Entity* self) { case BONE_SCIMITAR_DESTROY: g_api.PlaySfx(SFX_SKELETON_DEATH_C); - for (i = 0; i < 7; i++) { + for (i = 0; i < LEN(dead_parts_pos_x); i++) { newEntity = AllocEntity(&g_Entities[224], &g_Entities[256]); if (newEntity == NULL) { break; @@ -236,16 +267,16 @@ void EntityBoneScimitar(Entity* self) { CreateEntityFromCurrentEntity(E_BONE_SCIMITAR_HEAD, newEntity); newEntity->facingLeft = self->facingLeft; newEntity->params = i; - newEntity->ext.generic.unk88.S8.unk0 = D_801820F4[i]; + newEntity->ext.generic.unk88.S8.unk0 = dead_parts_selector[i]; if (self->facingLeft != 0) { - newEntity->posX.i.hi -= D_80182134[i]; + newEntity->posX.i.hi -= dead_parts_pos_x[i]; } else { - newEntity->posX.i.hi += D_80182134[i]; + newEntity->posX.i.hi += dead_parts_pos_x[i]; } - newEntity->posY.i.hi += D_80182144[i]; - newEntity->velocityX = D_801820FC[i]; - newEntity->velocityY = D_80182118[i]; + newEntity->posY.i.hi += dead_parts_pos_y[i]; + newEntity->velocityX = dead_parts_velocity_x[i]; + newEntity->velocityY = dead_parts_velocity_y[i]; newEntity->params |= self->params << 8; } @@ -271,7 +302,7 @@ void EntityBoneScimitarParts(Entity* entity) { if (entity->step) { entity->ext.generic.unk88.S8.unk0--; if (entity->ext.generic.unk88.S8.unk0 & 0xFF) { - entity->rotZ += D_801820E4[entity->params]; + entity->rotZ += anim_bone_rot[entity->params]; FallEntity(); MoveEntity(); return; diff --git a/src/st/nz0/e_breakable.c b/src/st/nz0/e_breakable.c new file mode 100644 index 0000000000..d3810eb40e --- /dev/null +++ b/src/st/nz0/e_breakable.c @@ -0,0 +1,93 @@ +#include "nz0.h" + +static u8 D_80180DE4[] = {4, 1, 4, 2, 0, 0, 0, 0}; +static u8 D_80180DEC[] = {4, 4, 4, 5, 4, 6, 4, 5, 0, 0, 0, 0}; +static u8 D_80180DF8[] = {4, 14, 4, 15, 4, 16, 4, 17, 0, 0, 0, 0}; +static u8* g_eBreakableAnimations[] = { + D_80180DE4, D_80180DEC, D_80180DF8, NULL, NULL, NULL, NULL, NULL}; +static u8 g_eBreakableHitboxes[] = {8, 8, 8, 0, 0, 0, 0, 0}; +static u8 g_eBreakableExplosionTypes[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static u16 g_eBreakableanimSets[] = { + ANIMSET_DRA(3), ANIMSET_OVL(1), ANIMSET_OVL(8), 0, 0, 0, 0, 0}; +static u8 g_eBreakableDrawModes[] = { + DRAW_TPAGE | DRAW_TPAGE2 | DRAW_UNK_40, + DRAW_TPAGE | DRAW_TPAGE2 | DRAW_UNK_40, + DRAW_TPAGE | DRAW_TPAGE2, + DRAW_DEFAULT, + DRAW_DEFAULT, + DRAW_DEFAULT, + DRAW_DEFAULT, + DRAW_DEFAULT}; + +#ifndef VERSION_PSP +// on PSP this might be either optimised out to BSS or completely removed +static u8 unused[] = {0, 0, 0, 0, 0, 0, 0, 0}; +#endif + +extern u16 g_eBreakableInit[]; + +void EntityBreakableNZ0(Entity* self) { + u16 breakableType = self->params >> 12; + s16 top, bottom, left, right; + Entity* entityDropItem; + Primitive* prim; + + if (self->step) { + AnimateEntity(g_eBreakableAnimations[breakableType], self); + if (breakableType == 2) { + prim = &g_PrimBuf[self->primIndex]; + if (g_Timer & 2) { + prim->clut = 0x21B; + } else { + prim->clut = 0x21C; + } + } + + if (self->unk44) { // If destroyed + if (breakableType == 2) { + g_api.FreePrimitives(self->primIndex); + self->flags &= ~FLAG_HAS_PRIMS; + } + g_api.PlaySfx(SFX_CANDLE_HIT); + entityDropItem = AllocEntity(&g_Entities[224], &g_Entities[256]); + if (entityDropItem != NULL) { + CreateEntityFromCurrentEntity(E_EXPLOSION, entityDropItem); + entityDropItem->params = + g_eBreakableExplosionTypes[breakableType]; + } + ReplaceBreakableWithItemDrop(self); + } + } else { + InitializeEntity(g_eBreakableInit); + self->zPriority = g_unkGraphicsStruct.g_zEntityCenter.unk - 20; + self->drawMode = g_eBreakableDrawModes[breakableType]; + self->hitboxHeight = g_eBreakableHitboxes[breakableType]; + self->animSet = g_eBreakableanimSets[breakableType]; + if (breakableType == 2) { + self->unk5A = 0x4B; + self->palette = 0x219; + self->primIndex = g_api.AllocPrimitives(PRIM_GT4, 1); + if (self->primIndex == -1) { + DestroyEntity(self); + return; + } + self->flags |= FLAG_HAS_PRIMS; + prim = &g_PrimBuf[self->primIndex]; + prim->tpage = 0x12; + prim->u0 = prim->u2 = 0xC8; + prim->u1 = prim->u3 = 0xF8; + prim->v0 = prim->v1 = 0x80; + prim->v2 = prim->v3 = 0xA0; + left = self->posX.i.hi - 23; + right = self->posX.i.hi + 25; + prim->x0 = prim->x2 = left; + prim->x1 = prim->x3 = right; + top = self->posY.i.hi - 23; + bottom = self->posY.i.hi + 9; + prim->y0 = prim->y1 = top; + prim->y2 = prim->y3 = bottom; + prim->priority = self->zPriority; + prim->drawMode = 0x73; + } + } +} diff --git a/src/st/nz0/e_elevator.c b/src/st/nz0/e_elevator.c new file mode 100644 index 0000000000..46ee35b921 --- /dev/null +++ b/src/st/nz0/e_elevator.c @@ -0,0 +1,150 @@ +#include "nz0.h" + +typedef enum ElevatorSubSteps { + /* 0 */ ELEVATOR_INIT, + /* 1 */ ELEVATOR_IDLE, + /* 2 */ ELEVATOR_ASCEND, + /* 3 */ ELEVATOR_DESCEND, +} ElevatorSubSteps; + +void EntityElevator(Entity* self) { + Primitive* prim; + s16 primIndex; + s32 player; + s32 x, y; + s32 temp; + + FntPrint("elevator:%x\n", g_ElevatorTarget); + + if (g_Player.unk0C & 3) { + temp = 0; + } else { + temp = GetPlayerCollisionWith(self, 16, 5, 4); + } + + //! FAKE: + player = PLAYER_CHARACTER; + + switch (self->step) { + case ELEVATOR_INIT: + InitializeEntity(g_EInitGeneric); + self->hitboxOffX = 0; + self->hitboxOffY = 68; + self->hitboxWidth = 16; + self->hitboxHeight = 5; + self->hitboxState = 1; + + if (g_ElevatorTarget != 0) { + y = g_ElevatorTargetPos[g_ElevatorTarget]; + self->posY.i.hi = y - g_Tilemap.scrollY.i.hi; + } else { + g_ElevatorTarget = self->params; + } + + primIndex = g_api.AllocPrimitives(PRIM_GT4, 32); + if (primIndex == -1) { + DestroyEntity(self); + return; + } + prim = &g_PrimBuf[primIndex]; + self->primIndex = primIndex; + self->ext.elevator.prim = prim; + self->flags |= FLAG_HAS_PRIMS; + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 8; + prim->v0 = 0x80; + prim->u1 = 0x20; + prim->v1 = 0x48; + prim->priority = 0x72; + prim->drawMode = 2; + prim = prim->next; + while (prim != NULL) { + prim->type = PRIM_SPRT; + prim->tpage = 0xF; + prim->clut = 9; + prim->u0 = 0; + prim->v0 = 0x80; + prim->u1 = 8; + prim->v1 = 0x40; + prim->priority = 0x5F; + prim->drawMode = 2; + prim = prim->next; + } + self->ext.elevator.elevatorTarget = g_ElevatorTarget; + + case ELEVATOR_IDLE: + if (temp != 0) { + if (g_pads[0].pressed & PAD_UP) { + if (--g_ElevatorTarget < 1) { + g_ElevatorTarget = 1; + } + } + if (g_pads[0].pressed & PAD_DOWN) { + if (++g_ElevatorTarget > 3) { + g_ElevatorTarget = 3; + } + } + } + + if (g_ElevatorTarget != self->ext.elevator.elevatorTarget) { + y = g_ElevatorTargetPos[g_ElevatorTarget]; + y -= g_Tilemap.scrollY.i.hi; + if (y >= self->posY.i.hi) { + self->step = ELEVATOR_DESCEND; + } else { + self->step = ELEVATOR_ASCEND; + } + func_801C29B0(0x6E6); + } + self->ext.elevator.elevatorTarget = g_ElevatorTarget; + break; + + case ELEVATOR_ASCEND: + self->posY.i.hi--; + y = g_ElevatorTargetPos[self->ext.elevator.elevatorTarget] - + g_Tilemap.scrollY.i.hi; + if (self->posY.i.hi >= y) { + if (temp != 0) { + g_api.func_8010DFF0(0, 1); + g_Entities[player].posY.i.hi--; + D_80097488.y.i.hi--; + } + } else { + self->posY.i.hi = y; + self->step = ELEVATOR_IDLE; + } + break; + + case ELEVATOR_DESCEND: + self->posY.i.hi++; + y = g_ElevatorTargetPos[self->ext.elevator.elevatorTarget] - + g_Tilemap.scrollY.i.hi; + if (y < self->posY.i.hi) { + self->posY.i.hi = y; + self->step = ELEVATOR_IDLE; + break; + } + if (temp != 0) { + g_api.func_8010DFF0(0, 1); + g_Entities[player].posY.i.hi++; + D_80097488.y.i.hi++; + } + break; + } + prim = self->ext.prim; + prim->x0 = self->posX.i.hi - 16; + prim->y0 = self->posY.i.hi; + + prim = prim->next; + x = self->posX.i.hi; + y = self->posY.i.hi - 56; + x -= 3; + while (prim != NULL) { + prim->x0 = x; + prim->y0 = y; + prim = prim->next; + y -= 0x40; + } +} diff --git a/src/st/nz0/e_init.c b/src/st/nz0/e_init.c new file mode 100644 index 0000000000..d20b101ece --- /dev/null +++ b/src/st/nz0/e_init.c @@ -0,0 +1,276 @@ +#include + +void EntityBreakableNZ0(Entity*); +void EntityExplosion(Entity*); +void EntityPrizeDrop(Entity*); +void EntityDamageDisplay(Entity*); +void EntityRedDoor(Entity*); +void EntityIntenseExplosion(Entity*); +void EntitySoulStealOrb(Entity*); +void EntityRoomForeground(Entity*); +void EntityStageNamePopup(Entity*); +void EntityEquipItemDrop(Entity*); +void EntityRelicOrb(Entity*); +void EntityHeartDrop(Entity*); +void EntityEnemyBlood(Entity*); +void EntityMessageBox(Entity*); +void EntityDummy(Entity*); +void EntityDummy(Entity*); +void func_801B0958(Entity*); +void func_801B0AA4(Entity*); +void EntityUnkId13(Entity*); +void EntityUnkId14(Entity*); +void EntityUnkId15(Entity*); +void EntityPurpleBrickScrollingBackground(Entity*); +void EntityLeftSecretRoomWall(Entity*); +void EntityBottomSecretRoomFloor(Entity*); +void func_801B1C18(Entity*); +void func_801B1E54(Entity*); +void EntityMoveableBox(Entity*); +void EntityCannonLever(Entity*); +void EntityCannon(Entity*); +void EntityCannonShot(Entity*); +void EntityCannonWall(Entity*); +void func_801B2AD8(Entity*); +void EntityElevator2(Entity*); +void func_801B19A0(Entity*); +void EntityRedEyeBust(Entity*); +void func_801B2FD8(Entity*); +void EntityFloorSpikes(Entity*); +void EntityBloodSkeleton(Entity*); +void EntityBoneScimitar(Entity*); +void EntityBoneScimitarParts(Entity*); +void EntityAxeKnight(Entity*); +void EntityAxeKnightThrowingAxe(Entity*); +void EntityBloodyZombie(Entity*); +void func_801C5D20(Entity*); +void EntityBloodSplatter(Entity*); +void EntitySkeleton(Entity*); +void func_801C6574(Entity*); +void func_801C6494(Entity*); +void EntitySpittleBone(Entity*); +void EntityRotateSpittlebone(Entity*); +void EntitySpittleBoneSpit(Entity*); +void EntityTableWithGlobe(Entity*); +void func_801B3648(Entity*); +void func_801B3A50(Entity*); +void func_801B37C0(Entity*); +void EntityWargExplosionPuffOpaque(Entity*); +void EntitySubWeaponContainer(Entity*); +void func_801C7538(Entity*); +void func_801C7654(Entity*); +void func_801C77B8(Entity*); +void func_801C7884(Entity*); +void EntityBossFightManager(Entity*); +void EntityBossRoomBlock(Entity*); +void EntitySlogra(Entity*); +void EntitySlograSpear(Entity*); +void EntitySlograSpearProjectile(Entity*); +void EntityGaibon(Entity*); +void func_801B69E8(Entity*); +void EntitySmallGaibonProjectile(Entity*); +void EntityLargeGaibonProjectile(Entity*); +void EntityElevator(Entity*); +void func_801B6DE4(Entity*); +void EntityLifeUpSpawn(Entity*); +void EntityMagicallySealedDoor(Entity*); +void EntityMariaCutscene(Entity*); +void EntityMaria(Entity*); +void func_801B8E0C(Entity*); + +PfnEntityUpdate PfnEntityUpdates[] = { + (PfnEntityUpdate)EntityBreakableNZ0, + (PfnEntityUpdate)EntityExplosion, + (PfnEntityUpdate)EntityPrizeDrop, + (PfnEntityUpdate)EntityDamageDisplay, + (PfnEntityUpdate)EntityRedDoor, + (PfnEntityUpdate)EntityIntenseExplosion, + (PfnEntityUpdate)EntitySoulStealOrb, + (PfnEntityUpdate)EntityRoomForeground, + (PfnEntityUpdate)EntityStageNamePopup, + (PfnEntityUpdate)EntityEquipItemDrop, + (PfnEntityUpdate)EntityRelicOrb, + (PfnEntityUpdate)EntityHeartDrop, + (PfnEntityUpdate)EntityEnemyBlood, + (PfnEntityUpdate)EntityMessageBox, + (PfnEntityUpdate)EntityDummy, + (PfnEntityUpdate)EntityDummy, + (PfnEntityUpdate)func_801B0958, + (PfnEntityUpdate)func_801B0AA4, + (PfnEntityUpdate)EntityUnkId13, + (PfnEntityUpdate)EntityUnkId14, + (PfnEntityUpdate)EntityUnkId15, + (PfnEntityUpdate)EntityPurpleBrickScrollingBackground, + (PfnEntityUpdate)EntityLeftSecretRoomWall, + (PfnEntityUpdate)EntityBottomSecretRoomFloor, + (PfnEntityUpdate)func_801B1C18, + (PfnEntityUpdate)func_801B1E54, + (PfnEntityUpdate)EntityMoveableBox, + (PfnEntityUpdate)EntityCannonLever, + (PfnEntityUpdate)EntityCannon, + (PfnEntityUpdate)EntityCannonShot, + (PfnEntityUpdate)EntityCannonWall, + (PfnEntityUpdate)func_801B2AD8, + (PfnEntityUpdate)EntityElevator2, + (PfnEntityUpdate)func_801B19A0, + (PfnEntityUpdate)EntityRedEyeBust, + (PfnEntityUpdate)func_801B2FD8, + (PfnEntityUpdate)EntityFloorSpikes, + (PfnEntityUpdate)EntityBloodSkeleton, + (PfnEntityUpdate)EntityBoneScimitar, + (PfnEntityUpdate)EntityBoneScimitarParts, + (PfnEntityUpdate)EntityAxeKnight, + (PfnEntityUpdate)EntityAxeKnightThrowingAxe, + (PfnEntityUpdate)EntityBloodyZombie, + (PfnEntityUpdate)func_801C5D20, + (PfnEntityUpdate)EntityBloodSplatter, + (PfnEntityUpdate)EntitySkeleton, + (PfnEntityUpdate)func_801C6574, + (PfnEntityUpdate)func_801C6494, + (PfnEntityUpdate)EntitySpittleBone, + (PfnEntityUpdate)EntityRotateSpittlebone, + (PfnEntityUpdate)EntitySpittleBoneSpit, + (PfnEntityUpdate)EntityTableWithGlobe, + (PfnEntityUpdate)func_801B3648, + (PfnEntityUpdate)func_801B3A50, + (PfnEntityUpdate)func_801B37C0, + (PfnEntityUpdate)EntityWargExplosionPuffOpaque, + (PfnEntityUpdate)EntitySubWeaponContainer, + (PfnEntityUpdate)func_801C7538, + (PfnEntityUpdate)func_801C7654, + (PfnEntityUpdate)func_801C77B8, + (PfnEntityUpdate)func_801C7884, + (PfnEntityUpdate)EntityBossFightManager, + (PfnEntityUpdate)EntityBossRoomBlock, + (PfnEntityUpdate)EntitySlogra, + (PfnEntityUpdate)EntitySlograSpear, + (PfnEntityUpdate)EntitySlograSpearProjectile, + (PfnEntityUpdate)EntityGaibon, + (PfnEntityUpdate)func_801B69E8, + (PfnEntityUpdate)EntitySmallGaibonProjectile, + (PfnEntityUpdate)EntityLargeGaibonProjectile, + (PfnEntityUpdate)EntityElevator, + (PfnEntityUpdate)func_801B6DE4, + (PfnEntityUpdate)EntityLifeUpSpawn, + (PfnEntityUpdate)EntityMagicallySealedDoor, + (PfnEntityUpdate)EntityMariaCutscene, + (PfnEntityUpdate)EntityMaria, + (PfnEntityUpdate)func_801B8E0C, +}; + +u16 g_eBreakableInit[] = { + 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; +u16 g_InitializeData0[] = { + 0x0003, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, +}; +u16 g_InitializeEntityData0[] = { + 0x0003, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, +}; +u16 g_MariaInit[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, +}; +u16 g_EInitGeneric[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0000, +}; +u16 g_InitDataEnt13[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, +}; +u16 D_80180C10[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, +}; +u16 g_eInitGeneric2[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, +}; +u16 g_eDamageDisplayInit[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, +}; +u16 D_80180C34[] = { + 0x8001, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, +}; +u16 D_80180C40[] = { + 0x8002, 0x0000, 0x004C, 0x0200, 0x0046, 0x0000, +}; +u16 g_BoneScimitarInit[] = { + 0x8003, 0x0001, 0x004D, 0x0204, 0x0069, 0x0000, +}; +u16 D_80180C58[] = { + 0x8003, 0x0000, 0x004D, 0x0204, 0x0002, 0x0000, +}; +u16 g_EAxeKnightInit[] = { + 0x8004, 0x0001, 0x0048, 0x0207, 0x00F6, 0x0000, +}; +u16 D_80180C70[] = { + 0x8004, 0x002F, 0x0048, 0x0205, 0x018F, 0x0000, +}; +u16 g_EBloodyZombieInit[] = { + 0x8005, 0x0001, 0x004A, 0x0209, 0x000D, 0x0000, +}; +u16 D_80180C88[] = { + 0x8006, 0x0001, 0x004E, 0x020C, 0x004B, 0x0000, +}; +u16 D_80180C94[] = { + 0x8006, 0x0000, 0x004E, 0x020C, 0x0002, 0x0000, +}; +u16 D_80180CA0[] = { + 0x8006, 0x0015, 0x004E, 0x020C, 0x004C, 0x0000, +}; +u16 D_80180CAC[] = { + 0x8007, 0x0034, 0x0050, 0x020D, 0x0051, 0x0000, +}; +u16 D_80180CB8[] = { + 0x8007, 0x0040, 0x0050, 0x020D, 0x0052, 0x0000, +}; +u16 D_80180CC4[] = { + 0x8008, 0x0000, 0x004B, 0x0219, 0x0005, 0x0000, +}; +u16 D_80180CD0[] = { + 0x8009, 0x0000, 0x004F, 0x0211, 0x0005, 0x0000, +}; +u16 D_80180CDC[] = { + 0x800A, 0x0000, 0x0053, 0x0215, 0x0005, 0x0000, +}; +u16 D_80180CE8[] = { + 0x800C, 0x0000, 0x004C, 0x021D, 0x0005, 0x0000, +}; +u16 D_80180CF4[] = { + 0x800C, 0x0000, 0x004C, 0x021D, 0x0002, 0x0000, +}; +u16 D_80180D00[] = { + 0x8001, 0x0008, 0x0000, 0x0000, 0x0005, 0x0000, +}; +u16 D_80180D0C[] = { + 0x800D, 0x0000, 0x0048, 0x0227, 0x00F3, 0x0000, +}; +u16 D_80180D18[] = { + 0x800D, 0x0000, 0x0048, 0x0227, 0x00F4, 0x0000, +}; +u16 D_80180D24[] = { + 0x800D, 0x0000, 0x0048, 0x0227, 0x00F5, 0x0000, +}; +u16 D_80180D30[] = { + 0x800E, 0x0000, 0x004C, 0x022A, 0x00FE, 0x0000, +}; +u16 D_80180D3C[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0x0000, +}; +u16 D_80180D48[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0000, +}; + +static u32 D_80180D54[] = {0x00000B10}; +static u32 D_80180D58[] = {0x0D080C08, 0x0F080E08, 0x00001008}; + +ObjInit2 D_80180D64[] = { + {0x8001, 0x0069, 0x0000, 0x0000, 0x00, 0x00, 0x00000000, D_80180D54}, + {0x8001, 0x0069, 0x0000, 0x0000, 0x00, 0x30, 0x00000000, D_80180D58}, +}; + +// Owned by EntityRedDoor to animate the tiles behind the door itself. +// There is a loop in EntityRedDoor that forces to write those tiles +// at every frame based on the door state to create the animation. +u16 g_eRedDoorTiles[][8] = { + 0x0761, 0x0769, 0x0771, 0x0779, 0x0130, 0x0138, 0x01C0, 0x01C5, + 0x0763, 0x076B, 0x0773, 0x077B, 0x0175, 0x017A, 0x0200, 0x0203, + 0x0762, 0x076A, 0x0772, 0x077A, 0x0000, 0x0000, 0x0000, 0x0000, +}; diff --git a/src/st/nz0/47CF0.c b/src/st/nz0/e_magically_sealed_door.c similarity index 100% rename from src/st/nz0/47CF0.c rename to src/st/nz0/e_magically_sealed_door.c diff --git a/src/st/nz0/45F2C.c b/src/st/nz0/e_skeleton.c similarity index 69% rename from src/st/nz0/45F2C.c rename to src/st/nz0/e_skeleton.c index c347519236..1c089badaa 100644 --- a/src/st/nz0/45F2C.c +++ b/src/st/nz0/e_skeleton.c @@ -6,12 +6,48 @@ #include "nz0.h" #include "sfx.h" +typedef enum { + SKELETON_INIT, + SKELETON_IDLE, + SKELETON_WALK_TOWARDS_PLAYER, + SKELETON_WALK_AWAY_FROM_PLAYER, + SKELETON_ATTACK, + SKELETON_JUMP, + SKELETON_DESTROY +} SKELETON_STEPS; + +static u8 anim_walk[] = {0x06, 0x01, 0x04, 0x02, 0x04, 0x03, 0x06, + 0x04, 0x05, 0x05, 0x05, 0x06, 0x00}; +static u8 anim_walk_backwards[] = {0x06, 0x01, 0x05, 0x06, 0x05, 0x05, 0x06, + 0x04, 0x04, 0x03, 0x04, 0x02, 0x00}; +static u8 anim_throw_bone[] = {0x05, 0x07, 0x06, 0x08, 0x05, 0x09, 0x05, + 0x0A, 0x05, 0x0B, 0x05, 0x0C, 0xFF, 0x00}; +static u8 anim_jump1[] = {0x01, 0x01, 0x04, 0x0D, 0x04, 0x0E, 0x01, 0x01, 0x00}; +static u8 anim_jump2[] = { + 0x01, 0x01, 0x04, 0x0D, 0x06, 0x0E, 0x04, 0x0D, 0x01, 0x01, 0x00}; +static u16 anim_bone_rot[] = {0x0100, 0x0080, 0x0048, 0x0020, 0x0040, 0x0010}; +static s8 dead_parts_selector[] = {0x30, 0x20, 0x14, 0x0C, 0x18, 0x10}; +static s32 dead_parts_velocity_x[] = { + FIX(.75), FIX(1.75), FIX(1.5), FIX(1), FIX(2), FIX(1.75)}; +static s32 dead_parts_velocity_y[] = { + FIX(-5), FIX(-3), FIX(-2), FIX(-3), FIX(-4), FIX(-.875)}; +static u16 dead_parts_pos_x[] = {0 - 4, 0, 4, -4, -4, 4}; +static u16 dead_parts_pos_y[] = {-16, -8, -4, -4, 9, 9}; +static u8 attack_timer_cycles[2][4] = { + {0x80, 0x08, 0x08, 0x40}, {0xF0, 0xC0, 0xA0, 0x80}}; +static u32 bone_projectile_velocity_x[] = { + FIX(-.125), FIX(-.5), FIX(-1), FIX(-1.5), + FIX(-2), FIX(-2.5), FIX(-3), FIX(-3.5)}; +static s16 sensors_ground[][2] = {{0, 19}, {0, 4}, {8, -4}, {-16, 0}}; +static s16 D_801824B8[] = {0, 19, 8, 0}; +static s16 sensors_move[][2] = {{-12, 16}, {0, -16}, {0, -16}}; + void func_801C5F2C(Entity* self) { - if ((func_801BCF74(&D_801824B8) & 0x60) == 0x60) { + if ((func_801BCF74(D_801824B8) & 0x60) == 0x60) { self->posX.val -= self->velocityX; } - if (!(func_801BD720(&D_801824C0, 3) & 2)) { + if (!(func_801BD720(sensors_move, LEN(sensors_move)) & 2)) { if ((--self->ext.generic.unk7C.U8.unk0) == 0) { SetStep(4); } @@ -36,17 +72,15 @@ void EntitySkeleton(Entity* self) { self->ext.generic.unk80.modeS8.unk0 = 0; self->ext.generic.unk84.S8.unk0 = 0; break; - case SKELETON_IDLE: // Wait for player to be close enough - if (func_801BCCFC(&D_801824A8) != 0) { + if (func_801BCCFC(sensors_ground) != 0) { self->step++; } break; - case SKELETON_WALK_TOWARDS_PLAYER: self->facingLeft = (GetSideToPlayer() & 1) ^ 1; self->ext.generic.unk80.modeS8.unk0 = self->facingLeft; - AnimateEntity(D_801823DC, self); + AnimateEntity(anim_walk, self); if (self->ext.generic.unk80.modeS8.unk0 == 0) { self->velocityX = FIX(-0.5); @@ -59,11 +93,10 @@ void EntitySkeleton(Entity* self) { } func_801C5F2C(self); break; - case SKELETON_WALK_AWAY_FROM_PLAYER: self->facingLeft = (GetSideToPlayer() & 1) ^ 1; self->ext.generic.unk80.modeS8.unk0 = self->facingLeft ^ 1; - AnimateEntity(D_801823EC, self); + AnimateEntity(anim_walk_backwards, self); if (self->ext.generic.unk80.modeS8.unk0 == 0) { self->velocityX = FIX(-0.5); @@ -76,14 +109,13 @@ void EntitySkeleton(Entity* self) { } func_801C5F2C(self); break; - case SKELETON_ATTACK: - animStatus = AnimateEntity(D_801823FC, self); + animStatus = AnimateEntity(anim_throw_bone, self); if (!animStatus) { SetStep(SKELETON_WALK_AWAY_FROM_PLAYER); self->ext.generic.unk7C.S8.unk0 = - D_80182480[self->params & 1] - [++self->ext.generic.unk84.S8.unk0 & 3]; + attack_timer_cycles[self->params & 1] + [++self->ext.generic.unk84.S8.unk0 & 3]; break; } @@ -105,11 +137,10 @@ void EntitySkeleton(Entity* self) { } } break; - case SKELETON_JUMP: switch (self->step_s) { case 0: - if (!(AnimateEntity(D_8018240C, self) & 1)) { + if (!(AnimateEntity(anim_jump1, self) & 1)) { u8 facing_ = self->ext.generic.unk80.modeS8.unk0; s32 facing; @@ -132,22 +163,19 @@ void EntitySkeleton(Entity* self) { self->step_s++; } break; - case 1: - if (func_801BCCFC(&D_801824A8) != 0) { + if (func_801BCCFC(sensors_ground) != 0) { self->step_s++; } - CheckFieldCollision(&D_801824C0, 2); + CheckFieldCollision(sensors_move, 2); break; - case 2: - if (AnimateEntity(D_80182418, self) & 1) { + if (AnimateEntity(anim_jump2, self) & 1) { self->step_s = 0; SetStep(SKELETON_WALK_AWAY_FROM_PLAYER); } } break; - case SKELETON_DESTROY: func_801C29B0(SFX_SKELETON_DEATH_C); for (i = 0; i < 6; i++) { // Spawn Skeleton pieces @@ -156,15 +184,15 @@ void EntitySkeleton(Entity* self) { CreateEntityFromCurrentEntity(0x30, newEntity); newEntity->facingLeft = self->facingLeft; newEntity->params = i; - newEntity->ext.generic.unk88.S8.unk0 = D_80182430[i]; + newEntity->ext.generic.unk88.S8.unk0 = dead_parts_selector[i]; if (self->facingLeft != 0) { - newEntity->posX.i.hi -= D_80182468[i]; + newEntity->posX.i.hi -= dead_parts_pos_x[i]; } else { - newEntity->posX.i.hi += D_80182468[i]; + newEntity->posX.i.hi += dead_parts_pos_x[i]; } - newEntity->posY.i.hi += D_80182474[i]; - newEntity->velocityX = D_80182438[i]; - newEntity->velocityY = D_80182450[i]; + newEntity->posY.i.hi += dead_parts_pos_y[i]; + newEntity->velocityX = dead_parts_velocity_x[i]; + newEntity->velocityY = dead_parts_velocity_y[i]; } else { break; } @@ -178,7 +206,7 @@ void func_801C6494(Entity* entity) { // From skeleton death explosion if (entity->step) { entity->ext.generic.unk88.S8.unk0--; if (entity->ext.generic.unk88.S8.unk0 & 0xFF) { - entity->rotZ += D_80182424[entity->params]; + entity->rotZ += anim_bone_rot[entity->params]; FallEntity(); MoveEntity(); return; @@ -223,7 +251,7 @@ void func_801C6574(Entity* entity) { // Bone Projectile from Skeleton xDistanceToPlayer = GetDistanceToPlayerX(); xDistanceToPlayer /= 32; xDistanceToPlayer = MAX(xDistanceToPlayer, 7); - velocityX = D_80182488[xDistanceToPlayer]; + velocityX = bone_projectile_velocity_x[xDistanceToPlayer]; xDistanceToPlayer = entity->facingLeft; if (xDistanceToPlayer > 0) { diff --git a/src/st/nz0/4672C.c b/src/st/nz0/e_spittle_bone.c similarity index 100% rename from src/st/nz0/4672C.c rename to src/st/nz0/e_spittle_bone.c diff --git a/src/st/nz0/47048.c b/src/st/nz0/e_subweapon_container.c similarity index 100% rename from src/st/nz0/47048.c rename to src/st/nz0/e_subweapon_container.c diff --git a/src/st/nz0/gaibon.c b/src/st/nz0/gaibon.c index 715edb3b17..7103d042d6 100644 --- a/src/st/nz0/gaibon.c +++ b/src/st/nz0/gaibon.c @@ -498,7 +498,7 @@ void EntityGaibon(Entity* self) { case GAIBON_NEAR_DEATH_TRANSFORM: if (AnimateEntity(D_801812FC, self) == 0) { self->ext.GS_Props.flag++; - self->palette = D_80180D36 + self->ext.GS_Props.flag; + self->palette = D_80180D30[3] + self->ext.GS_Props.flag; if (self->ext.GS_Props.flag == 6) { self->flags &= ~0xF; SetStep(4); @@ -516,7 +516,7 @@ void EntityGaibon(Entity* self) { self->flags &= ~0xF; // do-while needed on PSX but not PSP do { - self->palette = D_80180D36; + self->palette = D_80180D30[3]; func_801C29B0(SFX_EXPLODE_SMALL); self->step_s++; } while (0); diff --git a/src/st/nz0/maria.c b/src/st/nz0/maria.c index b6f1d6e882..08e6844a0a 100644 --- a/src/st/nz0/maria.c +++ b/src/st/nz0/maria.c @@ -4,7 +4,7 @@ void func_801B8E0C(Entity* self) { switch (self->step) { case 0: - InitializeEntity(D_80180BEC); + InitializeEntity(g_MariaInit); D_8003C8B8 = 0; g_unkGraphicsStruct.unk0 = 1; g_Player.padSim = PAD_LEFT; @@ -60,7 +60,7 @@ void EntityMaria(Entity* self) { } switch (self->step) { case 0: - InitializeEntity(D_80180BEC); + InitializeEntity(g_MariaInit); self->animSet = ANIMSET_OVL(0xF); self->animCurFrame = 1; self->unk5A = 0x48; diff --git a/src/st/nz0/nz0.h b/src/st/nz0/nz0.h index c9371d6878..4a7acbcbe4 100644 --- a/src/st/nz0/nz0.h +++ b/src/st/nz0/nz0.h @@ -61,7 +61,6 @@ void func_801C4CC0(void); extern u8 D_8003BE6F[]; extern PfnEntityUpdate PfnEntityUpdates[]; extern u16 g_InitializeEntityData0[]; -extern u16 D_80180BEC[]; extern u16 g_EInitGeneric[]; // Init Elevator2 extern u16 g_eInitGeneric2[]; extern u16 D_80180C34[]; @@ -79,28 +78,6 @@ extern s32 D_801826AC; // *** EntityBloodSkeleton properties END *** -// *** EntityBoneScimitar properties START *** - -extern u16 D_80180C4C[]; // Init -extern s32 D_8018208C; // Flag for special bone scimitar to appear or not -extern u8 D_80182090[]; // animation: Walking Forward -extern u8 D_801820A0[]; // animation: Walking Backwards -extern u8 D_801820B0[]; // animation: Swing Sword -extern u8 D_801820CC[]; // animation: Jumping -extern u8 D_801820D8[]; // animation: Landing -extern s8 D_801820F4[]; // Skeleton parts array selector -extern s32 D_801820FC[]; // Skeleton parts velocityX -extern s32 D_80182118[]; // Skeleton parts velocityY -extern u16 D_80182134[]; // Skeleton parts posX -extern u16 D_80182144[]; // Skeleton parts posY -extern s8 D_80182154[2][4]; // Skeleton attack timer cycle -extern s32 D_8018215C; -extern s32 D_8018216C; -extern s32 D_80182174; - -// *** EntityBoneScimitar properties END *** - -extern u16 D_80180C7C[]; extern u16 D_80180C88[]; extern u16 D_80180CAC[]; extern u16 D_80180CC4[]; @@ -207,63 +184,6 @@ extern s16 D_80181EDC[]; extern u32 D_80181EEC[]; extern ObjInit2 D_80182014[]; -// *** EntityAxeKnight properties START *** - -extern u16 D_80180C64[]; // Init -extern s32 D_80182180[]; -extern s32 D_80182188[]; -extern u8 D_80182210[]; // Animation: Walking -extern u8 D_80182220[]; // Animation: Ducking Throw -extern u8 D_80182244[]; // Animation: Standing Throw -extern u8 D_80182268[]; // Animation: Dying -extern s32 D_80182274[]; -extern u8 D_80182284[]; - -// *** EntityAxeKnight properties END *** - -extern s32 D_80182198[]; -extern s32 D_8018219A[]; - -extern u8 D_801822B4[]; -extern u16 D_801822D4[]; -extern const u8 D_801822E4[]; -extern const u8 D_801822EC[]; -extern const u8 D_801822FC[]; -extern const u8 D_80182320[]; -extern const u8 D_80182334[]; -extern const u8 D_8018237C[]; -extern s32 D_801823C4; - -// *** EntitySkeleton properties START *** - -typedef enum { - SKELETON_INIT, - SKELETON_IDLE, - SKELETON_WALK_TOWARDS_PLAYER, - SKELETON_WALK_AWAY_FROM_PLAYER, - SKELETON_ATTACK, - SKELETON_JUMP, - SKELETON_DESTROY -} SKELETON_STEPS; - -extern u8 D_801823DC[]; // animation: Walking Forward -extern u8 D_801823EC[]; // animation: Walking Backwards -extern u8 D_801823FC[]; // animation: Throwing bone -extern u8 D_8018240C[]; // animation: Jumping? -extern u8 D_80182418[]; // animation: Jumping? -extern s8 D_80182430[]; // skeleton pieces array selector -extern s32 D_80182438[]; // velocityX -extern s32 D_80182450[]; // velocityY -extern u16 D_80182468[]; // posX -extern u16 D_80182474[]; // posY -extern u8 D_80182480[2][4]; -extern s32 D_801824A8; -extern s32 D_801824C0; - -// *** EntitySkeleton properties END *** - -extern s32 D_801824B8; -extern s32 D_801824C0; extern s32 D_801824CC; extern s16 D_801824DC[]; extern u8 D_801824E2[]; @@ -271,20 +191,15 @@ extern u16 D_801824E4[]; extern u8 D_80181F30[]; extern u8 D_80180CF4[]; extern s32 D_80182600[]; -extern s32 D_8018216C; -extern s32 D_80182174; extern u16 g_InitializeData0[]; extern u16 D_80180BC8[]; extern u16 D_80181CA8[]; extern u16 D_80181CD8[]; extern u8* g_SubweaponAnimPrizeDrop[]; extern u16 D_80180C94[]; -extern u16 D_80182424[]; extern u16 D_80180CA0[]; -extern u32 D_80182488[]; extern u16 D_80180C58[]; extern u16 D_80180C58[]; -extern s16 D_801820E4[]; extern s32 D_80182504[]; extern u8 D_80182524[]; @@ -345,10 +260,6 @@ extern u8 D_801825F0[]; extern u16 D_80180C70[]; extern u16 D_80180CD0[]; extern u16 D_80180CDC[]; -extern u32 D_801822BC[]; -extern u32 D_801822C8[]; -extern s32 D_8018238C; -extern s32 D_801823A4; extern const char D_801B058C[]; // "charal %x\n" extern const char D_801B0598[]; // "charal %x\n" extern const char D_801B08C8[]; // "charal %x\n" @@ -389,7 +300,7 @@ extern const char D_80183B0C[]; extern u32 g_mariaCutsceneFlags; // EntityMaria, mostly animations -extern u16 D_80180BEC[]; +extern u16 g_MariaInit[]; extern u8 D_80181474[]; extern u8 D_80181490[]; extern u8 D_801814A0[]; diff --git a/src/st/nz0/random.c b/src/st/nz0/random.c deleted file mode 100644 index 04cd68787f..0000000000 --- a/src/st/nz0/random.c +++ /dev/null @@ -1,3 +0,0 @@ -#include - -#include "../random.h" diff --git a/src/st/nz0/3C8EC.c b/src/st/nz0/st_common.c similarity index 81% rename from src/st/nz0/3C8EC.c rename to src/st/nz0/st_common.c index 64de7315f6..9ff89b89a0 100644 --- a/src/st/nz0/3C8EC.c +++ b/src/st/nz0/st_common.c @@ -1,6 +1,41 @@ #include "nz0.h" -#include "../entity.h" +static s16 D_80181978[] = { + 0x0000, 0x0065, 0x00C9, 0x012D, 0x0191, 0x01F5, 0x0259, 0x02BC, 0x031F, + 0x0381, 0x03E3, 0x0444, 0x04A5, 0x0505, 0x0564, 0x05C2, 0x061F, 0x067C, + 0x06D7, 0x0732, 0x078B, 0x07E3, 0x083A, 0x088F, 0x08E4, 0x0937, 0x0988, + 0x09D8, 0x0A26, 0x0A73, 0x0ABF, 0x0B08, 0x0B50, 0x0B97, 0x0BDB, 0x0C1E, + 0x0C5E, 0x0C9D, 0x0CDA, 0x0D15, 0x0D4E, 0x0D85, 0x0DB9, 0x0DEC, 0x0E1C, + 0x0E4B, 0x0E77, 0x0EA1, 0x0EC8, 0x0EEE, 0x0F11, 0x0F31, 0x0F50, 0x0F6C, + 0x0F85, 0x0F9C, 0x0FB1, 0x0FC4, 0x0FD4, 0x0FE1, 0x0FEC, 0x0FF5, 0x0FFB, + 0x0FFF, 0x1000, 0x0FFF, 0x0FFB, 0x0FF5, 0x0FEC, 0x0FE1, 0x0FD4, 0x0FC4, + 0x0FB1, 0x0F9C, 0x0F85, 0x0F6C, 0x0F50, 0x0F31, 0x0F11, 0x0EEE, 0x0EC8, + 0x0EA1, 0x0E77, 0x0E4B, 0x0E1C, 0x0DEC, 0x0DB9, 0x0D85, 0x0D4E, 0x0D15, + 0x0CDA, 0x0C9D, 0x0C5E, 0x0C1E, 0x0BDB, 0x0B97, 0x0B50, 0x0B08, 0x0ABF, + 0x0A73, 0x0A26, 0x09D8, 0x0988, 0x0937, 0x08E4, 0x088F, 0x083A, 0x07E3, + 0x078B, 0x0732, 0x06D7, 0x067C, 0x061F, 0x05C2, 0x0564, 0x0505, 0x04A5, + 0x0444, 0x03E3, 0x0381, 0x031F, 0x02BC, 0x0259, 0x01F5, 0x0191, 0x012D, + 0x00C9, 0x0065, 0x0000, 0xFF9B, 0xFF37, 0xFED3, 0xFE6F, 0xFE0B, 0xFDA7, + 0xFD44, 0xFCE1, 0xFC7F, 0xFC1D, 0xFBBC, 0xFB5B, 0xFAFB, 0xFA9C, 0xFA3E, + 0xF9E1, 0xF984, 0xF929, 0xF8CE, 0xF875, 0xF81D, 0xF7C6, 0xF771, 0xF71C, + 0xF6C9, 0xF678, 0xF628, 0xF5DA, 0xF58D, 0xF541, 0xF4F8, 0xF4B0, 0xF469, + 0xF425, 0xF3E2, 0xF3A2, 0xF363, 0xF326, 0xF2EB, 0xF2B2, 0xF27B, 0xF247, + 0xF214, 0xF1E4, 0xF1B5, 0xF189, 0xF15F, 0xF138, 0xF112, 0xF0EF, 0xF0CF, + 0xF0B0, 0xF094, 0xF07B, 0xF064, 0xF04F, 0xF03C, 0xF02C, 0xF01F, 0xF014, + 0xF00B, 0xF005, 0xF001, 0xF000, 0xF001, 0xF005, 0xF00B, 0xF014, 0xF01F, + 0xF02C, 0xF03C, 0xF04F, 0xF064, 0xF07B, 0xF094, 0xF0B0, 0xF0CF, 0xF0EF, + 0xF112, 0xF138, 0xF15F, 0xF189, 0xF1B5, 0xF1E4, 0xF214, 0xF247, 0xF27B, + 0xF2B2, 0xF2EB, 0xF326, 0xF363, 0xF3A2, 0xF3E2, 0xF425, 0xF469, 0xF4B0, + 0xF4F8, 0xF541, 0xF58D, 0xF5DA, 0xF628, 0xF678, 0xF6C9, 0xF71C, 0xF771, + 0xF7C6, 0xF81D, 0xF875, 0xF8CE, 0xF929, 0xF984, 0xF9E1, 0xFA3E, 0xFA9C, + 0xFAFB, 0xFB5B, 0xFBBC, 0xFC1D, 0xFC7F, 0xFCE1, 0xFD44, 0xFDA7, 0xFE0B, + 0xFE6F, 0xFED3, 0xFF37, 0xFF9B, +}; + +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" u8 func_801BCAD4(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; diff --git a/src/st/nz0/st_update.c b/src/st/nz0/st_update.c new file mode 100644 index 0000000000..8477b24783 --- /dev/null +++ b/src/st/nz0/st_update.c @@ -0,0 +1,16 @@ +#include + +static u16 UNK_Invincibility0[] = { + PAL_OVL(0x163), PAL_OVL(0x164), PAL_OVL(0x166), PAL_OVL(0x164), + PAL_OVL(0x160), PAL_OVL(0x166), PAL_OVL(0x162), PAL_OVL(0x164), + PAL_OVL(0x167), PAL_OVL(0x164), PAL_OVL(0x167), PAL_OVL(0x168), + PAL_OVL(0x168), PAL_OVL(0x164), PAL_OVL(0x161), PAL_OVL(0x164), + PAL_OVL(0x165), PAL_OVL(0x165), PAL_OVL(0x163), PAL_OVL(0x163), + PAL_OVL(0x165), PAL_OVL(0x165), +}; + +#include "../random.h" + +#include "../update.h" + +#include "../update_stage_entities.h" diff --git a/src/st/nz0/update.c b/src/st/nz0/update.c deleted file mode 100644 index e447681b8d..0000000000 --- a/src/st/nz0/update.c +++ /dev/null @@ -1 +0,0 @@ -#include "../update.h" diff --git a/src/st/nz0/update_stage_entities.c b/src/st/nz0/update_stage_entities.c deleted file mode 100644 index 8886987cb8..0000000000 --- a/src/st/nz0/update_stage_entities.c +++ /dev/null @@ -1,3 +0,0 @@ -#include - -#include "../update_stage_entities.h" diff --git a/src/st/rwrp/e_init.c b/src/st/rwrp/e_init.c index 60b6078400..3679278d7a 100644 --- a/src/st/rwrp/e_init.c +++ b/src/st/rwrp/e_init.c @@ -82,7 +82,7 @@ ObjInit2 D_801804E0[] = { // Owned by EntityRedDoor to animate the tiles behind the door itself. // There is a loop in EntityRedDoor that forces to write those tiles // at every frame based on the door state to create the animation. -u16 g_eRedDoorTiles[2][8] = { +u16 g_eRedDoorTiles[][8] = { {0x7D, 0x75, 0x25, 0x1D, 0xC9, 0xC8, 0xC7, 0xC6}, {0x7F, 0x77, 0x27, 0x1F, 0xCD, 0xCC, 0xCB, 0xCA}, }; diff --git a/src/st/st0/34908.c b/src/st/st0/34908.c index d35dab4cca..ac54f5a164 100644 --- a/src/st/st0/34908.c +++ b/src/st/st0/34908.c @@ -1,8 +1,11 @@ #include "st0.h" - -#include "../entity.h" #include "sfx.h" +#include "../../destroy_entity.h" +#include "../../destroy_entities_from_index.h" +#include "../prevent_entity_from_respawning.h" +#include "../animate_entity.h" + u8 func_801B4AF0(u8 frames[], Entity* self, u8 arg2) { u16 animFrameStart = self->animFrameIdx * 2; u8* var_s1 = &frames[animFrameStart]; diff --git a/src/st/wrp/e_init.c b/src/st/wrp/e_init.c index 62a05e0450..7615bc4ed4 100644 --- a/src/st/wrp/e_init.c +++ b/src/st/wrp/e_init.c @@ -43,6 +43,8 @@ u16 g_InitializeData0[] = { }; u16 g_InitializeEntityData0[] = { 0x0003, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, +}; +u16 g_MariaInit[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, }; u16 g_EInitGeneric[] = { @@ -80,7 +82,7 @@ ObjInit2 D_801804E0[] = { // Owned by EntityRedDoor to animate the tiles behind the door itself. // There is a loop in EntityRedDoor that forces to write those tiles // at every frame based on the door state to create the animation. -u16 g_eRedDoorTiles[2][8] = { +u16 g_eRedDoorTiles[][8] = { {0x1D, 0x25, 0x75, 0x7D, 0xC6, 0xC7, 0xC8, 0xC9}, {0x1F, 0x27, 0x77, 0x7F, 0xCA, 0xCB, 0xCC, 0xCD}, }; diff --git a/src/st/wrp_psp/wrp_data_F7B0.c b/src/st/wrp_psp/wrp_data_F7B0.c index 1546583e12..26e1b39da3 100644 --- a/src/st/wrp_psp/wrp_data_F7B0.c +++ b/src/st/wrp_psp/wrp_data_F7B0.c @@ -1,6 +1,6 @@ #include "../wrp/wrp.h" -u16 g_eRedDoorTiles[2][8] = { +u16 g_eRedDoorTiles[][8] = { {0x1D, 0x25, 0x75, 0x7D, 0xC6, 0xC7, 0xC8, 0xC9}, {0x1F, 0x27, 0x77, 0x7F, 0xCA, 0xCB, 0xCC, 0xCD}, };