diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/enemy.c | 2 | ||||
| -rw-r--r-- | src/enemy/gleerok.c | 1258 |
2 files changed, 1259 insertions, 1 deletions
diff --git a/src/enemy.c b/src/enemy.c index b0594e0f..a56124d3 100644 --- a/src/enemy.c +++ b/src/enemy.c @@ -468,7 +468,7 @@ void (*const gEnemyFunctions[])(Entity* ent) = { [FALLING_BOULDER] = FallingBoulder, [BOBOMB] = Bobomb, [WALL_MASTER_2] = WallMaster2, - [GLEEROCK] = Gleerok, + [GLEEROK] = Gleerok, [VAATI_EYES_MACRO] = VaatiEyesMacro, [TEKTITE] = Tektite, [WIZZROBE_WIND] = WizzrobeWind, diff --git a/src/enemy/gleerok.c b/src/enemy/gleerok.c new file mode 100644 index 00000000..70a6c78b --- /dev/null +++ b/src/enemy/gleerok.c @@ -0,0 +1,1258 @@ +#define NENT_DEPRECATED +#include "entity.h" +#include "enemy.h" +#include "player.h" +#include "screen.h" +#include "functions.h" +#include "object.h" + +typedef struct { + /*0x00*/ u8 filler[0x30]; + /*0x30*/ u8 unk_30[6]; + /*0x36*/ u8 filler_36[0x2]; + /*0x38*/ Entity* ent; + /*0x3c*/ Entity* entities[5]; + /*0x50*/ Entity* ent2; +} Gleerok_HeapStruct; + +typedef struct { + Entity base; + u8 filler[0xc]; + u8 unk_74; + u8 unk_75; + u8 unk_76; + u8 unk_77; + u8 unk_78; + u8 unk_79; + u8 unk_7a; + u8 unk_7b; + union SplitWord unk_7c; + u8 unk_80; + u8 unk_81; + u8 unk_82; + u8 unk_83; + Gleerok_HeapStruct* unk_84; +} GleerokEntity; + +extern void (*const gUnk_080CD748[])(Entity*); +extern void (*const gUnk_080CD75C[])(GleerokEntity*); +extern void (*const gUnk_080CD7B8[])(GleerokEntity*); +extern void (*const gUnk_080CD7E4[])(GleerokEntity*); +extern void (*const gUnk_080CD810[])(GleerokEntity*); +extern void (*const gUnk_080CD828[])(GleerokEntity*); +extern void (*const gUnk_080CD848[])(GleerokEntity*); + +extern u8 gUnk_080CD774[]; +extern u8 gUnk_080CD7C4[]; +extern u8 gUnk_080CD884[]; +extern u8 gUnk_080CD7F8[]; +extern u8 gUnk_080CD840[]; +extern u8 gUnk_080CD844[]; + +extern u32 sub_0806FC80(Entity*, Entity*, s32); + +extern void sub_0802E518(GleerokEntity* this); +extern void sub_0802E7E4(Gleerok_HeapStruct* this); +extern void sub_0802E1D0(GleerokEntity* this); +extern u32 sub_0802EB9C(GleerokEntity* this); +extern void sub_0802D86C(GleerokEntity* this); +extern void sub_0802E430(GleerokEntity* this); +extern void sub_0802EBC4(GleerokEntity* this); +extern void sub_0802E9B0(GleerokEntity* this); + +extern bool32 sub_0802EB08(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3); +extern bool32 sub_0802EA18(u16 param_1, u16 param_2, u32 param_3); +extern bool32 sub_0802EA48(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); +extern bool32 sub_0802EA68(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); +extern bool32 sub_0802E7CC(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); +extern bool32 sub_0802EA88(Gleerok_HeapStruct* param_1); +extern bool32 sub_0802E768(Gleerok_HeapStruct* param_1); + +void Gleerok(Entity* this) { + gUnk_080CD748[GetNextFunction(this)](this); +} + +void sub_0802D034(GleerokEntity* this) { + sub_08078B48(); + + switch (super->type) { + case 2: + if (super->type2 == 0) { + super->type2 = 1; + super->actionDelay = 0; + super->field_0xf = 0x3c; + this->unk_74 = 0x10; + this->unk_75 = 0; + gScreen.controls.alphaBlend = this->unk_74; + gScreen.controls.layerFXControl = 0x1442; + SoundReq(SFX_EVAPORATE); + } else { + ++super->actionDelay; + if ((super->actionDelay & 0xf) == 0) { + this->unk_75++; + this->unk_74--; + gScreen.controls.alphaBlend = this->unk_74 | (this->unk_75 << 8); + if (gScreen.controls.alphaBlend == 0x1000) { + sub_0807AABC(&gPlayerEntity); + DeleteThisEntity(); + } + } + + if (super->field_0xf) { + if (--super->field_0xf == 0) { + SoundReq(SFX_APPARATE); + } + } + } + break; + case 1: + SoundReq(SFX_BOSS_DIE); + sub_0804A7D4(super); + break; + case 0: + gPlayerState.field_0x14 = 1; + + if (sub_0806FC80(super, &gPlayerEntity, super->frame & 0x3f)) { + gPlayerState.field_0x3f = 0xfa; + } + + gUnk_080CD75C[super->action](this); + sub_0802E518(this); + sub_0802E7E4(this->unk_84); + break; + } +} + +void sub_0802D158(GleerokEntity* this) { + super->action = 1; + gUnk_02034490[0] = 1; + SetFade(7, 8); +} + +void sub_0802D170(GleerokEntity* this) { + if (gFadeControl.active) + return; + + if (super->action == 1) { + this->unk_84->filler[1] = 0x10; + this->unk_84->filler[0x19] = 0x10; + if (sub_0802EB08(this->unk_84, 0x40, 2) == 0 && sub_0802EA88(this->unk_84) == 0) { + super->action = 2; + gPlayerEntity.x.HALF.HI = gRoomControls.origin_x + 0x98; + gPlayerEntity.y.HALF.HI = gRoomControls.origin_y + 0xd8; + gPlayerEntity.animationState = 0; + sub_0807BA8C(COORD_TO_TILE(&gPlayerEntity), 2); + gRoomControls.camera_target = super; + SetFade(6, 8); + } + } else { + super->action = 3; + this->unk_80 = 0; + ((Entity*)this->unk_84)->parent->actionDelay = 0x18; + this->unk_84->filler[0x19] = 0; + } +} + +void sub_0802D218(GleerokEntity* this) { + if (sub_0802EB08(this->unk_84, 0x40, 2)) + return; + + super->action = 4; + super->actionDelay = 0; + super->field_0xf = 0; + this->unk_7c.HALF_U.LO = 0xb4; + ((Entity*)(this->unk_84))->parent->actionDelay = 0xc; + CreateObjectWithParent(super, 0x67, 0x2, this->unk_7c.HALF_U.LO); +} + +void sub_0802D258(GleerokEntity* this) { + if (this->unk_7c.HALF_U.LO == 0) { + sub_0802E1D0(this); + if (super->type2 == 5) { + super->action = 5; + return; + } + } else { + if (--this->unk_7c.HALF_U.LO == 0) { + InitializeAnimation(super, 0x4e); + } + } + + if (super->actionDelay == 0) { + super->actionDelay = gUnk_080CD774[super->field_0xf]; + super->direction = gUnk_080CD774[super->field_0xf + 1]; + super->field_0xf = (super->field_0xf & 0x3f) + 2; + } else { + super->actionDelay--; + } + + if (super->direction <= 1) { + sub_0802EA48(this->unk_84, 5, 0x40, super->direction); + } else { + Gleerok_HeapStruct** tmp = &this->unk_84; + if (super->direction != 0xff) { + sub_0802EA68(*tmp, 5, 0x40, super->direction); + } + } + + if ((gRoomTransition.frameCount & 0x1f) == 0) { + SoundReq(SFX_BOSS_DIE); + } + + if ((gRoomTransition.frameCount & 0xf) == 0) { + Entity* fx; + u32 rand = Random() & 5; + u8* ptr = (u8*)this->unk_84; + rand *= 4; + ptr += 0x3c; + fx = CreateFx(*(Entity**)(ptr + rand), FX_GIANT_EXPLOSION3, 0); + if (fx) { + fx->spritePriority.b0 = 0; + } + } + + sub_0802E768(this->unk_84); +} + +NONMATCH("asm/non_matching/gleerok/sub_0802D33C.inc", void sub_0802D33C(GleerokEntity* this)) { + u8* unk_84 = (u8*)this->unk_84; + u8* ptr = unk_84; + u8* ptr2; + u32 i = 0; + ptr += 0x3c; + ptr2 = ptr; + + do { + DeleteEntity(*(Entity**)ptr); + ptr += 4; + } while (i < 4); + + ptr2 += (i << 2); + *(u32*)((*(u8**)ptr2) + 0x45) = 0; + *((*(u8**)ptr2) + 0x6d) |= 1; + ((Entity*)(*(u8**)(unk_84 + 0x50)))->health = 0; + ((Entity*)(*(u8**)(unk_84 + 0x50)))->type2 = 0; + ((Entity*)(*(u8**)(unk_84 + 0x50)))->spriteSettings.draw &= ~1; + DeleteThisEntity(); +} +END_NONMATCH + +void sub_0802D394(GleerokEntity* this) { + gUnk_080CD7B8[super->action](this); + super->spriteRendering.b3 = 3; +} + +NONMATCH("asm/non_matching/gleerok/sub_0802D3B8.inc", void sub_0802D3B8(GleerokEntity* this)) { + u32 uvar1; + Entity* ent; + Gleerok_HeapStruct* heap; + u32 val; + u8* ptr; + u8* ptr2; + + if (CheckGlobalFlag(3)) { + gScreen.lcd.displayControl &= 0xFDFF; + sub_0807AABC(&gPlayerEntity); + DeleteThisEntity(); + } + + super->action = 1; + + switch (super->type) { + case 0: + super->action = 2; + COLLISION_OFF(super); + super->spritePriority.b0 = 7; + this->unk_75 = 0; + this->unk_80 = 0; + this->unk_79 = 0; + this->unk_7c.WORD = 0x96; + + sub_0802EB9C(this); + this->unk_84 = zMalloc(0x54); + heap = this->unk_84; + + if (heap == NULL) { + sub_0804A7D4(super); + DeleteThisEntity(); + } + + super->myHeap = this->unk_84; + uvar1 = 0; + + do { + ent = CreateEnemy(GLEEROK, 1); + super->child = ent; + if (ent) { + ent->type2 = uvar1 + 1; + super->child->collisionLayer = super->collisionLayer; + super->child->x.HALF.HI = super->x.HALF.HI; + super->child->y.HALF.HI = super->y.HALF.HI + ((uvar1 + 1) * 12); + super->child->parent = super; + ((GleerokEntity*)super->child)->unk_84 = this->unk_84; + this->unk_84->entities[uvar1] = super->child; + ptr = this->unk_84->filler; + ptr2 = ptr + uvar1 * 4; + ptr2[1] = 0x10; + ptr2[0x19] = 0; + ptr[0x35] = 0; + } + } while (++uvar1 < 5); + + ent = CreateEnemy(GLEEROK, 2); + super->child = ent; + if (ent) { + super->child->collisionLayer = super->collisionLayer; + super->child->x.HALF.HI = super->x.HALF.HI; + super->child->y.HALF.HI = super->y.HALF.HI + ((uvar1 + 1) * 12); + super->child->parent = super; + ((GleerokEntity*)super->child)->unk_84 = this->unk_84; + heap->ent2 = super->child; + heap->filler[0x15] = 0x10; + heap->filler[0x2d] = 0; + heap->filler[0x35] = 0; + } +#ifndef EU + gPlayerState.controlMode = 3; +#endif + InitializeAnimation(super, 0x4c); + break; + case 1: + if (super->type2 == 1) { + COLLISION_ON(super); + super->flags2 |= 0x80; + } + ptr = gUnk_080CD7C4; + ptr += super->type2 * 4; + super->spritePriority.b0 = *(ptr + 1); + super->field_0xf = 0; + InitializeAnimation(super, 0x24); + break; + case 2: + super->spritePriority.b0 = 0; + super->field_0xf = 0; + InitAnimationForceUpdate(super, 0); + break; + case 3: + this->unk_74 = gUnk_080CD884[0]; + this->unk_75 = 0; + super->spritePriority.b0 = 6; + super->flags2 |= 0x80; + CopyPosition(super->parent, super); + InitializeAnimation(super, 0x4f); + break; + case 4: + InitAnimationForceUpdate(super, 0x2c); + break; + case 5: + super->spritePriority.b0 = 6; + CopyPosition(super->parent, super); + InitAnimationForceUpdate(super, 0x2d); + break; + case 6: + super->spritePriority.b0 = 6; + CopyPosition(super->parent, super); + InitializeAnimation(super, 0x50); + break; + } + + if (super->type) { + sub_0802D86C(this); + } +} +END_NONMATCH + +void sub_0802D650(GleerokEntity* this) { +#ifdef EU + sub_08078B48(); +#endif + + gUnk_080CD7E4[super->subAction](this); + sub_0802E7E4(this->unk_84); +} + +void sub_0802D674(GleerokEntity* this) { + u32 val; + gUnk_02034490[0] = 1; + + if (gPlayerEntity.z.WORD != 0) + return; + if (this->unk_7c.WORD == 0x96) { + SoundReq(SFX_BOSS_HIT); + } + + val = --this->unk_7c.WORD; + if (val == -1) { + super->subAction = 1; + this->unk_7c.WORD = 0x5a; + gRoomControls.camera_target = super; + SoundReq(SFX_BOSS_HIT); + } else if (val <= 0x3c) { + if (val == 0x3c) { + CreateSpeechBubbleExclamationMark(&gPlayerEntity, 0xc, -0x18); + } + gPlayerEntity.animationState = 0; + } else if (val <= 0x59) { + gPlayerEntity.animationState = 2; + } else if (val <= 0x77) { + gPlayerEntity.animationState = 6; + } +} + +void sub_0802D6F0(GleerokEntity* this) { + if (--this->unk_7c.WORD == -1) { + super->subAction = 2; + this->unk_7c.WORD = 0x5a; + InitScreenShake(0x96, 0); + } +} + +void sub_0802D714(GleerokEntity* this) { + Entity* enemy; + u32 index; + u32 val1, val2; + u8* ptr; + Gleerok_HeapStruct* heap; + if (--this->unk_7c.WORD != -1) + return; + + for (heap = this->unk_84, index = 0, val1 = 0, val2 = 0x10, ptr = this->unk_84->filler; index < 6; + ptr += 4, ++index) { + *(u16*)(ptr + 0x18) = val1; + *(ptr + 1) = val2; + } + + super->subAction = 3; + super->type2 = 0; + super->spriteSettings.draw = 1; + InitializeAnimation(super, 0x4d); + enemy = CreateEnemy(GLEEROK, 5); + super->child = enemy; + if (enemy) { + enemy->parent = super; + heap->ent = super->child; + ((GleerokEntity*)(super->child))->unk_84 = heap; + } + + heap->ent2->actionDelay = 0x18; +} + +void sub_0802D77C(GleerokEntity* this) { + if (gRoomTransition.frameCount & 1) + return; + + sub_0802E430(this); + + if (super->type2 != 2) + return; + + super->field_0xf = 0; + super->actionDelay = 0; + super->subAction = 4; + this->unk_84->ent2->actionDelay = 0xc; +} + +void sub_0802D7B4(GleerokEntity* this) { + u8 dir; + if (super->actionDelay == 0) { + if (gUnk_080CD7F8[super->field_0xf] == 0xff) { + super->field_0xf = 0; + super->actionDelay = 0; + super->action = 1; + super->subAction = 0; + this->unk_84->ent2->actionDelay = 0x18; + gRoomControls.camera_target = &gPlayerEntity; +#ifndef EU + gPlayerState.controlMode = 1; +#endif + gUnk_02034490[0] = 0; + SoundReq(BGM_BOSS_THEME); + return; + } else { + super->actionDelay = gUnk_080CD7F8[super->field_0xf]; + super->direction = gUnk_080CD7F8[super->field_0xf + 1]; + super->field_0xf += 2; + SoundReq(SFX_BOSS_HIT); + } + } else { + super->actionDelay--; + } + + if (super->direction <= 1) { + sub_0802EA48(this->unk_84, 5, 0x40, super->direction); + } else if (super->direction != 0xff) { + sub_0802EA68(this->unk_84, 5, 0x40, super->direction); + } + + sub_0802E768(this->unk_84); + sub_0802E518(this); +} + +NONMATCH("asm/non_matching/gleerok/sub_0802D86C.inc", void sub_0802D86C(GleerokEntity* this)) { + Entity* enemy; + Entity* enemy2; + switch (super->type) { + case 1: + if (super->type2 == 1) { + if (((GleerokEntity*)(super->parent))->unk_80 != 0 || super->spriteSettings.draw != 1) { + COLLISION_OFF(super); + } else { + COLLISION_ON(super); + } + } + case 2: + if ((super->spriteSettings.draw & 1) == 0) + return; + + super->iframes = super->parent->iframes; + if (super->iframes == 0) { + if (super->field_0xf == 0) { + UnloadOBJPalette(super); + LoadObjPalette(super, 0xc9); + } else { + super->field_0xf--; + UnloadOBJPalette(super); + LoadObjPalette(super, 0xca); + } + } + + if (((GleerokEntity*)(super->parent))->unk_80 == 0) + return; + if (!EntityInRectRadius(super, &gPlayerEntity, 8, 8)) + return; + + gPlayerState.field_0x14 = 1; + gPlayerState.field_0x3f = 0xfc; + + break; + case 4: + if (super->frame == 0) { + UpdateAnimationSingleFrame(super); + return; + } + + if (GravityUpdate(super, 0x1800)) + return; + + ((GleerokEntity*)(super->parent))->unk_7b = 1; + super->actionDelay = 0; + + do { + CreateObjectWithParent(super, OBJECT_67, 0, super->actionDelay); + } while (++super->actionDelay < 8); + + SoundReq(SFX_150); + DeleteThisEntity(); + break; + case 5: + if ((gRoomTransition.frameCount & 1) && super->parent->action == 2) + return; + + UpdateAnimationSingleFrame(super); + + if ((super->frame & 0x80) == 0) + return; + + enemy = CreateEnemy(GLEEROK, 6); + + super->child = enemy; + if (enemy) { + enemy->parent = super->parent; + this->unk_84->ent = super->child; + ((GleerokEntity*)super->child)->unk_84 = this->unk_84; + } + + DeleteThisEntity(); + break; + case 6: + if ((gRoomTransition.frameCount & 1) && super->parent->action == 2) + return; + + GetNextFrame(super); + + if ((super->frame & 0x80) == 0) + return; + + enemy = CreateEnemy(GLEEROK, 3); + + super->child = enemy; + if (enemy) { + enemy->parent = super->parent; + super->actionDelay = this->unk_84->filler[1]; + this->unk_84->ent = super->child; + ((GleerokEntity*)super->child)->unk_84 = this->unk_84; + } + + DeleteThisEntity(); + break; + case 3: + if (this->unk_74) { + if (--this->unk_74 == 0) { + u32 unk_74; + this->unk_75 += 2; + unk_74 = gUnk_080CD884[this->unk_75]; + this->unk_74 = unk_74; + + if (unk_74) { + UnloadOBJPalette(super); + LoadObjPalette(super, gUnk_080CD884[this->unk_75 + 1]); + } + } + } + + if ((super->bitfield & 0x80) && this->unk_74 == 0) { + if ((super->bitfield & 0x7f) == 0x1d) { + super->zVelocity = 0x30000; + super->parent->subAction = 4; + super->parent->type2 = 0; + ((GleerokEntity*)super->parent)->unk_7b = 0; + SoundReq(SFX_10C); + } + } else { + if (super->actionDelay != this->unk_84->filler[1]) { + if (((super->actionDelay - this->unk_84->filler[1]) & 0x1f) > 0x10) { + if (++super->frameIndex >= 0x31) { + super->frameIndex = 0x28; + } + } else { + if (--super->frameIndex <= 0x27) { + super->frameIndex = 0x30; + } + } + + super->actionDelay = this->unk_84->filler[1]; + } + } + + if (super->zVelocity <= 0) + return; + + GravityUpdate(super, 0x1800); + + if (super->zVelocity > 0) + return; + + enemy = CreateEnemy(GLEEROK, 4); + super->child = enemy; + if (enemy) { + enemy->parent = super->parent; + this->unk_84->ent = super->child; + ((GleerokEntity*)super->child)->unk_84 = this->unk_84; + // Making super in super->child volatile solves this but ugly + CopyPosition(super, super->child); + DeleteThisEntity(); + } + + break; + case 0: + gUnk_080CD810[super->subAction](this); + sub_0802E7E4(this->unk_84); + break; + } +} +END_NONMATCH + +void sub_0802DB84(GleerokEntity* this) { + u32 actionDelay; + super->direction = GetFacingDirection(super, &gPlayerEntity); + if (this->unk_84->filler[0x1] == super->direction) { + super->subAction = 1; + this->unk_78 = 0; + return; + } + + if (((this->unk_84->filler[0x1] - super->direction) & 0x1f) > 0x10) { + actionDelay = 0; + super->actionDelay &= 0xfe; + } else { + actionDelay = 1; + super->actionDelay = actionDelay; + } + + switch (this->unk_79) { + case 0: + super->speed = 0x30; + break; + case 1: + super->speed = 0x40; + break; + case 2: + super->speed = 0x50; + break; + } + + sub_0802EA48(this->unk_84, 5, super->speed, actionDelay); + sub_0802E768(this->unk_84); + sub_0802E518(this); + sub_0802EBC4(this); +} + +void sub_0802DC1C(GleerokEntity* this) { + u32 dir, diff, uVar1; + diff = GetFacingDirection(super, &gPlayerEntity); + diff = (this->unk_84->filler[1] - diff) & 0x1f; + + if (diff > 0x10) { + if (diff <= 0x1d) { + super->subAction = 0; + this->unk_84->ent2->actionDelay = 0; + return; + } + } else if (diff >= 3) { + super->subAction = 0; + this->unk_84->ent2->actionDelay = 0; + return; + } + if (this->unk_78) { + this->unk_78--; + } else { + u8 actionDelay; + ; + actionDelay = super->actionDelay; + diff = 0; + if (actionDelay == 1) { + diff = 1; + } + + sub_0802EA48(this->unk_84, 5, 0x20, diff); + if (sub_0802EA18(*(u16*)&this->unk_84->filler[0], *(u16*)&this->unk_84->filler[0x14], 4)) { + if (super->actionDelay == 1) { + *(u16*)&this->unk_84->filler[0x14] = (((this->unk_84->filler[0x1] - 4) & 0x1f) << 8) | 0xff; + } else { + *(u16*)&this->unk_84->filler[0x14] = (((this->unk_84->filler[0x1] + 4) & 0x1f) << 8); + } + + super->actionDelay ^= 1; + this->unk_78 = 0xc; + } + } + + sub_0802E9B0(this); + sub_0802E768(this->unk_84); + sub_0802E518(this); + sub_0802EBC4(this); +} + +void sub_0802DCE0(GleerokEntity* this) { + if (this->unk_84->ent2->actionDelay != 0xc) { + super->direction = GetFacingDirection(super, &gPlayerEntity); + if (this->unk_84->filler[0x15] == super->direction) { + this->unk_84->ent2->actionDelay = 0xc; + this->unk_82 = 4; + super->field_0xf = 0; + } else { + s32 svar1, diff; + diff = ((this->unk_84->filler[0x15] - super->direction) & 0x1f); + svar1 = 1; + if (diff > 0x10) { + svar1 = 0; + } + + sub_0802EA48(this->unk_84, 5, 0x20, svar1); + sub_0802E768(this->unk_84); + } + } else { + if (super->field_0xf < 6) { + if (this->unk_82 == 0) { + this->unk_82 = 4; + this->unk_84->entities[super->field_0xf]->field_0xf = 4; + super->field_0xf++; + } else { + this->unk_82--; + } + } else { + if (this->unk_84->ent2->field_0xf == 0) { + super->child = CreateProjectileWithParent(super, GLEEROK_PROJECTILE, 0); + + if (super->child) { + super->child->direction = this->unk_84->filler[0x15]; + super->child->type2 = this->unk_84->ent2->frame & 0xf; + super->child->parent = this->unk_84->ent2; + super->child->child = this->unk_84->entities[0]; + } + + this->unk_84->ent2->actionDelay = 0; + if (this->unk_74 == 0) { + this->unk_74 = 1; + } else { + super->subAction = 0; + sub_0802EB9C(this); + } + } + } + } + sub_0802E518(this); +} + +void sub_0802DDD8(GleerokEntity* this) { + u32 r2, r8, r4; + u32 rv; + u32 unk_76 = this->unk_76; + u32 uvar1 = 4; + if (unk_76) { + uvar1 = 6; + if (this->unk_79 == 2) { + if ((Random() & 1) == 0) { + uvar1 = 0xc; + } + } + } + + switch (super->type2) { + case 0: + rv = sub_0802EA88(this->unk_84); + if (rv != 0) + break; + + super->type2 = 1; + super->field_0xf = 0; + + if ((Random() & 1) == 0) { + super->direction = 0; + this->unk_7a = (this->unk_84->filler[1] + uvar1) & 0x1f; + } else { + super->direction = 1; + this->unk_7a = (this->unk_84->filler[1] - uvar1) & 0x1f; + } + + break; + case 1: + case 2: + if (super->type2 == 1) + goto code13; + if (this->unk_76 == 0) { + r2 = 1; + r8 = 2; + r4 = 1; + } else { + r2 = 2; + r8 = 6; + r4 = 0; + } + + if (this->unk_84->ent2->field_0xf == 1) { + super->child = CreateProjectileWithParent(super, GLEEROK_PROJECTILE, r2); + if (super->child) { + super->child->direction = this->unk_84->filler[0x15]; + super->child->type2 = this->unk_84->ent2->frame & 0xf; + super->child->parent = this->unk_84->ent2; + super->child->child = this->unk_84->entities[0]; + } + } + + if (this->unk_74 == 0) { + this->unk_74 = r4; + this->unk_84->entities[super->field_0xf]->field_0xf = r8; + + if (++super->field_0xf > 5) { + super->field_0xf = 0; + } + } else { + this->unk_74--; + } + + if (super->type2 == 1) { + code13: + sub_0802EA48(this->unk_84, 5, 0x40, super->direction); + } else { + if (this->unk_76 == 0) { + sub_0802EA48(this->unk_84, 5, 0x20, super->direction); + } else { + sub_0802EA48(this->unk_84, 5, 0x10, super->direction); + } + } + sub_0802E768(this->unk_84); + + if (this->unk_7a == this->unk_84->filler[0x15]) { + if (super->type2 == 1) { + super->type2 = 2; + super->direction ^= 1; + if (super->direction == 1) { + this->unk_7a = (this->unk_7a - (uvar1 * 2)) & 0x1f; + super->actionDelay = 1; + } else { + this->unk_7a = (this->unk_7a + (uvar1 * 2)) & 0x1f; + super->actionDelay &= 0xfe; + } + + this->unk_84->ent2->actionDelay = 0xc; + } else { + super->subAction = 0; + this->unk_84->ent2->actionDelay = 0; + sub_0802EB9C(this); + } + } + + break; + } + sub_0802E518(this); +} + +void sub_0802DFA8(GleerokEntity* this) { + gUnk_080CD828[super->type2](this); +} + +void sub_0802DFC0(GleerokEntity* this) { + u32 val = this->unk_84->filler[1] & 7; + if (val) { + if (val > 4) { + super->direction = 0; + } else { + super->direction = 1; + } + + sub_0802EA48(this->unk_84, 0, 0x20, super->direction); + sub_0802EA88(this->unk_84); + } else { + if (sub_0802EA88(this->unk_84) == 0) { + if (this->unk_7b) { + COLLISION_ON(super); + super->type2 = 1; + this->unk_84->ent2->actionDelay = 0x18; + SoundReq(SFX_BOSS_HIT); + } + } + } + + sub_0802E518(this); +} + +void sub_0802E034(GleerokEntity* this) { + Gleerok_HeapStruct* heap = this->unk_84; + u32 val; + + if (super->type2 == 1) { + super->direction = 2; + val = 0; + } else { + super->direction = 3; + val = gUnk_080CD840[heap->filler[1] >> 3]; + } + + if (val != heap->filler[0x19]) { + sub_0802EA68(heap, 0, 0x40, super->direction); + sub_0802EB08(heap, 0x40, 2); + } else { + if (sub_0802EB08(heap, 0x80, 2) == 0) { + if (super->type2 == 2) { + this->unk_7c.HALF.LO = 0x168; + this->unk_80 = 1; + heap->ent2->actionDelay = 0; + } + + super->type2++; + heap->filler[0x19] = 1; + } + } + + sub_0802E518(this); +} + +void sub_0802E0B8(GleerokEntity* this) { + u32 val; + + super->y.HALF.HI -= 4; + sub_0800445C(super); + super->y.HALF.HI += 4; + + val = super->frame & 0x3f; + if (val) { + if (sub_0806FC80(super, &gPlayerEntity, val)) { + gPlayerState.field_0x14 = 1; + gPlayerState.field_0x3f = 0xfa; + } + } + + if (gUnk_080CD844[this->unk_79 & 0x7f] >= super->health) { + if (this->unk_79 > 1) { + super->health = 0; + super->action = 0; + sub_08078B48(); + SoundReq(SFX_BOSS_DIE); + return; + } else { + COLLISION_OFF(super); + this->unk_79++; + this->unk_79 |= 0x80; + super->health = 0xff; + if (this->unk_7c.HALF_U.LO > 0x78) { + this->unk_7c.HALF.LO = 0x78; + } + } + } + + if ((--this->unk_7c.HALF.LO << 16) == 0xffff0000) { + COLLISION_OFF(super); + super->spriteOffsetX = 0; + super->type2 = 4; + InitializeAnimation(super, 0x4e); + } else { + if (super->bitfield & 0x80) { + if (super->iframes > 0) { + SoundReq(SFX_BOSS_HIT); + } + } + + if (this->unk_7c.HALF_U.LO < 0x78) { + super->spriteOffsetX ^= 1; + } + } + + sub_0802E518(this); +} + +void sub_0802E1D0(GleerokEntity* this) { + Gleerok_HeapStruct* heap = this->unk_84; + if (!(super->frame & 0x80)) { + GetNextFrame(super); + } + if (super->frame & 0x3f) { + if (sub_0806FC80(super, &gPlayerEntity, super->frame & 0x3f)) { + gPlayerState.field_0x14 = 1; + gPlayerState.field_0x3f = 0xfa; + } + } + if (super->frame & 0x40) { + u32 i; + for (i = 0; i < 6; i++) { + if (heap->unk_30[i]) { + heap->unk_30[i]--; + if (heap->unk_30[i] == 0) { + CreateFx(heap->entities[0], FX_LAVA_SPLASH, 0); + SoundReq(SFX_124); + if (i == 5) { + if (!(this->unk_79 & 0x80)) { + this->unk_7c.HALF_U.LO = 0xF0; + InitScreenShake(0xF0, 0); + } else { + for (this->unk_7c.HALF_U.LO = 0; this->unk_7c.HALF_U.LO < 4; this->unk_7c.HALF_U.LO++) { + CreateObjectWithParent(super, OBJECT_67, 1, this->unk_7c.HALF_U.LO); + } + this->unk_74 = 0; + this->unk_75 = 0x10; + this->unk_7c.HALF_U.LO = 0xB; + gScreen.controls.alphaBlend = this->unk_74 | (this->unk_75 << 8); + gScreen.controls.layerFXControl = 0x240; + InitScreenShake(0x1e, 0); + } + super->type2 = 5; + } + } + break; + } + } + } + sub_0802E518(this); +} + +void sub_0802E300(GleerokEntity* this) { + u32 dir, tmp; + u32 index; + u8* ptr; + u8* ptr2; + Entity* ent; + Gleerok_HeapStruct* heap; + if ((this->unk_79 & 0x80) == 0) { + this->unk_7c.HALF.LO--; + } else { + if (this->unk_74 != 0x10) { + if (this->unk_7c.HALF_U.LO) { + --this->unk_7c.HALF_U.LO; + if (this->unk_7c.HALF_U.LO == 0) { + this->unk_7c.HALF_U.LO = 0xb; + this->unk_75--; + this->unk_74++; + gScreen.controls.alphaBlend = this->unk_74 | (this->unk_75 << 8); + } + } + } + } + + if (this->unk_7c.HALF_U.LO == 0) { + if (this->unk_79 & 0x80) { + if (this->unk_75 != 0x10) { + this->unk_7c.HALF_U.LO = 0xb; + this->unk_75++; + this->unk_74--; + gScreen.controls.alphaBlend = this->unk_74 | (this->unk_75 << 8); + return; + } + } + + this->unk_79 &= 0x7f; + heap = this->unk_84; + dir = sub_0806F5A4(GetFacingDirection(super, &gPlayerEntity)) << 3; + index = 0; + ptr2 = &this->unk_80; + tmp = 0; + ptr = heap->filler; + do { + ((u16*)ptr)[0xc] = tmp; + ptr[1] = dir; + ptr += 4; + index++; + } while (index <= 5); + + super->subAction = 5; + super->type2 = 0; + *ptr2 = 0; + InitializeAnimation(super, 0x4d); + ent = CreateEnemy(GLEEROK, 5); + super->child = ent; + if (super->child) { + super->child->parent = super; + heap->ent = super->child; + ((GleerokEntity*)super->child)->unk_84 = heap; + } + + heap->ent2->actionDelay = 0x18; + } else { + if ((gRoomTransition.frameCount & 0xf) == 0) { + CreateProjectileWithParent(super, GLEEROK_PROJECTILE, 0x3); + } + } + + sub_0802E518(this); +} + +void sub_0802E430(GleerokEntity* this) { + gUnk_080CD848[super->type2](this); +} + +void sub_0802E448(GleerokEntity* this) { + Gleerok_HeapStruct* heap = this->unk_84; + s32 index; + for (index = 5; index >= 0; index--) { + u8* ptr = &heap->filler[0x30]; + if (ptr[index] == 0) { + CreateFx(heap->entities[0], FX_LAVA_SPLASH, 0); + SoundReq(SFX_PLY_LAND); + } + + if (ptr[index] != 10) { + if (++ptr[index] == 10 && index == 0) { + super->type2 = 1; + } + break; + } + } + + if (heap->filler[0x2d] <= 9) { + sub_0802EA68(heap, 5, 0x40, 3); + } + + GetNextFrame(super); + sub_0802E768(this->unk_84); + sub_0802E518(this); +} + +void sub_0802E4C0(GleerokEntity* this) { + GetNextFrame(super); + + if (super->frame & 0x80) { + if (super->action != 2) { + this->unk_74 = 0; + this->unk_75 = 8; + + if (this->unk_79) { + this->unk_76 = 0; + this->unk_77 = 3; + } + + sub_0802EBC4(this); + } else { + super->type2++; + } + } + + sub_0802E518(this); +} + +NONMATCH("asm/non_matching/gleerok/sub_0802E518.inc", void sub_0802E518(GleerokEntity* this)) { + u32 index; + u32 r6; + u32 sp4; + u32 sp8; + s32 r7; + Gleerok_HeapStruct* heap = this->unk_84; + CopyPosition(heap->entities[0]->parent, heap->entities[0]); + heap->entities[0]->direction = heap->filler[1]; + + r6 = heap->filler[1]; + if (r6 > 0x10) { + r6 ^= 0xf; + r6 = (r6 + 1) & 0xf; + } + + if (r6 == 0x10) { + r6 = 0xf; + } + + heap->entities[0]->speed = ((r6 ^ 0xf) + 0x12) << 8; + LinearMoveUpdate(heap->entities[0]); + sp4 = *(u32*)&heap->filler[0x30]; + sp8 = this->unk_80; + + for (index = 0; index <= 4; index++) { + s32 result; + CopyPosition(heap->entities[index], heap->entities[index + 1]); + result = FixedMul(gSineTable[heap->filler[0x19 + (index + 1) * 4]], ((u8*)sp4)[r6]); + result = FixedDiv(result, 0x100); + result = FixedMul(gSineTable[heap->filler[0x1 + (index + 1) * 4]], result); + result = FixedDiv(result, 0x100); + heap->entities[index]->x.WORD += result << 8; + + result = FixedMul(gSineTable[heap->filler[0x19 + (index + 1) * 4]], ((u8*)sp4)[r6]); + result = FixedDiv(result, 0x100); + heap->entities[index]->y.WORD -= result << 8; + } + + if (heap->ent2->actionDelay == 0x18) { + r7 = (heap->filler[0x15] >> 3) << 2; + if (heap->filler[0x2d] > 0xc) { + r7 += 3; + } else { + r7 += heap->filler[0x2d] >> 2; + } + + if (heap->ent2->animIndex != r7 + 0x18) { + InitAnimationForceUpdate(heap->ent2, r7 + 0x18); + } + } else { + if (this->unk_80 == 0) { + sub_0802E7CC(heap, 5, 0, 0); + r7 = (heap->ent2->animationState / 2 + heap->ent2->animationState) / 4; + r7 += heap->ent2->actionDelay; + } else { + if (super->iframes == 0) { + if ((super->animIndex != (heap->filler[0x15] >> 3) + 0x2f) || (super->frame & 0x80) != 0) { + r7 = (heap->filler[0x15] >> 3) + 0x28; + } + } else { + r7 = (heap->filler[0x15] >> 3) + 0x2f; + } + } + + if (heap->ent2->animIndex != r7) { + InitAnimationForceUpdate(heap->ent2, r7); + } else { + UpdateAnimationSingleFrame(heap->ent2); + } + } + + for (index = 0; index <= 4; index++) { + if (this->unk_80 == 0) { + u32 val; + sub_0802E7CC(heap, (u8)index, 0, 0); + r7 = heap->entities[index]->animationState * 12; + r7 += (((s32)heap->filler[0x19 + (index + 1) * 4]) / 3) * 12; + } else { + r7 = heap->filler[0x1 + index * 4] >> 3; + r7 += 0x48; + } + if (heap->entities[index]->animIndex != r7) { + InitializeAnimation(heap->entities[index], r7); + } + } +} +END_NONMATCH |
