| 196 | } |
| 197 | |
| 198 | void CBulletManager::FireShotmark(SBullet* bullet, const Fvector& vDir, const Fvector& vEnd, collide::rq_result& R, u16 target_material, const Fvector& vNormal, bool ShowMark) |
| 199 | { |
| 200 | SGameMtlPair* mtl_pair = GMLib.GetMaterialPair(bullet->bullet_material_idx, target_material); |
| 201 | Fvector particle_dir = vNormal; |
| 202 | |
| 203 | if (R.O) |
| 204 | { |
| 205 | particle_dir = vDir; |
| 206 | particle_dir.invert(); |
| 207 | |
| 208 | //на текущем актере отметок не ставим |
| 209 | if (!smart_cast<CActor*>(R.O) && mtl_pair && !mtl_pair->m_pCollideMarks->empty() && ShowMark) |
| 210 | { |
| 211 | //добавить отметку на материале |
| 212 | Fvector p; |
| 213 | p.mad(bullet->pos, bullet->dir, R.range - 0.01f); |
| 214 | ::Render->add_SkeletonWallmark(&R.O->renderable.xform, PKinematics(R.O->Visual()), &*mtl_pair->m_pCollideMarks, p, bullet->dir, bullet->wallmark_size); |
| 215 | } |
| 216 | } |
| 217 | else |
| 218 | { |
| 219 | //вычислить нормаль к пораженной поверхности |
| 220 | Fvector* pVerts = Level().ObjectSpace.GetStaticVerts(); |
| 221 | CDB::TRI* pTri = Level().ObjectSpace.GetStaticTris() + R.element; |
| 222 | |
| 223 | if (mtl_pair && !mtl_pair->m_pCollideMarks->empty() && ShowMark) |
| 224 | { |
| 225 | //добавить отметку на материале |
| 226 | ::Render->add_StaticWallmark(&*mtl_pair->m_pCollideMarks, vEnd, bullet->wallmark_size, pTri, pVerts); |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | ref_sound* pSound = (!mtl_pair || mtl_pair->CollideSounds.empty()) ? NULL : &mtl_pair->CollideSounds[::Random.randI(0, mtl_pair->CollideSounds.size())]; |
| 231 | |
| 232 | //проиграть звук |
| 233 | if (pSound && ShowMark) |
| 234 | { |
| 235 | CObject* O = Level().Objects.net_Find(bullet->parent_id); |
| 236 | bullet->m_mtl_snd = *pSound; |
| 237 | bullet->m_mtl_snd.play_at_pos(O, vEnd, 0); |
| 238 | } |
| 239 | |
| 240 | LPCSTR ps_name = (!mtl_pair || mtl_pair->CollideParticles.empty()) ? NULL : *mtl_pair->CollideParticles[::Random.randI(0, mtl_pair->CollideParticles.size())]; |
| 241 | |
| 242 | SGameMtl* tgt_mtl = GMLib.GetMaterialByIdx(target_material); |
| 243 | BOOL bStatic = !tgt_mtl->Flags.test(SGameMtl::flDynamic); |
| 244 | |
| 245 | if ((ps_name && ShowMark) || (bullet->flags.explosive && bStatic)) |
| 246 | { |
| 247 | Fmatrix pos; |
| 248 | pos.k.normalize(particle_dir); |
| 249 | Fvector::generate_orthonormal_basis(pos.k, pos.j, pos.i); |
| 250 | pos.c.set(vEnd); |
| 251 | if (ps_name && ShowMark) |
| 252 | { |
| 253 | //отыграть партиклы попадания в материал |
| 254 | CParticlesObject* ps = CParticlesObject::Create(ps_name, TRUE); |
| 255 |
nothing calls this directly
no test coverage detected