263 lines
8.2 KiB
C
263 lines
8.2 KiB
C
#include "PlayerStates.h"
|
|
#include "Hurtbox.h"
|
|
|
|
#include "Damagable.h"
|
|
#include "Player.h"
|
|
#include "animation_sprite.h"
|
|
|
|
// flip the facing direction of the player based on input
|
|
// does not do movement
|
|
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, const State* fallback) {
|
|
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 PlayerSlash();
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
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->jumpInput)
|
|
return PlayerJump();
|
|
return PlayerTryStartNewChain(self, 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();
|
|
if(self->jumpInput)
|
|
return PlayerJump();
|
|
InternalSpriteFlipWithMovement(self);
|
|
return PlayerTryStartNewChain(self, 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, NULL);
|
|
}
|
|
|
|
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 = 7.0f,
|
|
};
|
|
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 >= 1.5f)
|
|
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 = 7.0f,
|
|
};
|
|
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 = 2,
|
|
.knockdown = 1,
|
|
.stun = 0.5f,
|
|
.knockback = 15.0f,
|
|
};
|
|
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(ntime >= 1.f)
|
|
return PlayerIdle();
|
|
return PlayerKickA();
|
|
}
|
|
|
|
void PlayerSlash_Enter(Player* self) {
|
|
PlayerAttackEnter(self);
|
|
self->currentAnimation = self->slash;
|
|
animation_sprite_play_from(self->currentAnimation, 0.f);
|
|
}
|
|
|
|
const State* PlayerSlash_Update(Player* self, float deltaTime) {
|
|
static const DamageEventData damage = {
|
|
.damageAmount = 2,
|
|
.knockdown = 0,
|
|
.stun = 0.5f,
|
|
.knockback = 4.f
|
|
};
|
|
const float ntime = animation_sprite_get_time_normalized(self->currentAnimation);
|
|
const size_t frame = sprite_get_tile(self->sprite);
|
|
if(frame >= 2 && self->animationTriggers == 0) {
|
|
++self->animationTriggers;
|
|
PlayerHurtbox(self, damage, MakeVector(0.4f, 0.1f), MakeVector(0.2f, -0.7f));
|
|
}
|
|
if(!veqf(self->moveInput, ZeroVector) && ntime > 1.05f)
|
|
return PlayerWalk();
|
|
if(ntime >= 1.f)
|
|
return PlayerIdle();
|
|
return PlayerSlash();
|
|
|
|
}
|
|
|
|
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 = 0.1f,
|
|
.knockback = 17.0f,
|
|
};
|
|
static const float duration = 0.2f;
|
|
static const float speed = 4.f;
|
|
const float time = animation_sprite_get_time(self->currentAnimation);
|
|
rigidbody_set_velocity(self->rigidbody, MakeVector(self->facing * speed, -0.05f));
|
|
if(time > duration)
|
|
return PlayerIdle();
|
|
if(time > 0.1f) {
|
|
PlayerHurtbox(self, damage, MakeVector(0.2f, 0.15f), MakeVector(0.21f, -0.6f));
|
|
}
|
|
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;
|
|
}
|