| 107 | } |
| 108 | |
| 109 | void CStepManager::update() |
| 110 | { |
| 111 | START_PROFILE("Step Manager") |
| 112 | |
| 113 | if (m_step_info.disable) |
| 114 | return; |
| 115 | if (!m_blend) |
| 116 | return; |
| 117 | |
| 118 | SGameMtlPair* mtl_pair = m_object->material().get_current_pair(); |
| 119 | if (!mtl_pair) |
| 120 | return; |
| 121 | |
| 122 | // получить параметры шага |
| 123 | SStepParam& step = m_step_info.params; |
| 124 | u32 cur_time = Device.dwTimeGlobal; |
| 125 | |
| 126 | // время одного цикла анимации |
| 127 | float cycle_anim_time = get_blend_time() / step.cycles; |
| 128 | |
| 129 | // пройти по всем ногам и проверить время |
| 130 | for (u32 i = 0; i < m_legs_count; i++) |
| 131 | { |
| 132 | // если событие уже обработано для этой ноги, то skip |
| 133 | if (m_step_info.activity[i].handled && (m_step_info.activity[i].cycle == m_step_info.cur_cycle)) |
| 134 | continue; |
| 135 | |
| 136 | // вычислить смещённое время шага в соответствии с параметрами анимации ходьбы |
| 137 | u32 offset_time = m_time_anim_started + u32(1000 * (cycle_anim_time * (m_step_info.cur_cycle - 1) + cycle_anim_time * step.step[i].time)); |
| 138 | if (offset_time <= cur_time) |
| 139 | { |
| 140 | // Играть звук |
| 141 | if (is_on_ground()) |
| 142 | { |
| 143 | auto actor = smart_cast<CActor*>(m_object); |
| 144 | |
| 145 | if (mtl_pair->StepSounds.empty()) |
| 146 | { |
| 147 | if (actor) |
| 148 | { |
| 149 | Msg("!![%s] no sound for steps pair id0:[%d], id1:[%d]", __FUNCTION__, mtl_pair->GetMtl0(), mtl_pair->GetMtl1()); |
| 150 | } |
| 151 | |
| 152 | return; |
| 153 | } |
| 154 | |
| 155 | Fvector sound_pos = m_object->Position(); |
| 156 | sound_pos.y += 0.5; |
| 157 | GET_RANDOM(mtl_pair->StepSounds).play_no_feedback(m_object, 0, 0, &sound_pos, &m_step_info.params.step[i].power); |
| 158 | |
| 159 | if (actor) |
| 160 | actor->callback(GameObject::eOnActorFootStep)(actor->lua_game_object(), m_step_info.params.step[i].power); |
| 161 | } |
| 162 | |
| 163 | // Играть партиклы |
| 164 | if (!mtl_pair->CollideParticles.empty()) |
| 165 | { |
| 166 | LPCSTR ps_name = *mtl_pair->CollideParticles[::Random.randI(0, mtl_pair->CollideParticles.size())]; |
nothing calls this directly
no test coverage detected