diff --git a/src/entity.c b/src/entity.c index 41d9b4f1..79040e23 100644 --- a/src/entity.c +++ b/src/entity.c @@ -22,6 +22,7 @@ extern void sub_08017744(Entity*); extern void UnloadHitbox(); extern void sub_0804AA1C(); +void ClearDeletedEntity(Entity*); extern void _ClearAndUpdateEntities(); extern void UpdateEntities_arm(u32); @@ -232,7 +233,68 @@ void EraseAllEntities() { gUnk_03000000.unk[1].unk6 = 1; } -ASM_FUNC("./asm/getEmptyEntity.s", Entity* GetEmptyEntity()); +extern Entity gUnk_030015A0[0x48]; +extern Entity gUnk_03003BE0; + +NONMATCH("./asm/getEmptyEntity.s", Entity* GetEmptyEntity()) { + u8 flags_ip; + Entity* ptr; + Entity* end; + Entity* rv; + Entity* currentEnt; + LinkedList* nextList; + + LinkedList* listPtr; + LinkedList* endListPtr; + + if (gEntCount <= 0x46) { + ptr = gUnk_030015A0; + end = ptr + ARRAY_COUNT(gUnk_030015A0); + + do { + if (ptr->prev == 0) { + return ptr; + } + } while (++ptr < end); + } + + ptr = &gPlayerEntity; + + do { + if ((s32)ptr->prev < 0 && (ptr->flags & 0xc) && ptr != gUpdateContext.current_entity) { + ClearDeletedEntity(ptr); + return ptr; + } + } while (++ptr < &gUnk_03003BE0); + + flags_ip = 0; + rv = NULL; + listPtr = gEntityLists; + endListPtr = listPtr + ARRAY_COUNT(gEntityLists); + + do { + currentEnt = listPtr->first; + nextList = listPtr + 1; + while ((u32)currentEnt != (u32)listPtr) { + if (currentEnt->kind != MANAGER && flags_ip < (currentEnt->flags & 0x1c) && + gUpdateContext.current_entity != currentEnt) { + flags_ip = currentEnt->flags & 0x1c; + rv = currentEnt; + } + currentEnt = currentEnt->next; + } + + listPtr = nextList; + } while (listPtr < endListPtr); + + if (rv) { + DeleteEntity(rv); + ClearDeletedEntity(rv); + } + + return rv; +} +END_NONMATCH extern Entity gUnk_030011E8[7]; @@ -308,8 +370,6 @@ void DeleteEntity(Entity* ent) { } } -void ClearDeletedEntity(Entity*); - void ClearAllDeletedEntities(void) { Entity* ent = &gPlayerEntity; do { diff --git a/src/interrupts.c b/src/interrupts.c index 90556e62..2993fffb 100644 --- a/src/interrupts.c +++ b/src/interrupts.c @@ -17,7 +17,7 @@ extern u16* gUnk_02025EB0; extern u16* gUnk_0200B650; extern u8 gUpdateVisibleTiles; extern u8 gUnk_03003DF0[]; -extern u8 gUnk_03003BE0; +extern Entity gUnk_03003BE0; extern Entity* gPlayerClones[3]; extern u16 gUnk_080B2CD8[];