Files
Leviathan/Client/Game/engine/Ui/Controls/KUIControlEffectText.cpp
T
2026-06-01 12:46:52 +02:00

421 lines
11 KiB
C++

#include "stdafx.h"
#ifndef _COUNTRY_ME_
#include "KUIWndManager.h"
#include "KUIControlEffectText.h"
#include "KResourceManager.h"
#define _EFFECT_TEST
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIControlEffectText Implement
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace CONTROL_EFFECT_TEXT
{
const int MAX_WIDTH = 600; /// 2011.02.18 mantis 0012225 - prodongi
const int MAX_HEIGHT = 60;
KUIWnd* EffectTextCreator()
{
return new KUIControlEffectText;
}
const bool bRegister = KUIFactory::GetInstance()->RegisterCreator( EffectTextCreator, "effect_text");
KUIControlEffectText* CreateEffectText(KUIWndManager* pManager, KUIWnd* pParent, LPCSTR name, KUIControlEffectText::EFFECT_TYPE type,
int x, int y, bool scaleDown)
{
KUIWND_CREATE_ARG arg;
arg.lpszClassName = "effect_text";
arg.lpszSprName = "ui_frame.spr";
arg.pParent = pParent;
arg.rcRect = KRect(x,y,x + MAX_WIDTH,y + MAX_HEIGHT);
arg.lpszID = "_effect_text_id";
arg.lpszID += name;
KUIControlEffectText* pEffect = static_cast<KUIControlEffectText*>( pManager->CreateControl(arg) );
pEffect->SetEffectInfo(name, type, scaleDown);
return pEffect;
}
enum
{
STATE_MOVE = 0,
STATE_WAIT,
STATE_POPDOWN, // 점점 사라짐.
TOTAL_STATE,
};
const DWORD MOVE_TIME = 400;
const DWORD LINE_MOVE_TIME_DELAY = 200;
const DWORD CAPTION_MOVE_TIME_DELAY = 400;
const int CAPTION_Y_OFFSET = -20;
const int CAPTION_X_OFFSET = -50;
const int LINE_Y_OFFSET = 28;
const int LINE_X_OFFSET = 110;
const DWORD STATE_TIME[TOTAL_STATE] =
{
CAPTION_MOVE_TIME_DELAY + MOVE_TIME,
300,
1000,
};
const int LEFT_OFFEST = -400;
enum COLLISION_STATE
{
CS_NONE = 0, // 부딪히지 않았음.
CS_MOVE_RIGHT, // 부딛혀서 오른쪽으로 밀려남
CS_MOVE_LEFT_DOWN, // 좌측 대각선 아래로 내려감
CS_MOVE_DOWN,
TOTAL_CS,
};
const DWORD RIGHT_TIME = 100;
const DWORD RIGHT_OFFSET = 40;
// 1초당 얼만큼 움직일 것인가..
const float DOWN_SPEED = 500.f / 1000;
const int DOWN_OFFSET = 35;
LPCSTR TYPE_TO_COLOR[KUIControlEffectText::TOTAL_EFFECT_COUNT] =
{
"<#090101>",
"<#ffffff>",
};
LPCSTR TYPE_TO_BACK_NAME[KUIControlEffectText::TOTAL_EFFECT_COUNT] =
{
"static_playerview_conditionback_bad",
"static_playerview_conditionback_good",
};
LPCSTR TYPE_TO_LINE_NAME[KUIControlEffectText::TOTAL_EFFECT_COUNT] =
{
"static_playerview_conditionline_bad",
"static_playerview_conditionline_good",
};
}
using namespace CONTROL_EFFECT_TEXT;
KUIControlEffectText::KUIControlEffectText()
{
m_state = STATE_MOVE;
m_collisionState = COLLISION_STATE::CS_NONE;
m_collisionEffectStartTime = m_effectStartTime = m_curTime = 0;
m_remainDownOffest = m_downOffest = 0;
m_realRect = KRect(0,0,0,0);
m_curCaptionAlpha = 1.f;
m_curPrimitiveAlpha = 1.f;
}
KUIControlEffectText::~KUIControlEffectText()
{
}
void KUIControlEffectText::Process(DWORD time)
{
// using namespace CONTROL_EFFECT_TEXT;
m_curTime = time;
if(m_effectStartTime == 0)
{
m_effectStartTime = m_curTime;
m_state = STATE_MOVE;
return;
}
DWORD timeDiff = m_curTime - m_effectStartTime;
switch(m_state)
{
case STATE_MOVE:
{
if(timeDiff > CAPTION_MOVE_TIME_DELAY)
{
DWORD newTimeDiff = timeDiff - CAPTION_MOVE_TIME_DELAY;
// 최종적으로 caption이 위치해야할 곳
int captionLeft = m_rcRegion.left + m_backWidth - m_captionWidth;
int left_offset = m_scaleDown ? LEFT_OFFEST * 0.7f : LEFT_OFFEST;
int left = captionLeft + left_offset * (1.0f - getClampRatioSqrt(newTimeDiff,MOVE_TIME ) );
int y_offset = CAPTION_Y_OFFSET;
if(m_scaleDown)
{
left += 100;
y_offset = CAPTION_Y_OFFSET + 5;
}
m_curCaptionAlpha = 1.f;
m_pCaptionPhrase->SetPosition( (left + CAPTION_X_OFFSET) , m_rcRegion.top + y_offset, m_fZPos);
m_pCaptionPhrase->SetVisibility(m_curCaptionAlpha);
}
if(timeDiff > LINE_MOVE_TIME_DELAY)
{
DWORD newTimeDiff = timeDiff - LINE_MOVE_TIME_DELAY;
int lineLeft = m_rcRegion.left;
int left = lineLeft + LEFT_OFFEST * (1.0f - getClampRatioSqrt(newTimeDiff,MOVE_TIME) );
m_BackLine.SetRenderEnable(true);
m_BackLine.SetPosition(left + LINE_X_OFFSET,m_rcRegion.top + LINE_Y_OFFSET,m_fZPos);
}
int backLeft = m_rcRegion.left;
int left = backLeft + LEFT_OFFEST * (1.0f - getClampRatioSqrt(timeDiff,MOVE_TIME) );
m_Back.SetRenderEnable(true);
m_Back.SetPosition(left,m_rcRegion.top,m_fZPos);
}
break;
case STATE_WAIT:
break;
case STATE_POPDOWN:
_ChangeCurAlpha(1.0f - getClampRatio(timeDiff, STATE_TIME[m_state]) );
break;
}
// 끝났3
if(m_state == TOTAL_STATE)
{
SetDestroy(true);
}
else if(false == IsDestroy() && timeDiff >= STATE_TIME[m_state] )
{
m_state++;
m_effectStartTime = m_curTime;
}
// 이 부분부턴 충돌해서 밀리는 부분..
DWORD csTimeDiff = m_curTime - m_collisionEffectStartTime;
switch(m_collisionState)
{
case COLLISION_STATE::CS_NONE:
// 난데모 나이 -_-
m_collisionEffectStartTime = m_curTime;
break;
case COLLISION_STATE::CS_MOVE_RIGHT:
{
// 존내 밀려남
float ratio = getClampRatioSqrt(csTimeDiff, RIGHT_TIME);
int width = (m_rcRegion.GetWidth() + RIGHT_OFFSET) * ratio;
m_pCaptionPhrase->SetPosition(m_rcRegion.left + width, m_rcRegion.top, m_fZPos);
m_realRect = m_rcRegion + KRect(width, 0, width, 0);
if(ratio == 1.0f)
{
m_collisionState = CS_MOVE_LEFT_DOWN;
m_collisionEffectStartTime = m_curTime;
}
}
break;
case COLLISION_STATE::CS_MOVE_LEFT_DOWN:
{
float ratioSub = 1.f - getClampRatioPow(csTimeDiff, RIGHT_TIME);
int width = (m_rcRegion.GetWidth() + RIGHT_OFFSET) * ratioSub;
_CalDownOffset(csTimeDiff);
m_pCaptionPhrase->SetPosition(m_rcRegion.left + width, m_rcRegion.top + m_downOffest, m_fZPos);
m_realRect = m_rcRegion + KRect(width, m_downOffest, width, m_downOffest);
if(ratioSub == 0.0f)
{
m_collisionState = CS_MOVE_DOWN;
m_collisionEffectStartTime = m_curTime;
}
}
break;
case COLLISION_STATE::CS_MOVE_DOWN:
_CalDownOffset(csTimeDiff);
m_pCaptionPhrase->SetPosition(m_rcRegion.left - m_downOffest, m_rcRegion.top + m_downOffest, m_fZPos);
m_realRect = m_rcRegion + KRect(-m_downOffest, m_downOffest, -m_downOffest, m_downOffest);
break;
}
}
void KUIControlEffectText::AddDownOffset(int count)
{
// using namespace CONTROL_EFFECT_TEXT;
if(m_collisionState == COLLISION_STATE::CS_NONE)
return;
m_remainDownOffest += DOWN_OFFSET * count;
}
void KUIControlEffectText::OnCollision()
{
// using namespace CONTROL_EFFECT_TEXT;
assert(m_collisionState == COLLISION_STATE::CS_NONE);
m_collisionState = CS_MOVE_RIGHT;
}
void KUIControlEffectText::OnPosChangeNofity(int XOffset, int YOffset)
{
// 외부에서 Sprite Primitive의 Position 조절을 막기 위해서
// using namespace CONTROL_EFFECT_TEXT;
if(m_state == STATE_MOVE)
return;
KUIControl::OnPosChangeNofity(XOffset, YOffset);
}
void KUIControlEffectText::OnAlphaChangeNotify(float fAlpha)
{
// 외부에서 Sprite Primitive의 Visibility 조절을 막기 위해서
KUIWnd::OnAlphaChangeNotify(fAlpha);
float resVisiCap = m_fAlpha * m_curCaptionAlpha;
float resVisiPrim = m_fAlpha * m_curPrimitiveAlpha;
if(m_pCaptionPhrase)
m_pCaptionPhrase->SetVisibility( resVisiCap);
m_Back.SetVisibility( resVisiPrim);
m_BackLine.SetVisibility( resVisiPrim);
}
namespace
{
K3DMatrix SCALE_MATRIX = K3DMatrix(K3DVector(0.7f,0.f,0.f), K3DVector(0.0f,0.7f,0.f), K3DVector(0.0f,0.f,1.f) );
}
void KUIControlEffectText::SetEffectInfo(LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown)
{
using namespace CONTROL_EFFECT_TEXT;
m_scaleDown = scaleDown;
int x = m_rcRegion.left; int y = m_rcRegion.top;
// Sprite Image 추가
KResSprite* pBack = _getSpriteSet()->GetSpriteRes(TYPE_TO_BACK_NAME[type], 0);
m_Back.SetRes(pBack);
m_Back.SetPosition(x,y,m_fZPos);
m_Back.SetRenderEnable(false);
KResSprite* pLine = _getSpriteSet()->GetSpriteRes(TYPE_TO_LINE_NAME[type], 0);
m_BackLine.SetRes(pLine);
m_BackLine.SetPosition(x,y,m_fZPos);
m_BackLine.SetRenderEnable(false);
_registerSprite(&m_Back);
_registerSprite(&m_BackLine);
// caption 추가
std::string newCaption = TYPE_TO_COLOR[type];
newCaption += "<LEFT>";
newCaption += scaleDown ? "<size:23>" : "<size:33>";
newCaption += name;
SetCaption(newCaption.c_str() );
m_curCaptionAlpha = 0.f;
m_pCaptionPhrase->SetVisibility(m_curCaptionAlpha);
float scale_down_factor = 1.f;
// 70%만 표시
if( true == m_scaleDown)
{
m_Back.SetTransform(SCALE_MATRIX);
m_BackLine.SetTransform(SCALE_MATRIX);
scale_down_factor = 0.7f;
}
m_backWidth = pBack->GetSizeX() * scale_down_factor;
// 넓이 보정 ( 충돌체크용)
KTextPhrase::GetOneLineStringSize(newCaption.c_str(), &m_captionWidth);
m_rcRegion.right = m_rcRegion.left + pBack->GetSizeX() * scale_down_factor;
m_rcRegion.bottom= m_rcRegion.top + pBack->GetSizeY() * scale_down_factor;
m_realRect = m_rcRegion;
}
void KUIControlEffectText::_ChangeCurAlpha(float fAlpha)
{
m_curCaptionAlpha = fAlpha;
m_curPrimitiveAlpha = fAlpha;
float resVisiCaption = m_curCaptionAlpha * m_fAlpha;
float resVisiPrim = m_curPrimitiveAlpha * m_fAlpha;
if(NULL != m_pCaptionPhrase)
m_pCaptionPhrase->SetVisibility( resVisiCaption);
m_Back.SetVisibility( resVisiPrim);
m_BackLine.SetVisibility( resVisiPrim);
}
void KUIControlEffectText::_CalDownOffset(DWORD csTimeDiff)
{
using namespace CONTROL_EFFECT_TEXT;
if(m_remainDownOffest > m_downOffest)
{
int downHeight = std::min(m_remainDownOffest,static_cast<int>( csTimeDiff * DOWN_SPEED) );
m_downOffest = downHeight;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIControlEffectTextGroup Implement
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace CONTROL_EFFECT_TEXT_GROUP
{
KUIWnd* EffectTextGroupCreator()
{
return new KUIControlEffectTextGroup;
}
bool bRegister = KUIFactory::GetInstance()->RegisterCreator( EffectTextGroupCreator, "effect_text_group");
}
void KUIControlEffectTextGroup::Process(DWORD time)
{
KUIControl::Process(time);
#ifndef _KUI_INVALIDATION
// Delete dead entities
for(std::list<KUIWnd*>::iterator it = m_listChild.begin(); it != m_listChild.end();)
{
KUIWnd* pWnd = *it;
if(pWnd->IsDestroy() )
{
delete pWnd;
it = m_listChild.erase(it);
}
else
{
++it;
}
}
#endif
}
#ifdef _KUI_INVALIDATION
KUIControl* KUIControlEffectTextGroup::AddEffectControl(KUIWnd* pParent, LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown)
{
return CONTROL_EFFECT_TEXT::CreateEffectText(m_pManager, pParent, name, type, m_rcRegion.left-200, m_rcRegion.top, scaleDown);
}
#else
void KUIControlEffectTextGroup::AddEffectControl(LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown)
{
// 2010.08.12 - prodongi
//CONTROL_EFFECT_TEXT::CreateEffectText(m_pManager, this, name, type, m_rcRegion.left-200, m_rcRegion.top, scaleDown);
int offsetY = GetChildCount() * ((m_rcRegion.bottom - m_rcRegion.top) >> 1);
CONTROL_EFFECT_TEXT::CreateEffectText(m_pManager, this, name, type, m_rcRegion.left-200, m_rcRegion.top - offsetY, scaleDown);
}
#endif
#endif