diff --git a/asm/object/fireballChain.s b/asm/object/fireballChain.s deleted file mode 100644 index dfda3925..00000000 --- a/asm/object/fireballChain.s +++ /dev/null @@ -1,61 +0,0 @@ - .include "asm/macros.inc" - - .include "constants/constants.inc" - - .syntax unified - - .text - - - thumb_func_start FireballChain -FireballChain: @ 0x0809F8A4 - push {r4, r5, r6, r7, lr} - mov r7, r8 - push {r7} - adds r6, r0, #0 - ldr r0, _0809F904 @ =gEntCount - ldrb r0, [r0] - cmp r0, #0x42 - bhi _0809F8FC - movs r5, #0 -_0809F8B6: - movs r0, #0x1d - bl CreateProjectile - adds r4, r0, #0 - cmp r5, #0 - bne _0809F8C6 - mov r8, r4 - adds r7, r4, #0 -_0809F8C6: - strb r5, [r4, #0xa] - mov r0, r8 - str r0, [r4, #0x50] - str r7, [r4, #0x54] - adds r0, r6, #0 - adds r1, r4, #0 - bl CopyPosition - adds r1, r4, #0 - adds r1, #0x68 - adds r3, r5, #1 - movs r2, #7 -_0809F8DE: - ldrh r0, [r6, #0x2e] - strh r0, [r1] - adds r1, #2 - ldrh r0, [r6, #0x32] - strh r0, [r1] - adds r1, #2 - subs r2, #1 - cmp r2, #0 - bge _0809F8DE - adds r7, r4, #0 - adds r5, r3, #0 - cmp r5, #4 - ble _0809F8B6 - bl DeleteThisEntity -_0809F8FC: - pop {r3} - mov r8, r3 - pop {r4, r5, r6, r7, pc} - .align 2, 0 -_0809F904: .4byte gEntCount diff --git a/include/collision.h b/include/collision.h new file mode 100644 index 00000000..d57258a6 --- /dev/null +++ b/include/collision.h @@ -0,0 +1,33 @@ + +#ifndef COLLISION_H +#define COLLISION_H + +#include "global.h" +#include "entity.h" + +/** Collisions. */ +typedef enum { + COL_NONE = 0x0, + COL_NORTH_WEST = 0x2, + COL_NORTH_EAST = 0x4, + COL_NORTH_FULL = 0x6, + COL_NORTH_ANY = 0xe, + COL_SOUTH_WEST = 0x20, + COL_SOUTH_EAST = 0x40, + COL_SOUTH_FULL = 0x60, + COL_SOUTH_ANY = 0xe0, + COL_WEST_SOUTH = 0x200, + COL_WEST_NORTH = 0x400, + COL_WEST_FULL = 0x600, + COL_WEST_ANY = 0xe00, + COL_EAST_SOUTH = 0x2000, + COL_EAST_NORTH = 0x4000, + COL_EAST_FULL = 0x6000, + COL_EAST_ANY = 0xe000, +} Collisions; + +bool32 IsTileCollision(const u8*, s32, s32, u32); +void CalculateEntityTileCollisions(Entity*, u32, u32); +bool32 ProcessMovementInternal(Entity*, s32, s32, u32); + +#endif diff --git a/include/projectile/winder.h b/include/projectile/winder.h new file mode 100644 index 00000000..1fe479ff --- /dev/null +++ b/include/projectile/winder.h @@ -0,0 +1,12 @@ +#ifndef PROJECTILE_WINDER_H +#define PROJECTILE_WINDER_H +#include "enemy.h" + +#define WINDER_NUM_SEGMENTS 8 + +typedef struct { + Entity base; + s16 positions[2 * WINDER_NUM_SEGMENTS]; +} WinderEntity; + +#endif diff --git a/linker.ld b/linker.ld index 51a80d79..a0f8b4c0 100644 --- a/linker.ld +++ b/linker.ld @@ -787,7 +787,7 @@ SECTIONS { src/object/objectA2.o(.text); src/object/cloud.o(.text); src/object/minishLight.o(.text); - asm/object/fireballChain.o(.text); + src/object/fireballChain.o(.text); src/object/objectA6.o(.text); src/object/objectA7.o(.text); src/object/objectA8.o(.text); diff --git a/src/enemy/bobomb.c b/src/enemy/bobomb.c index 7e214b63..5ff23ab7 100644 --- a/src/enemy/bobomb.c +++ b/src/enemy/bobomb.c @@ -6,6 +6,7 @@ */ #include "asm.h" +#include "collision.h" #include "sound.h" #include "enemy.h" #include "object.h" @@ -160,7 +161,7 @@ void sub_0802C91C(Entity* this) { GetNextFrame(this); ProcessMovement0(this); if (this->field_0x82.HALF.LO) { - if (this->collisions) { + if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); InitializeAnimation(this, (this->direction >> 4) | 2); } @@ -173,7 +174,7 @@ void sub_0802C91C(Entity* this) { sub_0802CC18(this); } } else { - if (this->collisions) { + if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); InitializeAnimation(this, this->direction >> 4); } diff --git a/src/enemy/cloudPiranha.c b/src/enemy/cloudPiranha.c index 6922958c..e1075af3 100644 --- a/src/enemy/cloudPiranha.c +++ b/src/enemy/cloudPiranha.c @@ -7,6 +7,7 @@ #define NENT_DEPRECATED #include "global.h" +#include "collision.h" #include "enemy.h" #include "functions.h" #include "coord.h" @@ -259,7 +260,7 @@ void sub_080387F0(CloudPiranhaEntity* this) { if ((iVar4 == 0xf) || (iVar4 == 0x2a)) { super->direction = (super->direction + 0x10) & 0x1f; } else { - if (super->collisions != 0) { + if (super->collisions != COL_NONE) { sub_0800417E(super, super->collisions); } } diff --git a/src/enemy/flyingPot.c b/src/enemy/flyingPot.c index abba834c..1736979d 100644 --- a/src/enemy/flyingPot.c +++ b/src/enemy/flyingPot.c @@ -5,6 +5,7 @@ * @brief Flying pot enemy */ #define NENT_DEPRECATED +#include "collision.h" #include "functions.h" #include "enemy.h" #include "player.h" @@ -234,7 +235,7 @@ void FlyingPot_Action4(FlyingPotEntity* this) { void FlyingPot_Action5(FlyingPotEntity* this) { ProcessMovement2(super); - if (super->collisions != 0) { + if (super->collisions != COL_NONE) { sub_08037408(this); } } diff --git a/src/enemy/flyingSkull.c b/src/enemy/flyingSkull.c index 262781bb..85ebe162 100644 --- a/src/enemy/flyingSkull.c +++ b/src/enemy/flyingSkull.c @@ -1,4 +1,5 @@ #define NENT_DEPRECATED +#include "collision.h" #include "entity.h" #include "enemy.h" #include "functions.h" @@ -159,7 +160,7 @@ void sub_08039ECC(FlyingSkullEntity* this) { void sub_08039EE4(FlyingSkullEntity* this) { super->subAction = 1; COLLISION_OFF(super); - super->collisions = 0; + super->collisions = COL_NONE; super->hitbox = (Hitbox*)&gUnk_080FD340; gPlayerEntity.animationState; this->unk_0x76 = gPlayerEntity.animationState; @@ -175,7 +176,7 @@ void sub_08039F4C(FlyingSkullEntity* this) { void sub_08039F78(FlyingSkullEntity* this) { super->spritePriority.b1 = 1; - if (super->z.HALF.HI == 0 || super->collisions) { + if (super->z.HALF.HI == 0 || (super->collisions != COL_NONE)) { sub_0803A0E0(this); } } @@ -222,7 +223,7 @@ void sub_0803A09C(FlyingSkullEntity* this) { GetNextFrame(super); ProcessMovement2(super); - if (super->collisions) { + if (super->collisions != COL_NONE) { sub_0803A0E0(this); } } diff --git a/src/enemy/moldorm.c b/src/enemy/moldorm.c index 7a5ab69c..a73135cd 100644 --- a/src/enemy/moldorm.c +++ b/src/enemy/moldorm.c @@ -6,6 +6,7 @@ */ #include "enemy.h" +#include "collision.h" #include "functions.h" void sub_08022EAC(Entity*); @@ -103,7 +104,7 @@ void sub_08022D40(Entity* this) { sub_08022F14(this); ProcessMovement0(this); - if (this->collisions) { + if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); this->animationState = ((this->direction + 2) & 0x1c) >> 2; this->frameIndex = this->animationState; diff --git a/src/enemy/mulldozer.c b/src/enemy/mulldozer.c index 6a6a79de..1550c4d1 100644 --- a/src/enemy/mulldozer.c +++ b/src/enemy/mulldozer.c @@ -7,6 +7,7 @@ #define NENT_DEPRECATED #include "global.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -63,11 +64,11 @@ void sub_08032CAC(MulldozerEntity* this) { case 2: case 3: super->action = 6; - super->actionDelay = super->type != 0 ? 0x5a : 200; + super->actionDelay = (super->type != 0) ? 0x5a : 200; super->field_0xf = 2; this->unk_80 = 3; super->direction = super->knockbackDirection; - super->direction = (super->direction + ((Random() & 0x40) != 0 ? 4 : 0x1c)); + super->direction += ((Random() & 0x40) != 0) ? 4 : 0x1c; super->direction &= 0x1f; super->speed = 0; break; @@ -102,7 +103,7 @@ void Mulldozer_Action1(MulldozerEntity* this) { if (--super->actionDelay == 0) { sub_080330C0(this); } else { - if (sub_08033364(this) != 0) { + if (sub_08033364(this)) { sub_08033100(this); } } @@ -200,7 +201,7 @@ void sub_08032F48(MulldozerEntity* this) { } void sub_08032F64(MulldozerEntity* this) { - if (super->collisions != 0) { + if (super->collisions != COL_NONE) { sub_0800417E(super, super->collisions); super->animationState = super->direction >> 2; sub_08032F24(this); diff --git a/src/enemy/octorokBoss.c b/src/enemy/octorokBoss.c index 49ca9525..c5b944f7 100644 --- a/src/enemy/octorokBoss.c +++ b/src/enemy/octorokBoss.c @@ -6,6 +6,7 @@ */ #define NENT_DEPRECATED #include "enemy/octorokBoss.h" +#include "collision.h" #include "functions.h" #include "game.h" #include "object.h" @@ -639,14 +640,15 @@ void OctorokBoss_Action1_ChargeAttack(OctorokBossEntity* this) { if (this->timer == 0) { ProcessMovement0(super); - knockbackCondition = 0; + knockbackCondition = FALSE; if ((super->direction != 0) && (super->direction != 0x10)) { - knockbackCondition = ((u32)super->collisions & 0xee00) != 0; + knockbackCondition = ((super->collisions & (COL_EAST_ANY | COL_WEST_ANY)) != COL_NONE); } - if (((super->direction != 0x18) && (super->direction != 8)) && ((super->collisions & 0xee) != 0)) { - knockbackCondition = 1; + if (((super->direction != 0x18) && (super->direction != 8)) && + (super->collisions & (COL_NORTH_ANY | COL_SOUTH_ANY))) { + knockbackCondition = TRUE; } - if (knockbackCondition != 0) { + if (knockbackCondition) { super->knockbackDuration = 0x20; super->knockbackSpeed = 0x200; super->knockbackDirection = super->direction ^ 0x10; @@ -911,7 +913,7 @@ void OctorokBoss_Burning(OctorokBossEntity* this) { void OctorokBoss_Burning_SubAction0(OctorokBossEntity* this) { super->subAction = 1; super->speed = 0x200; - super->collisions = 0; + super->collisions = COL_NONE; super->direction = (u8)(-this->angle.HALF.HI ^ 0x80U) >> 3; this->timer = 0x78; this->angularSpeed.HWORD = 0x180; @@ -922,13 +924,13 @@ void OctorokBoss_Burning_SubAction0(OctorokBossEntity* this) { void OctorokBoss_Burning_SubAction1(OctorokBossEntity* this) { ProcessMovement0(super); - if (super->collisions != 0) { + if (super->collisions != COL_NONE) { super->subAction = 2; this->heap->targetAngle = this->angle.HALF.HI; - if ((super->collisions & 0xee00) != 0) { + if ((super->collisions & (COL_EAST_ANY | COL_WEST_ANY)) != COL_NONE) { this->heap->targetAngle = -this->heap->targetAngle; } - if ((super->collisions & 0xee) != 0) { + if ((super->collisions & (COL_NORTH_ANY | COL_SOUTH_ANY)) != COL_NONE) { this->heap->targetAngle = -this->heap->targetAngle ^ 0x80; } super->knockbackDuration = 0x18; @@ -951,10 +953,10 @@ void OctorokBoss_Burning_SubAction2(OctorokBossEntity* this) { if ((u32)(this->heap->targetAngle - this->angle.HALF.HI + 7) < 0xf) { super->subAction = 1; super->direction = ((u8) - this->angle.HALF.HI ^ 0x80) >> 3; - super->collisions = 0; + super->collisions = COL_NONE; ProcessMovement0(super); } else { - if ((u8)(this->heap->targetAngle - this->angle.HALF.HI) >= 0x81) { + if ((u8)(this->heap->targetAngle - this->angle.HALF.HI) > 0x80) { this->angle.HWORD -= this->angularSpeed.HWORD; } else { this->angle.HWORD += this->angularSpeed.HWORD; @@ -1161,7 +1163,7 @@ void OctorokBoss_StartRegularAttack(OctorokBossEntity* this) { super->subAction = ACTION1_SUBACTION2; super->speed = 0x200; this->timer = 0x3c; - super->collisions = 0; + super->collisions = COL_NONE; this->heap->unk_0 = 4; SoundReq(SFX_159); return; diff --git a/src/enemy/pesto.c b/src/enemy/pesto.c index f7f8baf1..7882e8e8 100644 --- a/src/enemy/pesto.c +++ b/src/enemy/pesto.c @@ -6,6 +6,7 @@ */ #include "enemy.h" +#include "collision.h" #include "object.h" #include "game.h" #include "functions.h" @@ -525,7 +526,7 @@ void sub_080244E8(Entity* this) { void sub_08024940(Entity* this) { u32 random = Random() & 0x70; - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); sub_080249F4(this); } diff --git a/src/enemy/puffstool.c b/src/enemy/puffstool.c index 18838cf6..76f4858b 100644 --- a/src/enemy/puffstool.c +++ b/src/enemy/puffstool.c @@ -6,6 +6,7 @@ */ #include "enemy.h" +#include "collision.h" #include "object.h" #include "functions.h" @@ -156,7 +157,7 @@ void sub_08025230(Entity* this) { this->direction = sub_08025C60(this); } - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { if (--this->field_0xf == 0) { sub_0800417E(this, this->collisions); } diff --git a/src/enemy/scissorsBeetle.c b/src/enemy/scissorsBeetle.c index 28ce9d57..29fddd38 100644 --- a/src/enemy/scissorsBeetle.c +++ b/src/enemy/scissorsBeetle.c @@ -1,4 +1,5 @@ #define NENT_DEPRECATED +#include "collision.h" #include "entity.h" #include "enemy.h" #include "functions.h" @@ -92,7 +93,7 @@ void sub_080389E8(ScissorsBeetleEntity* this) { sub_08038C2C((ScissorsBeetleEntity*)child); } else if (super->actionDelay) { super->actionDelay--; - } else if (super->collisions) { + } else if (super->collisions != COL_NONE) { super->actionDelay = 0xc; if ((child->animationState & 1) == 0) { child->animationState += Random() & 0x20 ? 1 : 7; diff --git a/src/enemy/spark.c b/src/enemy/spark.c index f6f9325d..7a977440 100644 --- a/src/enemy/spark.c +++ b/src/enemy/spark.c @@ -5,6 +5,7 @@ * @brief Spark enemy */ +#include "collision.h" #include "enemy.h" #include "object.h" #include "functions.h" @@ -40,7 +41,6 @@ void Spark_OnCollision(Entity* this) { } void Spark_OnGrabbed(Entity* this) { - /* ... */ } void sub_0802B33C(Entity* this) { @@ -57,7 +57,7 @@ void sub_0802B35C(Entity* this) { GetNextFrame(this); ProcessMovement0(this); is_head = this->type == 0; - if (this->collisions == 0) { + if (this->collisions == COL_NONE) { if (--this->field_0xf == 0) { this->field_0xf = 0x78; @@ -68,49 +68,49 @@ void sub_0802B35C(Entity* this) { this->field_0xf = 0x78; switch (DirectionRound(this->direction)) { case DirectionNorth: - if (this->collisions & 0xe) { + if ((this->collisions & COL_NORTH_ANY) != COL_NONE) { this->direction = is_head ? DirectionWest : DirectionEast; } else { - if ((this->collisions & 0xe000) == 0x4000 && is_head) { + if (((this->collisions & COL_EAST_ANY) == COL_EAST_NORTH) && is_head) { this->direction = DirectionEast; } - if ((this->collisions & 0xe00) == 0x400 && !is_head) { + if (((this->collisions & COL_WEST_ANY) == COL_WEST_NORTH) && !is_head) { this->direction = DirectionWest; } } break; case DirectionSouth: - if (this->collisions & 0xe0) { + if ((this->collisions & COL_SOUTH_ANY) != COL_NONE) { this->direction = is_head ? DirectionEast : DirectionWest; } else { - if ((this->collisions & 0xe000) == 0x2000 && !is_head) { + if (((this->collisions & COL_EAST_ANY) == COL_EAST_SOUTH) && !is_head) { this->direction = DirectionEast; } - if ((this->collisions & 0xe00) == 0x200 && is_head) { + if (((this->collisions & COL_WEST_ANY) == COL_WEST_SOUTH) && is_head) { this->direction = DirectionWest; } } break; case DirectionWest: - if (this->collisions & 0xe00) { + if ((this->collisions & COL_WEST_ANY) != COL_NONE) { this->direction = is_head ? DirectionSouth : DirectionNorth; } else { - if ((this->collisions & 0xe) == 4 && is_head) { + if (((this->collisions & COL_NORTH_ANY) == COL_NORTH_EAST) && is_head) { this->direction = DirectionNorth; } - if ((this->collisions & 0xe0) == 0x40 && !is_head) { + if (((this->collisions & COL_SOUTH_ANY) == COL_SOUTH_EAST) && !is_head) { this->direction = DirectionSouth; } } break; case DirectionEast: - if (this->collisions & 0xe000) { + if ((this->collisions & COL_EAST_ANY) != COL_NONE) { this->direction = is_head ? DirectionNorth : DirectionSouth; } else { - if ((this->collisions & 0xe) == 2 && !is_head) { + if (((this->collisions & COL_NORTH_ANY) == COL_NORTH_WEST) && !is_head) { this->direction = DirectionNorth; } - if ((this->collisions & 0xe0) == 0x20 && is_head) { + if (((this->collisions & COL_SOUTH_ANY) == COL_SOUTH_WEST) && is_head) { this->direction = DirectionSouth; } } diff --git a/src/enemy/stalfos.c b/src/enemy/stalfos.c index 61512e7e..31086dc1 100644 --- a/src/enemy/stalfos.c +++ b/src/enemy/stalfos.c @@ -7,6 +7,7 @@ #define NENT_DEPRECATED #include "global.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -366,7 +367,7 @@ void sub_0803992C(StalfosEntity* this) { super->direction = super->animationState << 3; this->unk_78 = (u16)gUnk_080CF900[Random() & 0xf]; CalculateEntityTileCollisions(super, super->direction, 0); - if ((gUnk_080CF910[super->animationState] & super->collisions) != 0) { + if ((gUnk_080CF910[super->animationState] & super->collisions) != COL_NONE) { InitAnimationForceUpdate(super, super->animationState); } else { InitAnimationForceUpdate(super, super->animationState + 4); diff --git a/src/enemy/tektite.c b/src/enemy/tektite.c index db461a94..776f08e5 100644 --- a/src/enemy/tektite.c +++ b/src/enemy/tektite.c @@ -5,6 +5,7 @@ * @brief Tektite enemy */ +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -135,7 +136,7 @@ void sub_0802F300(Entity* this) { this->field_0xf = 0; InitializeAnimation(this, 3); return; - } else if (this->collisions != 0) { + } else if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); } else if ((GetTileUnderEntity(this) & 0xf0) == 0x50) { this->direction = (this->direction + 0x10) & 0x1f; diff --git a/src/enemy/tektiteGolden.c b/src/enemy/tektiteGolden.c index af71db25..f8862aa8 100644 --- a/src/enemy/tektiteGolden.c +++ b/src/enemy/tektiteGolden.c @@ -5,6 +5,7 @@ * @brief Golden Tektite enemy */ +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -114,7 +115,7 @@ void sub_08038048(Entity* this) { this->actionDelay = 0x14; InitializeAnimation(this, 3); return; - } else if (this->collisions != 0) { + } else if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); } else if ((GetTileUnderEntity(this) & 0xf0) == 0x50) { this->direction = (this->direction + 0x10) & 0x1f; diff --git a/src/enemy/wisp.c b/src/enemy/wisp.c index 213453c2..73f82457 100644 --- a/src/enemy/wisp.c +++ b/src/enemy/wisp.c @@ -5,6 +5,7 @@ * @brief Wisp enemy */ +#include "collision.h" #include "enemy.h" #include "save.h" #include "object.h" @@ -102,7 +103,7 @@ void sub_08033674(Entity* this) { void sub_080336A8(Entity* this) { if (--this->actionDelay == 0) { sub_08033744(this); - } else if (this->collisions != 0) { + } else if (this->collisions != COL_NONE) { sub_0800417E(this, this->collisions); } ProcessMovement0(this); diff --git a/src/enemy/wizzrobeWind.c b/src/enemy/wizzrobeWind.c index 4ea7da19..4fce3d5a 100644 --- a/src/enemy/wizzrobeWind.c +++ b/src/enemy/wizzrobeWind.c @@ -7,6 +7,7 @@ #define NENT_DEPRECATED #include "global.h" +#include "collision.h" #include "enemy.h" #include "enemy/wizzrobe.h" #include "functions.h" @@ -262,7 +263,7 @@ void sub_0802F9C8(WizzrobeEntity* this) { } else { if (super->type2 != 0) { ProcessMovement0(super); - if (super->collisions != 0) { + if (super->collisions != COL_NONE) { super->flags &= 0x7f; this->timer1 = 0x28; } diff --git a/src/movement.c b/src/movement.c index 8fee2b1f..1e54b3c5 100644 --- a/src/movement.c +++ b/src/movement.c @@ -1,4 +1,5 @@ #include "global.h" +#include "collision.h" #include "entity.h" #include "room.h" #include "area.h" @@ -9,30 +10,6 @@ #include "transitions.h" #include "functions.h" -/** Collisions. */ -typedef enum { - COL_NONE = 0x0, - COL_NORTH_WEST = 0x2, - COL_NORTH_EAST = 0x4, - COL_NORTH_FULL = 0x6, - COL_NORTH_ANY = 0xe, - COL_SOUTH_WEST = 0x20, - COL_SOUTH_EAST = 0x40, - COL_SOUTH_FULL = 0x60, - COL_SOUTH_ANY = 0xe0, - COL_WEST_SOUTH = 0x200, - COL_WEST_NORTH = 0x400, - COL_WEST_FULL = 0x600, - COL_WEST_ANY = 0xe00, - COL_EAST_SOUTH = 0x2000, - COL_EAST_NORTH = 0x4000, - COL_EAST_FULL = 0x6000, - COL_EAST_ANY = 0xe000, -} Collisions; - -bool32 IsTileCollision(const u8*, s32, s32, u32); -void CalculateEntityTileCollisions(Entity*, u32, u32); -bool32 ProcessMovementInternal(Entity*, s32, s32, u32); bool32 sub_080AF0C8(Entity*); /** The type of the movement/collision? that is done. */ @@ -112,7 +89,8 @@ bool32 TileCollisionFunction2(s32 x, s32 y) { 0b1111111111111110, 0b1111111111111111, */ - 32768, 49152, 57344, 61440, 63488, 64512, 65024, 65280, 65408, 65472, 65504, 65520, 65528, 65532, 65534, 65535, + 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, + 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF, }; return gUnk_08133918[y & 0xf] >> (x & 0xf) & 1; @@ -122,24 +100,24 @@ bool32 TileCollisionFunction2(s32 x, s32 y) { bool32 TileCollisionFunction3(s32 x, s32 y) { static const u16 gUnk_08133938[] = { /* - 0b1, - 0b11, - 0b111, - 0b1111, - 0b11111, - 0b111111, - 0b1111111, - 0b11111111, - 0b111111111, - 0b1111111111, - 0b11111111111, - 0b111111111111, - 0b1111111111111, - 0b11111111111111, - 0b111111111111111, + 0b0000000000000001, + 0b0000000000000011, + 0b0000000000000111, + 0b0000000000001111, + 0b0000000000011111, + 0b0000000000111111, + 0b0000000001111111, + 0b0000000011111111, + 0b0000000111111111, + 0b0000001111111111, + 0b0000011111111111, + 0b0000111111111111, + 0b0001111111111111, + 0b0011111111111111, + 0b0111111111111111, 0b1111111111111111, */ - 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, + 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, }; return gUnk_08133938[y & 0xf] >> (x & 0xf) & 1; } @@ -165,7 +143,8 @@ bool32 TileCollisionFunction4(s32 x, s32 y) { 0b1100000000000000, 0b1000000000000000, */ - 65535, 65534, 65532, 65528, 65520, 65504, 65472, 65408, 65280, 65024, 64512, 63488, 61440, 57344, 49152, 32768, + 0xFFFF, 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, 0xFFE0, 0xFFC0, 0xFF80, + 0xFF00, 0xFE00, 0xFC00, 0xF800, 0xF000, 0xE000, 0xC000, 0x8000, }; return gUnk_08133958[y & 0xf] >> (x & 0xf) & 1; } @@ -175,23 +154,23 @@ bool32 TileCollisionFunction5(s32 x, s32 y) { static const u16 gUnk_08133978[] = { /* 0b1111111111111111, - 0b111111111111111, - 0b11111111111111, - 0b1111111111111, - 0b111111111111, - 0b11111111111, - 0b1111111111, - 0b111111111, - 0b11111111, - 0b1111111, - 0b111111, - 0b11111, - 0b1111, - 0b111, - 0b11, - 0b1, + 0b0111111111111111, + 0b0011111111111111, + 0b0001111111111111, + 0b0000111111111111, + 0b0000011111111111, + 0b0000001111111111, + 0b0000000111111111, + 0b0000000011111111, + 0b0000000001111111, + 0b0000000000111111, + 0b0000000000011111, + 0b0000000000001111, + 0b0000000000000111, + 0b0000000000000011, + 0b0000000000000001, */ - 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, + 0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF, 0xFFF, 0x7FF, 0x3FF, 0x1FF, 0xFF, 0x7F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x1, }; return gUnk_08133978[y & 0xf] >> (x & 0xf) & 1; } @@ -210,14 +189,14 @@ bool32 TileCollisionFunction6(s32 x, s32 y) { 0b1111111111111111, 0b1111111111111111, 0b1111111111111111, - 0b0, - 0b0, - 0b0, - 0b0, - 0b0, - 0b0, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, */ - 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 0, 0, 0, 0, 0, 0, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; return gUnk_08133998[y & 0xf] >> (x & 0xf) & 1; @@ -227,12 +206,12 @@ bool32 TileCollisionFunction6(s32 x, s32 y) { bool32 TileCollisionFunction7(s32 x, s32 y) { static const u16 gUnk_081339B8[] = { /* - 0b0, - 0b0, - 0b0, - 0b0, - 0b0, - 0b0, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, + 0b0000000000000000, 0b1111111111111111, 0b1111111111111111, 0b1111111111111111, @@ -244,7 +223,7 @@ bool32 TileCollisionFunction7(s32 x, s32 y) { 0b1111111111111111, 0b1111111111111111, */ - 0, 0, 0, 0, 0, 0, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, }; return gUnk_081339B8[y & 0xf] >> (x & 0xf) & 1; } @@ -270,7 +249,8 @@ bool32 TileCollisionFunction8(s32 x, s32 y) { 0b1111111111000000, 0b1111111111000000, */ - 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, 65472, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, }; return gUnk_081339D8[y & 0xf] >> (x & 0xf) & 1; } @@ -279,24 +259,24 @@ bool32 TileCollisionFunction8(s32 x, s32 y) { bool32 TileCollisionFunction9(s32 x, s32 y) { static const u16 gUnk_081339F8[] = { /* - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, - 0b1111111111, + 0b[000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, + 0b0000001111111111, */ - 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, 0x3FF, }; return gUnk_081339F8[y & 0xf] >> (x & 0xf) & 1; } diff --git a/src/npc/dog.c b/src/npc/dog.c index e54e6477..d63a8c4d 100644 --- a/src/npc/dog.c +++ b/src/npc/dog.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "functions.h" #include "npc.h" #include "item.h" @@ -143,17 +144,17 @@ void sub_08069D54(Entity* this) { if (this->x.HALF.HI < this->field_0x6e.HWORD) { this->x.HALF.HI = this->field_0x6e.HWORD + 1; - collisions = 0xe00; + collisions = COL_WEST_ANY; } else if (this->x.HALF.HI > this->field_0x6c.HWORD) { this->x.HALF.HI = this->field_0x6c.HWORD - 1; - collisions = 0xe000; + collisions = COL_EAST_ANY; } if (this->y.HALF.HI < this->field_0x70.HALF_U.LO) { this->y.HALF.HI = this->field_0x70.HALF_U.LO + 1; - collisions = 0xe; + collisions = COL_NORTH_ANY; } else if (this->y.HALF.HI > this->field_0x70.HALF_U.HI) { this->y.HALF.HI = this->field_0x70.HALF_U.HI - 1; - collisions = 0xe0; + collisions = COL_SOUTH_ANY; } sub_0800417E(this, collisions); sub_08069F6C(this); diff --git a/src/object/fireballChain.c b/src/object/fireballChain.c new file mode 100644 index 00000000..ac5322b7 --- /dev/null +++ b/src/object/fireballChain.c @@ -0,0 +1,41 @@ +#define NENT_DEPRECATED +#include "global.h" +#include "entity.h" +#include "functions.h" +#include "projectile.h" +#include "projectile/winder.h" + +void FireballChain(Entity* thisx) { + WinderEntity* newSegment; + Entity* parent; + Entity* child; + s32 i; + s32 j; + + if (gEntCount > 0x42) { + return; + } + + for (i = 0; i < 5; i++) { + u16* tmp; + + newSegment = (WinderEntity*)CreateProjectile(WINDER); + if (i == 0) { + child = parent = &newSegment->base; + } + + newSegment->base.type = i; + newSegment->base.parent = parent; + newSegment->base.child = child; + CopyPosition(thisx, &newSegment->base); + + for (j = 0, tmp = newSegment->positions; j < WINDER_NUM_SEGMENTS; j++) { + *tmp++ = thisx->x.HALF.HI; + *tmp++ = thisx->y.HALF.HI; + } + + child = &newSegment->base; + } + + DeleteThisEntity(); +} diff --git a/src/object/mazaalBossObject.c b/src/object/mazaalBossObject.c index 27f42ffb..adc3ab6d 100644 --- a/src/object/mazaalBossObject.c +++ b/src/object/mazaalBossObject.c @@ -80,7 +80,7 @@ void MazaalBossObject_Action0(MazaalBossObjectEntity* this) { gRoomControls.camera_target = super; sub_080809D4(); } else { - super->action = 1; + super->action = MAZAAL_BOSS_OBJECT_ACTION_1; super->actionDelay = 30; super->frameIndex = gRoomTransition.field_0x38; super->spritePriority.b0 = 7; diff --git a/src/object/playerClone.c b/src/object/playerClone.c index b8a94abc..cabbd7c9 100644 --- a/src/object/playerClone.c +++ b/src/object/playerClone.c @@ -1,5 +1,6 @@ #define NENT_DEPRECATED #include "entity.h" +#include "collision.h" #include "room.h" #include "asm.h" #include "sound.h" @@ -49,7 +50,12 @@ void PlayerClone_Init(PlayerCloneEntity* this) { SoundReq(SFX_112); } -const u16 PlayerCloneCollisions[] = { 0x2206, 0x6044, 0x4460, 0x622 }; +const u16 PlayerCloneCollisions[] = { + COL_NORTH_FULL | COL_WEST_SOUTH | COL_EAST_SOUTH, + COL_NORTH_EAST | COL_SOUTH_EAST | COL_EAST_FULL, + COL_SOUTH_FULL | COL_WEST_NORTH | COL_EAST_NORTH, + COL_NORTH_WEST | COL_SOUTH_WEST | COL_WEST_FULL, +}; void PlayerClone_Action1(PlayerCloneEntity* this) { static const Hitbox PlayerCloneHitbox = { 0, -3, { 5, 3, 3, 5 }, 6, 6 }; @@ -104,7 +110,8 @@ void PlayerClone_Action2(PlayerCloneEntity* this) { super->y.HALF.HI = gPlayerEntity.y.HALF.HI + this->unk7a; sub_08084CAC(this); sub_080085B0(super); - if ((super->collisions & 0x6666) != 0x6666) { + if ((super->collisions & (COL_NORTH_FULL | COL_SOUTH_FULL | COL_EAST_FULL | COL_WEST_FULL)) != + (COL_NORTH_FULL | COL_SOUTH_FULL | COL_EAST_FULL | COL_WEST_FULL)) { for (index = 0; index <= 3; index++) { if (PlayerCloneCollisions[index] == (PlayerCloneCollisions[index] & super->collisions)) { break; diff --git a/src/object/smallIceBlock.c b/src/object/smallIceBlock.c index 11994ed5..63c4c5a6 100644 --- a/src/object/smallIceBlock.c +++ b/src/object/smallIceBlock.c @@ -7,6 +7,7 @@ #define NENT_DEPRECATED #include "global.h" +#include "collision.h" #include "object.h" #include "functions.h" #include "hitbox.h" @@ -204,7 +205,7 @@ bool32 sub_0809953C(SmallIceBlockEntity* this) { uVar3 = sub_0800442E(super); if (uVar3 != 0) { - return 0; + return FALSE; } ProcessMovement2(super); sub_0800445C(super); @@ -216,17 +217,17 @@ bool32 sub_0809953C(SmallIceBlockEntity* this) { } switch (super->direction >> 3) { case 0: - if ((super->collisions & 0xe) == 0) { - return 0; + if ((super->collisions & COL_NORTH_ANY) == COL_NONE) { + return FALSE; } if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) { super->y.HALF.HI = (super->y.HALF.HI & 0xfff0) + 8; - return 1; + return TRUE; } sub_0809969C(this); break; case 1: - if ((super->collisions & 0xe000) == 0) { + if ((super->collisions & COL_EAST_ANY) == COL_NONE) { return FALSE; } if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) { @@ -236,7 +237,7 @@ bool32 sub_0809953C(SmallIceBlockEntity* this) { sub_0809969C(this); break; case 2: - if ((super->collisions & 0xe0) == 0) { + if ((super->collisions & COL_SOUTH_ANY) == COL_NONE) { return FALSE; } if ((u32)(super->y.HALF.HI & 0xf) - 7 < 3) { @@ -246,7 +247,7 @@ bool32 sub_0809953C(SmallIceBlockEntity* this) { sub_0809969C(this); break; default: - if ((super->collisions & 0xe00) != 0) { + if ((super->collisions & COL_WEST_ANY) != COL_NONE) { if ((u32)(super->x.HALF.HI & 0xf) - 7 < 3) { super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8; return TRUE; diff --git a/src/player.c b/src/player.c index 60257988..9f1c93eb 100644 --- a/src/player.c +++ b/src/player.c @@ -6,6 +6,7 @@ */ #include "global.h" +#include "collision.h" #include "asm.h" #include "sound.h" #include "entity.h" @@ -3018,7 +3019,7 @@ static void sub_080739EC(Entity* this) { if ((gPlayerState.jump_status & 0xC0) != 0) { gPlayerState.field_0xd = this->direction; if (gPlayerState.jump_status & 0x80) - this->collisions = 0; + this->collisions = COL_NONE; v = GRAVITY_RATE; } else { if ((u16)sub_0806F854(this, 0, -12)) { @@ -3414,7 +3415,7 @@ void SurfaceAction_7(Entity* this) { void SurfaceAction_MinishDoorFront(Entity* this) { if ((this->y.HALF.HI & 0xF) <= 0xD) { - this->collisions = 0x6600; + this->collisions = COL_EAST_FULL | COL_WEST_FULL; hide(this); } else { EnablePlayerDraw(this); @@ -3423,7 +3424,7 @@ void SurfaceAction_MinishDoorFront(Entity* this) { void SurfaceAction_MinishDoorBack(Entity* this) { if ((this->y.HALF.HI & 0xF) > 1) { - this->collisions = 0x6600; + this->collisions = COL_EAST_FULL | COL_WEST_FULL; hide(this); } else { EnablePlayerDraw(this); @@ -3432,7 +3433,7 @@ void SurfaceAction_MinishDoorBack(Entity* this) { void SurfaceAction_A(Entity* this) { if ((this->x.HALF.HI & 0xF) < 12) { - this->collisions = 0x66; + this->collisions = COL_NORTH_FULL | COL_SOUTH_FULL; hide(this); } else { EnablePlayerDraw(this); @@ -3441,7 +3442,7 @@ void SurfaceAction_A(Entity* this) { void SurfaceAction_B(Entity* this) { if ((this->x.HALF.HI & 0xF) > 4) { - this->collisions = 0x66; + this->collisions = COL_NORTH_FULL | COL_SOUTH_FULL; hide(this); } else { EnablePlayerDraw(this); diff --git a/src/projectile/arrowProjectile.c b/src/projectile/arrowProjectile.c index 91567d8b..755ee6f8 100644 --- a/src/projectile/arrowProjectile.c +++ b/src/projectile/arrowProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" #include "object.h" @@ -66,7 +67,7 @@ void ArrowProjectile_Action1(Entity* this) { } void ArrowProjectile_Action2(Entity* this) { - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { this->action = 3; COLLISION_OFF(this); this->actionDelay = 0x20; diff --git a/src/projectile/boneProjectile.c b/src/projectile/boneProjectile.c index 3f9858a9..429a94c9 100644 --- a/src/projectile/boneProjectile.c +++ b/src/projectile/boneProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -25,15 +26,15 @@ void sub_080A81C4(Entity* this) { void BoneProjectile_Init(Entity* this) { this->action = 1; - this->actionDelay = 0x3c; - this->z.HALF.HI = 0xfffe; + this->actionDelay = 60; + this->z.HALF.HI = -2; InitializeAnimation(this, 0); } void BoneProjectile_Action1(Entity* this) { GetNextFrame(this); ProcessMovement3(this); - if (this->collisions == 0) { + if (this->collisions == COL_NONE) { if (IsProjectileOffScreen(this)) { DeleteEntity(this); } else { diff --git a/src/projectile/cannonballProjectile.c b/src/projectile/cannonballProjectile.c index acf5ccd7..18e79a67 100644 --- a/src/projectile/cannonballProjectile.c +++ b/src/projectile/cannonballProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -49,7 +50,7 @@ void CannonballProjectile_Action1(Entity* this) { void CannonballProjectile_Action2(Entity* this) { GetNextFrame(this); ProcessMovement3(this); - if ((sub_080AB634(this) == 0) && (this->collisions != 0)) { + if ((sub_080AB634(this) == 0) && (this->collisions != COL_NONE)) { CreateFx(this, FX_DEATH, 0); DeleteThisEntity(); } diff --git a/src/projectile/dekuSeedProjectile.c b/src/projectile/dekuSeedProjectile.c index 94eb1e59..86fce52a 100644 --- a/src/projectile/dekuSeedProjectile.c +++ b/src/projectile/dekuSeedProjectile.c @@ -91,7 +91,7 @@ void DekuSeedProjectile_Action2(Entity* this) { COLLISION_ON(this); } } else { - sub_0800417E(this, (u32)this->collisions); + sub_0800417E(this, this->collisions); sub_08016AD2(this); InitializeAnimation(this, 0x19); sub_080A86A0(this); diff --git a/src/projectile/lakituLightning.c b/src/projectile/lakituLightning.c index 1f366e0f..171be05c 100644 --- a/src/projectile/lakituLightning.c +++ b/src/projectile/lakituLightning.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -32,7 +33,7 @@ void LakituLightning_Init(Entity* this) { void LakituLightning_Action1(Entity* this) { GetNextFrame(this); ProcessMovement3(this); - if ((this->collisions != 0) || (--this->actionDelay == 0)) { + if ((this->collisions != COL_NONE) || (--this->actionDelay == 0)) { CreateFx(this, FX_BLUE_EFC, 0); DeleteThisEntity(); } diff --git a/src/projectile/octorokBossProjectile.c b/src/projectile/octorokBossProjectile.c index 659f748c..54ac6c32 100644 --- a/src/projectile/octorokBossProjectile.c +++ b/src/projectile/octorokBossProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" #include "projectile.h" @@ -114,10 +115,10 @@ void OctorokBossProjectile_Action1(Entity* this) { this->field_0x78.HWORD--; LinearMoveAngle(this, this->speed, this->direction); CalculateEntityTileCollisions(this, this->direction >> 3, 0); - if ((this->collisions & 0xee00) != 0) { + if ((this->collisions & (COL_WEST_ANY | COL_EAST_ANY)) != COL_NONE) { this->direction = -this->direction; } - if ((this->collisions & 0xee) != 0) { + if ((this->collisions & (COL_NORTH_ANY | COL_SOUTH_ANY)) != COL_NONE) { this->direction = -this->direction ^ 0x80; } if (this->direction == this->field_0xf) { @@ -151,7 +152,7 @@ void OctorokBossProjectile_Action1(Entity* this) { GetNextFrame(this); if (GravityUpdate(this, 0x1800) != 0) { CalculateEntityTileCollisions(this, this->direction >> 3, 0); - if (this->collisions == 0) { + if (this->collisions == COL_NONE) { LinearMoveAngle(this, (s32)this->speed, (u32)this->direction); } else { OctorokBossProjectile_Action2(this); diff --git a/src/projectile/torchTrapProjectile.c b/src/projectile/torchTrapProjectile.c index 5ff167c0..38503e89 100644 --- a/src/projectile/torchTrapProjectile.c +++ b/src/projectile/torchTrapProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -39,7 +40,7 @@ void TorchTrapProjectile_Action1(Entity* this) { void TorchTrapProjectile_Action2(Entity* this) { GetNextFrame(this); ProcessMovement3(this); - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { DeleteThisEntity(); } if (IsProjectileOffScreen(this)) { diff --git a/src/projectile/v3ElectricProjectile.c b/src/projectile/v3ElectricProjectile.c index c52258cd..77308f1e 100644 --- a/src/projectile/v3ElectricProjectile.c +++ b/src/projectile/v3ElectricProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "player.h" #include "coord.h" @@ -96,7 +97,7 @@ void V3ElectricProjectile_Action2(Entity* this) { this->z.HALF.HI += 3; } ProcessMovement3(this); - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { DeleteThisEntity(); } GetNextFrame(this); diff --git a/src/projectile/v3HandProjectile.c b/src/projectile/v3HandProjectile.c index 4d4c55bf..ce11e1ef 100644 --- a/src/projectile/v3HandProjectile.c +++ b/src/projectile/v3HandProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "player.h" #include "functions.h" @@ -20,7 +21,7 @@ void V3HandProjectile_OnTick(Entity* this) { this->z.HALF.HI += 2; } ProcessMovement3(this); - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { DeleteThisEntity(); } GetNextFrame(this); diff --git a/src/projectile/v3TennisBallProjectile.c b/src/projectile/v3TennisBallProjectile.c index 455f67af..c487be01 100644 --- a/src/projectile/v3TennisBallProjectile.c +++ b/src/projectile/v3TennisBallProjectile.c @@ -1,4 +1,5 @@ #include "entity.h" +#include "collision.h" #include "enemy.h" #include "functions.h" @@ -62,7 +63,7 @@ void V3TennisBallProjectile_Action1(Entity* this) { void V3TennisBallProjectile_Action2(Entity* this) { ProcessMovement3(this); - if (this->collisions != 0) { + if (this->collisions != COL_NONE) { DeleteThisEntity(); } GetNextFrame(this); @@ -78,28 +79,28 @@ bool32 sub_080ACB40(Entity* this) { Entity* tmp = ((Entity**)(r1_grandparent->myHeap))[7]->child; if (tmp != this && child == tmp->child) { - return 0; + return FALSE; } tmp = ((Entity**)(r1_grandparent->myHeap))[8]->child; if (tmp != this && child == tmp->child) { - return 0; + return FALSE; } tmp = ((Entity**)(r1_grandparent->myHeap))[9]->child; if (tmp != this && child == tmp->child) { - return 0; + return FALSE; } tmp = ((Entity**)(r1_grandparent->myHeap))[10]->child; if (tmp != this && child == tmp->child) { - return 0; + return FALSE; } - return 1; + return TRUE; } void sub_080ACB90(Entity* this) { diff --git a/src/projectile/winder.c b/src/projectile/winder.c index ae1cb901..d15ce8a0 100644 --- a/src/projectile/winder.c +++ b/src/projectile/winder.c @@ -1,118 +1,133 @@ +#define NENT_DEPRECATED +#include "collision.h" #include "entity.h" #include "asm.h" #include "functions.h" #include "common.h" #include "projectile.h" +#include "projectile/winder.h" -extern void (*const Winder_Actions[])(Entity*); extern s16 gUnk_080B4488[]; -static const u8 gUnk_0812A6BC[]; -static const u16 gUnk_0812A6C4[]; -void sub_080AB9DC(Entity*); -bool32 sub_080AB9FC(Entity* this, u32 param_1); +typedef enum { + /* 0 */ WINDER_TYPE_HEAD, + /* 4 */ WINDER_TYPE_TAIL = 4, +} WinderType; -void Winder(Entity* this) { - Winder_Actions[this->action](this); - sub_080AB9DC(this); +void Winder_Init(WinderEntity* this); +void Winder_Move(WinderEntity* this); + +void Winder_SetPositions(WinderEntity*); +bool32 Winder_CheckForRailings(WinderEntity* this, u32 dir); + +void Winder(Entity* thisx) { + static void (*const Winder_Actions[])(WinderEntity*) = { + Winder_Init, + Winder_Move, + }; + WinderEntity* this = (WinderEntity*)thisx; + + Winder_Actions[super->action](this); + Winder_SetPositions(this); } -void Winder_Init(Entity* this) { - Entity* entity; - u16* puVar3; - s32 index; +void Winder_Init(WinderEntity* this) { + Entity* nextSegment; + u16* posPtr; + s32 i; - this->action += 1; - this->speed = 0x140; - this->z.WORD = 0; - if (this->type == 0) { - this->direction = Random() & 0x18; - this->parent = this; + super->action++; + super->speed = 0x140; + super->z.WORD = 0; + if (super->type == 0) { + super->direction = Random() & 0x18; + super->parent = super; } - InitializeAnimation(this, 0); - if (this->type < 4) { - entity = CreateProjectile(WINDER); - entity->type = this->type + 1; - entity->parent = this->parent; - entity->child = this; - CopyPosition(this, entity); + InitializeAnimation(super, 0); + if (super->type < WINDER_TYPE_TAIL) { + nextSegment = CreateProjectile(WINDER); + nextSegment->type = super->type + 1; + nextSegment->parent = super->parent; + nextSegment->child = super; + CopyPosition(super, nextSegment); } - puVar3 = &this->field_0x68.HWORD; - for (index = 7; index >= 0; --index) { - *puVar3 = this->x.HALF.HI; - puVar3 += 1; - *puVar3 = this->y.HALF.HI; - puVar3 += 1; + posPtr = this->positions; + for (i = 0; i < WINDER_NUM_SEGMENTS; i++) { + *posPtr++ = super->x.HALF.HI; + *posPtr++ = super->y.HALF.HI; } } -void sub_080AB950(Entity* this) { - if (this->type == 0) { +void Winder_Move(WinderEntity* this) { + static const u8 nextDirections[][2] = { + { DirectionEast, DirectionWest }, + { DirectionNorth, DirectionSouth }, + { DirectionEast, DirectionWest }, + { DirectionNorth, DirectionSouth }, + }; + static const u16 collisionChecks[] = { COL_NORTH_ANY, COL_EAST_ANY, COL_SOUTH_ANY, COL_WEST_ANY }; + + if (super->type == WINDER_TYPE_HEAD) { u8 dir; - ProcessMovement0(this); - dir = this->direction >> 3; - if (((gUnk_0812A6C4)[dir] & this->collisions) || sub_080AB9FC(this, this->direction)) { - this->direction = gUnk_0812A6BC[(Random() & 0x1) + (dir << 1)]; + + ProcessMovement0(super); + + dir = super->direction >> 3; + if ((collisionChecks[dir] & super->collisions) || Winder_CheckForRailings(this, super->direction)) { + super->direction = nextDirections[dir][Random() & 0x1]; } } else { - Entity* child; + WinderEntity* child; - if (this->parent == NULL) { + if (super->parent == NULL) { DeleteThisEntity(); } - if (this->parent->next == NULL) { + if (super->parent->next == NULL) { DeleteThisEntity(); } - child = this->child; - if (child && child->next) { - this->x.HALF.HI = child->field_0x68.HWORD; - this->y.HALF.HI = child->field_0x6a.HWORD; + child = (WinderEntity*)super->child; + if ((child != NULL) && (child->base.next != NULL)) { + super->x.HALF.HI = child->positions[0]; + super->y.HALF.HI = child->positions[1]; } else { DeleteThisEntity(); } } - GetNextFrame(this); + GetNextFrame(super); } -void sub_080AB9DC(Entity* this) { - MemCopy(&this->field_0x6c, &this->field_0x68, 0x1c); - this->cutsceneBeh.HWORD = this->x.HALF.HI; - this->field_0x86.HWORD = this->y.HALF.HI; +void Winder_SetPositions(WinderEntity* this) { + //! @bug Undefined behaviour for source and destination to overlap in a memcpy. In this case it is okay because the + //! copy will always be sequential, incremental and in chunks of <= 4 bytes, so it will copy the contents of + //! positions[0] and positions[1] to positions[2] and positions[3], then that of positions[2] and positions[3] to + //! positions[4] and positions[5], and so on. A safer way to do this would be a manual loop as in Winder_Move. + MemCopy(&this->positions[2], &this->positions[0], sizeof(u16) * (ARRAY_COUNT(this->positions) - 2)); + + this->positions[2 * (WINDER_NUM_SEGMENTS - 1)] = super->x.HALF.HI; + this->positions[2 * (WINDER_NUM_SEGMENTS - 1) + 1] = super->y.HALF.HI; } -bool32 sub_080AB9FC(Entity* this, u32 dir) { +bool32 Winder_CheckForRailings(WinderEntity* this, u32 dir) { + u32 tile; u32 val; - LayerStruct* layer = GetLayerByIndex(this->collisionLayer); - u32 tmp; - val = (((this->x.HALF.HI - gRoomControls.origin_x) >> 4) & 0x3f) | - ((((this->y.HALF.HI - gRoomControls.origin_y) >> 4) & 0x3f) << 6); - val += gUnk_080B4488[dir >> 3]; - tmp = layer->collisionData[val]; - if (tmp <= 0x1f) { - return 0; + LayerStruct* layer = GetLayerByIndex(super->collisionLayer); + u32 collisionData; + + tile = TILE(super->x.HALF.HI, super->y.HALF.HI); + tile += gUnk_080B4488[dir >> 3]; + collisionData = layer->collisionData[tile]; + + if (collisionData <= 0x1F) { + return FALSE; } - if (tmp > 0x3f) { - return 0; + if (collisionData > 0x3F) { + return FALSE; } - return 1; + return TRUE; } - -void (*const Winder_Actions[])(Entity*) = { - Winder_Init, - sub_080AB950, -}; -const u8 gUnk_0812A6BC[] = { - 8, 24, 0, 16, 8, 24, 0, 16, -}; -const u16 gUnk_0812A6C4[] = { - 0xe, - 0xe000, - 0xe0, - 0xe00, -};