NP3 EntityBloodyZombie + docs (#203)

Enemy: Bloody Zombie

![image](https://user-images.githubusercontent.com/96613413/235222802-a693edc6-c5f3-430c-a5be-85ae1337fa53.png)
It turns out that this enemy was already decompiled by me in NZ0
(Alchemy Laboratory), but it was incorrectly labeled as
EntityBloodDrips. I did get a chance to document and understand it
better this time though.
This commit is contained in:
Alejandro Asenjo Nitti 2023-04-29 04:25:11 -03:00 committed by GitHub
parent 9532b90fc5
commit 2a4e3d6f0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 505 additions and 219 deletions

View File

@ -54,11 +54,13 @@ segments:
- [0x31FB0, rodata]
- [0x3208C, .rodata, 4997C]
- [0x320A0, .rodata, 49BC8]
- [0x320B4, rodata]
- [0x320B4, .rodata, 4A654]
- [0x320DC, rodata]
- [0x32360, rodata]
- [0x3246C, c]
- [0x3DEF4, c]
- [0x4997C, c]
- [0x49BC8, c]
- [0x4A654, c]
- [0x52768, data]
- [0x53434]

View File

@ -40,6 +40,9 @@ DestroyEntity = 0x801BC4D4;
DestroyEntityFromIndex = 0x801BC540;
PreventEntityFromRespawning = 0x801BC5BC;
AnimateEntity = 0x801BC604;
GetPlayerDistanceX = 0x801BC7D4;
GetPlayerDistanceY = 0x801BC810;
GetPlayerSide = 0x801BC844;
MoveEntity = 0x801BC888;
FallEntity = 0x801BC8B8;
AllocEntity = 0x801BCD44;
@ -74,3 +77,4 @@ EntityBloodSplatter = 0x801C9F98;
EntityBat = 0x801C997C;
EntityZombie = 0x801C9BC8;
EntityUnkId4D = 0x801C9E28;
EntityBloodyZombie = 0x801CA654;

View File

@ -94,7 +94,7 @@ EntityLeftSecretRoomWall = 0x801B14C4;
EntityBottomSecretRoomFloor = 0x801B1770;
EntityAxeKnight = 0x801C45BC;
EntityAxeKnightThrowingAxe = 0x801C4D18;
EntityBloodDrips = 0x801C5568;
EntityBloodyZombie = 0x801C5568;
EntityBloodSplatter = 0x801C4EAC;
EntitySkeleton = 0x801C5FC4;
EntitySpittleBone = 0x801C672C;

View File

@ -290,10 +290,10 @@ typedef struct Entity {
/* 0x3E */ s16 hitPoints;
/* 0x40 */ s16 attack;
/* 0x42 */ s16 attackElement;
/* 0x44 */ u16 unk44;
/* 0x44 */ u16 unk44; // 1 = Takes a hit
/* 0x46 */ u8 hitboxWidth;
/* 0x47 */ u8 hitboxHeight;
/* 0x48 */ u8 unk48; // 1 = took hit
/* 0x48 */ u8 unk48; // 1 = Takes a hit
/* 0x49 */ u8 unk49; // invincibility frames
/* 0x4A */ s16 unk4A;
/* 0x4C */ AnimationFrame* unk4C;

View File

@ -140,6 +140,7 @@ typedef enum { MONO_SOUND, STEREO_SOUND } soundMode;
// This sound plays when MAX UP spawns and during Dracula transformation
#define NA_SE_UNK_62F 0x62F
#define NA_SE_EV_HEAVY_BLOCK_DRAG 0x609
#define NA_SE_EN_BLOOD_ZOMBIE_SWORD_SLASH 0x60B
#define NA_SE_AL_BACKSLIDE 0x617
#define NA_SE_EV_VASE_BREAK 0x61D
#define NA_SE_PL_BT_ECHO 0x61F
@ -160,6 +161,7 @@ typedef enum { MONO_SOUND, STEREO_SOUND } soundMode;
#define NA_SE_PL_BT_FIREBALL 0x680
#define NA_SE_PL_MAX_HP_MP_INCREASED 0x687
#define NA_SE_BREAK_GLASS 0x68B
#define NA_SE_EN_EXPLOSIVE_DEATH 0x693
#define NA_SE_EV_CLOCK_TICK 0x6A1
#define NA_SE_PL_COLLECT_GOLD 0x6A9
#define NA_SE_EN_SKELETON_THROW_BONE 0x6C8
@ -170,6 +172,10 @@ typedef enum { MONO_SOUND, STEREO_SOUND } soundMode;
#define NA_SE_VO_AL_SOUL_STEAL 0x6F4
#define NA_SE_VO_AL_DYING 0x6F6
#define NA_SE_VO_WO_BARK 0x706
#define NA_SE_EN_BLOODY_ZOMBIE_INJURED_SCREAM 0x746
#define NA_SE_EN_BLOODY_ZOMBIE_DEATH_SCREAM 0x747
#define NA_SE_EN_BLOODY_ZOMBIE_INJURED 0x748
#define NA_SE_EN_BLOODY_ZOMBIE_HEMORRHAGE 0x749
#define NA_SE_VO_AXE_KNIGHT_THROW 0x766
#define NA_SE_VO_AXE_KNIGHT_SCREAM 0x767
#define NA_SE_BO_DEFEATED 0x7D2

View File

@ -1422,7 +1422,10 @@ void PreventEntityFromRespawning(Entity* entity) {
INCLUDE_ASM("asm/us/st/np3/nonmatchings/3246C", func_801BC6BC);
s32 func_801BC7D4(void) {
/*
* Returns the absolute distance from g_CurrentEntity to player in the X Axis
*/
s32 GetPlayerDistanceX(void) {
s16 yDistance = g_CurrentEntity->posX.i.hi - PLAYER.posX.i.hi;
if (yDistance < 0) {
@ -1431,7 +1434,10 @@ s32 func_801BC7D4(void) {
return yDistance;
}
s32 func_801BC810(void) {
/*
* Returns the absolute distance from g_CurrentEntity to player in the Y Axis
*/
s32 GetPlayerDistanceY(void) {
s32 yDistance = g_CurrentEntity->posY.i.hi - PLAYER.posY.i.hi;
if (yDistance < 0) {
@ -1440,13 +1446,19 @@ s32 func_801BC810(void) {
return yDistance;
}
s16 func_801BC844(void) {
s16 var_a0 = g_CurrentEntity->posX.i.hi > PLAYER.posX.i.hi;
/**
* Returns the player's side position relative to g_CurrentEntity
* 0 = Player is on the right side
* 1 = Player is on the left side
* 2 = Player is above
*/
s16 GetPlayerSide(void) {
s16 side = g_CurrentEntity->posX.i.hi > PLAYER.posX.i.hi;
if (g_CurrentEntity->posY.i.hi > PLAYER.posY.i.hi) {
var_a0 |= 2;
side |= 2;
}
return var_a0;
return side;
}
void MoveEntity(void) {
@ -1466,12 +1478,12 @@ INCLUDE_ASM("asm/us/st/np3/nonmatchings/3246C", func_801BCB5C);
Entity* AllocEntity(Entity* start, Entity* end) {
Entity* current = start;
while (current < end) {
if (current->objectId == 0) {
DestroyEntity(current);
return current;
}
current++;
}
return NULL;
@ -1588,14 +1600,13 @@ void EntityDummy(Entity* arg0) {
}
s32 func_801BD308(u16* hitSensors, s16 sensorCount) {
s32 accelerationX = g_CurrentEntity->accelerationX;
Collider collider;
s16 i;
s32 accelerationX;
u16 temp_a1;
s16 x;
s16 y;
s16 i;
accelerationX = g_CurrentEntity->accelerationX;
if (accelerationX != 0) {
x = g_CurrentEntity->posX.i.hi;
y = g_CurrentEntity->posY.i.hi;

View File

@ -1188,8 +1188,8 @@ void func_801C90E8(void) {
return;
}
if ((g_CurrentEntity->unk7C.U8.unk0) == 0) {
if (func_801BC7D4() < 64) {
if (g_CurrentEntity->facing != (func_801BC844() & 1)) {
if (GetPlayerDistanceX() < 64) {
if (g_CurrentEntity->facing != (GetPlayerSide() & 1)) {
func_801BD114(4);
}
}

View File

@ -23,17 +23,17 @@ void EntityBat(Entity* entity) {
break;
case 1:
xDistance = func_801BC7D4();
yDistance = func_801BC810();
xDistance = GetPlayerDistanceX();
yDistance = GetPlayerDistanceY();
if ((xDistance < 0x60) && (yDistance < 0x60) &&
!(func_801BC844() & 2)) {
!(GetPlayerSide() & 2)) {
entity->step++;
}
break;
case 2:
if (AnimateEntity(&D_80182570, entity) == 0) {
entity->facing = (func_801BC844() & 1) ^ 1;
entity->facing = (GetPlayerSide() & 1) ^ 1;
entity->accelerationY = 0xE000;
if (entity->facing != 0) {
entity->accelerationX = 0x4000;
@ -49,7 +49,7 @@ void EntityBat(Entity* entity) {
case 3:
AnimateEntity(&D_80182554, entity);
MoveEntity();
if (func_801BC810() < 0x20) {
if (GetPlayerDistanceY() < 0x20) {
if (entity->facing == 0) {
entity->accelerationX = -0x10000;
} else {

View File

@ -37,7 +37,7 @@ void EntityZombie(Entity* self) {
case 1:
if (func_801BC8E4(D_801825BC) & 1) {
self->facing = (func_801BC844() & 1) ^ 1;
self->facing = (GetPlayerSide() & 1) ^ 1;
self->step++;
}
break;
@ -260,198 +260,3 @@ void EntityBloodSplatter(Entity* self) {
}
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CA498);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CA654);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CAE0C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CB018);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CBF18);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CC2E0);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD540);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD620);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD658);
void func_801CD734() {
while (PadRead(0))
func_801CD658();
while (!PadRead(0))
func_801CD658();
}
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD78C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD83C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CD91C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDA14);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDA6C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDAC8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDC80);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDD00);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDD80);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDE10);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDE88);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDF1C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CDFD8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE04C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE120);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE1E8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE228);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE258);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE2CC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE3FC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE4CC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CE69C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CF254);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CF5B8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CF778);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CF7A0);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801CF94C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D0730);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D0A00);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D0B40);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D0B78);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D0D40);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D1BB8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D1F38);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D2320);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D2470);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/49BC8", func_801D24A0);
POLY_GT4* func_801D251C(POLY_GT4* startPoly, s32 count) {
POLY_GT4* poly;
s8 unk;
s32 i;
if (startPoly->p3) {
startPoly->p3 = 0;
} else {
startPoly->p3 = 1;
}
poly = startPoly;
for (i = 0; i < count; i++) {
if (poly->p3) {
poly->pad3 &= ~8;
unk = 0;
} else {
poly->pad3 |= 8;
unk = 1;
}
poly = (POLY_GT4*)poly->tag;
if (poly == 0)
return 0;
poly->p3 = unk;
}
return poly;
}
void func_801D25A4(POLY_GT4* arg0) {
arg0->p1 = 0;
arg0->p2 = 0;
arg0->p3 = 0;
((POLY_GT4*)arg0->tag)->x1 = 0;
((POLY_GT4*)arg0->tag)->y1 = 0;
((POLY_GT4*)arg0->tag)->y0 = 0;
((POLY_GT4*)arg0->tag)->x0 = 0;
((POLY_GT4*)arg0->tag)->clut = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->u0 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->b1 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->r1 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->u1 = 0;
((POLY_GT4*)arg0->tag)->tpage = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->r2 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->b2 = 0;
((POLY_GT4*)arg0->tag)->u2 = 0;
((POLY_GT4*)arg0->tag)->v2 = 0;
((POLY_GT4*)arg0->tag)->r3 = 0;
((POLY_GT4*)arg0->tag)->b3 = 0;
((POLY_GT4*)arg0->tag)->x2 = 0;
((POLY_GT4*)arg0->tag)->y2 = 0;
}
void func_801D2684(POLY_GT4* arg0) {
func_801D25A4(arg0);
arg0->p3 = 8;
((POLY_GT4*)arg0->tag)->p3 = 1;
((POLY_GT4*)arg0->tag)->code = 2;
((POLY_GT4*)arg0->tag)->pad3 = 0xA;
}
void func_801D26D8(POLY_GT4* arg0) {
arg0->p3 = 0;
arg0->pad3 = 8;
((POLY_GT4*)arg0->tag)->p3 = 0;
((POLY_GT4*)arg0->tag)->code = 4;
((POLY_GT4*)arg0->tag)->pad3 = 8;
}
s32 func_801D2704(s32 arg0, u8 arg1) {
s32 var_v0;
s32 ret = 0;
u8* var_a0 = arg0 + 4;
u8* var_v1;
s32 i;
for (i = 0; i < 4; i++) {
var_v1 = var_a0;
do {
var_v0 = *var_v1 - arg1;
if (var_v0 < 0) {
var_v0 = 0;
} else {
ret |= 1;
}
*var_v1 = var_v0;
var_v1++;
} while (((s32)var_v1 < ((s32)var_a0 + 3)));
var_a0 += 0xC;
}
return ret;
}

