/* SGameFxSwordSlash.cpp 검광 표시 Fx Created 2006/04, by JiYoung */ #include "stdafx.h" #include "SGameFxSwordSlash.h" #include "KResourceDXDynamic.h" #include "KViewPort.h" #include "KSeqModel.h" #include "SGameAvatarEx.h" #include #include #include #include "SDebug_Util.h" #include "SGameWorld.h" #include "SGameSystem.h" //==================================================== // Utilities //==================================================== extern SGameSystem* g_pCurrentGameSystem; namespace { DWORD interpolateColor(DWORD colorA, DWORD colorB, float div) // A에서 B까지 [0, 1] 보간 // return = colorA*(1-div) + colorB*div { float a0,r0,g0,b0; float a1,r1,g1,b1; float invdiv=1.f-div; a0=(float)((colorA>>24)&0xff); r0=(float)((colorA>>16)&0xff); g0=(float)((colorA>>8)&0xff); b0=(float)(colorA&0xff); a1=(float)((colorB>>24)&0xff); r1=(float)((colorB>>16)&0xff); g1=(float)((colorB>>8)&0xff); b1=(float)(colorB&0xff); DWORD a, r, g, b; a = (DWORD)(a0*invdiv + a1*div); r = (DWORD)(r0*invdiv + r1*div); g = (DWORD)(g0*invdiv + g1*div); b = (DWORD)(b0*invdiv + b1*div); if (a>0xff) a=0xff; if (r>0xff) r=0xff; if (g>0xff) g=0xff; if (b>0xff) b=0xff; return (a<<24) | (r<<16) | (g<<8) | b; } } //============================================= // Trail rendering용 primitive //============================================= const int TrailPrimitive_defaultTrailWidth=10.0f; TrailPrimitive::TrailPrimitive(int maxTrails) : KMeshPrimitive() { indexBuffer=NULL; vertexBuffer=NULL; vertexCount=indexCount=polygonCount=0; maxTrailCount=0; trailWidth=TrailPrimitive_defaultTrailWidth; // 적당한 색 & UV color0[NODE_NEWEST_BOTTOM]=0x40ffffff; color1[NODE_NEWEST_BOTTOM]=0x00404040; u[NODE_NEWEST_BOTTOM]=0.0f; v[NODE_NEWEST_BOTTOM]=0.0f; color0[NODE_NEWEST_TOP]=0xc0ffffff; color1[NODE_NEWEST_TOP]=0x00808080; u[NODE_NEWEST_TOP]=0.0f; v[NODE_NEWEST_TOP]=1.0f; color0[NODE_OLDEST_BOTTOM]=0x00c0c0c0; color1[NODE_OLDEST_BOTTOM]=0x00404040; u[NODE_OLDEST_BOTTOM]=1.0f; v[NODE_OLDEST_BOTTOM]=0.0f; color0[NODE_OLDEST_TOP]=0x00808080; color1[NODE_OLDEST_TOP]=0x00808080; u[NODE_OLDEST_TOP]=1.0f; v[NODE_OLDEST_TOP]=1.0f; if (maxTrails>0) init(maxTrails); rebuildPolygon=true; m_bRight = true; trailRunning = false; } TrailPrimitive::~TrailPrimitive() { close(); } void TrailPrimitive::init(int maxTrails) { assert( (indexBuffer==NULL) && (vertexBuffer==NULL) ); if (maxTrails<=0) return; // Get sizes vertexCount=maxTrails*2; // each node has 2 vertexes polygonCount=(maxTrails-1)*4; // Triangle strip : each vertex pair makes 2 triangles, and 2 sides indexCount=3*polygonCount; // Triangle strip.. but render as triangle set maxTrailCount=maxTrails; if (trailCount>maxTrailCount) trailCount=maxTrailCount; // Make index buffer and vertex buffer. if (!createBuffers()) return; // WORKAROUND : to prevent 'smartptr burst' on deleting m_spIB / m_spVB. indexBuffer->AddRef(); vertexBuffer->AddRef(); // init trail nodes setTrailNodeCount(maxTrailCount); // Notify polygon informations to parent SetIndexBuffer(indexBuffer); // set m_spIB SetVertexBuffer(vertexBuffer); // set m_spVB SetPrimitivesCount(polygonCount); // Init parent parameters K3DMaterial *tempMaterial=new K3DMaterial; tempMaterial->Power=1.0f; SetMaterial(tempMaterial); K3DMatrix *tempMatrix=new K3DMatrix; K3DMatrixIdentity(*tempMatrix); SetUVTransform(tempMatrix); // m_pTransform=new K3DMatrix; // K3DMatrixIdentity(m_pTransform); // Set basic rendering parameters SetTransparent(true); // Add to Transparent primitive queue SetBlendMode(K3DMaterial::MBM_ALPHATEX); // Set render mode SetVisibility(1.0f); // Master alpha value rebuildPolygon=true; } void TrailPrimitive::close() { // clear buffers SetIndexBuffer(NULL); SetVertexBuffer(NULL); SetPrimitivesCount(0); if (indexBuffer!=NULL) { // SAFE_RELEASE(indexBuffer); indexBuffer->Release(); // Release() will delete SELF indexBuffer=NULL; } if (vertexBuffer!=NULL) { vertexBuffer->Release(); vertexBuffer=NULL; } vertexCount=indexCount=polygonCount=0; maxTrailCount=0; trailWidth=TrailPrimitive_defaultTrailWidth; K3DMatrix *tempMatrix=GetUVTransform(); SetUVTransform(NULL); SAFE_DELETE(tempMatrix); K3DMaterial *tempMaterial=GetMaterial(); SetMaterial(NULL); SAFE_DELETE(tempMaterial); // SAFE_DELETE(m_pTransform); trails.clear(); // // Note : Colors and UVs are not cleared // rebuildPolygon=true; } bool TrailPrimitive::buildPolygon() // 실제 버텍스 정보 만들기 { if (trails.size()<2) { vertexBuffer->setVertexCount(0); indexBuffer->setIndexCount(0); SetPrimitivesCount(0); return false; } void *p; int size=0; DynamicVertex *v; // Make vertex buffers deque::iterator it; size_t i; vertexBuffer->Lock(&p, size,D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); if (p!=NULL) { // Build vertex parameters <- 임시! 나중에 parameterize시킬 것 v=(DynamicVertex *)p; it=trails.begin(); for (i=0; ipos.x = it->base.x; v->pos.y = it->base.y; v->pos.z = it->base.z; v++; // top vertex v->pos.x = it->top.x; v->pos.y = it->top.y; v->pos.z = it->top.z; v++; it++; } vertexBuffer->Unlock(); } // Set geometry counts size=trailCount; if (size > (int)trails.size()) size=(int)trails.size(); vertexBuffer->setVertexCount(size*2); // 2 vertexes per a node indexBuffer->setIndexCount((size-1)*3*4); // 3-vertexes and 4-polygons per segment SetPrimitivesCount((size-1)*4); // 4 polygons per each segment return true; } void TrailPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum ) { if (rebuildPolygon) { // color, UV등이 바뀌면 파라미터를 다시 만든다 initPolygon(); rebuildPolygon=false; } if (buildPolygon()) { // Set rendering parameters //SetTransparent(true); // Add to Transparent primitive queue //SetBlendMode(K3DMaterial::MBM_ALPHATEX); // Set render mode SetVisibility(1.0f); // Master alpha value KMeshPrimitive::Render(viewport, dev, bUseAccum); } } void TrailPrimitive::runTrail(bool bOn) { if (bOn==true && trailRunning==false) { // Clear possible previous trails clearTrails(); } trailRunning=bOn; } void TrailPrimitive::addTrails(int count, DWORD starttime, DWORD endtime, K3DMatrix *matrix, bool isBow, float angle) { if (!trailRunning || matrix==NULL) { purgeTrails(count); return; } int i; TrailNode tn; K3DVector vBottom, vTop; vBottom.x=vBottom.y=vBottom.z=0.f; if( m_bRight ) //오른손 vTop.x=-trailWidth; else //왼손 vTop.x=+trailWidth; vTop.y=vTop.z=0.f; if ( isBow ) { SGameWorld* pGameWorld = dynamicCast(g_pCurrentGameSystem->GetGame()); float angle1 = pGameWorld->m_pGameCamera->getAngleX(); //float angle2;//atan2f(matrix->m31-vBottom.y, matrix->m30-vBottom.x ); float camera_z = pGameWorld->m_pGameCamera->getAngleZ() - sMathUtil::degree90; if (camera_z>K3D_PI) camera_z = camera_z -K3D_PI*2; float a1, a2; a1 = fmod(camera_z, K3D_PI*2); a2 = fmod(angle, K3D_PI*2); if (fabs(a1 - a2) > fabs(a1 - a2 - K3D_PI*2)) a2 += K3D_PI*2; else if(fabs(a1 - a2) > fabs(a1 - a2 + K3D_PI*2)) a2 -= K3D_PI*2; float minval = min(fabs(a1 - a2), min(fabs(a1 - a2 + K3D_PI*2), fabs(a1 - a2 - K3D_PI*2))); // 0~3.14 if (minval> K3D_PI/2 ) minval = K3D_PI-minval; // 0~1.57 minval = K3D_PI/2 - minval; // 1.57 ~ 0 //if (camera_z > char_z) angle2 = camera_z - char_z; //else angle2 = char_z - camera_z; //if (angle2>K3D_PI/2) angle2 = K3D_PI -angle2; //if (angle2<-(K3D_PI/2)) angle2 = angle2 + K3D_PI; float delta = max( angle1,minval); K3DMatrix matro; K3DMatrixRotationZ ( matro,delta ); K3DVectorTransform(vTop, vTop, matro); // K3DMatrixRotationZ ( *matrix, 1.57f ); // vTop.x = trailWidth * cos(pGameWorld->m_pGameCamera->getAngleX()); // vBottom.x = trailWidth * sin(pGameWorld->m_pGameCamera->getAngleX()); } for (i=0; i trailCount) trails.pop_front(); } } void TrailPrimitive::purgeTrails(int count) { while ( (trails.size()>0) && (count>0)) { trails.pop_front(); count--; } } void TrailPrimitive::clearTrails() { trails.clear(); } bool TrailPrimitive::createBuffers() // called in init(); to create proper indexBuffer / vertexBuffer / triangleCount { try { vertexBuffer=new KVertexBufferDX_dynamic(); if (vertexBuffer!=NULL) { // (UINT length, DWORD usage, DWORD FVF, D3DPOOL pool) if (!vertexBuffer->create(sizeof(DynamicVertex) * vertexCount, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, DynamicVertex::FVF, D3DPOOL_DEFAULT)) { throw 0; } } vertexBuffer->setVertexCount(vertexCount); indexBuffer=new KIndexBufferDX_dynamic(); if (indexBuffer!=NULL) { if (!indexBuffer->create(indexCount * sizeof(DWORD), D3DUSAGE_DYNAMIC, D3DFMT_INDEX32, D3DPOOL_DEFAULT)) { // index buffer createion failed throw 0; } } indexBuffer->setIndexCount(indexCount); rebuildPolygon=true; void *p; int size=0; indexBuffer->Lock(&p, size); if (p!=NULL) { DWORD *pu=(DWORD *)p; int i, n; n=0; for (i=0; iUnlock(); } } catch (int) { close(); return false; } return true; } void TrailPrimitive::setTrailNodeCount(int count) // Display되는 trail의 node갯수 (segment갯수+1) { assert(count>=2 && count<=maxTrailCount); trailCount=count; // Set dirty flag rebuildPolygon=true; } void TrailPrimitive::setTrailNodeColor(int nodeNumber // node번호. NODE_START_xxxx 나 NODE_END_xxxx , DWORD _color0, DWORD _color1 // 화면표시색 = (텍스처 * color0) + color1 , float _u, float _v // 텍스처 좌표 ) { assert(nodeNumber>=0 && nodeNumber=0 && nodeNumberIsExistTexture( texName, &loadpack ) ) { KTextureManager::GetManager()->RefreshTexture( texName, &loadpack ); texpack.spTexture = KTextureManager::GetManager() ->GetTexture( texName, &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); } } this->SetTexture(&texpack); } void TrailPrimitive::setTrailTexture(K3DTexture *texture) { TEXPACK texpack; texpack.spTexture=texture; this->SetTexture(&texpack); } void TrailPrimitive::initPolygon() { if (vertexBuffer==NULL || indexBuffer==NULL) return; // // Set vertex colors and UVs // void *p; int size=0; DynamicVertex *vtx; int i; float f, fi; //D3DLOCK_DISCARD 옵션은 비스타에서 문제 발생으로 제거됨 vertexBuffer->Lock(&p, size, D3DLOCK_NOSYSLOCK /*| D3DLOCK_DISCARD*/); if (p!=NULL) { // Build vertex parameters vtx=(DynamicVertex *)p; for (i=0; iclear(); vtx->color0 = interpolateColor(color0[NODE_OLDEST_BOTTOM], color0[NODE_NEWEST_BOTTOM], f); vtx->color1 = interpolateColor(color1[NODE_OLDEST_BOTTOM], color1[NODE_NEWEST_BOTTOM], f); vtx->u0 = u[NODE_OLDEST_BOTTOM]*fi + u[NODE_NEWEST_BOTTOM]*f; vtx->v0 = v[NODE_OLDEST_BOTTOM]*fi + v[NODE_NEWEST_BOTTOM]*f; vtx++; // top vertex vtx->clear(); vtx->color0 = interpolateColor(color0[NODE_OLDEST_TOP], color0[NODE_NEWEST_TOP], f); vtx->color1 = interpolateColor(color1[NODE_OLDEST_TOP], color1[NODE_NEWEST_TOP], f); vtx->u0 = u[NODE_OLDEST_TOP]*fi + u[NODE_NEWEST_TOP]*f; vtx->v0 = v[NODE_OLDEST_TOP]*fi + v[NODE_NEWEST_TOP]*f; vtx++; } vertexBuffer->Unlock(); } indexBuffer->setIndexCount((trailCount-1)*3*4); } //======================================================== // SGameFxSwordSlash main code //======================================================== const int SWORDSLASH_TRAILSEGMENTSIZE=1024; // buffer의 max크기 <- 디버깅용. 나중에 줄일 것 const int SWORDSLASH_DEFAULTSEGMENTSIZE=16; SGameFxSwordSlash::SGameFxSwordSlash( bool bRight ) : KSeqModel() // KSeqForm() { m_bRight = bRight; primitive=new TrailPrimitive(); primitive->init(SWORDSLASH_TRAILSEGMENTSIZE); // max length primitive->setTrailNodeCount(SWORDSLASH_DEFAULTSEGMENTSIZE); // current length primitive->SetUseRight( m_bRight ); K3DMatrixIdentity(m_matResult); K3DMatrixIdentity(m_matWorld); } SGameFxSwordSlash::~SGameFxSwordSlash() { delete primitive; } // // Inherits // void SGameFxSwordSlash::Render( KViewportObject *viewport, DWORD flag , const K3DMatrix * pAttachMat ) { if (primitive==NULL) return; primitive->SetTransform(&m_matResult, &m_matWorld); viewport->Register( primitive , 0 // default rendering mode ); } // // Original // void SGameFxSwordSlash::addTrails(int count, DWORD starttime, DWORD endtime, K3DMatrix *matrix, bool isBow, float angle) { if (primitive==NULL) return; primitive->addTrails(count, starttime, endtime, matrix, isBow, angle); } void SGameFxSwordSlash::purgeTrails(int count) { if (primitive==NULL) return; primitive->purgeTrails(count); } void SGameFxSwordSlash::clearTrails() { if (primitive==NULL) return; primitive->clearTrails(); } void SGameFxSwordSlash::runTrail(bool bOn) { if (primitive==NULL) return; primitive->runTrail(bOn); } bool SGameFxSwordSlash::IsRunTrail() { if (primitive==NULL) return false; return primitive->isTrailRunning(); } void SGameFxSwordSlash::setTrailWidth(float _width) { if (primitive==NULL) return; primitive->setTrailWidth(_width); } void SGameFxSwordSlash::setTrailNodeCount(int count) // Trail의 node갯수 (segment갯수-1). 길이 { if (primitive==NULL) return; primitive->setTrailNodeCount(count); } void SGameFxSwordSlash::setTrailNodeColor(int nodeNumber // node번호. TrailPrimitive::NODE_START_xxxx 나 TrailPrimitive::NODE_END_xxxx , int nIndex, DWORD color // 화면표시색 = (텍스처 * color0) + color1 ) { if (primitive==NULL) return; DWORD color0, color1; float u, v; primitive->getTriailNodeColor(nodeNumber, &color0, &color1, &u, &v); if( nIndex == 0 ) primitive->setTrailNodeColor(nodeNumber, color, color1, u, v); else if( nIndex == 1 ) primitive->setTrailNodeColor(nodeNumber, color0, color, u, v); } void SGameFxSwordSlash::getTriailNodeColor(int nodeNumber , DWORD *_color0, DWORD *_color1 , float *_u, float *_v ) { if (primitive==NULL) return; primitive->getTriailNodeColor(nodeNumber, _color0, _color1, _u, _v); } void SGameFxSwordSlash::setTrailTexture(const char *texName) { if (primitive==NULL) return; primitive->setTrailTexture(texName); } bool SGameFxSwordSlash::setupTrailByConfigurationText(const char *config) // Config파일 로딩 // NOTE! : 원래 이렇게 붙이려던 계획이 아닌, 기획자용 console command의 확장으로서 대충!만든 루틴임 // 따라서 여러모로 모양이 안 좋으므로 다른데 쓸 계획이 있으면 개선할 것! { if (primitive==NULL) return false; return primitive->setupTrailByConfigurationText(config); } //=================================================================================================== // Console용 입출력 함수군 // NOTE! : 원래 이렇게 붙이려던 계획이 아닌, 기획자용 console command의 확장으로서 대충!만든 루틴임 // 따라서 여러모로 모양이 안 좋으므로 다른데 쓸 계획이 있으면 개선할 것! //=================================================================================================== bool TrailPrimitive::setupTrailByConfigurationText(const char *config) // Config파일 로딩 { size_t len=strlen(config); if (len<=0) return false; char *tmpbuf=new char[len+1]; // twParseCommands()에서 strtok가 무슨짓을 할지 모르므로 copy strcpy(tmpbuf, config); bool ret=twParseCommands(tmpbuf); delete [] tmpbuf; return ret; } void TrailPrimitive::twprintNode(char *buffer, int nodeNo) { buffer[0]=0; if (nodeNo<0 || nodeNo>3) return; DWORD color0, color1; float u, v; getTriailNodeColor(nodeNo, &color0, &color1, &u, &v); sprintf(buffer, "color0 0x%08x, color1 0x%08x, u %f, v %f
" , color0, color1, u, v ); } void TrailPrimitive::twprintSize(char *buffer) { sprintf(buffer, " width %f, length %d
", getTrailWidth(), getTrailNodeCount()); } void TrailPrimitive::twprint(char *buffer) { char tmpbuf[1024]; buffer[0]=0; twprintNode(tmpbuf, 0); strcat(buffer, " Node00
"); strcat(buffer, tmpbuf); twprintNode(tmpbuf, 1); strcat(buffer, " Node01
"); strcat(buffer, tmpbuf); twprintNode(tmpbuf, 2); strcat(buffer, " Node10
"); strcat(buffer, tmpbuf); twprintNode(tmpbuf, 3); strcat(buffer, " Node11
"); strcat(buffer, tmpbuf); twprintSize(tmpbuf); strcat(buffer, "
"); strcat(buffer, tmpbuf); } // // String에서 command를 parse // bool TrailPrimitive::twParseCommands(char *buffer) { // Comment를 전부 삭제 size_t len=strlen(buffer); if (len==0) return false; char line[512]; char *text=new char[len*2]; // len+1이면 충분. (+1 for eos) char *p; int n; text[0]=0; p=strtok(buffer, "\r\n"); while (p!=NULL) { // Split by line strcpy(line, p); n=(int)strcspn(line, "!#"); // ! 이나 #으로 시작하면 커멘트 라인 line[n]=0; // 커멘트 이후 삭제 strcat(text, line); strcat(text, "\n"); p=strtok(NULL, "\r\n"); } const char *loadCommandList[] = { "wttexture" , "wttex" , "wtwidth" , "wtw" , "wtlength" , "wtl" , "wt00color0" , "wt00c0" , "wt00color1" , "wt00c1" , "wt00u" , "wt00v" , "wt01color0" , "wt01c0" , "wt01color1" , "wt01c1" , "wt01u" , "wt01v" , "wt10color0" , "wt10c0" , "wt10color1" , "wt10c1" , "wt10u" , "wt10v" , "wt11color0" , "wt11c0" , "wt11color1" , "wt11c1" , "wt11u" , "wt11v" , NULL // EOL }; std::string _key; std::string _param; std::vector arg; const char **c=loadCommandList; char lineBuf[1024]; while ((*c)!=NULL) { // Find command p=strstr(text, *c); if (p!=NULL) { p+=strlen(*c); n=(int)strspn(p, " \t"); if (n>0) { p+=n; n=(int)strcspn(p, " \t\r\n"); strncpy(line, p, n); line[n]=0; if (n>0) { _key=*c; _param=line; arg.clear(); arg.push_back(_param); processConsoleCommand(_key, (int)arg.size(), arg, lineBuf); } } } c++; } arg.clear(); delete [] text; return true; } bool TrailPrimitive::twLoadCommands(const char *filename) { int f=::_open(filename, _O_RDONLY | _O_TEXT, _S_IREAD | _S_IWRITE); if (f==-1) return false; long filesize=_lseek(f, 0, SEEK_END); _lseek(f, 0, SEEK_SET); char *text=new char[filesize*2]; int n=::_read(f, text, filesize*2); text[n]=0; bool b=twParseCommands(text); delete [] text; ::_close(f); return b; } // // 현재 커맨드를 file에 write // void TrailPrimitive::twWriteCommands(char *buffer) { const char *twSaveCommandList[] = { "wttexture" , "wtwidth" , "wtlength" , "wt00color0" , "wt00color1" , "wt00u" , "wt00v" , "wt01color0" , "wt01color1" , "wt01u" , "wt01v" , "wt10color0" , "wt10color1" , "wt10u" , "wt10v" , "wt11color0" , "wt11color1" , "wt11u" , "wt11v" , NULL // EOL }; string _key; std::vector arg; const char **c=twSaveCommandList; char lineBuf[1024]; // char *p; buffer[0]=0; while (*c!=NULL) { _key=*(c++); processConsoleCommand(_key, (int)arg.size(), arg, lineBuf); if (lineBuf[0]!=0) { strcat(buffer, lineBuf); strcat(buffer, "\n"); } } arg.clear(); } bool TrailPrimitive::twSaveCommand(const char *filename) { int f=::_open(filename, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_TEXT, _S_IREAD | _S_IWRITE); if (f==-1) return false; char buffer[2048]=""; twWriteCommands(buffer); ::_write(f, buffer, (unsigned int)strlen(buffer)); ::_close(f); return true; } const char *TrailDefaultFileName="twParams.txt"; void TrailPrimitive::processConsoleCommand(std::string &key, int argc, std::vector &argv, char *outputBuffer) { static char TrailTexName[512]=""; static char TrailFileName[512]=""; outputBuffer[0]=0; const char *cmd=key.c_str(); // Print information if ( (0==::_stricmp(cmd, "wtprint")) || (0==::_stricmp(cmd, "wtp"))) { twprint(outputBuffer); return; } // Save/load params if ( (0==::_stricmp(cmd, "wtsave")) || (0==::_stricmp(cmd, "wtsa"))) { const char *filename=TrailDefaultFileName; if (argc>0) { filename=argv[0].c_str(); } if (false==twSaveCommand(filename)) { sprintf(outputBuffer, "Save error"); return; } sprintf(outputBuffer, "Saved to %s", filename); return; } if ( (0==::_stricmp(cmd, "wtload")) || (0==::_stricmp(cmd, "wtlo"))) { const char *filename=TrailDefaultFileName; if (argc>0) { filename=argv[0].c_str(); } if (false==twLoadCommands(filename)) { sprintf(outputBuffer, "Load error"); return; } strcpy(TrailFileName, filename); sprintf(outputBuffer, "Loaded from %s", filename); return; } if ( (0==::_stricmp(cmd, "wtreload")) || (0==::_stricmp(cmd, "wtr"))) { if (false==twLoadCommands(TrailFileName)) { sprintf(outputBuffer, "Reload error"); } sprintf(outputBuffer, "Reloaded from %s", TrailFileName); return; } if ( (0==::_stricmp(cmd, "wttexreload")) || (0==::_stricmp(cmd, "wttexr"))) { // Texture reload if (TrailTexName[0]!=0) { this->setTrailTexture(TrailTexName); sprintf(outputBuffer, "Texture %s reloaded", TrailTexName); return; } sprintf(outputBuffer, "No texture"); } if ( (0==::_stricmp(cmd, "wttexture")) || (0==::_stricmp(cmd, "wttex")) ) { if (argc>0) { this->setTrailTexture(argv[0].c_str()); strcpy(TrailTexName, argv[0].c_str()); } sprintf(outputBuffer, "wttexture %s", TrailTexName); return; } if ( (0==::_stricmp(cmd, "wtwidth")) || (0==::_stricmp(cmd, "wtw")) ) { if (argc>0) { this->setTrailWidth(atof(argv[0].c_str())); } sprintf(outputBuffer, "wtwidth %f", this->getTrailWidth()); return; } if ( (0==::_stricmp(cmd, "wtlength")) || (0==::_stricmp(cmd, "wtl")) ){ if (argc>0) { int n=atoi(argv[0].c_str()); if (n>SWORDSLASH_TRAILSEGMENTSIZE) n=SWORDSLASH_TRAILSEGMENTSIZE; this->setTrailNodeCount(n); } sprintf(outputBuffer, "wtlength %d", this->getTrailNodeCount()); return; } if ( (cmd[2]=='0' || cmd[2]=='1') && (cmd[3]=='0' || cmd[3]=='1')) { DWORD color0, color1; float u, v; char *p; const char *c; int n=0; if (cmd[2]=='1') n+=2; if (cmd[3]=='1') n+=1; c=&(cmd[4]); this->getTriailNodeColor(n, &color0, &color1, &u, &v); if (0==::_stricmp(c, "color0") || 0==::_stricmp(c, "c0")) { if (argc>0) { color0=strtoul(argv[0].c_str(), &p, 16); this->setTrailNodeColor(n, color0, color1, u, v); } sprintf(outputBuffer, "wt%c%ccolor0 %08x", cmd[2], cmd[3], color0); return; } if (0==::_stricmp(c, "color1") || 0==::_stricmp(c, "c1")) { if (argc>0) { color1=strtoul(argv[0].c_str(), &p, 16); this->setTrailNodeColor(n, color0, color1, u, v); } sprintf(outputBuffer, "wt%c%ccolor1 %08x", cmd[2], cmd[3], color1); return; } if (0==::_stricmp(c, "u")) { if (argc>0) { u=atof(argv[0].c_str()); this->setTrailNodeColor(n, color0, color1, u, v); } sprintf(outputBuffer, "wt%c%cu %15f", cmd[2], cmd[3], u); return; } if (0==::_stricmp(c, "v")) { if (argc>0) { v=atof(argv[0].c_str()); this->setTrailNodeColor(n, color0, color1, u, v); } sprintf(outputBuffer, "wt%c%cv %15f", cmd[2], cmd[3], v); return; } // Invalid command twprintNode(outputBuffer, n); return; } // if (0==::_stricmp(cmd, "wthelp")) { strcpy(outputBuffer, " - 커맨드 일람 -
" "wtprint : 현재 파라미터를 프린트한다
" "wtsave [파일명] : 현재 파라미터를 파일에 세이브한다
" "wtload [파일명] : 현재 파라미터를 파일에서 로드한다
" "wtreload : 현재 파라미터를 이전에 로드한 파일에서 다시 로드한다
" "wttexreload : 텍스처를 다시 로드한다
" "
" "wt00color0 [ARGB]: 무기 위치 검광 손목쪽 색깔 0번 (ARGB)
" "wt00color1 [ARGB]: 무기 위치 검광 손목쪽 색깔 1번 (ARGB)
" "wt00u [float]: 무기 위치 검광 손목쪽 U값 (0.0 ~ 1.0)
" "wt00v [float]: 무기 위치 검광 손목쪽 V값 (0.0 ~ 1.0)
" "
" "wt01color0 [ARGB]: 무기 위치 검광 칼끝쪽 색깔 0번 (ARGB)
" "wt01color1 [ARGB]: 무기 위치 검광 칼끝쪽 색깔 1번 (ARGB)
" "wt01u [float]: 무기 위치 검광 칼끝쪽 U값 (0.0 ~ 1.0)
" "wt01v [float]: 무기 위치 검광 칼끝쪽 V값 (0.0 ~ 1.0)
" "
" "wt10color0 [ARGB]: 검광 과거위치 손목쪽 색깔 0번 (ARGB)
" "wt10color1 [ARGB]: 검광 과거위치 손목쪽 색깔 1번 (ARGB)
" "wt10u [float]: 검광 과거위치 손목쪽 U값 (0.0 ~ 1.0)
" "wt10v [float]: 검광 과거위치 손목쪽 V값 (0.0 ~ 1.0)
" "
" "wt11color0 [ARGB]: 검광 과거위치 칼끝쪽 색깔 0번 (ARGB)
" "wt11color1 [ARGB]: 검광 과거위치 칼끝쪽 색깔 1번 (ARGB)
" "wt11u [float]: 검광 과거위치 검광 손목쪽 U값 (0.0 ~ 1.0)
" "wt11v [float]: 검광 과거위치 검광 손목쪽 V값 (0.0 ~ 1.0)
" "
" "wttexture [파일명]: 텍스처 파일명
" "wtwidth [float]: 검광 너비. 10.0이면 일반 칼 길이정도의 너비
" "wtlength [float]: 검광 길이. 64정도면 보통 길이
" "
-참고-
" "wtp : wtprint의 약자
" "wt00c0 : wt00color0의 약자
" "wt00c1 : wt00color1의 약자
" "wt01c0, wt01c1, wt10c0, wt10c1, wt11c0, wt11c1 : 위와 같음
" "wtr : wtreload
" "wtlo : wtload
" "wtsa : wtsave
" "wttexr : wttexreload
" ); } //=========================================================== // Debugging utility // 콘솔에서 파라미터 잘 받아서 처리 // 나중에 지울것 or 막을것!! //=========================================================== #include "SGame.h" #include "SGameSystem.h" extern SGameSystem * g_pCurrentGameSystem; // defined in SGameSystem.cpp // localPlayer얻어오는데 사용 char *WeaponTrailProcessConsoleCommand(std::string &key, int argc, std::vector &argv) { static char TrailDbgMessage[2048]=""; SGameAvatarEx *localPlayer=g_pCurrentGameSystem->GetLocalPlayer(); if (localPlayer==NULL) return NULL; SGameFxSwordSlash *trail=localPlayer->GetRightWeaponTrailRenderer(); // 오른손 무기에 대해 적용 if (trail==NULL) return NULL; TrailPrimitive *prim=trail->getTrailPrimitive(); if (prim==NULL) return NULL; prim->processConsoleCommand(key, argc, argv, TrailDbgMessage); localPlayer->ActivateRightWeaponTrail(); // sonador 10.6.1 무기 강화 이펙트 추가 지원 return TrailDbgMessage; }