485 lines
13 KiB
C++
485 lines
13 KiB
C++
#include "stdafx.h"
|
||
// 2010.05.25 - prodongi
|
||
#include <windows.h>
|
||
//#include "Util.h"
|
||
#include "KSeqAvatarEx.h"
|
||
#include "SDefaultTextureResourceDB.h"
|
||
#include "SItemDB.h"
|
||
#include "KRenderObjectMesh.h"
|
||
// 2010.08.16 - prodongi
|
||
#include "SkillBaseFile.h"
|
||
#include <toolkit/nsl.h>
|
||
#include <toolkit/nsluni.h>
|
||
#include <kfile/KFileNameCipher.h>
|
||
#include <kfile/KFileManager.h>
|
||
|
||
#include "SGameAvatarEx.h"
|
||
#include "CommonUtil.h"
|
||
#include "SGameWorld.h"
|
||
#include "SGameSystem.h"
|
||
#include "TerrainSeamlessWorldInfo.h"
|
||
|
||
extern SGameSystem* g_pCurrentGameSystem;
|
||
|
||
// 2010.05.25 – A function that keeps the color value of the default hair when changing from the default hair to a new hair. – prodongi
|
||
void setMaintainHairColorNewToOld(int hairId, int hairColorIndex, int race, int sex, KSeqAvatarEx* seqAvatarEx)
|
||
{
|
||
if( hairId >= 701 && hairId <= 705 )
|
||
{
|
||
int nGroup = 1;
|
||
std::string texName = GetDefaultTextureResourceDB().GetTextureName( nGroup, hairColorIndex, race, sex);
|
||
|
||
int itemId = 0;
|
||
if (hairColorIndex == 1)
|
||
{
|
||
if (std::string::npos != texName.find("dem")) itemId = 960063;
|
||
else if (std::string::npos != texName.find("def")) itemId = 960063;
|
||
else if (std::string::npos != texName.find("asm")) itemId = 960065;
|
||
else if (std::string::npos != texName.find("asf")) itemId = 960065;
|
||
else if (std::string::npos != texName.find("gam")) itemId = 960067;
|
||
else if (std::string::npos != texName.find("gaf")) itemId = 960067;
|
||
}
|
||
else
|
||
{
|
||
if (std::string::npos != texName.find("dem")) itemId = 960064;
|
||
else if (std::string::npos != texName.find("def")) itemId = 960064;
|
||
else if (std::string::npos != texName.find("asm")) itemId = 960066;
|
||
else if (std::string::npos != texName.find("asf")) itemId = 960066;
|
||
else if (std::string::npos != texName.find("gam")) itemId = 960068;
|
||
else if (std::string::npos != texName.find("gaf")) itemId = 960068;
|
||
}
|
||
|
||
if (itemId == 0) return;
|
||
|
||
const ItemBaseEx_info* pItemInfo = GetItemDB().GetItemData(itemId);
|
||
if (!pItemInfo) return;
|
||
|
||
DWORD color = pItemInfo->dOptVar2[0];
|
||
color |= 0xff000000;
|
||
_CID( SET_COLORIZE );
|
||
KMsgSET_COLORIZE msg;
|
||
msg.color[0] = 0;
|
||
msg.color[1] = color; // Use only the second one
|
||
msg.color[2] = 0;
|
||
msg.color[3] = 0;
|
||
|
||
msg.nMode = K3DTexture::COLORIZED_GRAY;
|
||
seqAvatarEx->Perform( ANIPART_BIPED, MPART_HAIR, id_SET_COLORIZE, msg );
|
||
}
|
||
}
|
||
|
||
// 2010.08.16 - prodongi
|
||
int getHelmItemModelType(int race, int sex, ItemBaseEx_info const* itemInfo)
|
||
{
|
||
int flag = 0;
|
||
if( race == GCLAN_GAIA )
|
||
{
|
||
if( sex == SEX_MALE ) flag = itemInfo->model_type_gam;
|
||
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_gaf;
|
||
}
|
||
else if( race == GCLAN_DEVA )
|
||
{
|
||
if( sex == SEX_MALE ) flag = itemInfo->model_type_dem;
|
||
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_def;
|
||
}
|
||
else if(race == GCLAN_ASURA )
|
||
{
|
||
if( sex == SEX_MALE ) flag = itemInfo->model_type_asm;
|
||
else if( sex == SEX_FEMALE ) flag = itemInfo->model_type_asf;
|
||
}
|
||
return flag;
|
||
}
|
||
|
||
|
||
//#include "KUIControl.h" // bintitle. 2010.08.31.
|
||
#include "KUIControlScroll.h" // ''
|
||
#include <toolkit/XStringUtil.h>
|
||
|
||
// 최종수정 bintitle. 2010.09.29.
|
||
//
|
||
// *** 텍스트 목록 설정 ***
|
||
//
|
||
// 주어진 텍스트를 컨트롤의 너비에 맞게 잘라내어 리스트형태로 설정한다. // 도움말 윈도우등 문자를 리스트로 출력해야하는 부분들이 많아 추가하였습니다. bintitle. 2010.08.31.
|
||
//
|
||
// Argument -
|
||
// strText : 목록으로 설정할 텍스트.
|
||
// pCtrlText : 해당 컨트롤의 너비에 맞게 리스트를 만들고 리스트를 지정할 컨트롤.
|
||
// pScrollBase : 스크롤바.
|
||
// crrScrollPos : 현재 스크롤값.
|
||
// vLineList : 텍스트의 행을 보관할 배열.
|
||
// bNewText : arrList 를 새로 생성할지 여부.
|
||
//
|
||
void SetTextList( int nMaxListSize, std::string & strText, std::string & strDecoretion, char * pStrFontName, KUIControl * pCtrlText,
|
||
KUIControlScrollBase * pScrollBase, int & crrScrollPos, std::vector< std::string > & vLineList, bool bNewText )
|
||
{
|
||
std::string strNewStory("");
|
||
|
||
#ifdef _COUNTRY_ME_
|
||
if( bNewText )
|
||
pCtrlText->SplitLine( vLineList, strText, "Default", pCtrlText->GetFontSize(), false, true );
|
||
|
||
XStringUtil::Replace( strDecoretion, "<left>", "<right>" );
|
||
std::string::size_type fpos = strDecoretion.find( "<font:" );
|
||
if( fpos != std::string::npos )
|
||
{
|
||
std::string::size_type Epos = strDecoretion.find_first_of( ">" );
|
||
if( Epos != std::string::npos && Epos > fpos )
|
||
{
|
||
++Epos;
|
||
strDecoretion.replace( fpos, Epos - fpos, "<font:Default>" );
|
||
}
|
||
}
|
||
|
||
//strNewStory += "<font:Default><RIGHT>";
|
||
strNewStory += strDecoretion;
|
||
|
||
#else
|
||
if( bNewText )
|
||
/*pCtrlText->SplitLine( vLineList, strText,
|
||
pStrFontName ? pStrFontName : "Default",
|
||
pCtrlText->GetFontSize(), false, pCtrlText->GetFontSize() == KTextRender::KDEFAULT_FONT_SIZE ? false : true, true ); */
|
||
pCtrlText->SplitLine( vLineList, ( strDecoretion + strText ),
|
||
pStrFontName ? pStrFontName : "Default",
|
||
pCtrlText->GetFontSize(), false, true );
|
||
#endif
|
||
|
||
//strNewStory += strDecoretion;
|
||
|
||
int size = vLineList.size();
|
||
for( int i = 0; i < size; ++i )
|
||
{
|
||
if( i >= nMaxListSize || size <= crrScrollPos + i )
|
||
break;
|
||
|
||
// 각 행별로 꾸미기태그 적용.
|
||
strNewStory += strDecoretion + vLineList[ crrScrollPos + i ];
|
||
strNewStory += "<BR>";
|
||
}
|
||
|
||
// 스크롤바의 현재위치 조정추가. bintitle. 2010.10.29.
|
||
if( size < nMaxListSize || bNewText )
|
||
{
|
||
crrScrollPos = 0;
|
||
pScrollBase->SetPosition( crrScrollPos );
|
||
}
|
||
|
||
|
||
// 스크롤바 Thumb 조절.
|
||
pScrollBase->SetScrollRange( nMaxListSize, size );
|
||
|
||
|
||
// 텍스트 적용.
|
||
std::string fontName = CStringUtil::StringFormat("<font:%s>",pStrFontName); // 폰트 이름이 아예제거되서 기본폰트만 사용되서 추가..
|
||
strNewStory = fontName + strNewStory;
|
||
pCtrlText->SetCaption( strNewStory.c_str() );
|
||
}
|
||
|
||
|
||
/// 2010.10.27 - prodongi
|
||
std::string extractTokenValue(std::string const& str, std::string const& token)
|
||
{
|
||
std::string value;
|
||
std::string _token = "<" + token + ":";
|
||
std::string::size_type nPos = str.find(_token);
|
||
|
||
if( nPos != std::string::npos )
|
||
{
|
||
nPos += _token.length();
|
||
std::string strTemp( str.begin() + nPos, str.begin() + str.size() );
|
||
std::string::size_type nPos_End = strTemp.find_first_of( ">" );
|
||
strTemp = strTemp.substr( 0, nPos_End );
|
||
|
||
value = str.substr( nPos, strTemp.size());
|
||
}
|
||
return value;
|
||
}
|
||
|
||
|
||
/// 2010.11.04 - prodongi
|
||
void extractTokenAndText(std::string const& str, std::string& token, std::string& text)
|
||
{
|
||
std::string _str = str;
|
||
std::string::size_type posS, posE;
|
||
|
||
bool is = true;
|
||
while (is)
|
||
{
|
||
posS = _str.find_first_of("<");
|
||
|
||
if (posS == std::string::npos)
|
||
{
|
||
if (!_str.empty())
|
||
{
|
||
text += _str;
|
||
}
|
||
break;
|
||
}
|
||
else if (0 != posS)
|
||
{
|
||
text += _str.substr(0, posS);
|
||
_str = _str.substr(posS, _str.size());
|
||
}
|
||
else
|
||
{
|
||
posE = _str.find_first_of(">");
|
||
if (posE != std::string::npos)
|
||
{
|
||
token += _str.substr(posS, posE+1);
|
||
_str = _str.substr(posE+1, _str.size());
|
||
}
|
||
else
|
||
{
|
||
/// 잘 못된 스트링
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/// 2011.11.23 구분자가 L"|" 같은 경우에 대만 처럼 會같은 특별한 문자가 들어갈 경우에 wchar 변환 호환성으로 높이기 위해서 MultiByteToWideChar를 사용 - prodongi
|
||
void safeM2W(char const* szMsg, wchar_t const* delimiter, std::wstring& wstr)
|
||
{
|
||
if (0 == wcscmp(delimiter, L"|"))
|
||
{
|
||
static wchar_t wbuff[2049];
|
||
size_t _wbuffSize = 2048;
|
||
wchar_t* _wbuff = NULL;
|
||
|
||
bool _memAlloc = false;
|
||
size_t msgSize = strlen(szMsg);
|
||
if (msgSize > _wbuffSize)
|
||
{
|
||
_memAlloc = true;
|
||
_wbuffSize = msgSize;
|
||
_wbuff = new wchar_t[msgSize+1];
|
||
}
|
||
else
|
||
{
|
||
_wbuff = wbuff;
|
||
}
|
||
|
||
memset(_wbuff, 0, sizeof (wchar_t) * (_wbuffSize+1));
|
||
int codePage = KTextRender::GetDefaultCodePage();
|
||
::MultiByteToWideChar(codePage, 0, szMsg, strlen(szMsg), _wbuff, _wbuffSize);
|
||
wstr = _wbuff;
|
||
size_t a = wcslen(_wbuff);
|
||
|
||
if (_memAlloc)
|
||
{
|
||
SAFE_DELETE_ARRAY(_wbuff);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정
|
||
//2009-06-24: hunee
|
||
wstr = nsl::uni::conv(szMsg);
|
||
}
|
||
}
|
||
|
||
/// 2011.11.29 safeM2W를 사용해서 유니코드로 변환뒤에 해당 문자를 찾는다 - prodongi
|
||
bool safeFindString(char const* str, wchar_t const* delimiter)
|
||
{
|
||
std::wstring wstr;
|
||
safeM2W(str, delimiter, wstr);
|
||
std::wstring::size_type pos = wstr.find(delimiter);
|
||
return pos != std::string::npos;
|
||
}
|
||
|
||
/// 2011.11.29 - prodongi
|
||
void safeReplaceString(std::string& str, wchar_t const* from, wchar_t const* to)
|
||
{
|
||
std::wstring wstr;
|
||
safeM2W(str.c_str(), from, wstr);
|
||
|
||
std::wstring::size_type pos;
|
||
while( ( pos = wstr.find(from) ) != std::wstring::npos )
|
||
{
|
||
wstr.replace( pos, 1, to );
|
||
}
|
||
str = nsl::uni::conv(wstr);
|
||
}
|
||
|
||
void decodeDir(char const* curDir)
|
||
{
|
||
WIN32_FIND_DATA FileData;
|
||
HANDLE hSearch;
|
||
unsigned cnt = 0;
|
||
|
||
hSearch = FindFirstFile( (std::string( curDir ) + "*" ).c_str() , &FileData);
|
||
if (hSearch == INVALID_HANDLE_VALUE)
|
||
{
|
||
return ;
|
||
}
|
||
|
||
std::string decodeFileName;
|
||
std::string strFullPath;
|
||
while ( true )
|
||
{
|
||
if( strcmp( FileData.cFileName, "." ) && strcmp( FileData.cFileName, ".." ) )
|
||
{
|
||
decodeFileName = (FileData.cFileName);
|
||
KFileNameCipher::DecodeFileName(decodeFileName);
|
||
KStream* s = KFileManager::Instance().CreateStreamFromResource(decodeFileName.c_str());
|
||
if (s)
|
||
{
|
||
std::string reDir(curDir);
|
||
reDir += decodeFileName.c_str();
|
||
FILE* f = fopen(reDir.c_str(), "wb");
|
||
fwrite(s->GetMappedPtr(0), s->GetLength(), 1, f);
|
||
fclose(f);
|
||
}
|
||
}
|
||
|
||
if (!FindNextFile(hSearch, &FileData))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
FindClose(hSearch);
|
||
}
|
||
|
||
char* getIovationBlackBox()
|
||
{
|
||
typedef HRESULT (*RegProto)();
|
||
|
||
typedef int (*ioVerFn)( char ** );
|
||
typedef int (*ioBeginFn)( char ** );
|
||
typedef void (*ioFreeFn)( char **);
|
||
|
||
HMODULE hDLL = LoadLibrary( "StmOCX.dll" );
|
||
ioFreeFn freeFn;
|
||
ioBeginFn beginFn;
|
||
ioVerFn verFn;
|
||
|
||
char* bbData = NULL;
|
||
|
||
if ( hDLL == NULL )
|
||
{
|
||
_oprint("Faile iovation library load \n");
|
||
return NULL;
|
||
}
|
||
|
||
try {
|
||
|
||
freeFn = (ioFreeFn) GetProcAddress( hDLL, "io_FreeData" );
|
||
beginFn = (ioBeginFn) GetProcAddress( hDLL, "io_Begin" );
|
||
verFn = (ioVerFn) GetProcAddress( hDLL, "io_Version" );
|
||
|
||
#ifdef _DEV
|
||
// This is only for debugging purposes and is not needed
|
||
if ( verFn )
|
||
{
|
||
char *ver = NULL;
|
||
|
||
if ( verFn( &ver ) == 0 )
|
||
{
|
||
_oprint("iovation version: %d\n", ver);
|
||
if ( freeFn )
|
||
freeFn( &ver );
|
||
|
||
}
|
||
else
|
||
{
|
||
_oprint("failed get ioVersion version\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_oprint("Failed get address iovation io_vation function\n");
|
||
}
|
||
#endif
|
||
|
||
// this is the beginning of the call to get a blackbox
|
||
if ( beginFn )
|
||
{
|
||
char *bb = NULL;
|
||
int result = beginFn( &bb );
|
||
|
||
if ( result == 0 )
|
||
{
|
||
size_t dataSize = strlen(bb);
|
||
if (0 < dataSize)
|
||
{
|
||
bbData = new char[dataSize+1];
|
||
memcpy(bbData, bb, dataSize);
|
||
bbData[dataSize] = 0x00;
|
||
}
|
||
else
|
||
{
|
||
_oprint("invalid iovation black box data size\n");
|
||
}
|
||
#ifdef _DEV
|
||
_oprint(" iovation Blackbox: %s\n", bb);
|
||
#endif
|
||
|
||
if ( freeFn )
|
||
freeFn( &bb );
|
||
else
|
||
_oprint("iovation ioBegin failed\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_oprint("iovation Unable to locate io_Begin\n");
|
||
}
|
||
|
||
}
|
||
catch ( ... )
|
||
{
|
||
_oprint("iovation Caught exception\n");
|
||
}
|
||
|
||
FreeLibrary( hDLL );
|
||
return bbData;
|
||
}
|
||
|
||
|
||
bool getCurrentMapPostionXY(float x, float y, POINT& outPos)
|
||
{
|
||
if( g_pCurrentGameSystem == NULL )
|
||
return false;
|
||
|
||
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
|
||
if( pGameWorld == NULL )
|
||
return false;
|
||
|
||
const CTerrainSeamlessWorldInfo* pSeamlessWorldInfo = pGameWorld->GetSeamlessWorldInfo();
|
||
if( pSeamlessWorldInfo == NULL )
|
||
return false;
|
||
|
||
float fMapLen = float( pSeamlessWorldInfo->GetTileCountPerSegment() ) * float(pSeamlessWorldInfo->GetSegmentCountPerMap() ) * pSeamlessWorldInfo->GetTileLength();
|
||
outPos.x = (int)(x / fMapLen);
|
||
outPos.y = (int)(y / fMapLen);
|
||
// nWorldID = m_pSeamlessWorldInfo->GetWorldID( nMapX, nMapY );
|
||
return true;
|
||
}
|
||
|
||
bool IsRamadanPrayRoom()
|
||
{
|
||
if( g_pCurrentGameSystem == NULL )
|
||
return false;
|
||
|
||
SGameAvatarEx* pMyCharacter = g_pCurrentGameSystem->GetLocalPlayer();
|
||
if( pMyCharacter == NULL )
|
||
return false;
|
||
|
||
K3DVector vPos = pMyCharacter->GetCurPosWithChangeDir();
|
||
|
||
SGameWorld* pGameWorld = dynamicCast<SGameWorld*>(g_pCurrentGameSystem->GetGame());
|
||
if( pGameWorld == NULL )
|
||
return false;
|
||
|
||
const CTerrainSeamlessWorldInfo* pSeamlessWorldInfo = pGameWorld->GetSeamlessWorldInfo();
|
||
if( pSeamlessWorldInfo == NULL )
|
||
return false;
|
||
|
||
float fMapLen = float( pSeamlessWorldInfo->GetTileCountPerSegment() ) * float(pSeamlessWorldInfo->GetSegmentCountPerMap() ) * pSeamlessWorldInfo->GetTileLength();
|
||
int nx = (int)(vPos.x / fMapLen);
|
||
int ny = (int)(vPos.y / fMapLen);
|
||
if( nx == RAMADAN_PRAY_ROOM_X && ny == RAMADAN_PRAY_ROOM_Y )
|
||
return true;
|
||
|
||
return false;
|
||
} |