431
src/st/np3/4A654.c Normal file
View File

@ -0,0 +1,431 @@
#include "np3.h"
void EntityBloodyZombie(Entity* self) {
Primitive** primPtrPtr;
Primitive* prim;
Entity* newEntity;
s16 firstPrimIndex;
s32 animStatus;
s32 facing;
if ((self->unk44) && (self->step & 1)) {
func_801C2598(NA_SE_EN_BLOODY_ZOMBIE_INJURED_SCREAM);
func_801C2598(NA_SE_EN_BLOODY_ZOMBIE_INJURED);
func_801BD114(BLOODY_ZOMBIE_TAKE_HIT);
}
if ((self->flags & 0x100) && (self->step < 8)) {
func_801C2598(NA_SE_EN_BLOODY_ZOMBIE_DEATH_SCREAM);
self->unk3C = 0;
self->flags &= 0xDFFFFFFF;
func_801BD114(BLOODY_ZOMBIE_DYING);
}
switch (self->step) {
case BLOODY_ZOMBIE_INIT:
InitializeEntity(D_80180B38);
self->unk10 = 1;
self->unk12 = 4;
func_801BD114(BLOODY_ZOMBIE_UNK_2);
break;
case BLOODY_ZOMBIE_UNK_2:
if (func_801BC8E4(&D_801825D4) & 1) {
func_801BD114(BLOODY_ZOMBIE_WALK);
}
break;
case BLOODY_ZOMBIE_WALK:
if (self->unk2E == 0) {
self->unk80.modeS16.unk0 = 128;
self->unk2E++;
}
AnimateEntity(D_801825EC, self);
func_801BCB5C(D_801825E4);
if (self->facing == 0) {
self->accelerationX = -0x6000;
} else {
self->accelerationX = 0x6000;
}
if (--self->unk80.modeS16.unk0 == 0) {
self->unk80.modeS16.unk0 = 128;
self->facing ^= 1;
}
if (!(Random() % 64)) { // Drop BloodDrips from the enemy knife
newEntity = AllocEntity(D_8007D858, &D_8007D858[32]);
if (newEntity != NULL) {
CreateEntityFromEntity(0x49, self, newEntity);
if (self->facing != 0) {
newEntity->posX.i.hi += 16;
} else {
newEntity->posX.i.hi -= 16;
}
newEntity->posY.i.hi += 12;
}
}
facing = (GetPlayerSide() & 1);
if ((PLAYER.facing == facing) && (GetPlayerDistanceX() < 128)) {
self->facing = facing ^ 1;
func_801BD114(BLOODY_ZOMBIE_CHASE);
}
break;
case BLOODY_ZOMBIE_CHASE:
if (AnimateEntity(D_8018267C, self) == 0) {
facing = self->facing = (GetPlayerSide() & 1) ^ 1;
}
func_801BCB5C(D_801825E4);
if (self->facing != 0) {
self->accelerationX = 0xC000;
} else {
self->accelerationX = -0xC000;
}
if (!(Random() % 64)) { // Drop BloodDrips from the enemy knife
newEntity = AllocEntity(D_8007D858, &D_8007D858[32]);
if (newEntity != NULL) {
CreateEntityFromEntity(0x49, self, newEntity);
if (self->facing != 0) {
newEntity->posX.i.hi += 18;
} else {
newEntity->posX.i.hi -= 18;
}
newEntity->posY.i.hi += 12;
}
}
if (GetPlayerDistanceX() < 40) {
func_801BD114(BLOODY_ZOMBIE_ATTACK);
}
break;
case BLOODY_ZOMBIE_ATTACK:
animStatus = AnimateEntity(D_801825FC, self);
if ((animStatus & 0x80) && (self->animFrameIdx == 10)) {
func_801C2598(NA_SE_EN_BLOOD_ZOMBIE_SWORD_SLASH);
}
if (animStatus == 0) {
func_801BD114(BLOODY_ZOMBIE_WALK);
}
break;
case BLOODY_ZOMBIE_TAKE_HIT:
if (self->unk2E == 0) {
// Splat blood
newEntity = AllocEntity(D_8007D858, &D_8007D858[32]);
if (newEntity != NULL) {
CreateEntityFromEntity(0x4A, self, newEntity);
newEntity->facing = GetPlayerSide() & 1;
}
self->unk2E++;
}
if (AnimateEntity(D_80182620, self) == 0) {
func_801BD114(BLOODY_ZOMBIE_WALK);
self->unk2E++;
}
break;
case BLOODY_ZOMBIE_DYING:
if (self->unk2E == 0) {
firstPrimIndex = g_api.AllocPrimitives(PRIM_GT4, 0x14);
if (firstPrimIndex == -1) {
DestroyEntity(self);
return;
}
self->firstPolygonIndex = firstPrimIndex;
prim = &g_PrimBuf[firstPrimIndex];
*(s32*)&self->unk7C = prim;
self->flags |= FLAG_FREE_POLYGONS;
self->unk2E++;
}
if (self->animFrameIdx < 13) {
if (!(g_blinkTimer % 8)) {
func_801C2598(NA_SE_EN_BLOODY_ZOMBIE_HEMORRHAGE);
newEntity = AllocEntity(D_8007D858, &D_8007D858[32]);
if (newEntity != NULL) {
CreateEntityFromEntity(0x4A, self, newEntity);
newEntity->facing = self->unk84.U8.unk0;
if (self->facing != 0) {
newEntity->posX.i.hi -= 4;
} else {
newEntity->posX.i.hi += 4;
}
newEntity->posY.i.hi += 4;
}
self->unk84.U8.unk0 ^= 1;
}
self->unk80.modeS16.unk0 = 0;
} else {
if (self->unk80.modeS16.unk0 == 0) {
func_801C2598(NA_SE_EN_BLOODY_ZOMBIE_HEMORRHAGE);
}
self->unk80.modeS16.unk0++;
if (!(g_blinkTimer & 3)) {
primPtrPtr = func_801D24A0(*(s32*)&self->unk7C, 2);
if (primPtrPtr != NULL) {
func_801D2684(primPtrPtr);
(*primPtrPtr)->r3 = self->unk84.U8.unk0;
}
self->unk84.U8.unk0 ^= 1;
}
}
if (self->flags & FLAG_FREE_POLYGONS) {
prim = *(s32*)&self->unk7C;
while (prim != NULL) {
if (prim->p3 & 8) {
func_801CA498(prim);
}
prim = prim->next;
}
}
if (AnimateEntity(D_80182634, self) == 0) {
newEntity = AllocEntity(D_8007D858, &D_8007D858[32]);
if (newEntity != NULL) {
CreateEntityFromEntity(2, self, newEntity);
newEntity->subId = 2;
newEntity->posY.i.hi += 16;
if (self->facing != 0) {
newEntity->posX.i.hi -= 8;
} else {
newEntity->posX.i.hi += 8;
}
}
self->unk80.modeS16.unk0 = 64;
self->animCurFrame = 0;
func_801C2598(NA_SE_EN_EXPLOSIVE_DEATH);
self->step++;
}
break;
case BLOODY_ZOMBIE_DESTROY:
if (self->flags & FLAG_FREE_POLYGONS) {
prim = *(s32*)&self->unk7C;
while (prim != NULL) {
if (prim->p3 & 8) {
func_801CA498(prim);
}
prim = prim->next;
}
}
if (--self->unk80.modeS16.unk0 == 0) {
DestroyEntity(self);
}
break;
}
if ((u32)((u16)self->animCurFrame - 11) < 2) {
self->hitboxWidth = 18;
self->hitboxHeight = 12;
*(s16*)&self->unk10 = -12;
self->unk12 = -12;
} else {
self->hitboxWidth = 4;
self->hitboxHeight = 22;
self->unk10 = 1;
self->unk12 = 4;
}
}
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CAE0C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CB018);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CBF18);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CC2E0);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD540);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD620);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD658);
void func_801CD734() {
while (PadRead(0))
func_801CD658();
while (!PadRead(0))
func_801CD658();
}
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD78C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD83C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CD91C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDA14);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDA6C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDAC8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDC80);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDD00);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDD80);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDE10);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDE88);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDF1C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CDFD8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE04C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE120);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE1E8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE228);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE258);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE2CC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE3FC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE4CC);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CE69C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CF254);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CF5B8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CF778);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CF7A0);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801CF94C);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D0730);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D0A00);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D0B40);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D0B78);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D0D40);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D1BB8);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D1F38);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D2320);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D2470);
INCLUDE_ASM("asm/us/st/np3/nonmatchings/4A654", func_801D24A0);
POLY_GT4* func_801D251C(POLY_GT4* startPoly, s32 count) {
POLY_GT4* poly;
s8 unk;
s32 i;
if (startPoly->p3) {
startPoly->p3 = 0;
} else {
startPoly->p3 = 1;
}
poly = startPoly;
for (i = 0; i < count; i++) {
if (poly->p3) {
poly->pad3 &= ~8;
unk = 0;
} else {
poly->pad3 |= 8;
unk = 1;
}
poly = (POLY_GT4*)poly->tag;
if (poly == 0)
return 0;
poly->p3 = unk;
}
return poly;
}
void func_801D25A4(POLY_GT4* arg0) {
arg0->p1 = 0;
arg0->p2 = 0;
arg0->p3 = 0;
((POLY_GT4*)arg0->tag)->x1 = 0;
((POLY_GT4*)arg0->tag)->y1 = 0;
((POLY_GT4*)arg0->tag)->y0 = 0;
((POLY_GT4*)arg0->tag)->x0 = 0;
((POLY_GT4*)arg0->tag)->clut = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->u0 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->b1 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->r1 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->u1 = 0;
((POLY_GT4*)arg0->tag)->tpage = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->r2 = 0;
*(u16*)&((POLY_GT4*)arg0->tag)->b2 = 0;
((POLY_GT4*)arg0->tag)->u2 = 0;
((POLY_GT4*)arg0->tag)->v2 = 0;
((POLY_GT4*)arg0->tag)->r3 = 0;
((POLY_GT4*)arg0->tag)->b3 = 0;
((POLY_GT4*)arg0->tag)->x2 = 0;
((POLY_GT4*)arg0->tag)->y2 = 0;
}
void func_801D2684(POLY_GT4* arg0) {
func_801D25A4(arg0);
arg0->p3 = 8;
((POLY_GT4*)arg0->tag)->p3 = 1;
((POLY_GT4*)arg0->tag)->code = 2;
((POLY_GT4*)arg0->tag)->pad3 = 0xA;
}
void func_801D26D8(POLY_GT4* arg0) {
arg0->p3 = 0;
arg0->pad3 = 8;
((POLY_GT4*)arg0->tag)->p3 = 0;
((POLY_GT4*)arg0->tag)->code = 4;
((POLY_GT4*)arg0->tag)->pad3 = 8;
}
s32 func_801D2704(s32 arg0, u8 arg1) {
s32 var_v0;
s32 ret = 0;
u8* var_a0 = arg0 + 4;
u8* var_v1;
s32 i;
for (i = 0; i < 4; i++) {
var_v1 = var_a0;
do {
var_v0 = *var_v1 - arg1;
if (var_v0 < 0) {
var_v0 = 0;
} else {
ret |= 1;
}
*var_v1 = var_v0;
var_v1++;
} while (((s32)var_v1 < ((s32)var_a0 + 3)));
var_a0 += 0xC;
}
return ret;
}

