mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-27 15:00:36 +00:00
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:
parent
9532b90fc5
commit
2a4e3d6f0d
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -94,7 +94,7 @@ EntityLeftSecretRoomWall = 0x801B14C4;
|
||||
EntityBottomSecretRoomFloor = 0x801B1770;
|
||||
EntityAxeKnight = 0x801C45BC;
|
||||
EntityAxeKnightThrowingAxe = 0x801C4D18;
|
||||
EntityBloodDrips = 0x801C5568;
|
||||
EntityBloodyZombie = 0x801C5568;
|
||||
EntityBloodSplatter = 0x801C4EAC;
|
||||
EntitySkeleton = 0x801C5FC4;
|
||||
EntitySpittleBone = 0x801C672C;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
431
src/st/np3/4A654.c
Normal 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;
|
||||
}
|
@ -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[];
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "nz0.h"
|
||||
|
||||
void EntityBloodDrips(Entity* self) {
|
||||
void EntityBloodyZombie(Entity* self) {
|
||||
Primitive* prim;
|
||||
Primitive** prim2;
|
||||
Entity* newEntity;
|
||||
|
Loading…
Reference in New Issue
Block a user