tmc/src/item/itemSword.c

328 lines
11 KiB
C

#include "functions.h"
#include "item.h"
#include "object.h"
#include "player.h"
#include "playeritem.h"
#include "sound.h"
void sub_080759B8(ItemBehavior*, u32);
void sub_080754B8(ItemBehavior*, u32);
void sub_08075898(ItemBehavior*, u32);
void sub_08075580(ItemBehavior*, u32);
void sub_08075338(ItemBehavior*, u32);
void sub_080755F0(ItemBehavior*, u32);
void sub_0807564C(ItemBehavior*, u32);
void sub_08075738(ItemBehavior*, u32);
void sub_080758B0(ItemBehavior*, u32);
void sub_08075900(ItemBehavior*, u32);
void sub_08075694(ItemBehavior*, u32);
void ItemSword(ItemBehavior* this, u32 index) {
static void (*const stateFuncs[])(ItemBehavior*, u32) = {
sub_08075338, sub_080754B8, sub_080755F0, sub_0807564C, sub_08075738,
sub_08075580, sub_08075898, sub_080758B0, sub_08075900,
};
gPlayerState.framestate = PL_STATE_SWORD;
stateFuncs[this->stateID](this, index);
}
void sub_08075338(ItemBehavior* this, u32 index) {
u32 temp, temp2;
if (gPlayerState.flags & PL_MINISH) {
this->priority |= 0x80;
sub_08077D38(this, index);
gPlayerState.animation = ANIM_SWORD_MINISH;
SoundReq(SFX_PLY_VO1);
return;
}
if (gPlayerState.jump_status) {
if ((gPlayerState.jump_status & 7) != 3) {
if ((gPlayerState.jump_status & 0x78) == 0 && (u32)gPlayerEntity.zVelocity < Q_16_16(1.5) &&
(gPlayerState.skills & SKILL_DOWN_THRUST) && gPlayerEntity.z.WORD != 0) {
gPlayerState.jump_status |= 0x20;
gPlayerState.lastSwordMove = SWORD_MOVE_DOWN_THRUST;
gPlayerState.attack_status |= (8 >> index) | ((8 >> index) << 4);
sub_08077B98(this);
this->stateID = 6;
sub_08075898(this, index);
return;
}
}
#ifndef EU
sub_080759B8(this, index);
return;
} else if (gPlayerEntity.z.WORD) {
#endif
sub_080759B8(this, index);
return;
}
if (gPlayerState.flags & PL_ROLLING) {
if ((gPlayerState.skills & SKILL_ROLL_ATTACK) == 0) {
if (gPlayerState.item == NULL)
return;
DeleteEntity(gPlayerState.item);
gPlayerState.item = NULL;
return;
}
// Do the roll attack.
sub_08077D38(this, index);
sub_08077B98(this);
temp = (8 >> index);
gPlayerState.attack_status |= temp | (temp << 4);
gPlayerState.field_0xa |= temp;
gPlayerState.keepFacing |= temp;
this->stateID = 8;
this->timer = 0x14;
this->animPriority = 6;
this->priority |= 0x80;
gPlayerState.lastSwordMove = SWORD_MOVE_ROLL;
gPlayerState.flags |= PL_SWORD_THRUST;
SetItemAnim(this, ANIM_ROLLATTACK_SLIDE);
SoundReq(SFX_PLY_VO3);
return;
}
if ((gPlayerState.sword_state & 0x80) == 0) {
gPlayerState.sword_state = 0;
sub_0806F948(&gPlayerEntity);
}
if (gPlayerState.item) {
if (gPlayerState.item->id != 1) {
DeleteEntity(gPlayerState.item);
gPlayerState.item = NULL;
}
}
sub_08077D38(this, index);
sub_08077B98(this);
}
void sub_080754B8(ItemBehavior* this, u32 index) {
u32 swordBeam;
if ((gPlayerState.sword_state & 0x80) != 0) {
sub_08075694(this, index);
} else if (gPlayerState.attack_status != 0) {
UpdateItemAnim(this);
if (this->playerFrame != 0) {
this->priority &= ~0x80;
}
if (gPlayerEntity.frameSpriteSettings & 1) {
swordBeam = GetSwordBeam();
if (swordBeam && FindEntityByID(PLAYER_ITEM, PLAYER_ITEM_SWORD_BEAM1, 2) == 0) {
CreatePlayerItemWithParent(this, PLAYER_ITEM_SWORD_BEAM1);
if (swordBeam == 0xf) {
// SKILL_SWORD_BEAM (full health)
gPlayerState.lastSwordMove = SWORD_MOVE_FULL_BEAM;
} else {
// SKILL_PERIL_BEAM (low health)
gPlayerState.lastSwordMove = SWORD_MOVE_LOW_BEAM;
}
}
}
if ((this->playerFrame & 0x80) != 0) {
if (((gPlayerState.flags & PL_MINISH) != 0) || ((gPlayerState.skills & SKILL_SPIN_ATTACK) == 0)) {
sub_080759B8(this, index);
} else {
sub_08075580(this, index);
}
}
} else {
sub_080759B8(this, index);
}
}
void sub_08075580(ItemBehavior* this, u32 index) {
if ((IsItemActive(this) != 0) && (gPlayerState.jump_status == 0)) {
gPlayerState.field_0xa = gPlayerState.field_0xa & ~(8 >> index);
gPlayerState.sword_state = 1;
gPlayerState.item->hurtType = 0xd;
this->animPriority = 0;
this->stateID = 2;
if ((gPlayerState.skills & SKILL_FAST_SPIN) != 0) {
this->timer = 0x28; // TODO spin speed?
} else {
this->timer = 0x50;
}
SetItemAnim(this, ANIM_SWORD_CHARGE);
CreateObject(SWORD_PARTICLE, 0, 0);
return;
}
sub_080759B8(this, index);
}
void sub_080755F0(ItemBehavior* this, u32 index) {
if (IsItemActive(this) != 0) {
if (sub_08077EC8(this) == 0) {
if ((gPlayerState.sword_state | gPlayerState.attack_status) != 0) {
if (--this->timer == 0) {
this->stateID = 3;
this->priority |= 0x80;
gPlayerState.sword_state = gPlayerState.sword_state | 0x20;
}
} else {
sub_080759B8(this, index);
}
}
} else {
sub_080759B8(this, index);
}
}
void sub_0807564C(ItemBehavior* this, u32 index) {
if ((gPlayerState.sword_state | gPlayerState.attack_status) == 0) {
sub_080759B8(this, index);
} else {
if ((sub_08077EC8(this) == 0) && ((IsItemActive(this) == 0 || ((gPlayerState.sword_state & 0x80) != 0)))) {
sub_08075694(this, index);
}
}
}
void sub_08075694(ItemBehavior* this, u32 index) {
this->timer = 1;
if (gPlayerState.flags & PL_SWORD_THRUST) {
gPlayerState.flags &= ~PL_SWORD_THRUST;
gPlayerState.flags &= ~PL_ROLLING;
SetItemAnim(this, ANIM_ROLLATTACK_SPIN);
} else {
gPlayerState.lastSwordMove = SWORD_MOVE_SPIN;
SetItemAnim(this, ANIM_SPINATTACK);
}
gPlayerState.field_0xa = (8 >> index) | gPlayerState.field_0xa;
this->stateID = 4;
this->animPriority = 6;
gPlayerEntity.hurtType = 0x1e;
gPlayerState.sword_state |= 0x40;
gPlayerState.sword_state &= 0xdf;
if ((gPlayerState.chargeState.action == 4) && ((gPlayerState.flags & PL_CLONING) == 0)) {
gPlayerState.chargeState.action = 1;
DeleteClones();
}
SoundReq(SFX_PLY_VO2);
}
void sub_08075738(ItemBehavior* this, u32 index) {
u32 bVar6;
if (gPlayerState.attack_status == 0) {
sub_080759B8(this, index);
} else {
UpdateItemAnim(this);
if (IsItemActivatedThisFrame(this)) {
this->timer = 2;
}
if ((gPlayerState.sword_state & 0x10) != 0) {
if (!(gPlayerState.direction & DIR_NOT_MOVING_CHECK)) {
this->direction = gPlayerState.direction;
}
gPlayerEntity.direction = this->direction;
gPlayerEntity.speed = 0x180;
if ((this->playerFrame & 0x80) != 0) {
bVar6 = 10;
if ((gPlayerState.skills & SKILL_LONG_SPIN) != 0) {
bVar6 = 0xf;
}
if ((bVar6 <= ++this->subtimer) || (--this->timer == 0)) {
sub_080759B8(this, index);
}
}
} else {
if (((((gPlayerEntity.frameSpriteSettings & 1) != 0) && ((gPlayerState.sword_state & 0x80) == 0)) &&
((gPlayerState.skills & SKILL_FOURSWORD) != 0))) {
Entity* bombEnt = CreatePlayerItemWithParent(this, PLAYER_ITEM_SPIRAL_BEAM);
if (bombEnt) {
bombEnt->animationState = (gPlayerEntity.animationState & 6) | 0x80;
}
}
if ((((gPlayerEntity.frameSpriteSettings & 2) != 0) && ((gPlayerState.sword_state & 0x80) == 0)) &&
(((gPlayerState.skills & SKILL_GREAT_SPIN) != 0 && (--this->timer != 0)))) {
gPlayerState.sword_state |= 0x10;
gPlayerState.lastSwordMove = SWORD_MOVE_GREAT_SPIN;
this->direction = gPlayerEntity.animationState << 2;
this->timer = 1;
this->subtimer = 1;
gPlayerState.field_0xa = gPlayerState.field_0xa & ~(8 >> index);
SetItemAnim(this, ANIM_GREATSPIN);
}
if ((this->playerFrame & 0x80) != 0) {
sub_080759B8(this, index);
}
}
}
}
void sub_08075898(ItemBehavior* this, u32 index) {
if (gPlayerState.attack_status == 0) {
sub_080759B8(this, index);
}
}
void sub_080758B0(ItemBehavior* this, u32 index) {
if (gPlayerState.attack_status == 0) {
sub_080759B8(this, index);
} else {
UpdateItemAnim(this);
if ((this->playerFrame & 0x80) != 0) {
this->animPriority = 0;
if ((gPlayerState.sword_state & 0x20) != 0) {
this->stateID = 3;
} else {
this->stateID = 5;
}
gPlayerState.sword_state &= 0xf7;
}
}
}
void sub_08075900(ItemBehavior* this, u32 index) {
if (gPlayerState.floor_type == SURFACE_SWAMP) {
gPlayerState.flags &= ~PL_ROLLING;
sub_080759B8(this, index);
} else {
UpdateItemAnim(this);
if ((gPlayerState.sword_state & 0x80) != 0) {
gPlayerState.sword_state = 0xa0;
sub_0807564C(this, index);
} else {
if (this->timer != 0) {
if (--this->timer == 0) {
SetItemAnim(this, ANIM_ROLLATTACK_END);
}
gPlayerEntity.direction = (gPlayerEntity.animationState >> 1) << 3;
gPlayerEntity.speed = 0x300;
UpdatePlayerMovement();
if ((gRoomTransition.frameCount & 3) == 0) {
CreateFx(&gPlayerEntity, FX_DASH, 0x40);
}
} else {
if ((this->playerFrame & 0x80) != 0) {
gPlayerState.flags &= ~PL_ROLLING;
sub_080759B8(this, index);
}
}
}
}
}
void sub_080759B8(ItemBehavior* this, u32 index) {
if ((gPlayerState.flags & PL_MINISH) == 0) {
gPlayerEntity.hurtType = 0;
}
gPlayerState.flags &= ~PL_SWORD_THRUST;
gPlayerState.sword_state = 0;
gPlayerState.item = NULL;
DeleteItemBehavior(this, index);
}