Line data Source code
1 : #include "core/animations/AnimationState.hpp"
2 :
3 : #include "core/entities/Soldier.hpp"
4 :
5 : #include "core/physics/PhysicsEvents.hpp"
6 :
7 : #include <utility>
8 : #include <algorithm>
9 :
10 : namespace Soldank
11 : {
12 0 : AnimationState::AnimationState(std::shared_ptr<const AnimationData> animation_data)
13 0 : : animation_data_(std::move(animation_data))
14 0 : , speed_(animation_data_->GetSpeed())
15 0 : , count_(0)
16 0 : , frame_(1)
17 : {
18 0 : }
19 :
20 0 : void AnimationState::DoAnimation()
21 : {
22 0 : count_ += 1;
23 :
24 0 : if (count_ == speed_) {
25 0 : count_ = 0;
26 0 : frame_ += 1;
27 :
28 0 : if (frame_ > GetFramesCount()) {
29 0 : if (animation_data_->GetLooped()) {
30 0 : frame_ = 1;
31 : } else {
32 0 : frame_ = GetFramesCount();
33 : }
34 : }
35 : }
36 0 : }
37 :
38 0 : const glm::vec2& AnimationState::GetPosition(unsigned int index) const
39 : {
40 0 : return animation_data_->GetFrames().at(frame_ - 1).positions.at(index - 1);
41 : }
42 :
43 0 : unsigned int AnimationState::GetFramesCount() const
44 : {
45 0 : return animation_data_->GetFrames().size();
46 : }
47 :
48 0 : bool AnimationState::IsAny(const std::vector<AnimationType>& animations) const
49 : {
50 0 : return std::ranges::any_of(animations, [this](AnimationType animation_type) {
51 0 : return animation_type == animation_data_->GetAnimationType();
52 0 : });
53 : }
54 :
55 0 : void AnimationState::TryToShoot(Soldier& soldier, const PhysicsEvents& physics_events) const
56 : {
57 0 : if (soldier.weapons[soldier.active_weapon].GetWeaponParameters().kind == WeaponType::NoWeapon ||
58 0 : soldier.weapons[soldier.active_weapon].GetWeaponParameters().kind == WeaponType::Knife) {
59 :
60 : // We don't spawn projectiles for punching or stabbing... These have to be handled by the
61 : // animation
62 0 : return;
63 : }
64 :
65 0 : if (soldier.control.fire && IsSoldierShootingPossible(soldier)) {
66 0 : physics_events.soldier_fires_primary_weapon.Notify(soldier);
67 : }
68 : }
69 :
70 0 : void AnimationState::TryToThrowFlags(Soldier& soldier, const PhysicsEvents& physics_events) const
71 : {
72 0 : if (IsSoldierFlagThrowingPossible(soldier)) {
73 0 : if (soldier.control.flag_throw && soldier.is_holding_flags) {
74 0 : physics_events.soldier_throws_flags.Notify(soldier);
75 : }
76 : }
77 0 : }
78 :
79 0 : void AnimationState::Enter(Soldier& soldier) {}
80 :
81 0 : void AnimationState::Update(Soldier& soldier, const PhysicsEvents& physics_events) {}
82 :
83 0 : void AnimationState::Exit(Soldier& soldier, const PhysicsEvents& physics_events) {}
84 :
85 0 : bool AnimationState::IsSoldierShootingPossible(const Soldier& /*soldier*/) const
86 : {
87 : // By default we return false. Child classes should determine whether the player is able to
88 : // shoot or not in the current state
89 0 : return false;
90 : }
91 :
92 0 : bool AnimationState::IsSoldierFlagThrowingPossible(const Soldier& /*soldier*/) const
93 : {
94 : // By default we return false. Child classes should determine whether the player is able to
95 : // throw flags or not in the current state
96 0 : return false;
97 : }
98 : } // namespace Soldank
|