void CPHCollisionDamageReceiver::Hit(u16 source_id,u16 bone_id,float power,const Fvector& dir,Fvector &pos ) { DAMAGE_BONES_I i=FindBone(bone_id); if(i==m_controled_bones.end())return; power*=i->second; if(power<hit_threthhold)return; NET_Packet P; CPhysicsShellHolder *ph=PPhysicsShellHolder(); SHit HS; HS.GenHeader(GE_HIT,ph->ID()); // ph->u_EventGen(P,GE_HIT,ph->ID()); HS.whoID = ph->ID(); // P.w_u16 (ph->ID()); HS.weaponID = source_id; // P.w_u16 (source_id); HS.dir = dir; // P.w_dir (dir); HS.power = power; // P.w_float (power); HS.boneID = s16(bone_id); // P.w_s16 (s16(bone_id)); HS.p_in_bone_space = pos; // P.w_vec3 (pos); HS.impulse = 0.f; // P.w_float (0.f); HS.hit_type = (ALife::eHitTypeStrike); // P.w_u16 (ALife::eHitTypeStrike); HS.Write_Packet(P); ph->u_EventSend(P); }
void CStalkerActionKillWounded::execute () { inherited::execute (); if (!object().memory().enemy().selected()) return; const CEntityAlive *enemy = object().memory().enemy().selected(); object().sight().setup (CSightAction(enemy,true)); object().set_goal (eObjectActionFire1,weapon_to_kill(&object()),MIN_QUEUE,MAX_QUEUE,MIN_INTERVAL,MAX_INTERVAL); if (object().memory().visual().visible_now(enemy) && object().can_kill_enemy() && !object().can_kill_member()) return; // this is fake // but sometimes enemy can not be visible // when it plays animation inside another object // therefore we should use this ugly workaround // and hit enemy virtually NET_Packet P; SHit HS; HS.GenHeader (GE_HIT, enemy->ID()); HS.whoID = object().ID(); HS.weaponID = weapon_to_kill(&object())->object().ID(); HS.dir = Fvector().set(0.f,0.f,1.f); HS.power = 1.f; HS.boneID = smart_cast<CKinematics*>((const_cast<CEntityAlive*>(enemy))->Visual())->LL_GetBoneRoot(); HS.p_in_bone_space = Fvector().set(0.f,0.f,0.f); HS.impulse = 1.f; HS.hit_type = ALife::eHitTypeWound; HS.Write_Packet (P); object().u_EventSend (P); }
void CExplosive::ExplodeWaveProcessObject(collide::rq_results& storage, CPhysicsShellHolder*l_pGO) { Fvector l_goPos; if(l_pGO->Visual()) l_pGO->Center (l_goPos); else return; //мне непонятно зачем наносить хит от взрыва по объектам не имеющим вижуал - поэтому игнорируем #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_OpenCashedDraw(); } #endif float l_effect=ExplosionEffect(storage,this,l_pGO,m_vExplodePos,m_fBlastRadius); float l_impuls = m_fBlastHitImpulse * l_effect; float l_hit = m_fBlastHit * l_effect; if(l_impuls > .001f||l_hit> 0.001) { Fvector l_dir;l_dir.sub(l_goPos,m_vExplodePos); float rmag=_sqrt(m_fUpThrowFactor*m_fUpThrowFactor+1.f+2.f*m_fUpThrowFactor*l_dir.y); l_dir.y += m_fUpThrowFactor; //rmag -модуль l_dir после l_dir.y += m_fUpThrowFactor, модуль=_sqrt(l_dir^2+y^2+2.*(l_dir,y)),y=(0,m_fUpThrowFactor,0) (до этого модуль l_dir =1) l_dir.mul(1.f/rmag);//перенормировка NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, l_pGO->ID()); // cast_game_object()->u_EventGen (P,GE_HIT,l_pGO->ID()); HS.whoID =Initiator(); // P.w_u16 (Initiator()); HS.weaponID = cast_game_object()->ID(); // P.w_u16 (cast_game_object()->ID()); HS.dir = l_dir; // P.w_dir (l_dir); HS.power = l_hit; // P.w_float (l_hit); HS.p_in_bone_space = l_goPos; // P.w_vec3 (l_goPos); HS.impulse = l_impuls; // P.w_float (l_impuls); HS.hit_type = (m_eHitTypeBlast); // P.w_u16 (u16(m_eHitTypeBlast)); HS.boneID = 0; // P.w_s16 (0); HS.Write_Packet(P); cast_game_object()->u_EventSend (P); } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_ClosedCashedDraw(100000); } #endif }
void CAI_Rat::Exec_Action(float /**dt/**/) { switch (m_tAction) { case eRatActionAttackBegin : { u32 dwTime = Device.dwTimeGlobal; sound().play (eRatSoundAttack);//,0,0,m_dwHitInterval+1,m_dwHitInterval); if (memory().enemy().selected() && memory().enemy().selected()->g_Alive() && (dwTime - m_dwStartAttackTime > m_dwHitInterval)) { m_bActionStarted = true; m_dwStartAttackTime = dwTime; Fvector tDirection; Fvector position_in_bone_space; position_in_bone_space.set(0.f,0.f,0.f); tDirection.sub(memory().enemy().selected()->Position(),this->Position()); vfNormalizeSafe(tDirection); if (this->Local() && memory().enemy().selected()) { CEntityAlive *entity_alive = const_cast<CEntityAlive*>(memory().enemy().selected()); VERIFY (entity_alive); // entity_alive->Hit(m_fHitPower,tDirection,this,0,position_in_bone_space,0); u16 id_to = entity_alive->ID(); u16 id_from = ID(); NET_Packet l_P; SHit HS; HS.GenHeader(GE_HIT, id_to); // u_EventGen (l_P,GE_HIT, id_to); HS.whoID = (id_from); // l_P.w_u16 (id_from); HS.weaponID = (id_from); // l_P.w_u16 (id_from); HS.dir = (tDirection); // l_P.w_dir (tDirection); HS.power = (m_fHitPower); // l_P.w_float (m_fHitPower); HS.boneID = (0); // l_P.w_s16 (0); HS.p_in_bone_space = (position_in_bone_space); // l_P.w_vec3 (position_in_bone_space); HS.impulse = (0.f); // l_P.w_float (0.f); HS.hit_type = (ALife::eHitTypeWound); // l_P.w_u16 ((u16)ALife::eHitTypeWound); HS.Write_Packet(l_P); u_EventSend (l_P); } } else m_bActionStarted = false; break; } case eRatActionAttackEnd : { m_bActionStarted = false; break; } default: break; } }
void CBaseMonster::Hit_Psy(CObject *object, float value) { NET_Packet P; SHit HS; HS.GenHeader (GE_HIT, object->ID()); // // u_EventGen (P,GE_HIT, object->ID()); // HS.whoID = (ID()); // own // P.w_u16 (ID()); // own HS.weaponID = (ID()); // own // P.w_u16 (ID()); // own HS.dir = (Fvector().set(0.f,1.f,0.f)); // direction // P.w_dir (Fvector().set(0.f,1.f,0.f)); // direction HS.power = (value); // hit value // P.w_float (value); // hit value HS.boneID = (BI_NONE); // bone // P.w_s16 (BI_NONE); // bone HS.p_in_bone_space = (Fvector().set(0.f,0.f,0.f)); // P.w_vec3 (Fvector().set(0.f,0.f,0.f)); HS.impulse = (0.f); // P.w_float (0.f); HS.hit_type = (ALife::eHitTypeTelepatic); // P.w_u16 (u16(ALife::eHitTypeTelepatic)); HS.Write_Packet (P); u_EventSend (P); }
void CBaseMonster::Hit_Wound(CObject *object, float value, const Fvector &dir, float impulse) { NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, object->ID()); // u_EventGen (P,GE_HIT, object->ID()); HS.whoID = (ID()); // P.w_u16 (ID()); HS.weaponID = (ID()); // P.w_u16 (ID()); HS.dir = (dir); // P.w_dir (dir); HS.power = (value); // P.w_float (value); HS.boneID = (smart_cast<IKinematics*>(object->Visual())->LL_GetBoneRoot()); // P.w_s16 (smart_cast<IKinematics*>(object->Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (Fvector().set(0.f,0.f,0.f)); // P.w_vec3 (Fvector().set(0.f,0.f,0.f)); 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); }
void CActor::g_Physics (Fvector& _accel, float jump, float dt) { // Correct accel Fvector accel; accel.set (_accel); hit_slowmo -= dt; if (hit_slowmo<0) hit_slowmo = 0.f; accel.mul (1.f-hit_slowmo); if(g_Alive()) { if(mstate_real&mcClimb&&!cameras[eacFirstEye]->bClampYaw)accel.set(0.f,0.f,0.f); character_physics_support()->movement()->Calculate (accel,cameras[cam_active]->vDirection,0,jump,dt,false); bool new_border_state=character_physics_support()->movement()->isOutBorder(); if(m_bOutBorder!=new_border_state && Level().CurrentControlEntity() == this) { SwitchOutBorder(new_border_state); } character_physics_support()->movement()->GetPosition (Position()); character_physics_support()->movement()->bSleep =false; } if (Local() && g_Alive()) { if (character_physics_support()->movement()->gcontact_Was) Cameras().AddCamEffector (xr_new<CEffectorFall> (character_physics_support()->movement()->gcontact_Power)); if (!fis_zero(character_physics_support()->movement()->gcontact_HealthLost)) { const ICollisionDamageInfo* di=character_physics_support()->movement()->CollisionDamageInfo(); Fvector hdir;di->HitDir(hdir); SetHitInfo(this, NULL, 0, Fvector().set(0, 0, 0), hdir); // Hit (m_PhysicMovementControl->gcontact_HealthLost,hdir,di->DamageInitiator(),m_PhysicMovementControl->ContactBone(),di->HitPos(),0.f,ALife::eHitTypeStrike);//s16(6 + 2*::Random.randI(0,2)) if (Level().CurrentControlEntity() == this) { SHit HDS = SHit(character_physics_support()->movement()->gcontact_HealthLost,hdir,di->DamageInitiator(),character_physics_support()->movement()->ContactBone(),di->HitPos(),0.f,di->HitType()); // Hit(&HDS); NET_Packet l_P; HDS.GenHeader(GE_HIT, ID()); HDS.whoID = di->DamageInitiator()->ID(); HDS.weaponID = di->DamageInitiator()->ID(); HDS.Write_Packet(l_P); u_EventSend (l_P); } } } }
void CBreakableObject::ProcessDamage() { NET_Packet P; SHit HS; HS.GenHeader (GE_HIT, ID()); HS.whoID = (ID()); HS.weaponID = (ID()); HS.dir = (m_contact_damage_dir); HS.power = (m_max_frame_damage); HS.boneID = (PKinematics(Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (m_contact_damage_pos); HS.impulse = (0.f); HS.hit_type = (ALife::eHitTypeStrike); HS.Write_Packet (P); u_EventSend (P); m_max_frame_damage = 0.f; b_resived_damage =false; }
void CRadioactiveZone::UpdateWorkload (u32 dt) { if (IsEnabled() && GameID() != GAME_SINGLE) { OBJECT_INFO_VEC_IT it; Fvector pos; XFORM().transform_tiny(pos,CFORM()->getSphere().P); for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { if( !(*it).object->getDestroy() && (*it).object->CLS_ID == CLSID_OBJECT_ACTOR) { //===================================== NET_Packet l_P; l_P.write_start(); l_P.read_start(); float dist = (*it).object->Position().distance_to(pos); float power = Power(dist)*dt/1000; /// Msg("Zone Dist %f, Radiation Power %f, ", dist, power); SHit HS; HS.GenHeader(GE_HIT, (*it).object->ID()); HS.whoID =ID(); HS.weaponID = ID(); HS.dir = Fvector().set(0,0,0); HS.power = power; HS.boneID = BI_NONE; HS.p_in_bone_space = Fvector().set(0, 0, 0); HS.impulse = 0.0f; HS.hit_type = ALife::eHitTypeRadiation; HS.Write_Packet_Cont(l_P); (*it).object->OnEvent(l_P, HS.PACKET_TYPE); //===================================== }; } } inherited::UpdateWorkload(dt); }
void CRadioactiveZone::UpdateWorkload (u32 dt) { if (IsEnabled() && GameID() != eGameIDSingle) { OBJECT_INFO_VEC_IT it; Fvector pos; XFORM().transform_tiny(pos,CFORM()->getSphere().P); for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { if( !(*it).object->getDestroy() && smart_cast<CActor*>((*it).object)) { //===================================== NET_Packet l_P; l_P.write_start(); l_P.read_start(); float dist = (*it).object->Position().distance_to(pos); float power = Power(dist,nearest_shape_radius(it))*dt/1000; SHit HS; HS.GenHeader (GE_HIT, (*it).object->ID()); HS.whoID = ID(); HS.weaponID = ID(); HS.dir = Fvector().set(0,0,0); HS.power = power; HS.boneID = BI_NONE; HS.p_in_bone_space = Fvector().set(0, 0, 0); HS.impulse = 0.0f; HS.hit_type = m_eHitTypeBlowout; HS.Write_Packet_Cont(l_P); (*it).object->OnEvent(l_P, HS.PACKET_TYPE); //===================================== }; } } inherited::UpdateWorkload(dt); }
void CCustomZone::CreateHit ( u16 id_to, u16 id_from, const Fvector& hit_dir, float hit_power, s16 bone_id, const Fvector& pos_in_bone, float hit_impulse, ALife::EHitType hit_type) { if (OnServer()) { if(m_owner_id != u32(-1) ) id_from = (u16)m_owner_id; NET_Packet l_P; Fvector hdir = hit_dir; SHit Hit = SHit(hit_power, hdir, this, bone_id, pos_in_bone, hit_impulse, hit_type, 0.0f, false); Hit.GenHeader (GE_HIT, id_to); Hit.whoID = id_from; Hit.weaponID = this->ID(); Hit.Write_Packet (l_P); u_EventSend (l_P); }; }
void CScriptGameObject::Hit(CScriptHit *tpLuaHit) { CScriptHit &tLuaHit = *tpLuaHit; NET_Packet P; SHit HS; HS.GenHeader(GE_HIT,object().ID()); // object().u_EventGen(P,GE_HIT,object().ID()); THROW2 (tLuaHit.m_tpDraftsman,"Where is hit initiator??!"); // THROW2 (tLuaHit.m_tpDraftsman,"Where is hit initiator??!"); HS.whoID = u16(tLuaHit.m_tpDraftsman->ID()); // P.w_u16 (u16(tLuaHit.m_tpDraftsman->ID())); HS.weaponID = 0; // P.w_u16 (0); HS.dir = tLuaHit.m_tDirection; // P.w_dir (tLuaHit.m_tDirection); HS.power = tLuaHit.m_fPower; // P.w_float (tLuaHit.m_fPower); CKinematics *V = smart_cast<CKinematics*>(object().Visual()); // CKinematics *V = smart_cast<CKinematics*>(object().Visual()); VERIFY (V); // VERIFY (V); if (xr_strlen (tLuaHit.m_caBoneName)) // if (xr_strlen (tLuaHit.m_caBoneName)) HS.boneID = (V->LL_BoneID(tLuaHit.m_caBoneName)); // P.w_s16 (V->LL_BoneID(tLuaHit.m_caBoneName)); else // else HS.boneID = (s16(0)); // P.w_s16 (s16(0)); HS.p_in_bone_space = Fvector().set(0,0,0); // P.w_vec3 (Fvector().set(0,0,0)); HS.impulse = tLuaHit.m_fImpulse; // P.w_float (tLuaHit.m_fImpulse); HS.hit_type = (ALife::EHitType)(tLuaHit.m_tHitType); // P.w_u16 (u16(tLuaHit.m_tHitType)); HS.Write_Packet(P); object().u_EventSend(P); }
void CActorCondition::AffectDamage_InjuriousMaterialAndMonstersInfluence() { float one = 0.1f; float tg = Device.fTimeGlobal; if ( m_f_time_affected + one > tg ) { return; } clamp( m_f_time_affected, tg - (one * 3), tg ); float psy_influence = 0; float fire_influence = 0; float radiation_influence = GetInjuriousMaterialDamage(); // Get Radiation from Material // Add Radiation and Psy Level from Monsters CPda* const pda = m_object->GetPDA(); if ( pda ) { typedef xr_vector<CObject*> monsters; for ( monsters::const_iterator it = pda->feel_touch.begin(); it != pda->feel_touch.end(); ++it ) { CBaseMonster* const monster = smart_cast<CBaseMonster*>(*it); if ( !monster || !monster->g_Alive() ) continue; psy_influence += monster->get_psy_influence(); radiation_influence += monster->get_radiation_influence(); fire_influence += monster->get_fire_influence(); } } struct { ALife::EHitType type; float value; } hits[] = { { ALife::eHitTypeRadiation, radiation_influence * one }, { ALife::eHitTypeTelepatic, psy_influence * one }, { ALife::eHitTypeBurn, fire_influence * one } }; NET_Packet np; while ( m_f_time_affected + one < tg ) { m_f_time_affected += one; for ( int i=0; i<sizeof(hits)/sizeof(hits[0]); ++i ) { float damage = hits[i].value; ALife::EHitType type = hits[i].type; if ( damage > EPS ) { SHit HDS = SHit(damage, //. 0.0f, Fvector().set(0,1,0), NULL, BI_NONE, Fvector().set(0,0,0), 0.0f, type, 0.0f, false); HDS.GenHeader(GE_HIT, m_object->ID()); HDS.Write_Packet( np ); CGameObject::u_EventSend( np ); } } // for }//while }
void CPolterFlame::update_schedule() { inherited::update_schedule(); //--------------------------------------------------------------------- // Update Scanner if (m_object->g_Alive()) { // check the start of scanning if (!m_state_scanning && !m_object->EnemyMan.get_enemy()) { // check radius if (Actor()->Position().distance_to(m_object->Position()) < m_scan_radius) { // check timing if (m_scan_next_time < time()) { // start here m_state_scanning = true; // играть звук //m_scan_sound.play_at_pos(m_object, get_head_position(Actor()),sm_2D); ::Sound->play_at_pos(m_scan_sound, 0, Actor()->Position()); // постпроцесс Actor()->Cameras().AddPPEffector(new CMonsterEffector(m_scan_effector_info, m_scan_effector_time, m_scan_effector_time_attack, m_scan_effector_time_release)); } } } // check stop of scanning (it currently scans) else { if (!m_scan_sound._feedback()) { // stop here m_state_scanning = false; // count next scan time m_scan_next_time = time() + Random.randI(m_scan_delay_min,m_scan_delay_max); } } } //--------------------------------------------------------------------- // check all flames for (FLAME_ELEMS_IT it = m_flames.begin();it != m_flames.end();it++) { SFlameElement *elem = *it; // test switches to states switch(elem->state) { case ePrepare: // check if time_out if (elem->time_started + m_time_fire_delay < time()) select_state(elem,eFire); break; case eFire: if (elem->time_started + m_time_fire_play < time()) select_state(elem,eStop); else { // check if we need test hit to enemy if (elem->time_last_hit + m_hit_delay < time()) { // test hit collide::rq_result rq; if (Level().ObjectSpace.RayPick(elem->position, elem->target_dir, m_length, collide::rqtBoth, rq, NULL)) { if ((rq.O == elem->target_object) && (rq.range < m_length)) { float hit_value; hit_value = m_hit_value - m_hit_value * rq.range / m_length; NET_Packet P; SHit HS; HS.GenHeader (GE_HIT, elem->target_object->ID()); // u_EventGen (P,GE_HIT, element->target_object->ID()); HS.whoID = (m_object->ID()); // P.w_u16 (ID()); HS.weaponID = (m_object->ID()); // P.w_u16 (ID()); HS.dir = (elem->target_dir); // P.w_dir (element->target_dir); HS.power = (hit_value); // P.w_float (m_flame_hit_value); HS.boneID = (BI_NONE); // P.w_s16 (BI_NONE); HS.p_in_bone_space = (Fvector().set(0.f,0.f,0.f)); // P.w_vec3 (Fvector().set(0.f,0.f,0.f)); HS.impulse = (0.f); // P.w_float (0.f); HS.hit_type = (ALife::eHitTypeBurn); // P.w_u16 (u16(ALife::eHitTypeBurn)); HS.Write_Packet (P); m_object->u_EventSend (P); elem->time_last_hit = time(); } } } } break; case eStop: xr_delete(*it); break; } } // remove all flames in state stop // удалить все элементы, выполнение которых закончено m_flames.erase ( std::remove_if( m_flames.begin(), m_flames.end(), remove_predicate() ), m_flames.end() ); // check if we can create another flame if (m_object->g_Alive() && m_object->EnemyMan.get_enemy() && (m_flames.size() < m_count)) { // check aura radius and accessibility float dist = m_object->EnemyMan.get_enemy()->Position().distance_to(m_object->Position()); if ((dist < m_pmt_aura_radius) && m_object->control().path_builder().accessible(m_object->EnemyMan.get_enemy()->Position())) { // check timing if (m_time_flame_started + m_delay < time()) { create_flame(m_object->EnemyMan.get_enemy()); } } } }
void CBaseMonster::HitEntity(const CEntity *pEntity, float fDamage, float impulse, Fvector &dir, ALife::EHitType hit_type, bool draw_hit_marks) { if (!g_Alive()) return; if (!pEntity || pEntity->getDestroy()) return; if (!EnemyMan.get_enemy()) return; if (EnemyMan.get_enemy() == pEntity) { Fvector position_in_bone_space; position_in_bone_space.set(0.f,0.f,0.f); // перевод из локальных координат в мировые вектора направления импульса Fvector hit_dir; XFORM().transform_dir (hit_dir,dir); hit_dir.normalize (); CEntity *pEntityNC = const_cast<CEntity*>(pEntity); VERIFY (pEntityNC); NET_Packet l_P; SHit HS; HS.GenHeader(GE_HIT, pEntityNC->ID()); // u_EventGen (l_P,GE_HIT, pEntityNC->ID()); HS.whoID = (ID()); // l_P.w_u16 (ID()); HS.weaponID = (ID()); // l_P.w_u16 (ID()); HS.dir = (hit_dir); // l_P.w_dir (hit_dir); HS.power = (fDamage); // l_P.w_float (fDamage); HS.boneID = (smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot());// l_P.w_s16 (smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (position_in_bone_space); // l_P.w_vec3 (position_in_bone_space); HS.impulse = (impulse); // l_P.w_float (impulse); HS.hit_type = hit_type; // l_P.w_u16 ( u16(ALife::eHitTypeWound) ); HS.Write_Packet(l_P); u_EventSend (l_P); if (pEntityNC == Actor() && draw_hit_marks) { START_PROFILE("BaseMonster/Animation/HitEntity"); SDrawStaticStruct* s = CurrentGameUI()->AddCustomStatic("monster_claws", false); float h1,p1; Device.vCameraDirection.getHP (h1,p1); Fvector hd = hit_dir; hd.mul (-1); float d = -h1 + hd.getH (); s->wnd()->SetHeading (d); Fvector2 wnd_pos = s->wnd()->GetWndPos(); wnd_pos.y += 400.0f*_cos(d); wnd_pos.x += 500.0f*_sin(d); s->wnd()->SetWndPos(wnd_pos); STOP_PROFILE; //SetAttackEffector (); float time_to_lock = fDamage * MAX_LOCK_TIME; clamp (time_to_lock, 0.f, MAX_LOCK_TIME); Actor()->lock_accel_for (int(time_to_lock * 1000)); ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effBigMonsterHit); if(!ce) { const shared_str& eff_sect = pSettings->r_string(cNameSect(), "actor_hit_effect"); if(eff_sect.c_str()) { int id = -1; Fvector cam_pos,cam_dir,cam_norm; Actor()->cam_Active()->Get (cam_pos,cam_dir,cam_norm); cam_dir.normalize_safe (); dir.normalize_safe (); float ang_diff = angle_difference (cam_dir.getH(), dir.getH()); Fvector cp; cp.crossproduct (cam_dir,dir); bool bUp =(cp.y>0.0f); Fvector cross; cross.crossproduct (cam_dir, dir); VERIFY (ang_diff>=0.0f && ang_diff<=PI); float _s1 = PI_DIV_8; float _s2 = _s1+PI_DIV_4; float _s3 = _s2+PI_DIV_4; float _s4 = _s3+PI_DIV_4; if(ang_diff<=_s1){ id = 2; }else { if(ang_diff>_s1 && ang_diff<=_s2){ id = (bUp)?5:7; }else if(ang_diff>_s2 && ang_diff<=_s3){ id = (bUp)?3:1; }else if(ang_diff>_s3 && ang_diff<=_s4){ id = (bUp)?4:6; }else if(ang_diff>_s4){ id = 0; }else{ VERIFY(0); } } string64 sect_name; xr_sprintf (sect_name,"%s_%d",eff_sect.c_str(), id); AddEffector (Actor(), effBigMonsterHit, sect_name, fDamage); } } ////////////////////////////////////////////////////////////////////////// } Morale.on_attack_success(); m_time_last_attack_success = Device.dwTimeGlobal; } }
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); }