void CControlManagerCustom::check_jump_over_physics() { if (!m_man->path_builder().is_moving_on_path()) return; if (!m_man->check_start_conditions(ControlCom::eControlJump)) return; if (!m_object->check_start_conditions(ControlCom::eControlJump)) return; if (m_object->GetScriptControl()) return; Fvector prev_pos = m_object->Position(); float dist_sum = 0.f; for(u32 i = m_man->path_builder().detail().curr_travel_point_index(); i<m_man->path_builder().detail().path().size();i++) { const DetailPathManager::STravelPathPoint &travel_point = m_man->path_builder().detail().path()[i]; // получить список объектов вокруг врага m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,travel_point.position, m_object->Radius(), NULL); for (u32 k=0;k<m_nearest.size();k++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[k]); if (!obj || !obj->PPhysicsShell() || !obj->PPhysicsShell()->isActive() || (obj->Radius() < 0.5f)) continue; if (m_object->Position().distance_to(obj->Position()) < MAX_DIST_SUM / 2) continue; Fvector dir = Fvector().sub(travel_point.position, m_object->Position()); // проверка на Field-Of-View float my_h = m_object->Direction().getH(); float h = dir.getH(); float from = angle_normalize(my_h - deg(8)); float to = angle_normalize(my_h + deg(8)); if (!is_angle_between(h, from, to)) continue; dir = Fvector().sub(obj->Position(), m_object->Position()); // вычислить целевую позицию для прыжка Fvector target; obj->Center(target); target.y += obj->Radius(); // -------------------------------------------------------- m_jump->setup_data().flags.set (SControlJumpData::ePrepareSkip, true); m_jump->setup_data().target_object = 0; m_jump->setup_data().target_position = target; jump(m_jump->setup_data()); return; } dist_sum += prev_pos.distance_to(travel_point.position); if (dist_sum > MAX_DIST_SUM) break; prev_pos = travel_point.position; } }
void CMosquitoBald::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(O->object); if(!pGameObject) return; if(O->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); Fvector hit_dir; hit_dir.set( ::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = Power(dist>0.f?dist:0.f, Radius()); float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); if(power > 0.01f) { position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); PlayHitParticles(pGameObject); } }
void CMosquitoBald::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(O->object); if(!pGameObject) return; if(O->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); #ifdef DEBUG char l_pow[255]; sprintf_s(l_pow, "zone hit. %.1f", Power(pGameObject->Position().distance_to(P))); if(bDebug) Msg("%s %s",*pGameObject->cName(), l_pow); #endif Fvector hit_dir; hit_dir.set(::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = Power(dist>0.f?dist:0.f); float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); //статистика по объекту O->total_damage += power; O->hit_num++; if(power > 0.01f) { m_dwDeltaTime = 0; position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); PlayHitParticles(pGameObject); } }
void CMosquitoBald::UpdateSecondaryHit() { if(m_dwAffectFrameNum == Device.dwFrame) return; m_dwAffectFrameNum = Device.dwFrame; if(Device.dwPrecacheFrame) return; OBJECT_INFO_VEC_IT it; for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { if(!(*it).object->getDestroy()) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>((&(*it))->object); if(!pGameObject) return; if((&(*it))->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); Fvector hit_dir; hit_dir.set( ::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = m_fSecondaryHitPower * RelativePower(dist>0.f?dist:0.f, Radius()); if(power<0.0f) return; float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); } } }