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 CPHDestroyable::InitServerObject(CSE_Abstract* D) { CPhysicsShellHolder *obj =PPhysicsShellHolder() ; CSE_ALifeDynamicObjectVisual *l_tpALifeDynamicObject = smart_cast<CSE_ALifeDynamicObjectVisual*>(D); VERIFY (l_tpALifeDynamicObject); l_tpALifeDynamicObject->m_tGraphID =obj->ai_location().game_vertex_id(); l_tpALifeDynamicObject->m_tNodeID = obj->ai_location().level_vertex_id(); // l_tpALifePhysicObject->startup_animation=m_startup_anim; D->set_name_replace (""); //. D->s_gameid = u8(GameID()); D->s_RP = 0xff; D->ID = 0xffff; D->ID_Phantom = 0xffff; D->o_Position = obj->Position(); if (ai().get_alife()) l_tpALifeDynamicObject->m_tGraphID = ai().game_graph().current_level_vertex(); else l_tpALifeDynamicObject->m_tGraphID = 0xffff; obj->XFORM().getXYZ (D->o_Angle); D->s_flags.assign (M_SPAWN_OBJECT_LOCAL); D->RespawnTime = 0; }
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 CBaseGraviZone ::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder* GO = smart_cast<CPhysicsShellHolder*>(O->object); if(!GO) return; ////////////////////////////////////////////////////////////////////////// // зат¤гиваем объет по направлению к центру зоны Fvector throw_in_dir; Fvector zone_center; ThrowInCenter(zone_center); throw_in_dir.sub(zone_center, GO->Position()); float dist = throw_in_dir.magnitude(); float dist_to_radius = dist/Radius(); if(!fis_zero(dist)) { throw_in_dir.mul(1.f/dist); } else throw_in_dir.set(0.f,1.f,0.f); //--------------------------------------------------------- bool CanApplyPhisImpulse = GO->Local() == TRUE; /* if (EA && EA->g_Alive()) { CanApplyPhisImpulse &= (Level().CurrentControlEntity() && Level().CurrentControlEntity() == EA); };*/ //--------------------------------------------------------- if( CheckAffectField(GO,dist_to_radius)&& CanApplyPhisImpulse) { AffectPull(GO,throw_in_dir,dist); } else { ////////////////////////////////////////////////////////////////////////// // выброс аномалии //если врем¤ выброса еще не пришло if(m_dwBlowoutExplosionTime<(u32)m_iPreviousStateTime || m_dwBlowoutExplosionTime>=(u32)m_iStateTime) { AffectPull(GO,throw_in_dir,BlowoutRadiusPercent(GO)*Radius()); return; } AffectThrow(O,GO,throw_in_dir,dist); } }
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); } } }
void CBurer::UpdateGraviObject() { if ( !m_gravi_object.active ) { return; } if ( !m_gravi_object.enemy || (m_gravi_object.enemy && m_gravi_object.enemy->getDestroy()) ) { m_gravi_object.deactivate(); return; } if ( m_gravi_object.from_pos.distance_to(m_gravi_object.cur_pos) > m_gravi_object.from_pos.distance_to(m_gravi_object.target_pos) ) { m_gravi_object.deactivate(); return; } float dt = float(Device.dwTimeGlobal - m_gravi_object.time_last_update); float dist = dt * float(m_gravi.speed)/1000.f; if (dist < m_gravi.step) return; Fvector new_pos; Fvector dir; dir.sub(m_gravi_object.target_pos,m_gravi_object.cur_pos); dir.normalize(); new_pos.mad(m_gravi_object.cur_pos,dir,dist); // Trace to enemy Fvector enemy_center; m_gravi_object.enemy->Center(enemy_center); dir.sub(enemy_center, new_pos); dir.normalize(); float trace_dist = float(m_gravi.step); collide::rq_result l_rq; if (Level().ObjectSpace.RayPick(new_pos, dir, trace_dist, collide::rqtBoth, l_rq, NULL)) { const CObject *enemy = smart_cast<const CObject *>(m_gravi_object.enemy); if ((l_rq.O == enemy) && (l_rq.range < trace_dist)) { // check for visibility bool b_enemy_visible = false; xr_vector<CObject *> visible_objects; feel_vision_get(visible_objects); // find object for (u32 i = 0; i<visible_objects.size(); i++) { if (visible_objects[i] == enemy) { b_enemy_visible = true; break; } } if (b_enemy_visible) { Fvector impulse_dir; impulse_dir.set(0.0f,0.0f,1.0f); impulse_dir.normalize(); HitEntity(m_gravi_object.enemy, m_gravi.hit_power, m_gravi.impulse_to_enemy, impulse_dir, ALife::eHitTypeStrike, false); m_gravi_object.deactivate(); return; } } } m_gravi_object.cur_pos = new_pos; m_gravi_object.time_last_update = Device.dwTimeGlobal; // --------------------------------------------------------------------- // draw particle CParticlesObject* ps = CParticlesObject::Create(particle_gravi_wave,TRUE); // вычислить позицию и направленность партикла Fmatrix pos; pos.identity(); pos.k.set(dir); Fvector::generate_orthonormal_basis_normalized(pos.k,pos.j,pos.i); // установить позицию pos.translate_over(m_gravi_object.cur_pos); ps->UpdateParent(pos, zero_vel); ps->Play(false); // hit objects m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,m_gravi_object.cur_pos, m_gravi.radius, NULL); //xr_vector<CObject*> &m_nearest = Level().ObjectSpace.q_nearest; for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); if (!obj || !obj->m_pPhysicsShell) continue; Fvector dir; dir.sub(obj->Position(), m_gravi_object.cur_pos); dir.normalize(); obj->m_pPhysicsShell->applyImpulse(dir,m_gravi.impulse_to_objects * obj->m_pPhysicsShell->getMass()); } // играть звук Fvector snd_pos = m_gravi_object.cur_pos; snd_pos.y += 0.5f; if (sound_gravi_wave._feedback()) { sound_gravi_wave.set_position (snd_pos); } else ::Sound->play_at_pos (sound_gravi_wave,0,snd_pos); }
void CBlackGraviArtefact::GraviStrike() { xr_list<s16> elements_list; xr_list<Fvector> bone_position_list; Fvector object_pos ; Fvector strike_dir ; rq_storage.r_clear (); for(GAME_OBJECT_LIST_it it = m_GameObjectList.begin(); m_GameObjectList.end() != it; ++it) { CPhysicsShellHolder* pGameObject = *it; if(pGameObject->Visual()) pGameObject->Center(object_pos); else object_pos.set(pGameObject->Position()); strike_dir.sub(object_pos, Position()); float distance = strike_dir.magnitude(); float impulse = 100.f*m_fStrikeImpulse * (1.f - (distance/m_fRadius)* (distance/m_fRadius)); if(impulse > .001f) { //? BOOL enabled = getEnabled(); //? setEnabled (FALSE); impulse *= CExplosive::ExplosionEffect (rq_storage,NULL,pGameObject, Position(),m_fRadius); //? setEnabled (enabled); } float hit_power ; CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(pGameObject); if(pGameObject->m_pPhysicsShell) hit_power = 0; else if(pEntityAlive && pEntityAlive->g_Alive() && pEntityAlive->character_physics_support()->movement()->CharacterExist()) hit_power = 0; else hit_power = impulse; if(impulse > .001f) { while(!elements_list.empty()) { s16 element = elements_list.front(); Fvector bone_pos = bone_position_list.front(); NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, pGameObject->ID()); // u_EventGen (P,GE_HIT, pGameObject->ID()); HS.whoID =ID(); // P.w_u16 (ID()); HS.weaponID = ID(); // P.w_u16 (ID()); HS.dir = strike_dir; // P.w_dir (strike_dir); HS.power = hit_power; // P.w_float (hit_power); HS.boneID = element; // P.w_s16 (element); HS.p_in_bone_space = bone_pos; // P.w_vec3 (bone_pos); HS.impulse = impulse; // P.w_float (impulse); HS.hit_type = (ALife::eHitTypeWound); // P.w_u16 (u16(ALife::eHitTypeWound)); HS.Write_Packet(P); u_EventSend (P); elements_list.pop_front(); bone_position_list.pop_front(); } } } }
void CPseudoGigant::on_threaten_execute() { // разбросить объекты m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,Position(), 15.f, NULL); for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); if (!obj || !obj->m_pPhysicsShell) continue; Fvector dir; Fvector pos; pos.set(obj->Position()); pos.y += 2.f; dir.sub(pos, Position()); dir.normalize(); obj->m_pPhysicsShell->applyImpulse(dir,20 * obj->m_pPhysicsShell->getMass()); } // играть звук Fvector pos; pos.set (Position()); pos.y += 0.1f; m_sound_threaten_hit.play_at_pos(this,pos); // играть партиклы PlayParticles(m_kick_particles, pos, Direction()); CActor *pA = const_cast<CActor *>(smart_cast<const CActor *>(EnemyMan.get_enemy())); if (!pA) return; if ((pA->MovingState() & ACTOR_DEFS::mcJump) != 0) return; float dist_to_enemy = pA->Position().distance_to(Position()); float hit_value; hit_value = m_kick_damage - m_kick_damage * dist_to_enemy / m_threaten_dist_max; clamp (hit_value,0.f,1.f); // запустить эффектор Actor()->Cameras().AddCamEffector(xr_new<CMonsterEffectorHit>(m_threaten_effector.ce_time,m_threaten_effector.ce_amplitude * hit_value,m_threaten_effector.ce_period_number,m_threaten_effector.ce_power * hit_value)); Actor()->Cameras().AddPPEffector(xr_new<CMonsterEffector>(m_threaten_effector.ppi, m_threaten_effector.time, m_threaten_effector.time_attack, m_threaten_effector.time_release, hit_value)); // развернуть камеру if (pA->cam_Active()) { pA->cam_Active()->Move(Random.randI(2) ? kRIGHT : kLEFT, Random.randF(0.3f * hit_value)); pA->cam_Active()->Move(Random.randI(2) ? kUP : kDOWN, Random.randF(0.3f * hit_value)); } Actor()->lock_accel_for (m_time_kick_actor_slow_down); // Нанести хит NET_Packet l_P; SHit HS; HS.GenHeader (GE_HIT, pA->ID()); // u_EventGen (l_P,GE_HIT, pA->ID()); HS.whoID = (ID()); // l_P.w_u16 (ID()); HS.weaponID = (ID()); // l_P.w_u16 (ID()); HS.dir = (Fvector().set(0.f,1.f,0.f)); // l_P.w_dir (Fvector().set(0.f,1.f,0.f)); HS.power = (hit_value); // l_P.w_float (m_kick_damage); HS.boneID = (smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot()); // l_P.w_s16 (smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (Fvector().set(0.f,0.f,0.f)); // l_P.w_vec3 (Fvector().set(0.f,0.f,0.f)); HS.impulse = (80 * pA->character_physics_support()->movement()->GetMass()); // l_P.w_float (20 * pA->movement_control()->GetMass()); HS.hit_type = ( ALife::eHitTypeStrike); // l_P.w_u16 ( u16(ALife::eHitTypeWound) ); HS.Write_Packet (l_P); u_EventSend (l_P); }