| 370 | #endif |
| 371 | |
| 372 | std::pair<float, float> CBulletManager::ObjectHit(SBullet* bullet, const Fvector& end_point, collide::rq_result& R, u16 target_material, Fvector& hit_normal) |
| 373 | { |
| 374 | //----------- normal - start |
| 375 | if (R.O) |
| 376 | { |
| 377 | //вернуть нормаль по которой играть партиклы |
| 378 | CCF_Skeleton* skeleton = smart_cast<CCF_Skeleton*>(R.O->CFORM()); |
| 379 | if (skeleton) |
| 380 | { |
| 381 | Fvector e_center; |
| 382 | hit_normal.set(0, 0, 0); |
| 383 | if (skeleton->_ElementCenter((u16)R.element, e_center)) |
| 384 | hit_normal.sub(end_point, e_center); |
| 385 | float len = hit_normal.square_magnitude(); |
| 386 | if (!fis_zero(len)) |
| 387 | hit_normal.div(_sqrt(len)); |
| 388 | else |
| 389 | hit_normal.invert(bullet->dir); |
| 390 | } |
| 391 | } |
| 392 | else |
| 393 | { |
| 394 | //вычислить нормаль к поверхности |
| 395 | Fvector* pVerts = Level().ObjectSpace.GetStaticVerts(); |
| 396 | CDB::TRI* pTri = Level().ObjectSpace.GetStaticTris() + R.element; |
| 397 | hit_normal.mknormal(pVerts[pTri->verts[0]], pVerts[pTri->verts[1]], pVerts[pTri->verts[2]]); |
| 398 | } |
| 399 | //----------- normal - end |
| 400 | float old_speed, energy_lost; |
| 401 | old_speed = bullet->speed; |
| 402 | |
| 403 | //коэффициент уменьшение силы с падением скорости |
| 404 | float speed_factor = bullet->speed / bullet->max_speed; |
| 405 | //получить силу хита выстрела с учетом патрона |
| 406 | float power = bullet->hit_power * speed_factor; |
| 407 | |
| 408 | SGameMtl* mtl = GMLib.GetMaterialByIdx(target_material); |
| 409 | |
| 410 | // shoot_factor: коеффициент указывающий на текущие свойства пули |
| 411 | //(Если меньше 1, то пуля либо рикошетит(если контакт идёт по касательной), либо застряёт в текущем |
| 412 | //объекте, если больше 1, то пуля прошивает объект) |
| 413 | float shoot_factor = mtl->fShootFactor * bullet->pierce * speed_factor; |
| 414 | |
| 415 | float impulse = 0.f; |
| 416 | |
| 417 | #ifdef DEBUG |
| 418 | Fvector dbg_bullet_pos; |
| 419 | dbg_bullet_pos.mad(bullet->pos, bullet->dir, R.range); |
| 420 | int bullet_state = 0; |
| 421 | #endif |
| 422 | |
| 423 | if (fsimilar(mtl->fShootFactor, 1.0f, EPS)) //Если материал полностью простреливаемый, то |
| 424 | { |
| 425 | #ifdef DEBUG |
| 426 | bullet_state = 2; |
| 427 | #endif |
| 428 | return std::make_pair(power, impulse); |
| 429 | } |
nothing calls this directly
no test coverage detected