////////////////////////////////////////////////////////////////////// // // Game Source Code // // File: XPlayerLight.cpp // Description: Entity player class. // flashlight funtionality // // History: // - apr 17,2003: Created by Kirill - splitting Xplayer.cpp in multiple files // ////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "XPlayer.h" #include // <> look above #include "I3DEngine.h" // remove this #include // //----------------------------------------------------------------- Vec3d CPlayer::GetFLightPos( ) { if(IsMyPlayer()) { Vec3d pos; Vec3d ang; GetFirePosAngles(pos, ang); ang = ConvertToRadAngles(ang); return pos - ang; } if(m_pGame->pl_head->GetIVal()==0) { ICryCharInstance *pChar = m_pEntity->GetCharInterface()->GetCharacter(0); if(pChar) { ICryBone * bone = pChar->GetBoneByName("weapon_bone"); // find bone in the list of bones; if(bone) { Matrix44 mat; mat.SetIdentity(); Vec3d rot = m_pEntity->GetAngles(); rot.x=0; //mat.RotateMatrix_fix(angles); mat=Matrix44::CreateRotationZYX(-gf_DEGTORAD*rot)*mat; //NOTE: angles in radians and negated return m_pEntity->GetPos() + mat.TransformPointOLD(bone->GetBonePosition()) - Vec3d(0,0,0.3f); } } } else { Vec3d pos; Vec3d ang; GetFirePosAngles(pos, ang); return pos + Vec3d(0.f,0.f,.3f); /* if(m_pBoneHead) { // light->m_Origin = m_pEntity->GetPos() + m_pBoneHead->GetBonePosition(); Matrix44 mat; mat.Identity(); Vec3d rot = m_pEntity->GetAngles(); rot.x=0; //mat.RotateMatrix_fix(angles); mat=GetRotationZYX44(-gf_DEGTORAD*rot)*mat; //NOTE: angles in radians and negated return m_pEntity->GetPos() + mat.TransformPoint(m_pBoneHead->GetBonePosition()); } */ } return m_pEntity->GetPos() + Vec3d(0,0,2); } // //----------------------------------------------------------------- void CPlayer::ProceedFLight( ) { if(!m_bLightOn) return; if( !m_pDynLight ) return; FUNCTION_PROFILER( GetISystem(),PROFILE_GAME ); float totalLightScale = 1.0f - m_pGame->GetSystem( )->GetI3DEngine()->GetAmbientLightAmountForEntity(m_pEntity)*2.0f; // for local player make it always bright if( IsMyPlayer() ) totalLightScale = 1.0f; if(totalLightScale<.2f) totalLightScale = .2f; // // fixme - this causes crach in destructor m_pDynLight->m_Flags = DLF_PROJECT; if(IsMyPlayer()) m_pDynLight->m_fLightFrustumAngle = 30; else m_pDynLight->m_fLightFrustumAngle = m_pGame->p_lightfrustum->GetFVal(); // for other players - more light m_pDynLight->m_fRadius = m_pGame->p_lightrange->GetFVal(); m_pDynLight->m_Origin = GetFLightPos(); // light->m_ProjAngles = m_pEntity->GetAngles(); m_pDynLight->m_ProjAngles = Vec3d(m_pEntity->GetAngles().y,m_pEntity->GetAngles().x,m_pEntity->GetAngles().z-90); m_pDynLight->m_Color = CFColor(totalLightScale,totalLightScale,totalLightScale, 1.0f); m_pDynLight->m_SpecColor = CFColor(totalLightScale,totalLightScale,totalLightScale); // m_pDynLight->m_Color = CFColor(.45f,.45f,.45f, 1.0f); // m_pDynLight->m_SpecColor = CFColor(.45f,.45f,.45f); m_pDynLight->m_Flags |= (DLF_LIGHTSOURCE | DLF_SPECULAR_ONLY_FOR_HIGHSPEC); /* light->m_pShader = 0; if (!light->m_pLightImage) { //Light.m_pLightImage = m_IndInterface.m_pRenderer->EF_LoadTexture("FlashLightCube", 0, FT2_FORCECUBEMAP, eTT_Cubemap); light->m_pLightImage = m_pGame->GetSystem()->GetIRenderer()->EF_LoadTexture("Textures/Lights/Light_testgrid", 0, FT2_FORCECUBEMAP, eTT_Cubemap); } */ // m_pGame->GetSystem()->GetIRenderer()->EF_UpdateDLight(light); m_pGame->GetSystem()->GetI3DEngine()->AddDynamicLightSource(*m_pDynLight, GetEntity()); if (m_pLightTarget) { ray_hit hit; Vec3d dir = ConvertToRadAngles(m_pEntity->GetAngles()); dir*=20; int colliders = m_pGame->GetSystem()->GetIPhysicalWorld()->RayWorldIntersection(GetFLightPos(),dir,ent_all,0,&hit,1,m_pEntity->GetPhysics()); if (colliders) { hit.pt.z +=float (rand()%100/1000); Vec3d newPos = hit.pt -m_pEntity->GetPos(); // move it about 10 cm away from the point of collision float fDIST = newPos.Length(); newPos *= 1.f - 0.1f/fDIST; m_pLightTarget->SetPos(m_pEntity->GetPos()+newPos); } } } // // void CPlayer::UpdateLightBlinding() { FUNCTION_PROFILER( GetISystem(),PROFILE_GAME ); //return; if (m_pGame->m_PlayersWithLighs.empty() && ((IsMyPlayer()&&m_vBlindingList.empty()) || (m_bIsAI&&!m_stats.bIsBlinded)) ) return; ListOfPlayers::iterator pl = m_pGame->m_PlayersWithLighs.begin(); Vec3d tmp; Vec3d thisForward; float totalLightScale = m_pGame->GetSystem( )->GetI3DEngine()->GetAmbientLightAmountForEntity(m_pEntity); totalLightScale*=3.0f; if(totalLightScale>1.0f) totalLightScale=1.0f; //GetLightAmountForEntity( m_pEntity ); //if( m_bIsAI ) //m_pGame->GetSystem()->GetILog()->Log("\003 lScale %.3f", totalLightScale ); GetFirePosAngles(tmp, thisForward); thisForward=ConvertToRadAngles(thisForward); thisForward.normalize(); m_stats.curBlindingValue = 0.0f; for( ; pl!=m_pGame->m_PlayersWithLighs.end(); pl++ ) { if( (*pl)==this ) continue; CPlayer *curPlayer = (*pl); Vec3d blindingPos = curPlayer->GetFLightPos(); Vec3d direction = blindingPos - m_vEyePos; Vec3d curForward; float blindingValue=0.0f; float dist2 = 0; curPlayer->GetFirePosAngles(tmp, curForward); curForward=ConvertToRadAngles(curForward); curForward.normalize(); dist2 = direction.len2(); direction.normalize(); blindingValue = direction*thisForward; if(blindingValue<0.0f) continue; direction = -direction; //dist2 = (direction*curForward); blindingValue = blindingValue*(direction*curForward); blindingValue *= blindingValue; blindingValue *= blindingValue; blindingValue *= blindingValue; // blindingValue = blindingValue*blindingValue*blindingValue; dist2 = m_pGame->pl_dist->GetFVal()/dist2; if(dist2 > 1.0f) dist2 = cry_sqrtf(dist2); blindingValue *= dist2; blindingValue *= m_pGame->pl_intensity->GetFVal(); blindingValue *= (1.0f - totalLightScale); if(blindingValue<.2f) continue; ray_hit hit; IPhysicalEntity *physic = curPlayer->m_pEntity->GetPhysics(); if( m_pGame->GetSystem()->GetIPhysicalWorld()-> RayWorldIntersection(blindingPos,m_vEyePos-blindingPos,ent_terrain | ent_static, rwi_stop_at_pierceable,&hit,1, physic)) continue; if(IsMyPlayer()) { Vec3d scrPos; GetGame()->GetSystem()->GetIRenderer()->ProjectToScreen( blindingPos.x, blindingPos.y, blindingPos.z, &scrPos.x,&scrPos.y,&scrPos.z); scrPos.z = blindingValue; scrPos.x *= 8.0f; scrPos.y *= 6.0f; // m_vBlindingPosList.push_back(scrPos); BlindingList::iterator curB = m_vBlindingList.find(curPlayer); if( curB == m_vBlindingList.end() ) { m_vBlindingList[curPlayer] = scrPos; } else { (curB->second).x = scrPos.x; (curB->second).y = scrPos.y; if((curB->second).z < scrPos.z) (curB->second).z = scrPos.z; } } if(m_bIsAI && m_stats.curBlindingValue < blindingValue) { m_stats.curBlindingValue = blindingValue; } } float fade = m_pTimer->GetFrameTime()*m_pGame->pl_fadescale->GetFVal(); BlindingList::iterator curB = m_vBlindingList.begin(); for( ; curB != m_vBlindingList.end(); ) { (curB->second).z -= fade; if((curB->second).z<=0.0f) // remove { BlindingList::iterator nextB = curB; nextB++; m_vBlindingList.erase( curB ); curB = nextB; continue; } curB++; } m_LastUsed = m_vBlindingList.begin(); if( m_bIsAI ) { IAIObject *pObject = m_pEntity->GetAI(); IPuppet *pPuppet=0; if (pObject->CanBeConvertedTo(AIOBJECT_PUPPET,(void**)&pPuppet)) { if(m_stats.curBlindingValue > 1.6f) { if(!m_stats.bIsBlinded) { pObject->SetSignal(0, "SHARED_BLINDED"); m_stats.bIsBlinded = true; } } else { if(m_stats.bIsBlinded) { pObject->SetSignal(0, "SHARED_UNBLINDED"); m_stats.bIsBlinded = false; } } } } //if(m_stats.curBlindingValue > .1f) //m_pGame->GetSystem()->GetILog()->Log("\003 blind %.3f", m_stats.curBlindingValue ); } // // void CPlayer::SwitchFlashLight( bool on ) { // only perform switch, if the player actually has a flashlight // or if switching off if (!m_stats.has_flashlight && !m_bLightOn) return; if(m_bLightOn == on) return; FUNCTION_PROFILER( GetISystem(),PROFILE_GAME ); m_bLightOn = on; m_pEntity->SendScriptEvent( ScriptEvent_FlashLightSwitch , (int)(m_bLightOn)); if( m_bLightOn ) m_pGame->m_PlayersWithLighs.push_back( this ); else { ListOfPlayers::iterator self = std::find(m_pGame->m_PlayersWithLighs.begin(), m_pGame->m_PlayersWithLighs.end(), this); if(self!=m_pGame->m_PlayersWithLighs.end()) m_pGame->m_PlayersWithLighs.erase(self); } if (on && !m_bIsAI) { m_pLightTarget = m_pGame->GetSystem()->GetAISystem()->CreateAIObject(AIOBJECT_ATTRIBUTE,0); if (m_pLightTarget) { m_pLightTarget->Bind(m_pEntity->GetAI()); m_pLightTarget->SetPos(m_pEntity->GetPos()); } } else { if (m_pLightTarget) { m_pGame->GetSystem()->GetAISystem()->RemoveObject(m_pLightTarget); m_pLightTarget = 0; } } } // //-------------------------------------------------------------------------------------- bool CPlayer::InitLight( const char* sImg, const char* sShader ) { if (m_pDynLight) delete m_pDynLight; m_pDynLight = new CDLight(); if(sImg && sImg[0]) { m_pDynLight->m_fAnimSpeed = 0; int nFlags2 = FT2_FORCECUBEMAP; // if (bUseAsCube) // nFlags2 |= FT2_REPLICATETOALLSIDES; // if (fAnimSpeed) // nFlags2 |= FT2_CHECKFORALLSEQUENCES; m_pDynLight->m_pLightImage = m_pGame->GetSystem()->GetIRenderer()->EF_LoadTexture(sImg, 0, nFlags2, eTT_Cubemap); m_pDynLight->m_Flags = DLF_PROJECT; } else m_pDynLight->m_Flags = DLF_POINT; if(sShader && sShader[0]) m_pDynLight->m_pShader = m_pGame->GetSystem()->GetIRenderer()->EF_LoadShader((char*)sShader, eSH_World); return true; } void CPlayer::GiveFlashLight(bool val) { if (m_stats.has_flashlight == val) return; m_stats.has_flashlight = val; // make sure we turn off the flashlight, if we take it away if (val == false && m_bLightOn) { SwitchFlashLight(false); } } float CPlayer::GetLightRadius() { if(m_pDynLight && m_bLightOn) return m_pDynLight->m_fRadius; return 0; } //GetLightAmountForEntity // //-----------------------------------------------------------------