/* * Copyright (C) 2006-2010 - Frictional Games * * This file is part of Penumbra Overture. * * Penumbra Overture is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Penumbra Overture is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Penumbra Overture. If not, see . */ #include "PlayerHelper.h" #include "Init.h" #include "GameEntity.h" #include "GameObject.h" #include "GameArea.h" #include "Player.h" #include "Inventory.h" #include "Notebook.h" #include "NumericalPanel.h" #include "DeathMenu.h" #include "GameEnemy.h" #include "MapHandler.h" #include "PlayerHands.h" #include "GameMusicHandler.h" ////////////////////////////////////////////////////////////////////////// // HIT GROUND CALLBACK ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerBodyCallback::cPlayerBodyCallback(cPlayer *apPlayer) { mpPlayer = apPlayer; cInit *pInit = apPlayer->GetInit(); mfFallSpeed_Min = pInit->mpGameConfig->GetFloat("Player","FallSpeed_Min",0); mfFallDamage_Min = pInit->mpGameConfig->GetFloat("Player","FallDamage_Min",0); msFallSound_Min = pInit->mpGameConfig->GetString("Player","FallSound_Min",""); mfFallSpeed_Med = pInit->mpGameConfig->GetFloat("Player","FallSpeed_Med",0); mfFallDamage_Med = pInit->mpGameConfig->GetFloat("Player","FallDamage_Med",0); msFallSound_Med = pInit->mpGameConfig->GetString("Player","FallSound_Med",""); mfFallSpeed_Max = pInit->mpGameConfig->GetFloat("Player","FallSpeed_Max",0); mfFallDamage_Max = pInit->mpGameConfig->GetFloat("Player","FallDamage_Max",0); msFallSound_Max = pInit->mpGameConfig->GetString("Player","FallSound_Max",""); } //----------------------------------------------------------------------- void cPlayerBodyCallback::OnHitGround(iCharacterBody *apCharBody,const cVector3f &avVel) { //if(avVel.y < -5.5f) // mpPlayer->FootStep(1.0f,"run",true); if(mpPlayer->GetMoveState() == ePlayerMoveState_Jump) { if(avVel.y < 0) { if(avVel.y < - 3.5f) { mpPlayer->FootStep(1.0f,"run",true); } mpPlayer->SetLandedFromJump(true); } } else if(avVel.y < -8.5f) { mpPlayer->FootStep(1.0f,"run",true); } tString sSound = ""; float fVol = 1.0f; cSoundHandler *pSoundHandler = mpPlayer->GetInit()->mpGame->GetSound()->GetSoundHandler(); //Log("Speed: %f\n",avVel.y); ///////////////////// //Fall damage //Hard if(avVel.y < mfFallSpeed_Max) { sSound = msFallSound_Max; fVol = 1.0f; mpPlayer->Damage(mfFallDamage_Max,ePlayerDamageType_BloodSplash); pSoundHandler->PlayGui("player_fall_damage",false,1); //Log("Hard\n"); } //Medium else if(avVel.y < mfFallSpeed_Med) { sSound = msFallSound_Med; fVol = 1.0f; mpPlayer->Damage(mfFallDamage_Med,ePlayerDamageType_BloodSplash); pSoundHandler->PlayGui("player_fall_damage",false,0.75f); //Log("Medium\n"); } //Light else if(avVel.y < mfFallSpeed_Min) { sSound = msFallSound_Min; fVol = 1.0f; mpPlayer->Damage(mfFallDamage_Min,ePlayerDamageType_BloodSplash); pSoundHandler->PlayGui("player_fall_damage",false,0.5f); //Log("Light\n"); } if(sSound != "") { cWorld3D *pWorld = mpPlayer->GetInit()->mpGame->GetScene()->GetWorld3D(); cSoundEntity *pSound = pWorld->CreateSoundEntity("HitGround",sSound,true); if(pSound) { iCharacterBody *pCharBody = mpPlayer->GetCharacterBody(); pSound->SetVolume(fVol * pSound->GetVolume()); pSound->SetPosition(pCharBody->GetPosition() - cVector3f(0,pCharBody->GetSize().y/2 - 0.2f,0)); } } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // GROUND RAY CALLBACK ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerGroundRayCallback::cPlayerGroundRayCallback() { mpMaterial = NULL; mbOnGround = false; } //----------------------------------------------------------------------- void cPlayerGroundRayCallback::Clear() { mfMinDist = 1000; mpMaterial = NULL; } //----------------------------------------------------------------------- void cPlayerGroundRayCallback::OnWorldExit() { mpMaterial = NULL; } void cPlayerGroundRayCallback::Reset() { mpMaterial = NULL; } //----------------------------------------------------------------------- bool cPlayerGroundRayCallback::OnIntersect(iPhysicsBody *pBody,cPhysicsRayParams *apParams) { mbOnGround = true; if(apParams->mfDistGetMaterial()->GetSurfaceData() && pBody->GetMaterial()->GetSurfaceData()->GetStepType()!="") { mpMaterial = pBody->GetMaterial(); mfMinDist = apParams->mfDist; } return true; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // PICK RAY CALLBACK ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerPickRayCallback::cPlayerPickRayCallback() { mfMaxDistance = 10.0f; mpPickedBody = NULL; mLastEntityType = eGameEntityType_LastEnum; } //----------------------------------------------------------------------- void cPlayerPickRayCallback::Clear() { mfPickedDist = mfMaxDistance+10.0f; mfPickedAreaDist = mfMaxDistance+10.0f; mpPickedBody = NULL; mpPickedAreaBody = NULL; mfMinStaticDist = mfMaxDistance+10.0f; } //----------------------------------------------------------------------- void cPlayerPickRayCallback::OnWorldExit() { mpPickedBody = NULL; } //----------------------------------------------------------------------- bool cPlayerPickRayCallback::OnIntersect(iPhysicsBody *apBody,cPhysicsRayParams *apParams) { float &fDist = apParams->mfDist; //Must be positive if(fDist < 0) return true; //Must be below max distance if(fDist > mfMaxDistance) return true; //No characters allowed if(apBody->IsCharacter()) return true; //Check if is below current picked dist iGameEntity *pEntity = NULL; if(apBody->GetUserData()) pEntity = (iGameEntity*)apBody->GetUserData(); ////////////////////////////// // Entity if(pEntity) { //Skip stick area if(pEntity->GetType() == eGameEntityType_StickArea) return true; //Area if( pEntity->GetType() == eGameEntityType_Area || pEntity->GetType()== eGameEntityType_StickArea || pEntity->GetType()== eGameEntityType_DamageArea || pEntity->GetType()== eGameEntityType_ForceArea) { if( mfPickedAreaDist > fDist && (pEntity->GetDescription() != _W("") || pEntity->GetCallbackScript(eGameEntityScriptType_PlayerInteract) != NULL || pEntity->GetCallbackScript(eGameEntityScriptType_PlayerExamine) != NULL || pEntity->GetHasInteraction())) { mfPickedAreaDist = fDist; mvPickedAreaPos = apParams->mvPoint; mpPickedAreaBody = apBody; } } //Other entity else { if(mfPickedDist > fDist) { mfPickedDist = fDist; mvPickedPos = apParams->mvPoint; mpPickedBody = apBody; } } } /////////////////////////////// // Non Entity else { if(mfPickedDist > fDist) { mfPickedDist = fDist; mpPickedBody = NULL; } } return true; /*float &fDist = apParams->mfDist; iGameEntity *pEntity = NULL; if(apBody->GetUserData()) pEntity = (iGameEntity*)apBody->GetUserData(); //Don't wanna pick characters if(apBody->IsCharacter() && apBody->GetUserData()==NULL) return true; if(pEntity && pEntity->IsActive()==false) return true; //If it is outside of the examine distance skip if(pEntity && pEntity->GetMaxExamineDist() < fDist) return true; //////////////////////////// //Not picked bool bStatic = false; if(pEntity && pEntity->GetType()== eGameEntityType_Object) { cGameObject* pObject = static_cast(pEntity); if(pObject->GetInteractMode() == eObjectInteractMode_Static) { bStatic = true; } } if( pEntity==NULL || bStatic) { if(fDist < mfPickedDist) { mfMinStaticDist = fDist; mfPickedDist = fDist; mpPickedBody = NULL; mvPickedPos = apParams->mvPoint; mLastEntityType = eGameEntityType_LastEnum; } } //////////////////////////// //Picked else { if(pEntity->GetType() == eGameEntityType_Area) { if(fDist < mfPickedDist) { mpPickedBody = apBody; mLastEntityType = pEntity->GetType(); mvPickedPos = apParams->mvPoint; mfPickedDist = fDist; } } else { if (fDist < mfPickedDist || (mLastEntityType == eGameEntityType_Area)) { mpPickedBody = apBody; mLastEntityType = pEntity->GetType(); mvPickedPos = apParams->mvPoint; mfPickedDist = fDist; } } } return true;*/ } void cPlayerPickRayCallback::CalculateResults() { //Check if an area is closer than the closest normal body if(mpPickedAreaBody && mfPickedAreaDist < mfPickedDist) { bool bUseArea = false; if(mpPickedBody) { iGameEntity *pEntity = (iGameEntity*)mpPickedBody->GetUserData(); cGameArea *pArea = (cGameArea*)mpPickedAreaBody->GetUserData(); if(pEntity) { //Too for from object if(pEntity->GetMaxExamineDist() < mfPickedDist) bUseArea = true; //No description for object and it is not possible to interact with it else if(pEntity->GetDescription()==_W("")) { if( mpPickedBody->GetMass()==0) bUseArea = true; else if(pEntity->GetType() == eGameEntityType_Object) { cGameObject *pObject = static_cast(pEntity); if(pObject->GetInteractMode() == eObjectInteractMode_Static) bUseArea= true; } } } else { bUseArea = true; } } else { bUseArea = true; } if(bUseArea) { mpPickedBody = mpPickedAreaBody; mfPickedDist = mfPickedAreaDist; mvPickedPos = mvPickedAreaPos; } } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // HEAD MOVE ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerHeadMove::cPlayerHeadMove(cPlayer *apPlayer) { mfAdd =0; mfPos =0; mbActive = false; mpPlayer = apPlayer; mbFootStepped = false; mbWasActive = false; mfClimbCount = 0; mfClimbPos = 0; } //----------------------------------------------------------------------- void cPlayerHeadMove::Update(float afTimeStep) { /////////////////////////////// //Climb count iCharacterBody *pBody = mpPlayer->GetCharacterBody(); /*float fUpVel = (pBody->GetPosition().y - pBody->GetLastPosition().y) / afTimeStep;*/ if(pBody->IsClimbing() && mfClimbCount==0) { mfClimbCount = 0.5f; mfClimbPos = mfPos; } else if(mfClimbCount > 0) { mfClimbCount -= afTimeStep; if(mfClimbCount < 0) { mfClimbCount = 0; mfPos = mfClimbPos; mfAdd = mfHeadMoveSpeed; } } /////////////////////////////// //Head movement if(mbActive) { mbWasActive = true; mfPos += mfAdd*afTimeStep * mpPlayer->GetHeadMoveSpeedMul(); if(mfAdd < 0) { if(mfPos <= mfMinHeadMove * mpPlayer->GetHeadMoveSpeedMul()) { mfPos = mfMinHeadMove * mpPlayer->GetHeadMoveSpeedMul(); mfAdd = mfHeadMoveSpeed; //Create a footstep. if(mfFootStepMul>0) mpPlayer->FootStep(mfFootStepMul); mbFootStepped = true; } } else { if(mfPos >= mfMaxHeadMove * mpPlayer->GetHeadMoveSpeedMul()) { mfPos = mfMaxHeadMove * mpPlayer->GetHeadMoveSpeedMul(); mfAdd = -mfHeadMoveSpeed; } } } else { if(mbWasActive==true && (mbFootStepped==false || (mfPos < 0 && mfAdd<0)) ) { if(mfFootStepMul>0) mpPlayer->FootStep(mfFootStepMul*0.6f); } mbFootStepped = false; mbWasActive = false; if(mfPos==0) return; if(mfPos <0){ mfPos += mfHeadMoveBackSpeed*afTimeStep; if(mfPos > 0){ mfPos = 0; } } else { mfPos -= mfHeadMoveBackSpeed*afTimeStep; if(mfPos < 0){ mfPos = 0; } } } } //----------------------------------------------------------------------- void cPlayerHeadMove::Start() { if(mbActive==false) { mbActive = true; } if(fabs(fabs(mfAdd) - mfHeadMoveSpeed) > 0.001f) { mfAdd = mfHeadMoveSpeed; } } void cPlayerHeadMove::Stop() { mbActive = false; } //----------------------------------------------------------------------- float cPlayerHeadMove::GetPos() { if(mfClimbCount > 0) return mfClimbPos; return mfPos; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // HEALTH ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerHealth::cPlayerHealth(cInit *apInit) { mpInit = apInit; mfTimeCount = 0; mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer(); mpDamageGfx = mpDrawer->CreateGfxObject("player_hurt.bmp","diffalpha2d"); mfGfxAlpha =0; mfGfxAlphaAdd =0; mfGfxGlobalAlpha =0; mfTerrorCheckCount =0; mpSoundEntry = NULL; } //----------------------------------------------------------------------- void cPlayerHealth::Reset() { mfTerrorCheckCount =0; if(mpSoundEntry) mpSoundEntry->mpSound->Stop(); mpSoundEntry = NULL; mlTerrorLevel =0; } //----------------------------------------------------------------------- void cPlayerHealth::Update(float afTimeStep) { cPlayer *pPlayer = mpInit->mpPlayer; if(pPlayer->GetHealth() <= 0) { if(mpSoundEntry) mpSoundEntry->mpSound->Stop(); mpSoundEntry = NULL; mfGfxAlpha -= afTimeStep *2.0f; return; } //////////////////////////// //ALpha mfGfxAlpha += mfGfxAlphaAdd * afTimeStep; if(mfGfxAlphaAdd < 0 && mfGfxAlpha < 0) mfGfxAlpha = 0; if(mfGfxAlphaAdd > 0 && mfGfxAlpha >= 1.0f) { mfGfxAlpha = 1.0f; mfGfxAlphaAdd = -1.5; } //////////////////////////// //Heart timer if(mfTimeCount<=0) { if(pPlayer->GetHealth() >50) { pPlayer->SetHealthSpeedMul(1.0f); mfGfxGlobalAlpha =0; } else { float fVolume = 0.5; if(pPlayer->GetHealth() >25) { mfTimeCount = 1.7f; pPlayer->SetHealthSpeedMul(0.8f); mfGfxGlobalAlpha = 0.5f; } else if(pPlayer->GetHealth()>10) { mfTimeCount = 1.0; fVolume = 0.75f; pPlayer->SetHealthSpeedMul(0.6f); mfGfxGlobalAlpha = 0.75f; } else { mfTimeCount = 0.7f; fVolume = 1.0f; pPlayer->SetHealthSpeedMul(0.4f); mfGfxGlobalAlpha = 1.0f; } mpInit->mpGame->GetSound()->GetSoundHandler()->PlayGui("player_heartbeat",false,fVolume); mfGfxAlphaAdd = 3.5f; } } else { mfTimeCount -= afTimeStep; } //////////////////////////// //Increase health over time: switch(mpInit->mDifficulty) { case eGameDifficulty_Easy: pPlayer->AddHealth(afTimeStep * 1.4f); break; case eGameDifficulty_Normal: pPlayer->AddHealth(afTimeStep * 0.4f); break; case eGameDifficulty_Hard: pPlayer->AddHealth(afTimeStep * 0.14f); break; } //////////////////////////// //Check for enemies. /*if(mfTerrorCheckCount <=0) { //Check the current terror level. int lTerrorLevel =0; tGameEnemyIterator it = mpInit->mpMapHandler->GetGameEnemyIterator(); while(it.HasNext()) { iGameEnemy *pEnemy = it.Next(); if(pEnemy->IsActive()==false || pEnemy->GetHealth() <=0) continue; int lState = pEnemy->GetStateMachine()->CurrentState()->GetId(); if(lState == eGameEnemyState_Hunt || lState == eGameEnemyState_Attack) { lTerrorLevel = 3; } else if(lTerrorLevel < 2 && lState == eGameEnemyState_Investigate) { lTerrorLevel = 2; } else if(lTerrorLevel < 1) { lTerrorLevel = 1; } } if(mlTerrorLevel != lTerrorLevel) { mlTerrorLevel = lTerrorLevel; cSoundHandler *pSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); //Fade out the current sound if there is any. if(mpSoundEntry) { mpSoundEntry->mfNormalVolumeFadeDest = 0; mpSoundEntry->mfNormalVolumeFadeSpeed = -0.25f; mpSoundEntry = NULL; } mpSoundEntry = NULL; tString sSound=""; float fVolume; if(mlTerrorLevel==0) { } else if(mlTerrorLevel==1) { sSound = "horror_roach_idle"; fVolume = 0.3f; } else if(mlTerrorLevel==2) { sSound = "horror_roach_notice"; fVolume = 0.45f; } else if(mlTerrorLevel==3) { sSound = "horror_roach_attack"; fVolume = 0.6f; } if(sSound != "") { iSoundChannel *pChannel = pSoundHandler->PlayGui(sSound, true, fVolume); pChannel->SetPriority(200); mpSoundEntry = pSoundHandler->GetEntryFromSound(pChannel); mpSoundEntry->mfNormalVolumeMul =0; mpSoundEntry->mfNormalVolumeFadeDest =1; mpSoundEntry->mfNormalVolumeFadeSpeed = 0.55f; } } mfTerrorCheckCount = 0.2f; } else { mfTerrorCheckCount -= afTimeStep; }*/ } void cPlayerHealth::Draw() { if(mfGfxAlpha <=0) return; mpDrawer->DrawGfxObject(mpDamageGfx,cVector3f(0,0,50),cVector2f(800,600), cColor(1, mfGfxGlobalAlpha * mfGfxAlpha)); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // EAR RING ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerEarRing::cPlayerEarRing(cInit *apInit,cPlayer *apPlayer) { mpInit = apInit; mpPlayer = apPlayer; mpSoundEntry = NULL; mfTimeCount =0; mbDeaf = false; } //----------------------------------------------------------------------- void cPlayerEarRing::Reset() { cSoundHandler *pSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); if(mpSoundEntry) mpSoundEntry->mpSound->Stop(); pSoundHandler->SetVolume(1.0f,0.1f,eSoundDest_World); mpSoundEntry = NULL; mfTimeCount =0; mbDeaf = false; } //----------------------------------------------------------------------- void cPlayerEarRing::Update(float afTimeStep) { if(mfTimeCount >0) { cSoundHandler *pSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); mfTimeCount -= afTimeStep; mfDeafTime -= afTimeStep; if(mbDeaf && mfDeafTime <= 0) { mbDeaf = false; pSoundHandler->SetVolume(0.2f,1.5f,eSoundDest_World); } if(mfTimeCount <= 0) { mfTimeCount =0; pSoundHandler->SetVolume(1.0f,3.5f,eSoundDest_World); if(mpSoundEntry) { mpSoundEntry->mfNormalVolumeFadeDest = 0; mpSoundEntry->mfNormalVolumeFadeSpeed = -0.25f; mpSoundEntry = NULL; } } } } //----------------------------------------------------------------------- void cPlayerEarRing::Start(float afTime) { if(mpInit->mpPlayer->GetHealth() <=0) return; if(mfTimeCount >0) { } else { cSoundHandler *pSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); iSoundChannel *pChannel = pSoundHandler->PlayGui("player_ear_ring", true, 0.5f); pChannel->SetPriority(200); mpSoundEntry = pSoundHandler->GetEntryFromSound(pChannel); mpSoundEntry->mfNormalVolumeMul =0; mpSoundEntry->mfNormalVolumeFadeDest =1; mpSoundEntry->mfNormalVolumeFadeSpeed = 0.55f; pSoundHandler->SetVolume(0.0f,1.2f,eSoundDest_World); } mfTimeCount = afTime; mbDeaf = true; mfDeafTime = afTime *0.3f; } //----------------------------------------------------------------------- void cPlayerEarRing::Stop(bool abStopDirectly) { cSoundHandler *pSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); if(abStopDirectly) { if(mpSoundEntry) mpSoundEntry->mpSound->Stop(); mpSoundEntry = NULL; pSoundHandler->SetVolume(1,5,eSoundDest_World); } else { mfTimeCount =0; pSoundHandler->SetVolume(1.0f,3.5f,eSoundDest_World); if(mpSoundEntry) { mpSoundEntry->mfNormalVolumeFadeDest = 0; mpSoundEntry->mfNormalVolumeFadeSpeed = -0.25f; mpSoundEntry = NULL; } } } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // LEAN ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerLean::cPlayerLean(cInit *apInit, cPlayer *apPlayer) { mpPlayer = apPlayer; mpInit = apInit; mfMaxMovement = 0.5f; mfMaxRotation = cMath::ToRad(15); mpHeadShape = NULL; } void cPlayerLean::Reset() { mfDir = 0; mfMaxTime = 0.8f; mfMovement = 0; mfRotation =0; mfMoveSpeed = 0; mbPressed = false; } //----------------------------------------------------------------------- void cPlayerLean::OnWorldLoad() { iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld(); float fRadius = mpInit->mpPlayer->GetSize().x/2 * 0.63f; float fHeight = mpInit->mpPlayer->GetCameraHeightAdd()*2; if(fHeight < 0)fHeight = fHeight * -1; cMatrixf mtxOffset = cMath::MatrixRotateZ(kPi2f); mpHeadShape = pPhysicsWorld->CreateCylinderShape(fRadius,fHeight,&mtxOffset); } //----------------------------------------------------------------------- void cPlayerLean::Update(float afTimeStep) { //////////////////////////////// //If pressed move in direction if(mbPressed) { mbPressed = false; float fGoalPos = mfMaxMovement * mfDir; float fGoalRot = mfMaxRotation * -mfDir; ////////////// //Position float fPrevMovement = mfMovement; float fMoveSpeed = (fGoalPos - mfMovement); if(fabsf(fMoveSpeed) <0.1f) fMoveSpeed = 0.1f*mfDir; mfMovement += fMoveSpeed * afTimeStep * 3; if(fGoalPos < 0 && mfMovement < fGoalPos) mfMovement =fGoalPos; if(fGoalPos > 0 && mfMovement > fGoalPos) mfMovement =fGoalPos; ////////////// //Rotation float fPrevRotation = mfRotation; float fRotSpeed = fGoalRot - mfRotation; if(fabsf(fRotSpeed) <0.13f) fRotSpeed = 0.13f*-mfDir; mfRotation += fRotSpeed * afTimeStep * 2; if(fGoalRot < 0 && mfRotation < fGoalRot) mfRotation = fGoalRot; if(fGoalRot > 0 && mfRotation > fGoalRot) mfRotation = fGoalRot; //////////////////// //Check collision cCamera3D *pCam = mpInit->mpPlayer->GetCamera(); iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld(); float fReverseMov = fPrevMovement - mfMovement; float fReverseRot = fPrevRotation - mfRotation; iCharacterBody *pCharBody = mpPlayer->GetCharacterBody(); float fHeightAdd = mpPlayer->GetSize().y + mpPlayer->GetHeightAdd() + mpPlayer->GetCameraHeightAdd(); cVector3f vStartPos = pCharBody->GetFeetPosition() + cVector3f(0,fHeightAdd,0); cVector3f vPos = vStartPos + pCam->GetRight() * mfMovement; int lCount = 0; while(pPhysicsWorld->CheckShapeWorldCollision(NULL,mpHeadShape, cMath::MatrixTranslate(vPos),NULL,false,true,NULL,false)) { mfMovement += fReverseMov; mfRotation += fReverseRot; if(fReverseMov < 0 && mfMovement <0) { mfMovement =0; mfRotation =0; break; } if(fReverseMov > 0 && mfMovement >0){ mfMovement =0; mfRotation =0; break; } vPos = vStartPos + pCam->GetRight() * mfMovement; lCount++; if(lCount >10){ mfMovement =0; mfRotation =0; break; } } } //////////////////////////// // Not pressed move back else { float fMoveSpeed = (0 - mfMovement); mfMovement += fMoveSpeed * afTimeStep * 6; float fRotSpeed = 0 - mfRotation; mfRotation += fRotSpeed * afTimeStep * 3; } mpPlayer->GetCamera()->AddRoll(mfRotation); } //----------------------------------------------------------------------- bool cPlayerLean::OnIntersect(iPhysicsBody *pBody,cPhysicsRayParams *apParams) { if(pBody == mpPlayer->GetCharacterBody()->GetBody())return true; mbIntersect = true; return false; } //----------------------------------------------------------------------- void cPlayerLean::Lean(float afMul, float afTimeStep) { mbPressed = true; mfDir = afMul; } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // DAMAGE ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerDamage::cPlayerDamage(cInit *apInit) { mpInit = apInit; mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer(); mpPostEffects = mpInit->mpGame->GetGraphics()->GetRendererPostEffects(); mbActive = false; mType = ePlayerDamageType_BloodSplash; mvHitGfx[ePlayerDamageType_BloodSplash] = mpDrawer->CreateGfxObject("player_hit_blood_splash.bmp","diffalpha2d"); mvHitGfx[ePlayerDamageType_Ice] = mpDrawer->CreateGfxObject("player_hit_ice.bmp","diffalpha2d"); mvHeadSwingAcc = cVector2f(17.0f, 17.0f); } cPlayerDamage::~cPlayerDamage() { for(int i=0; iDestroyGfxObject(mvHitGfx[i]); } //----------------------------------------------------------------------- void cPlayerDamage::Start(float afSize, ePlayerDamageType aType) { if(mbActive) return; mfSize = afSize; mType = aType; mfAlpha = 0; mfAlphaAdd = 4.3f; mbActive = true; if(!mpInit->mpPlayer->GetFearFilter()->IsActive()) { mpPostEffects->SetImageTrailActive(true); mpPostEffects->SetImageTrailAmount(0); } mvHeadSwingSpeed = cVector2f(cMath::RandRectf(-1,1), cMath::RandRectf(0,0.5f)); if(mvHeadSwingSpeed.x == 0 && mvHeadSwingSpeed.y == 0) mvHeadSwingSpeed.x = 1; else mvHeadSwingSpeed.Normalise(); mvHeadSwingSpeed = mvHeadSwingSpeed * afSize*1.5f; mpInit->mpPlayer->GetCharacterBody()->SetMoveSpeed(eCharDir_Forward,0); mpInit->mpPlayer->GetCharacterBody()->SetMoveSpeed(eCharDir_Right,0); } //----------------------------------------------------------------------- void cPlayerDamage::Update(float afTimeStep) { if(mbActive==false) return; //Alpha update mfAlpha += mfAlphaAdd * afTimeStep; if(mfAlphaAdd >0) { if(mfAlpha >= 1){ mfAlpha = 1; mfAlphaAdd = -2.2f; } } else if(mfAlphaAdd <0) { if(mfAlpha <= 0){ mfAlpha = 0; } } //Update swing mpInit->mpPlayer->GetCamera()->AddYaw(mvHeadSwingSpeed.x*afTimeStep); mpInit->mpPlayer->GetCamera()->AddPitch(mvHeadSwingSpeed.y*afTimeStep); if(mvHeadSwingSpeed.x >0){ mvHeadSwingSpeed.x -= (mvHeadSwingAcc.x/mfSize) * afTimeStep * 2.2f; if(mvHeadSwingSpeed.x <0) mvHeadSwingSpeed.x =0; } else { mvHeadSwingSpeed.x += (mvHeadSwingAcc.x/mfSize) * afTimeStep * 2.2f; if(mvHeadSwingSpeed.x >0) mvHeadSwingSpeed.x =0; } if(mvHeadSwingSpeed.y >0){ mvHeadSwingSpeed.y -= (mvHeadSwingAcc.x/mfSize) * afTimeStep * 2.2f; if(mvHeadSwingSpeed.y <0) mvHeadSwingSpeed.y =0; } else { mvHeadSwingSpeed.y += (mvHeadSwingAcc.x/mfSize) * afTimeStep * 2.2f; if(mvHeadSwingSpeed.y >0) mvHeadSwingSpeed.y =0; } //Blur update if(mpInit->mpPlayer->IsDead()==false) { if(!mpInit->mpPlayer->GetFearFilter()->IsActive()) { mpPostEffects->SetImageTrailAmount(mfAlpha *0.92f); } } //Has it ended? if(mvHeadSwingSpeed.x == 0 && mvHeadSwingSpeed.y == 0 && mfAlpha ==0) { mbActive = false; if(mpInit->mpPlayer->IsDead()==false) { if(!mpInit->mpPlayer->GetFearFilter()->IsActive()) { mpPostEffects->SetImageTrailActive(false); mpPostEffects->SetImageTrailAmount(0); } } } } //----------------------------------------------------------------------- void cPlayerDamage::Draw() { if(mbActive==false) return; mpDrawer->DrawGfxObject(mvHitGfx[mType],cVector3f(0,0,3),cVector2f(800, 600),cColor(1,mfAlpha*0.6f)); } //----------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////// // DEATH ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerDeath::cPlayerDeath(cInit *apInit) { mpInit = apInit; mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer(); mpPostEffects = mpInit->mpGame->GetGraphics()->GetRendererPostEffects(); mpFadeGfx = mpDrawer->CreateGfxObject("player_death_fade.bmp","smoke2d"); mpBlackGfx = mpDrawer->CreateGfxObject("player_death_black.bmp","smoke2d"); } cPlayerDeath::~cPlayerDeath() { mpDrawer->DestroyGfxObject(mpFadeGfx); } //----------------------------------------------------------------------- void cPlayerDeath::Reset() { mbActive = false; mfHeightAdd =0; mfRoll =0; mpPostEffects->SetImageTrailActive(false); } //----------------------------------------------------------------------- void cPlayerDeath::Start() { if(mbActive) return; if(mpInit->mpInventory->IsActive()) mpInit->mpInventory->SetActive(false); if(mpInit->mpNotebook->IsActive()) mpInit->mpNotebook->SetActive(false); if(mpInit->mpNumericalPanel->IsActive()) mpInit->mpNumericalPanel->SetActive(false); mpInit->mpPlayer->GetFlashLight()->SetActive(false); mpInit->mpPlayer->GetGlowStick()->SetActive(false); mpInit->mpPlayer->GetFlare()->SetActive(false); mpInit->mpPlayerHands->SetCurrentModel(0,""); mpInit->mpPlayerHands->SetCurrentModel(1,""); mpInit->mpPlayer->ChangeState(ePlayerState_Normal); mfHeightAdd =0; mfRoll =0; mfMinHeightAdd = -1.3f; if(mpInit->mpPlayer->GetMoveState() == ePlayerMoveState_Crouch) mfMinHeightAdd = -0.7f; mbActive = true; mbStartFade = false; mfFadeAlpha =0; mfBlackAlpha = 0; mpPostEffects->SetImageTrailActive(true); mpPostEffects->SetImageTrailAmount(0.7f); mpInit->mpPlayer->GetEarRing()->Stop(false); for(int i=0; i<=10;++i) { mpInit->mpMusicHandler->Stop(0.2f,i); } } //----------------------------------------------------------------------- void cPlayerDeath::Update(float afTimeStep) { if(mbActive==false) return; mfHeightAdd-= 0.95f*afTimeStep; if(mfHeightAdd < mfMinHeightAdd){ mfHeightAdd = mfMinHeightAdd; mbStartFade = true; mpInit->mpDeathMenu->SetActive(true); } mfRoll += cMath::ToRad(40.0f)*afTimeStep; if(mfRoll > cMath::ToRad(65.0f)) mfRoll = cMath::ToRad(65.0f); mpInit->mpPlayer->GetCamera()->AddRoll(mfRoll); if(mbStartFade) { mfFadeAlpha += 0.7f * afTimeStep; if(mfFadeAlpha > 1) mfFadeAlpha = 1; if(mfFadeAlpha > 0.6f){ mfBlackAlpha += 0.45f * afTimeStep; if(mfBlackAlpha >1) mfBlackAlpha =1; } } } //----------------------------------------------------------------------- void cPlayerDeath::Draw() { if(mbActive==false) return; cVector3f vPos(-mfFadeAlpha*400 - mfBlackAlpha*200,-mfFadeAlpha*400 - mfBlackAlpha*200,4); cVector2f vSize(800 + mfFadeAlpha*800 + mfBlackAlpha*400, 600 + mfFadeAlpha*800+ mfBlackAlpha*400); mpDrawer->DrawGfxObject(mpFadeGfx,vPos,vSize,cColor(mfFadeAlpha,0)); mpDrawer->DrawGfxObject(mpBlackGfx,cVector3f(0,0,5),cVector2f(800,600),cColor(mfBlackAlpha,0)); } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // FLASHLIGHT ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerFlashLight::cPlayerFlashLight(cInit *apInit) { mpInit = apInit; mpInit->mpPlayerHands->AddModelFromFile("hud_object_flashlight.hud"); Reset(); } //----------------------------------------------------------------------- cPlayerFlashLight::~cPlayerFlashLight() { } //----------------------------------------------------------------------- void cPlayerFlashLight::Reset() { mbActive = false; mfAlpha =0; mfFlickerTime =0; mfRayCastTime = 0; mpClosestBody = NULL; mfClosestDist = 10000.0f; mbDisabled = false; } //----------------------------------------------------------------------- bool cPlayerFlashLight::OnIntersect(iPhysicsBody *pBody,cPhysicsRayParams *apParams) { if(pBody->GetCollide()==false) return true; if(pBody->IsCharacter() && pBody == mpInit->mpPlayer->GetCharacterBody()->GetBody()) return true; if(apParams->mfDist < mfClosestDist) { mfClosestDist = apParams->mfDist; mpClosestBody = pBody; } return true; } //----------------------------------------------------------------------- void cPlayerFlashLight::OnWorldLoad() { } //----------------------------------------------------------------------- void cPlayerFlashLight::Update(float afTimeStep) { if(mbActive) { ////////////////////////// //Hits enemy if(mfRayCastTime >= 1)//1.0f/20.0f) { mfRayCastTime =0; cCamera3D *pCam = mpInit->mpPlayer->GetCamera(); iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld(); iHudModel *pHudModel = mpInit->mpPlayerHands->GetModel("Flashlight"); cVector3f vForward = pCam->GetForward(); if(pHudModel && pHudModel->GetEntity()) { vForward = cMath::MatrixMul( pHudModel->GetEntity()->GetWorldMatrix().GetRotation(), cVector3f(0,-1,0)); } if(pHudModel == mpInit->mpPlayerHands->GetCurrentModel(0)) { tGameEnemyIterator it = mpInit->mpMapHandler->GetGameEnemyIterator(); while(it.HasNext()) { iGameEnemy *pEnemy = it.Next(); if(pEnemy->GetHealth() <=0 || pEnemy->IsActive()==false) continue; cVector3f vToEnemy = pEnemy->GetMover()->GetCharBody()->GetPosition() - mpInit->mpPlayer->GetCharacterBody()->GetPosition(); float fSqrDist = vToEnemy.SqrLength(); vToEnemy.Normalise(); if(fSqrDist < 100.0f) { float fAngle = cMath::Vector3Angle(vToEnemy,vForward); if(fAngle < cMath::ToRad(25)) { cVector3f vStart = pCam->GetPosition(); cVector3f vEnd = pEnemy->GetMover()->GetCharBody()->GetPosition(); mvStart =vStart; mvEnd = vEnd; mpClosestBody = NULL; mfClosestDist = 10000.0f; pPhysicsWorld->CastRay(this,vStart,vEnd,true,false,false,false); if( mpClosestBody == NULL || mpClosestBody->IsCharacter()==true) { if(pEnemy->GetUsesTriggers()) { pEnemy->OnFlashlight(pCam->GetPosition()); } } } } } ////////////////////////////// //Get forward //cVector3f vForward = pCam->GetForward(); /*float fAngleX = cMath::RandRectf(cMath::ToRad(-3),cMath::ToRad(3)); float fAngleY = cMath::RandRectf(0,k2Pif); cVector3f vForward = cMath::MatrixMul( cMath::MatrixRotate(cVector3f(fAngleX,fAngleY,0),eEulerRotationOrder_XYZ), cVector3f(0,1,0)); vForward = cMath::MatrixMul( pHudModel->GetEntity()->GetWorldMatrix().GetRotation(), //cMath::MatrixInverse(pCam->GetViewMatrix().GetRotation()), //cMath::MatrixRotate(cVector3f(pCam->GetPitch(),pCam->GetYaw(),pCam->GetRoll()), // eEulerRotationOrder_YXZ), vForward*-1); ////////////////////////////// //Get start and end cVector3f vStart = pCam->GetPosition(); cVector3f vEnd = pCam->GetPosition() + vForward* 20.0f; mvStart =vStart; mvEnd = vEnd; mpClosestBody = NULL; mfClosestDist = 10000.0f; pPhysicsWorld->CastRay(this,vStart,vEnd,true,false,false,false); if(mpClosestBody) { iGameEntity *pEntity = (iGameEntity*)mpClosestBody->GetUserData(); if( pEntity && pEntity->GetType() == eGameEntityType_Enemy && pEntity->IsActive() && pEntity->GetHealth() >0) { iGameEnemy *pEnemy = static_cast(pEntity); if(pEnemy->GetUsesTriggers()) pEnemy->OnFlashlight(vStart); } }*/ //mpInit->mpEffectHandler->GetSubTitle()->Add("Cast rays!\n",0.5f); } } else { mfRayCastTime += afTimeStep; } } iHudModel *pHudModel = mpInit->mpPlayerHands->GetCurrentModel(0); ////////////////////////// //Player power if( mbActive && mpInit->mpInventory->IsActive()==false && mpInit->mpNotebook->IsActive() == false && mpInit->mpNumericalPanel->IsActive() == false) { mpInit->mpPlayer->AddPower(-0.1f * afTimeStep); if(mpInit->mpPlayer->GetPower()==0) { SetActive(false); } } ////////////////////////// //Flicker at low energy if(mbActive && mpInit->mpInventory->IsActive()==false && pHudModel->msName == "Flashlight") { if(mpInit->mpPlayer->GetPower() < 3.0f) { if(mfFlickerTime <= 0) { if(pHudModel->mvLights[0]->IsVisible()) { pHudModel->mvLights[0]->SetVisible(false); pHudModel->mvBillboards[0]->SetVisible(false); mfFlickerTime = cMath::RandRectf(0.04f,0.15f); cSoundHandler *pSoundHanlder = mpInit->mpGame->GetSound()->GetSoundHandler(); pSoundHanlder->PlayGui("item_flashlight_flicker",false,1); } else { pHudModel->mvLights[0]->SetVisible(true); pHudModel->mvBillboards[0]->SetVisible(true); mfFlickerTime = cMath::RandRectf(0.05f,1.5f); } } else { mfFlickerTime -= afTimeStep; } } } } //----------------------------------------------------------------------- void cPlayerFlashLight::SetActive(bool abX) { cSoundHandler *pSoundHanlder = mpInit->mpGame->GetSound()->GetSoundHandler(); if(abX && (mpInit->mpPlayer->GetPower()==0 || mbDisabled)) { pSoundHanlder->PlayGui("item_flashlight_nopower",false,1); return; } if(mbActive == abX) return; mbActive = abX; ///////////////////////////// //Active if(mbActive) { mpInit->mpPlayerHands->SetCurrentModel(0,"Flashlight"); //pSoundHanlder->PlayGui("item_flashlight_on",false,1); } ///////////////////////////// //Not active else if(mpInit->mpPlayerHands->GetCurrentModel(0) && mpInit->mpPlayerHands->GetCurrentModel(0)->msName == "Flashlight" && mpInit->mpPlayerHands->GetCurrentModel(0)->GetState() != eHudModelState_Unequip) { mpInit->mpPlayerHands->SetCurrentModel(0,""); if(mpInit->mpPlayer->GetPower()==0) pSoundHanlder->PlayGui("item_flashlight_nopower",false,1); //else // pSoundHanlder->PlayGui("item_flashlight_off",false,1); } } //----------------------------------------------------------------------- void cPlayerFlashLight::SetDisabled(bool abX) { if(abX==true) SetActive(false); mbDisabled = abX; } //----------------------------------------------------------------------- void cPlayerFlashLight::OnPostSceneDraw() { /*iLowLevelGraphics *mpLowGfx = mpInit->mpGame->GetGraphics()->GetLowLevel(); mpLowGfx->DrawLine(mvStart,mvEnd,cColor(1,0,1));*/ } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // GLOW STICK ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerGlowStick::cPlayerGlowStick(cInit *apInit) { mpInit = apInit; mpInit->mpPlayerHands->AddModelFromFile("hud_object_glowstick.hud"); Reset(); } //----------------------------------------------------------------------- cPlayerGlowStick::~cPlayerGlowStick() { } //----------------------------------------------------------------------- void cPlayerGlowStick::Reset() { mbActive = false; } //----------------------------------------------------------------------- void cPlayerGlowStick::OnWorldLoad() { } //----------------------------------------------------------------------- void cPlayerGlowStick::Destroy() { } //----------------------------------------------------------------------- void cPlayerGlowStick::Update(float afTimeStep) { } //----------------------------------------------------------------------- void cPlayerGlowStick::SetActive(bool abX) { if(mbActive == abX) return; mbActive = abX; cSoundHandler *pSoundHanlder = mpInit->mpGame->GetSound()->GetSoundHandler(); if(mbActive) { //Log("Setting the glowstick to TRUE\n"); mpInit->mpPlayerHands->SetCurrentModel(0,"Glowstick"); //pSoundHanlder->PlayGui("item_glowstick_on",false,1); } else if(mpInit->mpPlayerHands->GetCurrentModel(0) && mpInit->mpPlayerHands->GetCurrentModel(0)->msName == "Glowstick" && mpInit->mpPlayerHands->GetCurrentModel(0)->GetState() != eHudModelState_Unequip) { //Log("Setting the glowstick to FALSE\n"); mpInit->mpPlayerHands->SetCurrentModel(0,""); //pSoundHanlder->PlayGui("item_glowstick_off",false,1); } } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // FLARE ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerFlare::cPlayerFlare(cInit *apInit) { mpInit = apInit; mpInit->mpPlayerHands->AddModelFromFile("hud_object_flare.hud"); mfTime = mpInit->mpGameConfig->GetFloat("Items","FlareGlowTime",1); mfLightPulse = 1.0f; mfLightPulseAdd = 0.88f; mpLight =NULL; Reset(); } //----------------------------------------------------------------------- cPlayerFlare::~cPlayerFlare() { } //----------------------------------------------------------------------- void cPlayerFlare::Reset() { mbActive = false; mpLight =NULL; } //----------------------------------------------------------------------- void cPlayerFlare::OnWorldLoad() { mpLight =NULL; } //----------------------------------------------------------------------- void cPlayerFlare::Update(float afTimeStep) { if(mbActive) { ////////////////////////////////////// // Model entities are loaded and light gotten if(mpLight) { ////////////////////// // Fade at end if(mfTime <=30) { mfLightRadius = (mfTime/30.0f) * mfMaxLightRadius; } float fRadius = mfLightRadius; ////////////////////// // Pulse mfLightPulse += mfLightPulseAdd*afTimeStep; if(mfLightPulseAdd >0 && mfLightPulse >= 1.0f) { mfLightPulse = 1.0f; mfLightPulseAdd = -mfLightPulseAdd; } if(mfLightPulseAdd <0 && mfLightPulse <= 0.0f) { mfLightPulse = 0.0f; mfLightPulseAdd = -mfLightPulseAdd; } fRadius = (mfLightPulse*0.4f +0.8f)*mfLightRadius; if(mpLight) mpLight->SetFarAttenuation(fRadius); ////////////////////// // Time if( mpInit->mpInventory->IsActive()==false && mpInit->mpNotebook->IsActive() == false && mpInit->mpNumericalPanel->IsActive() == false) { mfTime -= afTimeStep; if(mfTime <=0) { SetActive(false); } } } ////////////////////////////////////// // Model entities not loaded yet else { if(mpModel == mpInit->mpPlayerHands->GetCurrentModel(0)) { if(mpModel->mvLights.empty()==false) { mpLight = mpModel->mvLights[0]; mfMaxLightRadius = mpLight->GetFarAttenuation(); mfLightRadius = mfMaxLightRadius; } else { Warning("No lights in flare!\n"); } } } } } //----------------------------------------------------------------------- void cPlayerFlare::SetActive(bool abX) { if(mbActive == abX) return; mbActive = abX; cSoundHandler *pSoundHanlder = mpInit->mpGame->GetSound()->GetSoundHandler(); if(mbActive) { mpInit->mpPlayerHands->SetCurrentModel(0,"Flare"); if(mpInit->mpPlayer->GetFlashLight()->IsActive()) mpInit->mpPlayer->GetFlashLight()->SetActive(false); if(mpInit->mpPlayer->GetGlowStick()->IsActive()) mpInit->mpPlayer->GetGlowStick()->SetActive(false); mfTime = mpInit->mpGameConfig->GetFloat("Items","FlareGlowTime",1); mpModel = mpInit->mpPlayerHands->GetModel("Flare"); mpLight = NULL; } else { /////////////////////////////// //Check if hud model should be put down. if(mpInit->mpPlayerHands->GetCurrentModel(0) && mpInit->mpPlayerHands->GetCurrentModel(0)->msName == "Flare" && mpInit->mpPlayerHands->GetCurrentModel(0)->GetState() != eHudModelState_Unequip) { mpInit->mpPlayerHands->SetCurrentModel(0,""); } /////////////////////////////// //Create entity cCamera3D *pCam = mpInit->mpPlayer->GetCamera(); cVector3f vRot = cVector3f(pCam->GetPitch(),pCam->GetYaw(), pCam->GetRoll()); cMatrixf mtxStart = cMath::MatrixRotate(vRot, eEulerRotationOrder_XYZ); mtxStart.SetTranslation(pCam->GetPosition()); iEntity3D *pEntity = mpInit->mpGame->GetScene()->GetWorld3D()->CreateEntity("Throw",mtxStart, "items_flare_thrown.ent", true); if(pEntity) { iGameEntity *pEntity = mpInit->mpMapHandler->GetLatestEntity(); cVector3f vRot =cMath::MatrixMul(mtxStart.GetRotation(),cVector3f(1,0.3f,0)); for(int i=0; i< pEntity->GetBodyNum(); ++i) { iPhysicsBody *pBody = pEntity->GetBody(i); pBody->AddImpulse(pCam->GetForward() * 3.0f); pBody->AddTorque(vRot); } //setup light if(mfTime <=30) { float fRadius = (mfTime/30.0f); if(fRadius <0)fRadius =0; for(int i=0; i< pEntity->GetLightNum(); ++i) { iLight3D *pLight = pEntity->GetLight(i); pLight->SetFarAttenuation(pLight->GetFarAttenuation() * fRadius); } } } } } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // NOISE FILTER ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerNoiseFilter::cPlayerNoiseFilter(cInit *apInit) { mpInit = apInit; mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer(); mlAmount = 6; for(int i=0; iCreateGfxObject(sFileName,"smoke2d"); if(pObject==NULL) { FatalError("Error loading noise filter!\n"); } mvGfxNoise.push_back(pObject); } mvCurrentGfx.resize(20 * 15,cMath::RandRectl(0,mlAmount-1)); mfAlpha = 0.3f; mfTimeCount =0; mbActive = mpInit->mpConfig->GetBool("Graphics", "NoiseFilter",true); } //----------------------------------------------------------------------- cPlayerNoiseFilter::~cPlayerNoiseFilter() { mpInit->mpConfig->SetBool("Graphics", "NoiseFilter",mbActive); for(size_t i=0; i< mvGfxNoise.size(); ++i) { mpDrawer->DestroyGfxObject(mvGfxNoise[i]); } } //----------------------------------------------------------------------- void cPlayerNoiseFilter::Draw() { if(mbActive == false) return; for(int x=0;x <20;++x) for(int y=0; y< 15; ++y) { cVector3f vPos((float)x*40, (float)y*40,0); mpDrawer->DrawGfxObject(mvGfxNoise[mvCurrentGfx[x*y]],vPos,40,cColor(mfAlpha,0)); //mpDrawer->DrawGfxObject(mvGfxNoise[0],vPos,40,cColor(mfAlpha,mfAlpha)); } } //----------------------------------------------------------------------- void cPlayerNoiseFilter::Update(float afTimeStep) { if(mbActive == false) return; if(mfTimeCount <=0) { for(int x=0;x <20;++x) for(int y=0; y< 15; ++y) { //Change the image int lCurrent = mvCurrentGfx[x*y]; int lRand = cMath::RandRectl(0,mlAmount-1); if(lRand == lCurrent){ ++lRand; if(lRand >= mlAmount) lRand=0; } mvCurrentGfx[x*y] = lRand; } mfTimeCount = 1 / 15.0f; } else { mfTimeCount -= afTimeStep; } } //----------------------------------------------------------------------- void cPlayerNoiseFilter::SetActive(bool abX) { mbActive = abX; } //----------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////// // FEAR FILTER ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerFearFilter::cPlayerFearFilter(cInit *apInit) { mpInit = apInit; Reset(); } //----------------------------------------------------------------------- cPlayerFearFilter::~cPlayerFearFilter() { } //----------------------------------------------------------------------- void cPlayerFearFilter::Draw() { } //----------------------------------------------------------------------- void cPlayerFearFilter::Update(float afTimeStep) { if(mpInit->mpPlayer->IsDead())return; if(mbActive) { mfAlpha += afTimeStep * 0.5f; if(mfAlpha > mfMaxAlpha) mfAlpha = mfMaxAlpha; mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailAmount(mfAlpha); } else if(mfAlpha >0) { mfAlpha -= afTimeStep * 0.15f; if(mfAlpha < 0) { mfAlpha =0; mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(false); } else { mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailAmount(mfAlpha); } } } //----------------------------------------------------------------------- void cPlayerFearFilter::Reset() { mbActive = false; mfAlpha =0; mfMaxAlpha = 0.58f; } //----------------------------------------------------------------------- void cPlayerFearFilter::SetActive(bool abX) { if(mbActive == abX) return; mbActive = abX; mfAlpha =0; mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(true); mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailAmount(0); } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // LOOK AT ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerLookAt::cPlayerLookAt(cPlayer *apPlayer) { mpPlayer = apPlayer; Reset(); } //----------------------------------------------------------------------- cPlayerLookAt::~cPlayerLookAt() { } //----------------------------------------------------------------------- void cPlayerLookAt::Update(float afTimeStep) { if(mbActive==false) return; cCamera3D *pCam = mpPlayer->GetCamera(); cVector3f vGoalAngle = cMath::GetAngleFromPoints3D(pCam->GetPosition(),mvTargetPos); //Get distance to goal cVector3f vDist; vDist.x = cMath::GetAngleDistanceRad(pCam->GetPitch(),vGoalAngle.x); vDist.y = cMath::GetAngleDistanceRad(pCam->GetYaw(),vGoalAngle.y); //Get the Speed cVector3f vSpeed; vSpeed.x = cMath::Min(vDist.x * mfSpeedMul, mfMaxSpeed); vSpeed.y = cMath::Min(vDist.y * mfSpeedMul, mfMaxSpeed); //Add Pitch pCam->AddPitch(vSpeed.x * afTimeStep); //Add yaw pCam->AddYaw(vSpeed.y * afTimeStep); mpPlayer->GetCharacterBody()->SetYaw(pCam->GetYaw()); } void cPlayerLookAt::Reset() { mbActive = false; mfMaxSpeed = 9999.0f; mfSpeedMul = 1.0f; mvTargetPos = cVector3f(0,1,0); } void cPlayerLookAt::SetTarget(const cVector3f &avTargetPos, float afSpeedMul, float afMaxSpeed) { mvTargetPos = avTargetPos; mfSpeedMul = afSpeedMul; mfMaxSpeed = afMaxSpeed; } void cPlayerLookAt::SetActive(bool abX) { mbActive = abX; } //----------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////// // HIDDEN ////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------- cPlayerHidden::cPlayerHidden(cInit *apInit) { mpInit = apInit; mpRenderer = mpInit->mpGame->GetGraphics()->GetRenderer3D(); mpDrawer = mpInit->mpGame->GetGraphics()->GetDrawer(); mpSoundHandler = mpInit->mpGame->GetSound()->GetSoundHandler(); mfUpdateCount = 1.0f / 3.0f; cVector2f vScreenSize = mpInit->mpGame->GetGraphics()->GetLowLevel()->GetScreenSize(); mfStartEffectOffset = 40; mfHiddenEffectOffset = 0; mfEffectOffsetAdd = mfStartEffectOffset - mfHiddenEffectOffset; mfStartAspect = vScreenSize.x / vScreenSize.y; mfHiddenAspect = mfStartAspect*0.82f; mfAspectAdd = mfStartAspect - mfHiddenAspect; mfStartFov = cMath::ToRad(70); mfHiddenFov = cMath::ToRad(78); mfFovAdd = mfHiddenFov- mfStartFov; mfEnemyTooCloseMax = 4.5f; mfCloseEffectFovMax = cMath::ToRad(2); mfCloseEffectFovMin = cMath::ToRad(-11); Reset(); //Get images mpInShadowGfx = mpDrawer->CreateGfxObject("player_in_shadow.jpg","diffadditive2d"); //Get font mpFont = mpInit->mpGame->GetResources()->GetFontManager()->CreateFontData("verdana.fnt"); } //----------------------------------------------------------------------- cPlayerHidden::~cPlayerHidden() { } //----------------------------------------------------------------------- void cPlayerHidden::OnWorldLoad() { cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); mpLight = pWorld->CreateLightPoint("HiddenLight"); mpLight->SetFarAttenuation(13); mpLight->SetDiffuseColor(cColor(0,0,0,0)); mpLight->SetVisible(false); mpLight->SetCastShadows(false); } void cPlayerHidden::OnWorldExit() { } //----------------------------------------------------------------------- void cPlayerHidden::Draw() { /*if(mfLight <= mfMaxLight) { mpFont->Draw(5,12,cColor(0.3f,1,0.3f),eFontAlign_Left,_W("Light: %f\n"),mfLight); if(!mbHidden) mpFont->Draw(cVector3f(5,19,5),12,cColor(1,1,1),eFontAlign_Left,_W("Hidden count: %f"),mfHiddenCount); } else { mpFont->Draw(5,12,cColor(1,0.3f,0.3f),eFontAlign_Left,_W("Light: %f\n"),mfLight); } if(mbHidden) mpFont->Draw(cVector3f(5,19,5),12,cColor(1,1,1),eFontAlign_Left,_W("Hidden\n")); */ /*float fAdd =0; if(mfCloseEffectFov >= 0) { float fT = mfCloseEffectFov / mfCloseEffectFovMax; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMax; } else { float fT = mfCloseEffectFov / mfCloseEffectFovMin; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMin; } mpFont->Draw(5,12,cColor(1,1,1),eFontAlign_Left,"CloseCount: %f TooClose: %d\n", mfEnemyTooCloseCount, mbEnemyTooClose); mpFont->Draw(cVector3f(5,19,5),12,cColor(1,1,1),eFontAlign_Left,"Fov: %f Add: %f\n", mfCloseEffectFov,fAdd);*/ //Draw in shadow effect if(mfInShadowAlpha>0) { float fAlpha = (mfInShadowPulse*0.5f + 0.5f) * mfInShadowAlpha *0.85f; mpDrawer->DrawGfxObject(mpInShadowGfx,cVector3f(-mfEffectOffset,-mfEffectOffset,0), cVector2f(800+mfEffectOffset*2, 600+mfEffectOffset*2), cColor(fAlpha,fAlpha)); } } //----------------------------------------------------------------------- void cPlayerHidden::UnHide() { if(mbHidden){ mpLight->FadeTo(cColor(0,0,0,0),mpLight->GetFarAttenuation(),mfHiddenOffTime); if(mfHiddenOnCount >2) mpSoundHandler->PlayGui("player_hidden_off",false,1); } mbHidden = false; mfHiddenCount =0; mfHiddenOnCount =0; if(mbEnemyTooClose) { mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(false); } mfEnemyTooCloseCount =0; mbEnemyTooClose = false; } //----------------------------------------------------------------------- bool cPlayerHidden::InShadows() { if(mfLight <= mfMaxLight) return true; return false; } //----------------------------------------------------------------------- static float GetMaxRGB(const cColor &aCol) { float fAmount = aCol.r; if(fAmount < aCol.g) fAmount = aCol.g; if(fAmount < aCol.b) fAmount = aCol.b; return fAmount; } void cPlayerHidden::Update(float afTimeStep) { iCharacterBody *pCharBody = mpInit->mpPlayer->GetCharacterBody(); bool bIsCrouching = false; if(mpInit->mpPlayer->GetMoveState() == ePlayerMoveState_Crouch) bIsCrouching = true; /////////////////////////////////// // Update Hidden effect if(mbHidden) { //Aspect if(mfAspect > mfHiddenAspect) { mfAspect -= afTimeStep * mfAspectAdd *(1/mfHiddenOnTime); if(mfAspect < mfHiddenAspect) mfAspect = mfHiddenAspect; mpInit->mpPlayer->GetCamera()->SetAspect(mfAspect); } //FOV if(mfFov < mfHiddenFov) { mfFov += afTimeStep * mfFovAdd*(1/mfHiddenOnTime); if(mfFov > mfHiddenFov) mfFov = mfHiddenFov; mpInit->mpPlayer->GetCamera()->SetFOV(mfFov); } //Effect offset if(mfEffectOffset > mfHiddenEffectOffset) { mfEffectOffset -= afTimeStep * mfEffectOffsetAdd*(1/mfHiddenOnTime); if(mfEffectOffset < mfHiddenEffectOffset) mfEffectOffset = mfHiddenEffectOffset; } } else { //Aspect if(mfAspect < mfStartAspect) { mfAspect += afTimeStep * mfAspectAdd * (1/mfHiddenOffTime); if(mfAspect > mfStartAspect) mfAspect = mfStartAspect; mpInit->mpPlayer->GetCamera()->SetAspect(mfAspect); } //FOV if(mfFov > mfStartFov) { mfFov -= afTimeStep * mfFovAdd * (1/mfHiddenOffTime); if(mfFov < mfStartFov) mfFov = mfStartFov; mpInit->mpPlayer->GetCamera()->SetFOV(mfFov); } //Effect offset if(mfEffectOffset < mfStartEffectOffset) { mfEffectOffset += afTimeStep * mfEffectOffsetAdd * (1/mfHiddenOffTime); if(mfEffectOffset > mfStartEffectOffset) mfEffectOffset = mfStartEffectOffset; } } /////////////////////////////////// // Update In Shadow effect //Alpha if(mfLight <= mfMaxLight && bIsCrouching) { mfInShadowAlpha += afTimeStep; if(mfInShadowAlpha>1) mfInShadowAlpha = 1; } else { mfInShadowAlpha -= afTimeStep; if(mfInShadowAlpha<0) mfInShadowAlpha = 0; } //Pulse mfInShadowPulse += afTimeStep * mfInShadowPulseAdd; if(mfInShadowPulseAdd<0 && mfInShadowPulse<0) { mfInShadowPulse =0; mfInShadowPulseAdd = -mfInShadowPulseAdd; } else if(mfInShadowPulseAdd>0 && mfInShadowPulse>1) { mfInShadowPulse =1; mfInShadowPulseAdd = -mfInShadowPulseAdd; } if(mbInShadows) mpLight->SetPosition(mpInit->mpPlayer->GetCamera()->GetPosition()); ////////////////////////////////////////// // Check if the player is hidden if( mfLight <= mfMaxLight && bIsCrouching && mpInit->mpPlayer->GetHealth()>0) { cVector3f vDiff = pCharBody->GetLastPosition() - pCharBody->GetPosition(); if(fabsf(vDiff.x) < 0.01f && fabsf(vDiff.y) < 0.01f && fabsf(vDiff.z) < 0.01f) { if(!mbHidden) { if(mfHiddenCount >= mfHiddenTime) { mbInShadows = false; mbHidden = true; mpLight->SetVisible(true); mpLight->SetPosition(mpInit->mpPlayer->GetCamera()->GetPosition()); mpLight->FadeTo(cColor(0.1f,0.1f,0.6f,0),12,mfHiddenOnTime); mpSoundHandler->PlayGui("player_hidden_on",false,1); } else { mfHiddenCount += afTimeStep; } } else { mfHiddenOnCount += afTimeStep; } } else { UnHide(); } if(!mbHidden) { if(!mbInShadows) { mpLight->FadeTo(cColor(0.09f,0.09f,0.28f,0),6,1); mpLight->SetVisible(true); } mbInShadows = true; } } else { if(mbInShadows) { mbInShadows = false; mpLight->FadeTo(cColor(0,0,0,0),8,1); } UnHide(); } //////////////////////////////////////////7 // Update the current light level if(mfUpdateCount <= 0) { mfUpdateCount = 1.0f / 2.0f; mfLight = GetMaxRGB(mpInit->mpGame->GetGraphics()->GetRenderer3D()->GetAmbientColor()); cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); if(pWorld==NULL) return; iPhysicsWorld *pPhysicsWorld = pWorld->GetPhysicsWorld(); cBoundingVolume *pPlayerBV = pCharBody->GetBody()->GetBV(); //Just to be sure... if(mpInit->mpPlayer->GetFlashLight()->IsActive()) mfLight+= 0.5; //Iterate lights cLight3DListIterator lightIt = pWorld->GetLightIterator(); while(lightIt.HasNext()) { iLight3D *pLight = lightIt.Next(); if(pLight == mpLight) continue; if(pLight->IsActive()==false || pLight->IsVisible()==false) continue; if(cMath::CheckCollisionBV(*pPlayerBV,*pLight->GetBoundingVolume())) { //Check line of sight if(HasLineOfSight(pLight,pPhysicsWorld)==false) continue; //Get highest value of rg b float fAmount = GetMaxRGB(pLight->GetDiffuseColor()); //Get distance to the light float fDist = cMath::Vector3Dist( pLight->GetWorldPosition(), pPlayerBV->GetWorldCenter()); //Calculate attenuation float fT = 1 - fDist / pLight->GetFarAttenuation(); if(fT<0)fT =0; fAmount *= fT; mfLight += fAmount; } } } else { mfUpdateCount -= afTimeStep; } //////////////////////////////////////////////////// //Check if enemy is too close and act accordingly. UpdateEnemyTooClose(afTimeStep); } //----------------------------------------------------------------------- bool cPlayerHidden::OnIntersect(iPhysicsBody *pBody,cPhysicsRayParams *apParams) { //bool bDebug = pBody->GetName() == "polySurface76"; if(pBody->IsCharacter() || pBody->GetCollide()==false || pBody->GetBlocksLight()==false) { //if(bDebug)Log("Out on first!\n"); return true; } iGameEntity* pEntity = (iGameEntity*)pBody->GetUserData(); if(pEntity && pEntity->GetMeshEntity()) { cMeshEntity *pMeshEntity = pEntity->GetMeshEntity(); if(pMeshEntity->IsShadowCaster()==false) return true; bool bFoundSolid = false; for(int i=0; i< pMeshEntity->GetSubMeshEntityNum(); ++i) { iMaterial *pMaterial = pMeshEntity->GetSubMeshEntity(i)->GetMaterial(); if(pMaterial && (pMaterial->IsTransperant()==false && pMaterial->HasAlpha()==false)) { bFoundSolid = true; break; } } if(bFoundSolid==false){ //if(bDebug)Log("Out on non solid!\n"); return true; } } mbIntersected = true; //if(bDebug)Log("Intersection!!\n"); return false; } //----------------------------------------------------------------------- bool cPlayerHidden::HasLineOfSight(iLight3D *pLight,iPhysicsWorld *pPhysicsWorld) { if(pLight->GetCastShadows()==false) return true; if(mpRenderer->GetShowShadows()== eRendererShowShadows_None) return true; iCharacterBody *pCharBody = mpInit->mpPlayer->GetCharacterBody(); cVector3f vPlayerPos = pCharBody->GetPosition(); //Check frustum of spotlight if(pLight->GetLightType() == eLight3DType_Spot) { cLight3DSpot *pSpotLight = static_cast(pLight); if(pSpotLight->GetFrustum()->CollideBoundingVolume(pLight->GetBoundingVolume()) == eFrustumCollision_Outside) { return false; } } int lCount =0; cVector3f vPosAdd[5]; int lPosAddNum = 5; //Centre vPosAdd[0] = cVector3f(0,0,0); //Head vPosAdd[1] = cVector3f(0,pCharBody->GetSize().y/2 -0.1f,0); //Feet vPosAdd[2] = cVector3f(0,-(pCharBody->GetSize().y/2 + 0.1f),0); cVector3f vRight = cMath::Vector3Cross( cMath::Vector3Normalize(pLight->GetWorldPosition()-vPlayerPos), cVector3f(0,1,0)); //Right vPosAdd[3] = vRight * (pCharBody->GetSize().x *0.4f); //Left vPosAdd[4] = vRight * (pCharBody->GetSize().x *-0.4f); for(int i=0; iCastRay( this,vPlayerPos + vPosAdd[i], pLight->GetWorldPosition(), false,false,false,false); if(mbIntersected) ++lCount; else { break; } } return lCount < lPosAddNum; } //----------------------------------------------------------------------- void cPlayerHidden::UpdateEnemyTooClose(float afTimeStep) { cCamera3D *pCam = mpInit->mpPlayer->GetCamera(); cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D(); if(pWorld==NULL) return; ///////////////////////////// // Update too close effect if(mbEnemyTooClose && mfEnemyTooCloseCount >1.2f) { if(mfCloseEffectFovAdd > 0) { mfCloseEffectFov += mfCloseEffectFovAdd*afTimeStep; if(mfCloseEffectFov >= mfCloseEffectFovMax) { mfCloseEffectFovAdd = -mfCloseEffectFovAdd; mfCloseEffectFov = mfCloseEffectFovMax; if(mfEnemyTooCloseCount > mfEnemyTooCloseMax*0.4f) mpSoundHandler->PlayGui("player_scare_mid",false,1); else mpSoundHandler->PlayGui("player_scare_low",false,1); } } else { mfCloseEffectFov += mfCloseEffectFovAdd*afTimeStep; if(mfCloseEffectFov <= mfCloseEffectFovMin) { mfCloseEffectFovAdd = -mfCloseEffectFovAdd; mfCloseEffectFov = mfCloseEffectFovMin; //if(mfEnemyTooCloseCount > mfEnemyTooCloseMax*0.6f) // mpSoundHandler->PlayGui("player_scare_mid",false,1); //else // mpSoundHandler->PlayGui("player_scare_low",false,1); } } float fAdd =0; if(mfCloseEffectFov >= 0) { float fT = mfCloseEffectFov / mfCloseEffectFovMax; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMax; } else { float fT = mfCloseEffectFov / mfCloseEffectFovMin; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMin; } pCam->SetFOV(mfFov + fAdd); mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(true); mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailAmount(0.8f); } else if(mfCloseEffectFov !=0) { mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(false); if(mfCloseEffectFov < 0) { mfCloseEffectFov += afTimeStep * cMath::ToRad(7); if(mfCloseEffectFov>0) mfCloseEffectFov =0; } else { mfCloseEffectFov -= afTimeStep * cMath::ToRad(7); if(mfCloseEffectFov<0) mfCloseEffectFov =0; } float fAdd =0; if(mfCloseEffectFov >= 0) { float fT = mfCloseEffectFov / mfCloseEffectFovMax; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMax; } else { float fT = mfCloseEffectFov / mfCloseEffectFovMin; fAdd = sin(fT * kPi2f) * mfCloseEffectFovMin; } pCam->SetFOV(mfFov + fAdd); } ///////////////////////////// //Update the count if(InShadows())//mbHidden) { if(mfCheckEnemyCloseCount <=0) { float fMaxDist = mbHidden ? 11.0f : 11.0f; float fMaxDistSqr = fMaxDist*fMaxDist; //Reset variables mbEnemyTooClose = false; mfCheckEnemyCloseCount = 0.3f; ///Get needed data iPhysicsWorld *pPhysicsWorld = pWorld->GetPhysicsWorld(); //Iterate enemies tGameEnemyIterator enemyIt = mpInit->mpMapHandler->GetGameEnemyIterator(); while(enemyIt.HasNext()) { iGameEnemy *pEnemy = enemyIt.Next(); if(pEnemy->GetHealth() <=0 || pEnemy->IsActive()==false) continue; iCharacterBody *pCharBody = pEnemy->GetMover()->GetCharBody(); //Check if the enemy is close enough float fDistSqr = cMath::Vector3DistSqr(pCam->GetPosition(), pCharBody->GetPosition()); if(fDistSqr > fMaxDistSqr) continue; //Check if enemy is in FOV cVector3f vDir = pCharBody->GetPosition() - pCam->GetPosition(); vDir.Normalise(); float fAngle = cMath::Vector3Angle(pCam->GetForward(),vDir); if(fAngle > pCam->GetFOV()*0.5f) continue; //Check if ther is a line of sight mbIntersected = false; pPhysicsWorld->CastRay( this,pCam->GetPosition(), pCharBody->GetPosition(), false,false,false,false); if(mbIntersected==false) { mbEnemyTooClose = true; break; } } } else { mfCheckEnemyCloseCount -= afTimeStep; } //////////////////////////////// // Update the count if enemy is near if(mbEnemyTooClose) { mfEnemyTooCloseCount+= afTimeStep; //Do some effect //Check if limit is reached if(mfEnemyTooCloseCount> mfEnemyTooCloseMax) { UnHide(); mpInit->mpPlayer->ChangeMoveState(ePlayerMoveState_Walk); mpSoundHandler->PlayGui("player_scare_high",false,1); cSoundEntity *pSound = pWorld->CreateSoundEntity("Scare","player_scare_high",true); if(pSound) { pSound->SetPosition(pCam->GetPosition()); } //Show player to nearby enemies. tGameEnemyIterator enemyIt = mpInit->mpMapHandler->GetGameEnemyIterator(); while(enemyIt.HasNext()) { iGameEnemy *pEnemy = enemyIt.Next(); if(pEnemy->GetHealth() <=0 || pEnemy->IsActive()==false) continue; iCharacterBody *pCharBody = pEnemy->GetMover()->GetCharBody(); //Check if the enemy is close enough float fDist = cMath::Vector3Dist(pCam->GetPosition(), pCharBody->GetPosition()); if(fDist <= 8) { pEnemy->ShowPlayer(mpInit->mpPlayer->GetCharacterBody()->GetFeetPosition()); } } } } else if(mfEnemyTooCloseCount >0) { mfEnemyTooCloseCount-= afTimeStep; mpInit->mpGame->GetGraphics()->GetRendererPostEffects()->SetImageTrailActive(false); } } } //----------------------------------------------------------------------- void cPlayerHidden::Reset() { mpLight = NULL; mfHiddenOnTime = 1; mfHiddenOffTime = 0.5f; mfHiddenOnCount = 0; mfEffectOffset = mfStartEffectOffset; mfAspect = mfStartAspect; mfFov = mfStartFov; mbInShadows = false; mfLight = 1.0f; mfMaxLight = 0.25f; mfHiddenCount = 0; mfHiddenTime = 1.4f; mbHidden = false; mfInShadowAlpha = 0; mfInShadowPulse = 0; mfInShadowPulseAdd = 1; mfCheckEnemyCloseCount =0; mfEnemyTooCloseCount =0; mbEnemyTooClose = false; mfCloseEffectFovAdd = cMath::ToRad(15); mfCloseEffectFov = 0; } //-----------------------------------------------------------------------