#include "PlayerStates.h" #include "Hurtbox.h" #include "Damagable.h" #include "Player.h" static inline void InternalSpriteFlipWithMovement(Player* self) { if(self->moveInput.x > 0.f) self->facing = 1; if(self->moveInput.x < -0.1f) self->facing = -1; sprite_flip_horizontal(self->sprite, self->facing != 1); } void PlayerAnimationExit(Player* self) { self->animationTriggers = 0; self->attackInput = 0; } static const State* PlayerTryStartNewChain(Player* self) { if(self->attackInput == 1) { return PlayerJabA(); } if(self->attackInput == 2) { if(self->height > 0.f) return PlayerAirHeavy(); else if(PlayerInputIsQuarterCircleForward(self)) return PlayerSlide(); else return PlayerKickA(); } return NULL; } void PlayerIdleEnter(Player* self) { self->currentAnimation = self->idle; rigidbody_set_velocity(self->rigidbody, ZeroVector); animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerIdleUpdate(Player* self, float deltaTime) { if(!veqf(self->moveInput, ZeroVector)) return PlayerWalk(); if(self->attackInput == 1) return PlayerJabA(); if(self->attackInput == 2) return PlayerKickA(); if(self->jumpInput) return PlayerJump(); return PlayerIdle(); } void PlayerWalk_Enter(Player* self) { self->currentAnimation = self->walk; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerWalk_Update(Player* self, float deltaTime) { rigidbody_set_velocity(self->rigidbody, vmulf(vnormalizedf(self->moveInput), PLAYER_SPEED)); if(veqf(self->moveInput, ZeroVector)) return PlayerIdle(); const State* attackState = PlayerTryStartNewChain(self); if(attackState) return attackState; if(self->jumpInput) return PlayerJump(); InternalSpriteFlipWithMovement(self); return PlayerWalk(); } void PlayerAttackEnter(Player* self) { self->attackInput = 0; rigidbody_set_velocity(self->rigidbody, ZeroVector); InternalSpriteFlipWithMovement(self); } static void PlayerHurtbox(Player* self, DamageEventData damage, Vector hitbox_size, Vector offset) { Hurtbox box = { .owner = Player_as_BehaviourEntity(self), .damage = damage, .size = hitbox_size, .offset = vaddf(offset, MakeVector(0.f, self->height)), .depth_extent = 0.15f, }; HurtboxCast(&box, self->facing); } void PlayerJabA_Enter(Player* self) { PlayerAttackEnter(self); self->currentAnimation = self->jab_a; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerJabA_Update(Player* self, float deltaTime) { const static DamageEventData damage = { .damageAmount = 1, .knockdown = 0, .stun = 0.15f, .knockback = 0.07f, }; const float ntime = animation_sprite_get_time_normalized(self->currentAnimation); if(self->animationTriggers == 0 && ntime > 0.33f) { PlayerHurtbox(self, damage, MakeVector(0.1f, 0.1f), MakeVector(0.265f, -0.6f)); ++self->animationTriggers; } if(ntime > 1.0f) { if(self->attackInput == 1) return PlayerJabB(); else if(self->attackInput == 2) return PlayerKickA(); } if(!veqf(self->moveInput, ZeroVector) && ntime > 1.05f) return PlayerWalk(); if(ntime >= 2.0f) return PlayerIdle(); return PlayerJabA(); } void PlayerJabB_Enter(Player* self) { PlayerAttackEnter(self); self->currentAnimation = self->jab_b; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerJabB_Update(Player* self, float deltaTime) { static const DamageEventData damage = { .damageAmount = 1, .knockdown = 0, .stun = 0.15f, .knockback = 0.05f, }; const float ntime = animation_sprite_get_time_normalized(self->currentAnimation); const size_t frame = sprite_get_tile(self->sprite); if(self->animationTriggers == 0 && ntime > 0.33f) { PlayerHurtbox(self, damage, MakeVector(0.13f, 0.05f), MakeVector(0.32f, -0.7f)); ++self->animationTriggers; } if(ntime > 1.0f && self->attackInput == 1) return PlayerKickA(); if(!veqf(self->moveInput, ZeroVector) && ntime > 1.05f) return PlayerWalk(); if(ntime >= 2.0f) return PlayerIdle(); return PlayerJabB(); } void PlayerKickA_Enter(Player* self) { PlayerAttackEnter(self); self->currentAnimation = self->kick_a; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerKickA_Update(Player* self, float deltaTime) { static const DamageEventData damage = { .damageAmount = 3, .knockdown = 1, .stun = 0.5f, .knockback = 0.15f, }; const float ntime = animation_sprite_get_time_normalized(self->currentAnimation); const size_t frame = sprite_get_tile(self->sprite); if(frame >= 3 && frame <= 4) { PlayerHurtbox(self, damage, MakeVector(0.16f, 0.06f), MakeVector(0.33f, -0.4f)); } if(!veqf(self->moveInput, ZeroVector) && ntime > 1.05f) return PlayerWalk(); if(ntime >= 1.f) return PlayerIdle(); return PlayerKickA(); } void PlayerSlide_Enter(Player* self) { PlayerAttackEnter(self); self->currentAnimation = self->slide; // adjust for the downward motion of the quartercircle Transform* trans = rigidbody_get_transform(self->rigidbody); trans->position.y -= 0.03f; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerSlide_Update(Player* self, float deltaTime) { static const DamageEventData damage = { .damageAmount = 3, .knockdown = 1, .stun = 1.f, .knockback = 0.3f, }; const float time = animation_sprite_get_time(self->currentAnimation); rigidbody_set_velocity(self->rigidbody, MakeVector(self->facing * 3.f, -0.05f)); if(time > 0.34f) return PlayerIdle(); if(time > 0.1f) PlayerHurtbox(self, damage, MakeVector(0.16, 0.06f), MakeVector(0.33f, -0.03f)); return PlayerSlide(); } void PlayerJump_Enter(Player* self) { if(self->jumpInput) { self->jumpInput = 0; self->currentAnimation = self->jump; self->verticalVelocity = 3.f; } animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerJump_Update(Player* self, float deltaTime) { self->verticalVelocity -= 5.f * deltaTime; if(self->height == 0.f) { self->verticalVelocity = 0.f; return PlayerIdle(); } if(self->attackInput == 2) return PlayerAirHeavy(); return PlayerJump(); } void PlayerAirHeavy_Enter(Player* self) { self->currentAnimation = self->air_heavy; animation_sprite_play_from(self->currentAnimation, 0.f); } const State* PlayerAirHeavy_Update(Player* self, float deltaTime) { const static DamageEventData damage = { .damageAmount = 4, .knockdown = 1, .stun = 0.75f, .knockback = 0.15f }; const float ntime = animation_sprite_get_time_normalized(self->currentAnimation); size_t frame = sprite_get_tile(self->sprite); if(frame == 1) PlayerHurtbox(self, damage, MakeVector(0.12f, 0.12f), MakeVector(0.12f, -0.48f)); const State* result = PlayerJump_Update(self, deltaTime); return (result == PlayerJump()) ? PlayerAirHeavy() : result; }