client/GameLib/MapOutdoor.cpp

1594 lines
42 KiB
C++
Raw Blame History

#include "StdAfx.h"
#include "../eterlib/StateManager.h"
#include "../eterlib/Camera.h"
#include "../PRTerrainLib/StdAfx.h"
#include "../EffectLib/EffectManager.h"
#include "MapOutdoor.h"
#include "TerrainPatch.h"
#include "AreaTerrain.h"
//#define USE_LEVEL
// unsigned int uiNumSplat;
struct FGetObjectHeight
{
bool m_bHeightFound;
float m_fReturnHeight;
float m_fRequestX, m_fRequestY;
FGetObjectHeight(float fRequestX, float fRequestY)
{
m_fRequestX=fRequestX;
m_fRequestY=fRequestY;
m_bHeightFound=false;
m_fReturnHeight=0.0f;
}
void operator () (CGraphicObjectInstance * pObject)
{
if (pObject->GetObjectHeight(m_fRequestX, m_fRequestY, &m_fReturnHeight))
{
#ifdef SPHERELIB_STRICT
printf("FIND %f\n", m_fReturnHeight);
#endif
m_bHeightFound = true;
}
}
};
struct FGetPickingPoint
{
D3DXVECTOR3 m_v3Start;
D3DXVECTOR3 m_v3Dir;
D3DXVECTOR3 m_v3PickingPoint;
bool m_bPicked;
FGetPickingPoint(D3DXVECTOR3 & v3Start, D3DXVECTOR3 & v3Dir) : m_v3Start(v3Start), m_v3Dir(v3Dir), m_bPicked(false) {}
void operator() (CGraphicObjectInstance * pInstance)
{
if( pInstance && pInstance->GetType() == CGraphicThingInstance::ID )
{
CGraphicThingInstance * pThing = (CGraphicThingInstance *)pInstance;
if (!pThing->IsObjectHeight())
return;
float fX, fY, fZ;
if (pThing->Picking(m_v3Start, m_v3Dir, fX, fY))
{
if (pThing->GetObjectHeight(fX, -fY, &fZ))
{
m_v3PickingPoint.x = fX;
m_v3PickingPoint.y = fY;
m_v3PickingPoint.z = fZ;
m_bPicked = true;
}
}
}
}
};
CMapOutdoor::CMapOutdoor()
{
CGraphicImage * pAlphaFogImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer("D:/ymir work/special/fog.tga");
CGraphicImage * pAttrImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/white.dds");
CGraphicImage * pBuildTransparentImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir Work/special/PCBlockerAlpha.dds");
m_AlphaFogImageInstance.SetImagePointer(pAlphaFogImage);
m_attrImageInstance.SetImagePointer(pAttrImage);
m_BuildingTransparentImageInstance.SetImagePointer(pBuildTransparentImage);
Initialize();
__SoftwareTransformPatch_Initialize();
__SoftwareTransformPatch_Create();
}
CMapOutdoor::~CMapOutdoor()
{
__SoftwareTransformPatch_Destroy();
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
//ms_AreaLoaderThread.Shutdown();
Destroy();
}
bool CMapOutdoor::Initialize()
{
BYTE i;
for (i = 0; i < AROUND_AREA_NUM; ++i)
{
m_pArea[i] = NULL;
m_pTerrain[i] = NULL;
}
m_pTerrainPatchProxyList = NULL;
m_lViewRadius = 0L;
m_fHeightScale = 0.0f;
m_sTerrainCountX = m_sTerrainCountY = 0;
m_CurCoordinate.m_sTerrainCoordX = -1;
m_CurCoordinate.m_sTerrainCoordY = -1;
m_PrevCoordinate.m_sTerrainCoordX = -1;
m_PrevCoordinate.m_sTerrainCoordY = -1;
m_EntryPointMap.clear();
m_lCenterX = m_lCenterY = 0;
m_lOldReadX = m_lOldReadY = -1;
#ifdef WORLD_EDITOR
m_pwIndices = NULL;
#else
memset(m_pwaIndices, 0, sizeof(m_pwaIndices));
for (i = 0; i < TERRAINPATCH_LODMAX; ++i)
m_IndexBuffer[i].Destroy();
#endif
m_bSettingTerrainVisible = false;
m_bDrawWireFrame = false;
m_bDrawShadow = false;
m_bDrawChrShadow = false;
m_iSplatLimit = 50000;
m_wPatchCount = 0;
m_pRootNode = NULL;
//////////////////////////////////////////////////////////////////////////
// Character Shadow
m_lpCharacterShadowMapTexture = NULL;
m_lpCharacterShadowMapRenderTargetSurface = NULL;
m_lpCharacterShadowMapDepthSurface = NULL;
m_lpBackupRenderTargetSurface = NULL;
m_lpBackupDepthSurface = NULL;
// Character Shadow
//////////////////////////////////////////////////////////////////////////
m_iRenderedPatchNum = 0;
m_iRenderedSplatNum = 0;
//////////////////////////////////////////////////////////////////////////
m_fOpaqueWaterDepth = 400.0f;
//////////////////////////////////////////////////////////////////////////
m_TerrainVector.clear();
m_TerrainDeleteVector.clear();
m_TerrainLoadRequestVector.clear();
m_TerrainLoadWaitVector.clear();
m_AreaVector.clear();
m_AreaDeleteVector.clear();
m_AreaLoadRequestVector.clear();
m_AreaLoadWaitVector.clear();
//////////////////////////////////////////////////////////////////////////
m_PatchVector.clear();
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
//m_bBGLoadingEnable = false;
m_eTerrainRenderSort = DISTANCE_SORT;
D3DXMatrixIdentity(&m_matWorldForCommonUse);
InitializeFog();
InitializeVisibleParts();
m_dwBaseX = 0;
m_dwBaseY = 0;
m_settings_envDataName = "";
m_bShowEntirePatchTextureCount = false;
m_bTransparentTree = true;
CMapBase::Clear();
__XMasTree_Initialize();
SpecialEffect_Destroy();
m_bEnableTerrainOnlyForHeight = FALSE;
m_bEnablePortal = FALSE;
m_wShadowMapSize = 512;
return true;
}
bool CMapOutdoor::Destroy()
{
m_bEnableTerrainOnlyForHeight = FALSE;
m_bEnablePortal = FALSE;
XMasTree_Destroy();
DestroyTerrain();
DestroyArea();
DestroyTerrainPatchProxyList();
FreeQuadTree();
ReleaseCharacterShadowTexture();
CTerrain::DestroySystem();
CArea::DestroySystem();
RemoveAllMonsterAreaInfo();
m_rkList_kGuildArea.clear();
m_kPool_kMonsterAreaInfo.Destroy();
m_AlphaFogImageInstance.Destroy();
CSpeedTreeForestDirectX8::Instance().Clear();
return true;
}
void CMapOutdoor::Clear()
{
UnloadWaterTexture();
Destroy(); // <20><><EFBFBD><EFBFBD>
Initialize(); // <20>ʱ<EFBFBD>ȭ
}
bool CMapOutdoor::SetTerrainCount(short sTerrainCountX, short sTerrainCountY)
{
if (0 == sTerrainCountX || MAX_MAPSIZE < sTerrainCountX)
return false;
if (0 == sTerrainCountY || MAX_MAPSIZE < sTerrainCountY)
return false;
m_sTerrainCountX = sTerrainCountX;
m_sTerrainCountY = sTerrainCountY;
return true;
}
void CMapOutdoor::OnBeginEnvironment()
{
if (!mc_pEnvironmentData)
return;
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
rkForest.SetFog(
mc_pEnvironmentData->GetFogNearDistance(),
mc_pEnvironmentData->GetFogFarDistance()
);
const D3DLIGHT8& c_rkLight = mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER];
rkForest.SetLight(
(const float *)&c_rkLight.Direction,
(const float *)&c_rkLight.Ambient,
(const float *)&c_rkLight.Diffuse);
rkForest.SetWindStrength(mc_pEnvironmentData->fWindStrength);
}
void CMapOutdoor::OnSetEnvironmentDataPtr()
{
SetEnvironmentScreenFilter();
SetEnvironmentSkyBox();
SetEnvironmentLensFlare();
}
void CMapOutdoor::OnResetEnvironmentDataPtr()
{
m_SkyBox.Unload();
SetEnvironmentScreenFilter();
SetEnvironmentSkyBox();
SetEnvironmentLensFlare();
}
void CMapOutdoor::SetEnvironmentScreenFilter()
{
if (!mc_pEnvironmentData)
return;
m_ScreenFilter.SetEnable(mc_pEnvironmentData->bFilteringEnable);
m_ScreenFilter.SetBlendType(mc_pEnvironmentData->byFilteringAlphaSrc, mc_pEnvironmentData->byFilteringAlphaDest);
m_ScreenFilter.SetColor(mc_pEnvironmentData->FilteringColor);
}
void CMapOutdoor::SetEnvironmentSkyBox()
{
if (!mc_pEnvironmentData)
return;
m_SkyBox.SetSkyBoxScale(mc_pEnvironmentData->v3SkyBoxScale);
m_SkyBox.SetGradientLevel(mc_pEnvironmentData->bySkyBoxGradientLevelUpper, mc_pEnvironmentData->bySkyBoxGradientLevelLower);
m_SkyBox.SetRenderMode( (mc_pEnvironmentData->bSkyBoxTextureRenderMode == TRUE) ? CSkyObject::SKY_RENDER_MODE_TEXTURE : CSkyObject::SKY_RENDER_MODE_DIFFUSE);
for( int i = 0; i < 6; ++i )
{
if (!mc_pEnvironmentData->strSkyBoxFaceFileName[i].empty())
m_SkyBox.SetFaceTexture( mc_pEnvironmentData->strSkyBoxFaceFileName[i].c_str(), i );
}
if (!mc_pEnvironmentData->strCloudTextureFileName.empty())
m_SkyBox.SetCloudTexture(mc_pEnvironmentData->strCloudTextureFileName.c_str());
m_SkyBox.SetCloudScale(mc_pEnvironmentData->v2CloudScale);
m_SkyBox.SetCloudHeight(mc_pEnvironmentData->fCloudHeight);
m_SkyBox.SetCloudTextureScale(mc_pEnvironmentData->v2CloudTextureScale);
m_SkyBox.SetCloudScrollSpeed(mc_pEnvironmentData->v2CloudSpeed);
m_SkyBox.Refresh();
// Temporary
m_SkyBox.SetCloudColor(mc_pEnvironmentData->CloudGradientColor, mc_pEnvironmentData->CloudGradientColor, 1);
if (!mc_pEnvironmentData->SkyBoxGradientColorVector.empty())
m_SkyBox.SetSkyColor(mc_pEnvironmentData->SkyBoxGradientColorVector, mc_pEnvironmentData->SkyBoxGradientColorVector, 1);
// Temporary
m_SkyBox.StartTransition();
}
void CMapOutdoor::SetEnvironmentLensFlare()
{
if (!mc_pEnvironmentData)
return;
m_LensFlare.CharacterizeFlare(mc_pEnvironmentData->bLensFlareEnable == 1 ? true : false,
mc_pEnvironmentData->bMainFlareEnable == 1 ? true : false,
mc_pEnvironmentData->fLensFlareMaxBrightness,
mc_pEnvironmentData->LensFlareBrightnessColor);
m_LensFlare.Initialize("d:/ymir work/environment");
if (!mc_pEnvironmentData->strMainFlareTextureFileName.empty())
m_LensFlare.SetMainFlare(mc_pEnvironmentData->strMainFlareTextureFileName.c_str(),
mc_pEnvironmentData->fMainFlareSize);
}
void CMapOutdoor::SetWireframe(bool bWireFrame)
{
m_bDrawWireFrame = bWireFrame;
}
bool CMapOutdoor::IsWireframe()
{
return m_bDrawWireFrame;
}
//////////////////////////////////////////////////////////////////////////
// TerrainPatchList
//////////////////////////////////////////////////////////////////////////
void CMapOutdoor::CreateTerrainPatchProxyList()
{
m_wPatchCount = ((m_lViewRadius * 2) / TERRAIN_PATCHSIZE) + 2;
m_pTerrainPatchProxyList = new CTerrainPatchProxy[m_wPatchCount * m_wPatchCount];
m_iPatchTerrainVertexCount = (TERRAIN_PATCHSIZE+1)*(TERRAIN_PATCHSIZE+1);
m_iPatchWaterVertexCount = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 6;
m_iPatchTerrainVertexSize = 24;
m_iPatchWaterVertexSize = 16;
SetIndexBuffer();
}
void CMapOutdoor::DestroyTerrainPatchProxyList()
{
if (m_pTerrainPatchProxyList)
{
delete [] m_pTerrainPatchProxyList;
m_pTerrainPatchProxyList = NULL;
}
#ifdef WORLD_EDITOR
m_IndexBuffer.Destroy();
#else
for (int i = 0; i < TERRAINPATCH_LODMAX; ++i)
m_IndexBuffer[i].Destroy();
#endif
}
//////////////////////////////////////////////////////////////////////////
// Area
//////////////////////////////////////////////////////////////////////////
void CMapOutdoor::EnablePortal(bool bFlag)
{
m_bEnablePortal = bFlag;
for (int i = 0; i < AROUND_AREA_NUM; ++i)
if (m_pArea[i])
m_pArea[i]->EnablePortal(bFlag);
}
void CMapOutdoor::DestroyArea()
{
m_AreaVector.clear();
m_AreaDeleteVector.clear();
CArea::ms_kPool.FreeAll();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
m_pArea[i] = NULL;
}
//////////////////////////////////////////////////////////////////////////
// Terrain
//////////////////////////////////////////////////////////////////////////
void CMapOutdoor::DestroyTerrain()
{
m_TerrainVector.clear();
m_TerrainDeleteVector.clear();
CTerrain::ms_kPool.FreeAll();
for (int i=0; i < AROUND_AREA_NUM; ++i)
m_pTerrain[i] = NULL;
}
//////////////////////////////////////////////////////////////////////////
// New
//////////////////////////////////////////////////////////////////////////
bool CMapOutdoor::GetTerrainNum(float fx, float fy, BYTE * pbyTerrainNum)
{
if (fy < 0)
fy = -fy;
int ix, iy;
PR_FLOAT_TO_INT(fx, ix);
PR_FLOAT_TO_INT(fy, iy);
WORD wTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE);
WORD wTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE);
return GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, pbyTerrainNum);
}
bool CMapOutdoor::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
{
return GetPickingPointWithRay(ms_Ray, v3IntersectPt);
}
bool CMapOutdoor::__PickTerrainHeight(float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep, float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick)
{
CTerrain * pTerrain;
D3DXVECTOR3 v3CurPos;
float fRayRangeInv=1.0f/fRayRange;
while (fPos < fRayRange && fPos<fLimitRange)
{
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, fPos*fRayRangeInv);
BYTE byTerrainNum;
float fMultiplier = 1.0f;
if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum))
{
if (GetTerrainPointer(byTerrainNum, &pTerrain))
{
int ix, iy;
PR_FLOAT_TO_INT(v3CurPos.x, ix);
PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy);
float fMapHeight = pTerrain->GetHeight(ix, iy);
if ( fMapHeight >= v3CurPos.z)
{
*pv3Pick = v3CurPos;
return true;
}
else
{
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
}
}
}
fPos += fStep * fMultiplier;
}
return false;
}
bool CMapOutdoor::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
{
bool bObjectPick = false;
bool bTerrainPick = false;
D3DXVECTOR3 v3ObjectPick, v3TerrainPick;
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
float fRayRange;
rRay.GetStartPoint(&v3Start);
rRay.GetDirection(&v3Dir, &fRayRange);
rRay.GetEndPoint(&v3End);
Vector3d v3dStart, v3dEnd;
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
if (!m_bEnableTerrainOnlyForHeight)
{
//DWORD baseTime = timeGetTime();
CCullingManager & rkCullingMgr = CCullingManager::Instance();
FGetPickingPoint kGetPickingPoint(v3Start, v3Dir);
rkCullingMgr.ForInRange2d(v3dStart, &kGetPickingPoint);
if (kGetPickingPoint.m_bPicked)
{
bObjectPick = true;
v3ObjectPick = kGetPickingPoint.m_v3PickingPoint;
}
}
float fPos = 0.0f;
//float fStep = 1.0f;
//float fRayRangeInv=1.0f/fRayRange;
bTerrainPick=true;
if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
bTerrainPick=false;
if (bObjectPick && bTerrainPick)
{
if ( D3DXVec3Length( &(v3ObjectPick - v3Start) ) >= D3DXVec3Length( &(v3TerrainPick - v3Start) ) )
*v3IntersectPt = v3TerrainPick;
else
*v3IntersectPt = v3ObjectPick;
return true;
}
else if (bObjectPick)
{
*v3IntersectPt = v3ObjectPick;
return true;
}
else if (bTerrainPick)
{
*v3IntersectPt = v3TerrainPick;
return true;
}
return false;
}
bool CMapOutdoor::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
{
bool bTerrainPick = false;
D3DXVECTOR3 v3TerrainPick;
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
float fRayRange;
rRay.GetStartPoint(&v3Start);
rRay.GetDirection(&v3Dir, &fRayRange);
rRay.GetEndPoint(&v3End);
Vector3d v3dStart, v3dEnd;
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
float fPos = 0.0f;
bTerrainPick=true;
if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
bTerrainPick=false;
if (bTerrainPick)
{
*v3IntersectPt = v3TerrainPick;
return true;
}
return false;
}
/*
{
bool bTerrainPick = false;
D3DXVECTOR3 v3TerrainPick;
CTerrain * pTerrain;
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
float fRayRange;
rRay.GetStartPoint(&v3Start);
rRay.GetDirection(&v3Dir, &fRayRange);
rRay.GetEndPoint(&v3End);
Vector3d v3dStart, v3dEnd;
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
float fAdd = 1.0f / fRayRange;
float ft = 0.0f;
while (ft < 1.0f)
{
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, ft);
BYTE byTerrainNum;
float fMultiplier = 1.0f;
if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum))
{
if (GetTerrainPointer(byTerrainNum, &pTerrain))
{
int ix, iy;
PR_FLOAT_TO_INT(v3CurPos.x, ix);
PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy);
float fMapHeight = pTerrain->GetHeight(ix, iy);
if ( fMapHeight >= v3CurPos.z)
{
bTerrainPick = true;
v3TerrainPick = v3CurPos;
break;
}
else
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
}
}
ft += fAdd * fMultiplier;
}
if (bTerrainPick)
{
*v3IntersectPt = v3TerrainPick;
return true;
}
return false;
}
*/
void CMapOutdoor::GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap)
{
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
{
*pwHeightMap = NULL;
return;
}
*pwHeightMap = m_pTerrain[c_rucTerrainNum]->GetHeightMap();
}
void CMapOutdoor::GetNormalMap(const BYTE & c_rucTerrainNum, char ** pucNormalMap)
{
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
{
*pucNormalMap = NULL;
return;
}
*pucNormalMap = m_pTerrain[c_rucTerrainNum]->GetNormalMap();
}
void CMapOutdoor::GetWaterMap(const BYTE & c_rucTerrainNum, BYTE ** pucWaterMap)
{
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
{
*pucWaterMap = NULL;
return;
}
*pucWaterMap = m_pTerrain[c_rucTerrainNum]->GetWaterMap();
}
void CMapOutdoor::GetWaterHeight(BYTE byTerrainNum, BYTE byWaterNum, long * plWaterHeight)
{
if (byTerrainNum < 0 || byTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[byTerrainNum])
{
*plWaterHeight = -1;
return;
}
m_pTerrain[byTerrainNum]->GetWaterHeight(byWaterNum, plWaterHeight);
}
bool CMapOutdoor::GetWaterHeight(int iX, int iY, long * plWaterHeight)
{
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
return false;
WORD wTerrainCoordX, wTerrainCoordY;
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
return false;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return false;
WORD wLocalX, wLocalY;
wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::WATERMAP_XSIZE);
wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::WATERMAP_YSIZE);
return pTerrain->GetWaterHeight(wLocalX, wLocalY, plWaterHeight);
}
//////////////////////////////////////////////////////////////////////////
// Update
//////////////////////////////////////////////////////////////////////////
bool CMapOutdoor::GetTerrainNumFromCoord(WORD wCoordX, WORD wCoordY, BYTE * pbyTerrainNum)
{
*pbyTerrainNum = (wCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
(wCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH);
if (*pbyTerrainNum < 0 || *pbyTerrainNum > AROUND_AREA_NUM)
return false;
return true;
}
void CMapOutdoor::BuildViewFrustum(D3DXMATRIX & mat)
{
//m_plane[0] = D3DXPLANE(mat._14 + mat._13, mat._24 + mat._23, mat._34 + mat._33, mat._44 + mat._43);
m_plane[0] = D3DXPLANE( mat._13, mat._23, mat._33, mat._43); // Near
m_plane[1] = D3DXPLANE(mat._14 - mat._13, mat._24 - mat._23, mat._34 - mat._33, mat._44 - mat._43); // Far
m_plane[2] = D3DXPLANE(mat._14 + mat._11, mat._24 + mat._21, mat._34 + mat._31, mat._44 + mat._41); // Left
m_plane[3] = D3DXPLANE(mat._14 - mat._11, mat._24 - mat._21, mat._34 - mat._31, mat._44 - mat._41); // Right
m_plane[4] = D3DXPLANE(mat._14 + mat._12, mat._24 + mat._22, mat._34 + mat._32, mat._44 + mat._42); // Bottom
m_plane[5] = D3DXPLANE(mat._14 - mat._12, mat._24 - mat._22, mat._34 - mat._32, mat._44 - mat._42); // Top
for (int i = 0; i < 6; ++i)
D3DXPlaneNormalize(&m_plane[i],&m_plane[i]);
}
bool MAPOUTDOOR_GET_HEIGHT_USE2D = true;
bool MAPOUTDOOR_GET_HEIGHT_TRACE = false;
void CMapOutdoor::__HeightCache_Update()
{
m_kHeightCache.m_isUpdated=true;
}
void CMapOutdoor::__HeightCache_Init()
{
m_kHeightCache.m_isUpdated=false;
for (UINT uIndex=0; uIndex!=SHeightCache::HASH_SIZE; ++uIndex)
m_kHeightCache.m_akVct_kItem[uIndex].clear();
}
float CMapOutdoor::GetHeight(float fx, float fy)
{
float fTerrainHeight = GetTerrainHeight(fx, fy);
if (!m_bEnableTerrainOnlyForHeight)
{
CCullingManager & rkCullingMgr = CCullingManager::Instance();
float CHECK_HEIGHT = 25000.0f;
float fObjectHeight = -CHECK_HEIGHT;
Vector3d aVector3d;
aVector3d.Set(fx, -fy, fTerrainHeight);
FGetObjectHeight kGetObjHeight(fx, fy);
RangeTester<FGetObjectHeight> kRangeTester_kGetObjHeight(&kGetObjHeight);
rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight);
if (kGetObjHeight.m_bHeightFound)
fObjectHeight = kGetObjHeight.m_fReturnHeight;
return fMAX(fObjectHeight, fTerrainHeight);
}
return fTerrainHeight;
}
float CMapOutdoor::GetCacheHeight(float fx, float fy)
{
unsigned int nx=int(fx);
unsigned int ny=int(fy);
DWORD dwKey=0;
#ifdef __HEIGHT_CACHE_TRACE__
static DWORD s_dwTotalCount=0;
static DWORD s_dwHitCount=0;
static DWORD s_dwErrorCount=0;
s_dwTotalCount++;
#endif
std::vector<SHeightCache::SItem>* pkVct_kItem=NULL;
if (m_kHeightCache.m_isUpdated && nx<16*30000 && ny<16*30000)
{
nx>>=4;
ny>>=4;
//short aPos[2]={nx, ny};
dwKey=(ny<<16)|nx;//CalcCRC16Words(2, aPos);
pkVct_kItem=&m_kHeightCache.m_akVct_kItem[dwKey%SHeightCache::HASH_SIZE];
std::vector<SHeightCache::SItem>::iterator i;
for (i=pkVct_kItem->begin(); i!=pkVct_kItem->end(); ++i)
{
SHeightCache::SItem& rkItem=*i;
if (rkItem.m_dwKey==dwKey)
{
#ifdef __HEIGHT_CACHE_TRACE__
s_dwHitCount++;
if (s_dwTotalCount>1000)
{
DWORD dwHitRate=s_dwHitCount*1000/s_dwTotalCount;
static DWORD s_dwMaxHitRate=0;
if (s_dwMaxHitRate<dwHitRate)
{
s_dwMaxHitRate=dwHitRate;
printf("HitRate %f\n", s_dwMaxHitRate*0.1f);
}
}
#endif
return rkItem.m_fHeight;
}
}
}
else
{
#ifdef __HEIGHT_CACHE_TRACE__
s_dwErrorCount++;
//printf("NoCache (%f, %f)\n", fx/100.0f, fy/100.0f);
#endif
}
#ifdef __HEIGHT_CACHE_TRACE__
if (s_dwTotalCount>=1000000)
{
printf("HitRate %f\n", s_dwHitCount*1000/s_dwTotalCount*0.1f);
printf("ErrRate %f\n", s_dwErrorCount*1000/s_dwTotalCount*0.1f);
s_dwHitCount=0;
s_dwTotalCount=0;
s_dwErrorCount=0;
}
#endif
float fTerrainHeight = GetTerrainHeight(fx, fy);
#ifdef SPHERELIB_STRICT
if (MAPOUTDOOR_GET_HEIGHT_TRACE)
printf("Terrain %f\n", fTerrainHeight);
#endif
CCullingManager & rkCullingMgr = CCullingManager::Instance();
float CHECK_HEIGHT = 25000.0f;
float fObjectHeight = -CHECK_HEIGHT;
if (MAPOUTDOOR_GET_HEIGHT_USE2D)
{
Vector3d aVector3d;
aVector3d.Set(fx, -fy, fTerrainHeight);
FGetObjectHeight kGetObjHeight(fx, fy);
RangeTester<FGetObjectHeight> kRangeTester_kGetObjHeight(&kGetObjHeight);
rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight);
if (kGetObjHeight.m_bHeightFound)
fObjectHeight = kGetObjHeight.m_fReturnHeight;
}
else
{
Vector3d aVector3d;
aVector3d.Set(fx, -fy, fTerrainHeight);
Vector3d toTop;
toTop.Set(0,0,CHECK_HEIGHT);
FGetObjectHeight kGetObjHeight(fx, fy);
rkCullingMgr.ForInRay(aVector3d, toTop, &kGetObjHeight);
if (kGetObjHeight.m_bHeightFound)
fObjectHeight = kGetObjHeight.m_fReturnHeight;
}
float fHeight=fMAX(fObjectHeight, fTerrainHeight);
if (pkVct_kItem)
{
if (pkVct_kItem->size()>=200)
{
#ifdef __HEIGHT_CACHE_TRACE__
printf("ClearCacheHeight[%d]\n", dwKey%SHeightCache::HASH_SIZE);
#endif
pkVct_kItem->clear();
}
SHeightCache::SItem kItem;
kItem.m_dwKey=dwKey;
kItem.m_fHeight=fHeight;
pkVct_kItem->push_back(kItem);
}
return fHeight;
}
bool CMapOutdoor::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
{
if (ix <= 0)
ix = 0;
else if (ix >= m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE)
ix = m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE;
if (iy <= 0)
iy = 0;
else if (iy >= m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
iy = m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE;
WORD usCoordX, usCoordY;
usCoordX = (WORD) (ix / (CTerrainImpl::TERRAIN_XSIZE));
usCoordY = (WORD) (iy / (CTerrainImpl::TERRAIN_YSIZE));
if (usCoordX >= m_sTerrainCountX - 1)
usCoordX = m_sTerrainCountX - 1;
if (usCoordY >= m_sTerrainCountY - 1)
usCoordY = m_sTerrainCountY - 1;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum))
return false;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return false;
while (ix >= CTerrainImpl::TERRAIN_XSIZE)
ix -= CTerrainImpl::TERRAIN_XSIZE;
while (iy >= CTerrainImpl::TERRAIN_YSIZE)
iy -= CTerrainImpl::TERRAIN_YSIZE;
return pTerrain->GetNormal(ix, iy, pv3Normal);
}
float CMapOutdoor::GetTerrainHeight(float fx, float fy)
{
if (fy < 0)
fy = -fy;
long lx, ly;
PR_FLOAT_TO_INT(fx, lx);
PR_FLOAT_TO_INT(fy, ly);
WORD usCoordX, usCoordY;
usCoordX = (WORD) (lx / CTerrainImpl::TERRAIN_XSIZE);
usCoordY = (WORD) (ly / CTerrainImpl::TERRAIN_YSIZE);
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum))
return 0.0f;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return 0.0f;
return pTerrain->GetHeight(lx, ly);
}
//////////////////////////////////////////////////////////////////////////
// For Grass
float CMapOutdoor::GetHeight(float * pPos)
{
pPos[2] = GetHeight(pPos[0], pPos[1]);
return pPos[2];
}
bool CMapOutdoor::GetBrushColor(float fX, float fY, float* pLowColor, float* pHighColor)
{
bool bSuccess = false;
// float fU, fV;
//
// GetOneToOneMappingCoordinates(fX, fY, fU, fV);
//
// if (fU >= 0.0f && fU <= 1.0f && fV >= 0.0f && fV <= 1.0f)
// {
// int nImageCol = (m_cBrushMap.GetWidth() - 1) * fU;
// int nImageRow = (m_cBrushMap.GetHeight() - 1) * fV;
//
// // low
// BYTE* pPixel = m_cBrushMap.GetPixel(nImageCol, nImageRow);
// pLowColor[0] = (pPixel[0] / 255.0f);
// pLowColor[1] = (pPixel[1] / 255.0f);
// pLowColor[2] = (pPixel[2] / 255.0f);
// pLowColor[3] = (pPixel[3] / 255.0f);
//
// // high
// pPixel = m_cBrushMap2.GetPixel(nImageCol, nImageRow);
// pHighColor[0] = (pPixel[0] / 255.0f);
// pHighColor[1] = (pPixel[1] / 255.0f);
// pHighColor[2] = (pPixel[2] / 255.0f);
// pHighColor[3] = (pPixel[3] / 255.0f);
//
// bSuccess = true;
// }
pLowColor[0] = (1.0f);
pLowColor[1] = (1.0f);
pLowColor[2] = (1.0f);
pLowColor[3] = (1.0f);
pHighColor[0] = (1.0f);
pHighColor[1] = (1.0f);
pHighColor[2] = (1.0f);
pHighColor[3] = (1.0f);
return bSuccess;
}
// End of for grass
//////////////////////////////////////////////////////////////////////////
BOOL CMapOutdoor::GetAreaPointer(const BYTE c_byAreaNum, CArea ** ppArea)
{
if (c_byAreaNum >= AROUND_AREA_NUM)
{
*ppArea = NULL;
return FALSE;
}
if (NULL == m_pArea[c_byAreaNum])
{
*ppArea = NULL;
return FALSE;
}
*ppArea = m_pArea[c_byAreaNum];
return TRUE;
}
BOOL CMapOutdoor::GetTerrainPointer(const BYTE c_byTerrainNum, CTerrain ** ppTerrain)
{
if (c_byTerrainNum >= AROUND_AREA_NUM)
{
*ppTerrain = NULL;
return FALSE;
}
if (NULL == m_pTerrain[c_byTerrainNum])
{
*ppTerrain = NULL;
return FALSE;
}
*ppTerrain = m_pTerrain[c_byTerrainNum];
return TRUE;
}
void CMapOutdoor::InitializeFog()
{
memset(&m_matAlphaFogTexture, 0, sizeof(D3DXMATRIX));
m_matAlphaFogTexture._31 = -0.001f;
m_matAlphaFogTexture._41 = -7.0f;
m_matAlphaFogTexture._42 = 0.5f;
}
void CMapOutdoor::SaveAlphaFogOperation()
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matAlphaFogTexture);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SetTexture(1, m_AlphaFogImageInstance.GetTexturePointer()->GetD3DTexture());
}
void CMapOutdoor::RestoreAlphaFogOperation()
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
void CMapOutdoor::SetDrawShadow(bool bDrawShadow)
{
m_bDrawShadow = bDrawShadow;
}
void CMapOutdoor::SetDrawCharacterShadow(bool bDrawChrShadow)
{
m_bDrawChrShadow = bDrawChrShadow;
}
DWORD CMapOutdoor::GetShadowMapColor(float fx, float fy)
{
if (fy < 0)
fy = -fy;
float fTerrainSize = (float) (CTerrainImpl::TERRAIN_XSIZE);
float fXRef = fx - (float) (m_lCurCoordStartX);
float fYRef = fy - (float) (m_lCurCoordStartY);
CTerrain * pTerrain;
if (fYRef < -fTerrainSize)
return 0xFFFFFFFF;
else if (fYRef >= -fTerrainSize && fYRef < 0.0f)
{
if (fXRef < -fTerrainSize)
return 0xFFFFFFFF;
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
{
if (GetTerrainPointer(0, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef + fTerrainSize);
else
return 0xFFFFFFFF;
}
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
{
if (GetTerrainPointer(1, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef, fYRef + fTerrainSize);
else
return 0xFFFFFFFF;
}
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
{
if (GetTerrainPointer(2, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef + fTerrainSize);
else
return 0xFFFFFFFF;
}
else
return 0xFFFFFFFF;
}
else if (fYRef >= 0.0f && fYRef < fTerrainSize)
{
if (fXRef < -fTerrainSize)
return 0xFFFFFFFF;
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
{
if (GetTerrainPointer(3, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef);
else
return 0xFFFFFFFF;
}
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
{
if (GetTerrainPointer(4, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef, fYRef);
else
return 0xFFFFFFFF;
}
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
{
if (GetTerrainPointer(5, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef);
else
return 0xFFFFFFFF;
}
else
return 0xFFFFFFFF;
}
else if (fYRef >= fTerrainSize && fYRef < 2.0f * fTerrainSize)
{
if (fXRef < -fTerrainSize)
return 0xFFFFFFFF;
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
{
if (GetTerrainPointer(6, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef - fTerrainSize);
else
return 0xFFFFFFFF;
}
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
{
if (GetTerrainPointer(7, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef, fYRef - fTerrainSize);
else
return 0xFFFFFFFF;
}
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
{
if (GetTerrainPointer(8, &pTerrain))
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef - fTerrainSize);
else
return 0xFFFFFFFF;
}
else
return 0xFFFFFFFF;
}
else
return 0xFFFFFFFF;
return 0xFFFFFFFF;
}
bool CMapOutdoor::isAttrOn(float fX, float fY, BYTE byAttr)
{
int iX, iY;
PR_FLOAT_TO_INT(fX, iX);
PR_FLOAT_TO_INT(fY, iY);
return isAttrOn(iX, iY, byAttr);
}
bool CMapOutdoor::GetAttr(float fX, float fY, BYTE * pbyAttr)
{
int iX, iY;
PR_FLOAT_TO_INT(fX, iX);
PR_FLOAT_TO_INT(fY, iY);
return GetAttr(iX, iY, pbyAttr);
}
bool CMapOutdoor::isAttrOn(int iX, int iY, BYTE byAttr)
{
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
return false;
WORD wTerrainCoordX, wTerrainCoordY;
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
return false;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return false;
WORD wLocalX, wLocalY;
wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE);
wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE);
return pTerrain->isAttrOn(wLocalX, wLocalY, byAttr);
}
bool CMapOutdoor::GetAttr(int iX, int iY, BYTE * pbyAttr)
{
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
return false;
WORD wTerrainCoordX, wTerrainCoordY;
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
return false;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
return false;
WORD wLocalX, wLocalY;
wLocalX = (WORD) (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE);
wLocalY = (WORD) (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE);
BYTE byAttr = pTerrain->GetAttr(wLocalX, wLocalY);
*pbyAttr = byAttr;
return true;
}
// MonsterAreaInfo
CMonsterAreaInfo * CMapOutdoor::AddMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY)
{
CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc();
pMonsterAreaInfo->Clear();
pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY);
pMonsterAreaInfo->SetSize(lSizeX, lSizeY);
m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo);
return pMonsterAreaInfo;
}
void CMapOutdoor::RemoveAllMonsterAreaInfo()
{
m_MonsterAreaInfoPtrVectorIterator = m_MonsterAreaInfoPtrVector.begin();
while (m_MonsterAreaInfoPtrVectorIterator != m_MonsterAreaInfoPtrVector.end())
{
CMonsterAreaInfo * pMonsterAreaInfo = *m_MonsterAreaInfoPtrVectorIterator;
pMonsterAreaInfo->Clear();
++m_MonsterAreaInfoPtrVectorIterator;
}
m_kPool_kMonsterAreaInfo.FreeAll();
m_MonsterAreaInfoPtrVector.clear();
}
bool CMapOutdoor::GetMonsterAreaInfoFromVectorIndex(DWORD dwMonsterAreaInfoVectorIndex, CMonsterAreaInfo ** ppMonsterAreaInfo)
{
if (dwMonsterAreaInfoVectorIndex >= m_MonsterAreaInfoPtrVector.size())
return false;
*ppMonsterAreaInfo = m_MonsterAreaInfoPtrVector[dwMonsterAreaInfoVectorIndex];
return true;
}
//////////////////////////////////////////////////////////////////////////
CMonsterAreaInfo * CMapOutdoor::AddNewMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY,
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType,
DWORD dwVID, DWORD dwCount, CMonsterAreaInfo::EMonsterDir eMonsterDir)
{
CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc();
pMonsterAreaInfo->Clear();
pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY);
pMonsterAreaInfo->SetSize(lSizeX, lSizeY);
pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType);
if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType)
pMonsterAreaInfo->SetMonsterVID(dwVID);
else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType)
pMonsterAreaInfo->SetMonsterGroupID(dwVID);
pMonsterAreaInfo->SetMonsterCount(dwCount);
pMonsterAreaInfo->SetMonsterDirection(eMonsterDir);
m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo);
return pMonsterAreaInfo;
}
//////////////////////////////////////////////////////////////////////////
void CMapOutdoor::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
{
*pdwBaseX = m_dwBaseX;
*pdwBaseY = m_dwBaseY;
}
void CMapOutdoor::SetBaseXY(DWORD dwBaseX, DWORD dwBaseY)
{
m_dwBaseX = dwBaseX;
m_dwBaseY = dwBaseY;
}
void CMapOutdoor::SetEnvironmentDataName(const std::string& strEnvironmentDataName)
{
m_envDataName = strEnvironmentDataName;
}
void CMapOutdoor::__XMasTree_Initialize()
{
m_kXMas.m_pkTree=NULL;
m_kXMas.m_iEffectID=-1;
}
void CMapOutdoor::XMasTree_Destroy()
{
if (m_kXMas.m_pkTree)
{
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
m_kXMas.m_pkTree->Clear();
rkForest.DeleteInstance(m_kXMas.m_pkTree);
m_kXMas.m_pkTree=NULL;
}
if (-1 != m_kXMas.m_iEffectID)
{
CEffectManager& rkEffMgr = CEffectManager::Instance();
rkEffMgr.DestroyEffectInstance(m_kXMas.m_iEffectID);
m_kXMas.m_iEffectID=-1;
}
}
void CMapOutdoor::__XMasTree_Create(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName)
{
assert(NULL==m_kXMas.m_pkTree);
assert(-1==m_kXMas.m_iEffectID);
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
DWORD dwCRC32 = GetCaseCRC32(c_szTreeName, strlen(c_szTreeName));
m_kXMas.m_pkTree=rkForest.CreateInstance(x, y, z, dwCRC32, c_szTreeName);
CEffectManager& rkEffMgr = CEffectManager::Instance();
rkEffMgr.RegisterEffect(c_szEffName);
m_kXMas.m_iEffectID = rkEffMgr.CreateEffect(c_szEffName,
D3DXVECTOR3(x, y, z),
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
}
void CMapOutdoor::XMasTree_Set(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName)
{
XMasTree_Destroy();
__XMasTree_Create(x, y, z, c_szTreeName, c_szEffName);
}
void CMapOutdoor::SpecialEffect_Create(DWORD dwID, float x, float y, float z, const char* c_szEffName)
{
CEffectManager& rkEffMgr = CEffectManager::Instance();
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID);
if (m_kMap_dwID_iEffectID.end() != itor)
{
DWORD dwEffectID = itor->second;
if (rkEffMgr.SelectEffectInstance(dwEffectID))
{
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
mat._41 = x;
mat._42 = y;
mat._43 = z;
rkEffMgr.SetEffectInstanceGlobalMatrix(mat);
return;
}
}
rkEffMgr.RegisterEffect(c_szEffName);
DWORD dwEffectID = rkEffMgr.CreateEffect(c_szEffName,
D3DXVECTOR3(x, y, z),
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
m_kMap_dwID_iEffectID.insert(std::make_pair(dwID, dwEffectID));
}
void CMapOutdoor::SpecialEffect_Delete(DWORD dwID)
{
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID);
if (m_kMap_dwID_iEffectID.end() == itor)
return;
CEffectManager& rkEffMgr = CEffectManager::Instance();
int iEffectID = itor->second;
rkEffMgr.DestroyEffectInstance(iEffectID);
}
void CMapOutdoor::SpecialEffect_Destroy()
{
CEffectManager& rkEffMgr = CEffectManager::Instance();
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.begin();
for (; itor != m_kMap_dwID_iEffectID.end(); ++itor)
{
int iEffectID = itor->second;
rkEffMgr.DestroyEffectInstance(iEffectID);
}
}
void CMapOutdoor::ClearGuildArea()
{
m_rkList_kGuildArea.clear();
}
void CMapOutdoor::RegisterGuildArea(int isx, int isy, int iex, int iey)
{
RECT rect;
rect.left = isx;
rect.top = isy;
rect.right = iex;
rect.bottom = iey;
m_rkList_kGuildArea.push_back(rect);
}
void CMapOutdoor::VisibleMarkedArea()
{
std::map<int, BYTE*> kMap_pbyMarkBuf;
std::set<int> kSet_iProcessedMapIndex;
std::list<RECT>::iterator itorRect = m_rkList_kGuildArea.begin();
for (; itorRect != m_rkList_kGuildArea.end(); ++itorRect)
{
const RECT & rkRect = *itorRect;
int ix1Cell;
int iy1Cell;
BYTE byx1SubCell;
BYTE byy1SubCell;
WORD wx1TerrainNum;
WORD wy1TerrainNum;
int ix2Cell;
int iy2Cell;
BYTE byx2SubCell;
BYTE byy2SubCell;
WORD wx2TerrainNum;
WORD wy2TerrainNum;
ConvertToMapCoords(float(rkRect.left), float(rkRect.top), &ix1Cell, &iy1Cell, &byx1SubCell, &byy1SubCell, &wx1TerrainNum, &wy1TerrainNum);
ConvertToMapCoords(float(rkRect.right), float(rkRect.bottom), &ix2Cell, &iy2Cell, &byx2SubCell, &byy2SubCell, &wx2TerrainNum, &wy2TerrainNum);
ix1Cell = ix1Cell + wx1TerrainNum*CTerrain::ATTRMAP_XSIZE;
iy1Cell = iy1Cell + wy1TerrainNum*CTerrain::ATTRMAP_YSIZE;
ix2Cell = ix2Cell + wx2TerrainNum*CTerrain::ATTRMAP_XSIZE;
iy2Cell = iy2Cell + wy2TerrainNum*CTerrain::ATTRMAP_YSIZE;
for (int ixCell = ix1Cell; ixCell <= ix2Cell; ++ixCell)
for (int iyCell = iy1Cell; iyCell <= iy2Cell; ++iyCell)
{
int ixLocalCell = ixCell % CTerrain::ATTRMAP_XSIZE;
int iyLocalCell = iyCell % CTerrain::ATTRMAP_YSIZE;
int ixTerrain = ixCell / CTerrain::ATTRMAP_XSIZE;
int iyTerrain = iyCell / CTerrain::ATTRMAP_YSIZE;
int iTerrainNum = ixTerrain+iyTerrain*100;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum))
continue;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
continue;
if (kMap_pbyMarkBuf.end() == kMap_pbyMarkBuf.find(iTerrainNum))
{
BYTE * pbyBuf = new BYTE [CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE];
ZeroMemory(pbyBuf, CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE);
kMap_pbyMarkBuf[iTerrainNum] = pbyBuf;
}
BYTE * pbyBuf = kMap_pbyMarkBuf[iTerrainNum];
pbyBuf[ixLocalCell+iyLocalCell*CTerrain::ATTRMAP_XSIZE] = 0xff;
}
}
std::map<int, BYTE*>::iterator itorTerrain = kMap_pbyMarkBuf.begin();
for (; itorTerrain != kMap_pbyMarkBuf.end(); ++itorTerrain)
{
int iTerrainNum = itorTerrain->first;
int ixTerrain = iTerrainNum%100;
int iyTerrain = iTerrainNum/100;
BYTE * pbyBuf = itorTerrain->second;
BYTE byTerrainNum;
if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum))
continue;
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
continue;
pTerrain->AllocateMarkedSplats(pbyBuf);
}
stl_wipe_second(kMap_pbyMarkBuf);
}
void CMapOutdoor::DisableMarkedArea()
{
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
if (!m_pTerrain[i])
continue;
m_pTerrain[i]->DeallocateMarkedSplats();
}
}
void CMapOutdoor::ConvertToMapCoords(float fx, float fy, int *iCellX, int *iCellY, BYTE * pucSubCellX, BYTE * pucSubCellY, WORD * pwTerrainNumX, WORD * pwTerrainNumY)
{
if ( fy < 0 )
fy = -fy;
int ix, iy;
PR_FLOAT_TO_INT(fx, ix);
PR_FLOAT_TO_INT(fy, iy);
*pwTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE);
*pwTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE);
float maxx = (float) CTerrainImpl::TERRAIN_XSIZE;
float maxy = (float) CTerrainImpl::TERRAIN_YSIZE;
while (fx < 0)
fx += maxx;
while (fy < 0)
fy += maxy;
while (fx >= maxx)
fx -= maxx;
while (fy >= maxy)
fy -= maxy;
float fooscale = 1.0f / (float)(CTerrainImpl::HALF_CELLSCALE);
float fCellX, fCellY;
fCellX = fx * fooscale;
fCellY = fy * fooscale;
PR_FLOAT_TO_INT(fCellX, *iCellX);
PR_FLOAT_TO_INT(fCellY, *iCellY);
float fRatioooscale = ((float)CTerrainImpl::HEIGHT_TILE_XRATIO) * fooscale;
float fSubcellX, fSubcellY;
fSubcellX = fx * fRatioooscale;
fSubcellY = fy * fRatioooscale;
PR_FLOAT_TO_INT(fSubcellX, *pucSubCellX);
PR_FLOAT_TO_INT(fSubcellY, *pucSubCellY);
*pucSubCellX = (*pucSubCellX) % CTerrainImpl::HEIGHT_TILE_XRATIO;
*pucSubCellY = (*pucSubCellY) % CTerrainImpl::HEIGHT_TILE_YRATIO;
}