356 lines
9.8 KiB
C++
356 lines
9.8 KiB
C++
#include "stdafx.h"
|
|
#include "SGameEnvironmentService.h"
|
|
#include "GameDefine.h"
|
|
#include "WorldLocation.h"
|
|
#include "SWorldLocationDB.h"
|
|
#include "SEnvPrimitive.h"
|
|
#include "SGameWeather.h"
|
|
#include "SGameSky.h"
|
|
#include "SGameLens.h"
|
|
#include "SGameWeatherService.h"
|
|
#include "SGameMilesSoundMgr.h"
|
|
#include "SSoundResourceDB.h"
|
|
|
|
using namespace env_fx;
|
|
|
|
bool IEnvironmentState::IsValid( const SLerpArgument& arg ) const
|
|
{
|
|
if( m_tmBegin < m_tmEnd )
|
|
return ( m_tmBegin <= arg.tmTime && m_tmEnd > arg.tmTime );
|
|
else
|
|
return ( m_tmBegin <= arg.tmTime || m_tmEnd > arg.tmTime );
|
|
}
|
|
|
|
void IEnvironmentState::PrepareLerp( SLerpArgument& arg )
|
|
{
|
|
arg.calcMinites = arg.tmTime.GetDiffMinitesFrom( m_tmBegin );
|
|
|
|
if( (int)arg.calcMinites < m_nLerpDuration_min_ )
|
|
{
|
|
arg.lerpAction = SLerpArgument::LERP_PREV;
|
|
arg.lerpTime = (float)arg.calcMinites / (float)m_nLerpDuration_min_;
|
|
}
|
|
else if( (int)arg.calcMinites > m_nActiveDuration_min_ - m_nLerpDuration_min_ )
|
|
{
|
|
arg.lerpAction = SLerpArgument::LERP_NEXT;
|
|
arg.lerpTime = 1.f - (float)( m_nActiveDuration_min_ - (int)arg.calcMinites )
|
|
/ (float)m_nLerpDuration_min_;
|
|
}
|
|
else
|
|
{
|
|
arg.lerpAction = SLerpArgument::LERP_NONE;
|
|
}
|
|
}
|
|
|
|
// sonador 1.1.17 던전 진입시 환경값 설정 오류 수정
|
|
const WorldLocationBase* IEnvironmentState::GetLocationDB( SLerpArgument& arg )
|
|
{
|
|
int nTimeID = GetStateType();
|
|
const WorldLocationBase* data = GetWorldLocationDB().GetWLData( arg.localID, nTimeID, arg.weatherID );
|
|
if( !data )
|
|
data = GetWorldLocationDB().GetWLData( arg.localID, nTimeID, 0 );
|
|
return data;
|
|
}
|
|
|
|
void SEnvironmentDawn::OnEnter( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentDawn::OnLeave( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentDawn::OnPerform( SLerpArgument& arg )
|
|
{
|
|
if( arg.isIndoor || arg.weatherID != 0 )
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
}
|
|
else
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 1.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
}
|
|
arg.context->lensFlare->SetRenderFlag( FALSE );
|
|
}
|
|
|
|
void SEnvironmentDaylight::OnEnter( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentDaylight::OnLeave( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentDaylight::OnPerform( SLerpArgument& arg )
|
|
{
|
|
if( arg.isIndoor || arg.weatherID != 0 )
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
arg.context->lensFlare->SetRenderFlag( FALSE );
|
|
}
|
|
else
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 1.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
arg.context->lensFlare->SetRenderFlag( TRUE );
|
|
}
|
|
}
|
|
|
|
void SEnvironmentEvening::OnEnter( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentEvening::OnLeave( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentEvening::OnPerform( SLerpArgument& arg )
|
|
{
|
|
if( arg.isIndoor || arg.weatherID != 0 )
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
}
|
|
else
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 1.f, arg.time );
|
|
}
|
|
arg.context->lensFlare->SetRenderFlag( FALSE );
|
|
}
|
|
|
|
void SEnvironmentNight::OnEnter( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentNight::OnLeave( SLerpArgument& arg )
|
|
{
|
|
}
|
|
|
|
void SEnvironmentNight::OnPerform( SLerpArgument& arg )
|
|
{
|
|
if( arg.isIndoor || arg.weatherID != 0 )
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 0.f, arg.time );
|
|
}
|
|
else
|
|
{
|
|
arg.context->sky->SetVisibilitySun( true, 0.f, arg.time );
|
|
arg.context->sky->SetVisibilityMoon( true, 1.f, arg.time );
|
|
}
|
|
arg.context->lensFlare->SetRenderFlag( FALSE );
|
|
}
|
|
|
|
SEnvironmentService::SEnvironmentService
|
|
( SGameSky* pSky
|
|
, SGameLensFlare* pLensFlare
|
|
, SGameWeatherService* pWeather
|
|
, SGameMilesSoundMgr* pSoundMgr )
|
|
: m_pCurrentState ( 0 )
|
|
, m_pPreviousState ( 0 )
|
|
, m_pContext ( 0 )
|
|
, m_pSoundMgr ( pSoundMgr )
|
|
{
|
|
tm begin, end;
|
|
::memset( (void*)&begin, 0, sizeof( tm ) );
|
|
::memset( (void*)&end, 0, sizeof( tm ) );
|
|
|
|
begin.tm_hour = 5; begin.tm_min = 0;
|
|
end.tm_hour = 8; end.tm_min = 0;
|
|
m_ctEnvironmentStates.push_back( new SEnvironmentDawn( begin, end, 30 ) );
|
|
|
|
begin.tm_hour = 8; begin.tm_min = 0;
|
|
end.tm_hour = 17; end.tm_min = 0;
|
|
m_ctEnvironmentStates.push_back( new SEnvironmentDaylight( begin, end, 0 ) );
|
|
|
|
begin.tm_hour = 17; begin.tm_min = 0;
|
|
end.tm_hour = 20; end.tm_min = 0;
|
|
m_ctEnvironmentStates.push_back( new SEnvironmentEvening( begin, end, 30 ) );
|
|
|
|
begin.tm_hour = 20; begin.tm_min = 0;
|
|
end.tm_hour = 5; end.tm_min = 0;
|
|
m_ctEnvironmentStates.push_back( new SEnvironmentNight( begin, end, 0 ) );
|
|
|
|
m_pContext = new SEnvironmentContext();
|
|
m_pContext->sky = pSky;
|
|
m_pContext->lensFlare = pLensFlare;
|
|
m_pContext->weatherService = pWeather;
|
|
}
|
|
|
|
SEnvironmentService::~SEnvironmentService()
|
|
{
|
|
env_fx::util::wipe_seq( m_ctEnvironmentStates );
|
|
SAFE_DELETE( m_pContext );
|
|
}
|
|
|
|
void SEnvironmentService::Perform( SLerpArgument& arg )
|
|
{
|
|
// complete lerp argument
|
|
_prepareLerpArgument( arg );
|
|
|
|
// change state
|
|
IEnvironmentState* pState = 0;
|
|
pState = _switchState( arg );
|
|
assert( pState && "there is wrong values in world time states" );
|
|
|
|
// enter & leave action
|
|
bool stateChanged = false;
|
|
if( m_pCurrentState != pState )
|
|
{
|
|
if( m_pCurrentState )
|
|
{
|
|
m_pCurrentState->OnLeave( arg );
|
|
m_pPreviousState = m_pCurrentState;
|
|
}
|
|
|
|
m_pCurrentState = pState;
|
|
|
|
if( m_pCurrentState )
|
|
m_pCurrentState->OnEnter( arg );
|
|
|
|
stateChanged = true;
|
|
}
|
|
|
|
// proceed current state
|
|
if( m_pCurrentState )
|
|
{
|
|
// perform current state
|
|
m_pCurrentState->OnPerform( arg );
|
|
|
|
// proceed lerp action
|
|
m_pCurrentState->PrepareLerp( arg );
|
|
arg.timeState = m_pCurrentState->GetStateType();
|
|
if( arg.lerpAction == SLerpArgument::LERP_NONE )
|
|
{
|
|
arg.locData = m_pCurrentState->GetLocationDB( arg );
|
|
arg.locLerpData = m_pCurrentState->GetLocationDB( arg );
|
|
}
|
|
else if( arg.lerpAction == SLerpArgument::LERP_PREV )
|
|
{
|
|
if( m_pPreviousState == 0 ) // sonador 1.1.20 환경값 보간 오류 수정
|
|
m_pPreviousState = _getPrevState( m_pCurrentState->GetStateType() );
|
|
arg.locData = m_pPreviousState->GetLocationDB( arg );
|
|
arg.locLerpData = m_pCurrentState->GetLocationDB( arg );
|
|
}
|
|
else if( arg.lerpAction == SLerpArgument::LERP_NEXT )
|
|
{
|
|
IEnvironmentState* pNext = _getNextState( m_pCurrentState->GetStateType() );
|
|
arg.locData = m_pCurrentState->GetLocationDB( arg );
|
|
arg.locLerpData = pNext->GetLocationDB( arg );
|
|
}
|
|
}
|
|
|
|
// change weather
|
|
if( arg.context->weatherService )
|
|
{
|
|
arg.context->weatherService->ChangeInOut( arg.isIndoor );
|
|
|
|
if( arg.weatherID != arg.context->weatherService->GetState() || stateChanged )
|
|
{
|
|
int prevWeatherState = arg.context->weatherService->GetState();
|
|
|
|
float precipitation = 0.0f;
|
|
if( arg.locLerpData )
|
|
precipitation = env_fx::util::GetRandomNumberInRange( arg.locLerpData->precipitation_min, arg.locLerpData->precipitation_max ) * 0.01f;
|
|
arg.context->weatherService->ChangeState( arg.weatherID, precipitation, arg.weatherOptionFactor, true );
|
|
|
|
if( prevWeatherState != IGameWeatherState::WS_NONE )
|
|
arg.weatherChanged = true;
|
|
}
|
|
}
|
|
|
|
// change env sound
|
|
if( arg.locLerpData == 0 || m_pSoundMgr == 0 )
|
|
return;
|
|
|
|
static DWORD m_dwEnvFxSoundTime = arg.time;
|
|
static DWORD m_dwEnvFxSoundDelayTime = 20000;
|
|
static int m_nPrevEnvFxSoundIndex = 0;
|
|
static int m_nMusicFadeInTime = 10000;
|
|
static int m_nMusicFadeOutTime = 10000;
|
|
static std::string m_strCurEnvFxSoundName = "";
|
|
|
|
if( stateChanged || arg.weatherChanged )
|
|
{
|
|
int nSoundIndex = rand() % 3;
|
|
std::string soundFileName = GetResourceDB().GetSoundResourceName( arg.locLerpData->environmental_sound_ID[nSoundIndex] );
|
|
if( soundFileName != m_strCurEnvFxSoundName )
|
|
{
|
|
m_strCurEnvFxSoundName = soundFileName;
|
|
m_nPrevEnvFxSoundIndex = nSoundIndex;
|
|
m_pSoundMgr->SwapPlayMusic( m_strCurEnvFxSoundName.c_str(), m_nMusicFadeInTime, m_nMusicFadeOutTime, m_pSoundMgr->GetEnvVolume(), true );
|
|
}
|
|
}
|
|
else if( m_dwEnvFxSoundTime != 0 && (arg.time - m_dwEnvFxSoundTime) > m_dwEnvFxSoundDelayTime )
|
|
{
|
|
int nSoundIndex = rand() % 3;
|
|
while( nSoundIndex == m_nPrevEnvFxSoundIndex )
|
|
{
|
|
nSoundIndex = rand() % 3;
|
|
}
|
|
|
|
int nRand = rand() % 100;
|
|
if(nRand > arg.locLerpData->environmental_sound_ratio[nSoundIndex] )
|
|
{
|
|
std::string soundFileName = GetResourceDB().GetSoundResourceName( arg.locLerpData->environmental_sound_ID[nSoundIndex] );
|
|
if( soundFileName != m_strCurEnvFxSoundName )
|
|
{
|
|
m_strCurEnvFxSoundName = soundFileName;
|
|
m_nPrevEnvFxSoundIndex = nSoundIndex;
|
|
m_pSoundMgr->SwapPlayMusic( m_strCurEnvFxSoundName.c_str(), m_nMusicFadeInTime, m_nMusicFadeOutTime, m_pSoundMgr->GetEnvVolume(), true );
|
|
}
|
|
}
|
|
|
|
m_dwEnvFxSoundTime = arg.time;
|
|
}
|
|
}
|
|
|
|
void SEnvironmentService::_prepareLerpArgument( SLerpArgument& arg )
|
|
{
|
|
arg.context = m_pContext;
|
|
}
|
|
|
|
IEnvironmentState* SEnvironmentService::_switchState( const SLerpArgument& arg )
|
|
{
|
|
IEnvironmentState* pResult = 0;
|
|
size_t state_size = m_ctEnvironmentStates.size();
|
|
|
|
for( size_t n = 0; n < state_size; ++n )
|
|
{
|
|
IEnvironmentState* pState = m_ctEnvironmentStates[ n ];
|
|
if( pState->IsValid( arg ) )
|
|
{
|
|
pResult = pState;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pResult;
|
|
}
|
|
|
|
IEnvironmentState* SEnvironmentService::_getNextState( int nCurrentState )
|
|
{
|
|
IEnvironmentState* pResult = 0;
|
|
size_t state_size = m_ctEnvironmentStates.size();
|
|
size_t nNext = (size_t)nCurrentState + 1;
|
|
if( nNext >= state_size )
|
|
nNext = 0;
|
|
pResult = m_ctEnvironmentStates[ nNext ];
|
|
return pResult;
|
|
}
|
|
|
|
IEnvironmentState* SEnvironmentService::_getPrevState( int nCurrentState ) // sonador 1.1.20 환경값 보간 오류 수정
|
|
{
|
|
IEnvironmentState* pResult = 0;
|
|
size_t nPrev = 0;
|
|
if( (size_t)nCurrentState <= 0 )
|
|
nPrev = m_ctEnvironmentStates.size() - 1;
|
|
else
|
|
nPrev = (size_t)nCurrentState - 1;
|
|
pResult = m_ctEnvironmentStates[ nPrev ];
|
|
return pResult;
|
|
} |