Files
Leviathan/Client/Game/game/GameSystem/SGameFxSwordSlash.cpp
T
2026-06-01 12:46:52 +02:00

1146 lines
28 KiB
C++

/*
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 <sys/stat.h>
#include <io.h>
#include <fcntl.h>
#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<TrailNode>::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; i<trails.size(); i++) {
// bottom vertex
v->pos.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<SGameWorld*>(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<count; i++) {
tn.matrix=matrix[i];
K3DVectorTransform(tn.base, vBottom, tn.matrix);
K3DVectorTransform(tn.top, vTop, tn.matrix);
tn.time=(endtime-starttime)*i/count + starttime;
trails.push_back(tn);
if ((int)trails.size() > 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; i<maxTrailCount-1; i++) {
// 1st
*pu=n; pu++;
*pu=n+1; pu++;
*pu=n+2; pu++;
// 2nd
*pu=n+2; pu++;
*pu=n+1; pu++;
*pu=n+3; pu++;
// 1st, backside
*pu=n; pu++;
*pu=n+2; pu++;
*pu=n+1; pu++;
// 2nd, backside
*pu=n+2; pu++;
*pu=n+3; pu++;
*pu=n+1; pu++;
n+=2;
}
indexBuffer->Unlock();
}
} 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<NODE_MAX);
color0[nodeNumber]=_color0;
color1[nodeNumber]=_color1;
u[nodeNumber]=_u;
v[nodeNumber]=_v;
// Set dirty flag
rebuildPolygon=true;
}
void TrailPrimitive::getTriailNodeColor(int nodeNumber
, DWORD *_color0, DWORD *_color1
, float *_u, float *_v
)
{
assert(nodeNumber>=0 && nodeNumber<NODE_MAX);
if (_color0!=NULL) *_color0=color0[nodeNumber];
if (_color1!=NULL) *_color1=color1[nodeNumber];
if (_u!=NULL) *_u=u[nodeNumber];
if (_v!=NULL) *_v=v[nodeNumber];
}
void TrailPrimitive::setTrailTexture(const char *texName)
{
TEXPACK texpack;
if (texName!=NULL) {
// Load texture
NX3LoadPack loadpack;
loadpack.Init();
if( KTextureManager::GetManager()->IsExistTexture( 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; i<trailCount; i++) {
f=((float)i) / (float)(trailCount-1);
fi=1.0f-f;
// bottom vertex
vtx->clear();
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 <br>"
, color0, color1, u, v
);
}
void TrailPrimitive::twprintSize(char *buffer)
{
sprintf(buffer, " width %f, length %d <br>", getTrailWidth(), getTrailNodeCount());
}
void TrailPrimitive::twprint(char *buffer) {
char tmpbuf[1024];
buffer[0]=0;
twprintNode(tmpbuf, 0);
strcat(buffer, " Node00 <br>");
strcat(buffer, tmpbuf);
twprintNode(tmpbuf, 1);
strcat(buffer, " Node01 <br>");
strcat(buffer, tmpbuf);
twprintNode(tmpbuf, 2);
strcat(buffer, " Node10 <br>");
strcat(buffer, tmpbuf);
twprintNode(tmpbuf, 3);
strcat(buffer, " Node11 <br>");
strcat(buffer, tmpbuf);
twprintSize(tmpbuf);
strcat(buffer, " <br>");
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<std::string> 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<std::string> 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<std::string> &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, " - 커맨드 일람 -<br>"
"wtprint : 현재 파라미터를 프린트한다<br>"
"wtsave [파일명] : 현재 파라미터를 파일에 세이브한다 <br>"
"wtload [파일명] : 현재 파라미터를 파일에서 로드한다 <br>"
"wtreload : 현재 파라미터를 이전에 로드한 파일에서 다시 로드한다 <br>"
"wttexreload : 텍스처를 다시 로드한다 <br>"
"<br>"
"wt00color0 [ARGB]: 무기 위치 검광 손목쪽 색깔 0번 (ARGB)<br>"
"wt00color1 [ARGB]: 무기 위치 검광 손목쪽 색깔 1번 (ARGB)<br>"
"wt00u [float]: 무기 위치 검광 손목쪽 U값 (0.0 ~ 1.0)<br>"
"wt00v [float]: 무기 위치 검광 손목쪽 V값 (0.0 ~ 1.0)<br>"
"<br>"
"wt01color0 [ARGB]: 무기 위치 검광 칼끝쪽 색깔 0번 (ARGB)<br>"
"wt01color1 [ARGB]: 무기 위치 검광 칼끝쪽 색깔 1번 (ARGB)<br>"
"wt01u [float]: 무기 위치 검광 칼끝쪽 U값 (0.0 ~ 1.0)<br>"
"wt01v [float]: 무기 위치 검광 칼끝쪽 V값 (0.0 ~ 1.0)<br>"
"<br>"
"wt10color0 [ARGB]: 검광 과거위치 손목쪽 색깔 0번 (ARGB)<br>"
"wt10color1 [ARGB]: 검광 과거위치 손목쪽 색깔 1번 (ARGB)<br>"
"wt10u [float]: 검광 과거위치 손목쪽 U값 (0.0 ~ 1.0)<br>"
"wt10v [float]: 검광 과거위치 손목쪽 V값 (0.0 ~ 1.0)<br>"
"<br>"
"wt11color0 [ARGB]: 검광 과거위치 칼끝쪽 색깔 0번 (ARGB)<br>"
"wt11color1 [ARGB]: 검광 과거위치 칼끝쪽 색깔 1번 (ARGB)<br>"
"wt11u [float]: 검광 과거위치 검광 손목쪽 U값 (0.0 ~ 1.0)<br>"
"wt11v [float]: 검광 과거위치 검광 손목쪽 V값 (0.0 ~ 1.0)<br>"
"<br>"
"wttexture [파일명]: 텍스처 파일명<br>"
"wtwidth [float]: 검광 너비. 10.0이면 일반 칼 길이정도의 너비<br>"
"wtlength [float]: 검광 길이. 64정도면 보통 길이<br>"
"<br> -참고- <br>"
"wtp : wtprint의 약자<br>"
"wt00c0 : wt00color0의 약자<br>"
"wt00c1 : wt00color1의 약자<br>"
"wt01c0, wt01c1, wt10c0, wt10c1, wt11c0, wt11c1 : 위와 같음<br>"
"wtr : wtreload<br>"
"wtlo : wtload<br>"
"wtsa : wtsave<br>"
"wttexr : wttexreload<br>"
);
}
//===========================================================
// 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<std::string> &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;
}