| 69 | } |
| 70 | |
| 71 | void AnimateItem(ItemInfo& item) |
| 72 | { |
| 73 | if (!item.IsLara()) |
| 74 | { |
| 75 | item.TouchBits.ClearAll(); |
| 76 | item.HitStatus = false; |
| 77 | } |
| 78 | |
| 79 | ExecuteAnimCommands(item, true); |
| 80 | item.Animation.FrameNumber++; |
| 81 | |
| 82 | const auto* anim = &GetAnimData(item); |
| 83 | |
| 84 | const auto* dispatch = GetStateDispatch(item); |
| 85 | if (dispatch != nullptr) |
| 86 | { |
| 87 | SetStateDispatch(item, *dispatch); |
| 88 | anim = &GetAnimData(item); |
| 89 | |
| 90 | item.Animation.ActiveState = anim->StateID; |
| 91 | |
| 92 | if (!item.IsLara()) |
| 93 | { |
| 94 | // Reset RequiredState if already reached. |
| 95 | if (item.Animation.RequiredState == item.Animation.ActiveState) |
| 96 | item.Animation.RequiredState = NO_VALUE; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | if (item.Animation.FrameNumber > anim->EndFrameNumber) |
| 101 | { |
| 102 | ExecuteAnimCommands(item, false); |
| 103 | |
| 104 | item.Animation.AnimNumber = anim->NextAnimNumber; |
| 105 | item.Animation.FrameNumber = anim->NextFrameNumber; |
| 106 | |
| 107 | anim = &GetAnimData(item); |
| 108 | |
| 109 | if (item.Animation.ActiveState != anim->StateID) |
| 110 | { |
| 111 | item.Animation.ActiveState = |
| 112 | item.Animation.TargetState = anim->StateID; |
| 113 | } |
| 114 | |
| 115 | if (!item.IsLara()) |
| 116 | { |
| 117 | // Reset RequiredState if already reached. |
| 118 | if (item.Animation.RequiredState == item.Animation.ActiveState) |
| 119 | item.Animation.RequiredState = NO_VALUE; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | auto animAccel = (anim->VelocityEnd - anim->VelocityStart) / std::max(anim->EndFrameNumber, 1); |
| 124 | auto animVel = anim->VelocityStart + (animAccel * item.Animation.FrameNumber); |
| 125 | |
| 126 | if (item.Animation.IsAirborne) |
| 127 | { |
| 128 | if (item.IsLara()) |