View File

@ -5,7 +5,7 @@ extern void ReplaceBreakableWithItemDrop(Entity*);
extern s32 func_801BCB5C(u16* arg0);
extern s32 func_801BD308(u16* hitSensors, s16 sensorCount);
extern s32 func_801BD588(Entity* arg0, s32 arg1, s32 arg2, s32 arg3);
extern s32 func_801BC7D4(void);
extern s32 GetPlayerDistanceX(void);
extern void func_801C2598(s16 arg0);
extern s32 func_801CD658();
extern void EntityPrizeDrop(Entity* entity);
@ -80,6 +80,33 @@ extern u8 D_80182594[];
extern u8 D_801825A8[];
extern u8 D_801825BC[];
extern u16 D_801825CC;
// *** EntityBloodyZombie properties START ***
typedef enum {
BLOODY_ZOMBIE_INIT,
BLOODY_ZOMBIE_WALK,
BLOODY_ZOMBIE_UNK_2,
BLOODY_ZOMBIE_CHASE,
BLOODY_ZOMBIE_ATTACK,
BLOODY_ZOMBIE_TAKE_HIT = 6,
BLOODY_ZOMBIE_DYING = 8,
BLOODY_ZOMBIE_DESTROY
} EntityBloodyZombieSteps;
extern u16 D_80180B38[]; // InitProps
extern s32 D_801825D4;
extern u16 D_801825E4[];
extern u8 D_801825EC[]; // Animation: Walking
extern u8 D_801825FC[]; // Animation: Bloody Zombie sword slash
extern u8 D_80182620[]; // Animation: Recoil from being hit
extern u8 D_80182634[]; // Animation: Dying
extern u8 D_8018267C[]; // Animation: Walking faster
// unk80 Walking direction timer
// unk84 BloodSplatter facing
// *** EntityBloodyZombie properties END ***
extern s32 D_8018268C;
extern s32 D_801826A4;
extern PfnEntityUpdate PfnEntityUpdates[];

View File

@ -1,6 +1,6 @@
#include "nz0.h"
void EntityBloodDrips(Entity* self) {
void EntityBloodyZombie(Entity* self) {
Primitive* prim;
Primitive** prim2;
Entity* newEntity;