v19 Taskbar Cooldown Fix

09/14/2014 02:25 Sanctuary'#1
Einfach die void CWndTaskBar::OnDraw Funktion in der WndTaskbar.cpp mit dieser ersetzen:
PHP Code:
void CWndTaskBar::OnDraw( C2DRender* p2DRender )
{
    if( 
NULL == g_pPlayer )
        return;

    
DWORD dwCur = g_tmCurrent;
    
CRect rect = GetWindowRect();
    
CRect rectSkillQueue;

    
CD3DFont* pOldFont = p2DRender->GetFont();
    
p2DRender->SetFont( CWndBase::m_Theme.m_pFontWndTitle );
     
    if( 
m_nPosition == TASKBAR_TOP || m_nPosition == TASKBAR_BOTTOM )
    {
        
rectSkillQueue.SetRect( rect.Width() - 32 * 4 - 6, 0, rect.Width(), rect.Height() );
    }
    else
    if( 
m_nPosition == TASKBAR_LEFT || m_nPosition == TASKBAR_RIGHT )
    {
        
rectSkillQueue.SetRect( 0, rect.Height() - 32 * 4 - 6, rect.Width(), rect.Height() );
    }

    
// 드래그 하이라이트 슬롯 표시
    
if( m_GlobalShortcut.IsEmpty() == FALSE )
    {
        
DWORD dwColor;
        if( 
m_dwHighAlpha < 128 )
            
dwColor = D3DCOLOR_ARGB( m_dwHighAlpha, 0, 0, 255 );
        else
            
dwColor = D3DCOLOR_ARGB( 128 - ( m_dwHighAlpha - 128 ), 0, 0, 255 );

        
LPWNDCTRL pApplet = GetWndCtrl( WIDC_CUSTOM1 );
        
LPWNDCTRL pItem   = GetWndCtrl( WIDC_CUSTOM2 );
        
LPWNDCTRL pSkill  = GetWndCtrl( WIDC_CUSTOM3 );

        
CRect rectApplet = pApplet->rect;
        
CRect rectItem = pItem->rect;
        
CRect rectSkill = pSkill->rect;

        
rectApplet.top = 42;
        
rectApplet.bottom = 47;
        
rectApplet.left -= 6;
        
rectApplet.right += 6;
        
rectItem.top = 42;
        
rectItem.bottom = 47;
        
rectItem.left -= 6;
        
rectItem.right += 6;
        
rectSkill.top = 42;
        
rectSkill.bottom = 47;
        
rectSkill.left -= 3;
        
rectSkill.right += 4;
     
        switch( 
m_GlobalShortcut.m_dwShortcut )
        {
            case 
SHORTCUT_APPLET:
            case 
SHORTCUT_ITEM:
            case 
SHORTCUT_MOTION:
                
p2DRender->RenderFillRect( rectApplet, dwColor );
                
p2DRender->RenderFillRect( rectItem, dwColor );
                break;
            case 
SHORTCUT_SKILL:
                if( 
m_GlobalShortcut.m_dwType == 0 )
                {
                    
DWORD dwSkill = g_pPlayer->GetSkill( 0, m_GlobalShortcut.m_dwId )->dwSkill;
                    
DWORD dwComboStyleSrc = prj.GetSkillProp( dwSkill )->dwComboStyle;
                    if( 
dwComboStyleSrc == CT_STEP  || dwComboStyleSrc == CT_GENERAL  )        // 스텝이나 제네럴이면 합격
                        
p2DRender->RenderFillRect( rectItem, dwColor );     
                    
p2DRender->RenderFillRect( rectSkill, dwColor );
                }
                else
                    
p2DRender->RenderFillRect( rectItem, dwColor );
                break;
        }     
    }

    
// 애플렛 아이콘 출력
    
CPoint point = POINT_APPLET;
    for( 
int i = 0; i < m_nMaxSlotApplet; i++ )
    {
        
LPSHORTCUT lpShortcut = &m_aSlotApplet[ i ] ;
        if( !
lpShortcut->IsEmpty() )
        {
            if( 
lpShortcut->m_pTexture )
                
p2DRender->RenderTexture( point, lpShortcut->m_pTexture );
            if( 
lpShortcut->m_dwShortcut == SHORTCUT_ITEM )
            {
                
CItemBase* pItemBase = g_pPlayer->GetItemId( lpShortcut->m_dwId );
                
CItemElem* pItemElem = (CItemElem*)pItemBase;
                if( 
pItemElem )
                {
                    if( 
pItemElem->GetProp()->dwPackMax > 1 )
                    {
                        
TCHAR szTemp[ 32 ];
#if __VER >= 8    // __JEFF_VER_8
                        
_stprintf( szTemp, "%d", g_pPlayer?g_pPlayer->m_Inventory.GetItemCount( pItemElem->m_dwItemId ): 0 );
#else    // __JEFF_VER_8
                        
_stprintf( szTemp, "%d", pItemElem->m_nItemNum );
#endif    // __JEFF_VER_8
                        
CSize size = m_p2DRender->m_pFont->GetTextExtent( szTemp );
                        
p2DRender->TextOut( point.x + 32 - size.cx, point.y + 32 - size.cy, szTemp, 0xfff6cc4d );
                        
p2DRender->TextOut( point.x + 31 - size.cx, point.y + 31 - size.cy, szTemp, 0xfff6cc4d );
                    }
                    
DWORD dwGroup = g_pPlayer->m_cooltimeMgr.GetGroup( pItemElem->GetProp() );
                    if( 
dwGroup )
                    {
                        
DWORD dwEnd = g_pPlayer->m_cooltimeMgr.GetTime( dwGroup );        // 이벤트 종료 시각
                        
if( dwEnd != 0 && dwEnd > dwCur )
                        {
                            
DWORD dwBase = g_pPlayer->m_cooltimeMgr.GetBase( dwGroup );    // 이벤트 시작 시각
                            
RenderRadar( p2DRender, point, dwCur - dwBase, dwEnd - dwBase );
                        }
                    }
                }
                else
                {
#if __VER >= 8    // __JEFF_VER_8
                    
ItemProp* pItemProp    = prj.GetItemProp( lpShortcut->m_dwItemId );
                    if( 
pItemProp && pItemProp->dwPackMax > 1 )    // 병합 가능한 아이템이면?
                    
{
                        
DWORD dwId    = g_pPlayer->m_Inventory.Find( lpShortcut->m_dwItemId );
                        if( 
dwId != NULL_ID )    // 같은 종류의 아이템이 있다면?
                        
{
                            
lpShortcut->m_dwId    = dwId;
                            
g_DPlay.SendAddAppletTaskBar( i, lpShortcut );
                        }
                        else
                        {
                            
lpShortcut->Empty();
                            
g_DPlay.SendRemoveAppletTaskBar( i );
                        }
                    }
                    else
                    {
                        
lpShortcut->Empty();
                        
g_DPlay.SendRemoveAppletTaskBar( i );
                    }
#else    // __JEFF_VER_8
                    
lpShortcut->Empty();
                    
g_DPlay.SendRemoveAppletTaskBar( i );
#endif    // __JEFF_VER_8
                
}
            }
            else
            if( 
lpShortcut->m_dwShortcut == SHORTCUT_APPLET )
            {
                
AppletFunc* pAppletFunc = g_WndMng.GetAppletFunc( lpShortcut->m_dwId );
                if( 
pAppletFunc && pAppletFunc->m_cHotkey )
                {
                    
CPoint ptHotkey( point.x + 8, point.y - 9 );
                    
DRAW_HOTKEY( p2DRender, ptHotkey, pAppletFunc->m_cHotkey );
                }
            }
            else if( 
lpShortcut->m_dwShortcut == SHORTCUT_SKILL && lpShortcut->m_dwType != 2 ) //극단스킬은 쿨타임 관련 Render를 하지 않는다.
            
{
                
RenderCollTime( point, lpShortcut->m_dwId, p2DRender );
            }
        
#if __VER >= 12 // __LORD
            
else if( lpShortcut->m_dwShortcut == SHORTCUT_LORDSKILL)
            {
                    
RenderLordCollTime( point, lpShortcut->m_dwId, p2DRender );
            }
        
#endif
            
else
            if( 
lpShortcut->m_dwShortcut == SHORTCUT_MOTION )
            {
                if( 
lpShortcut->m_dwId == MOT_BASE_ESCAPE )
                {
                    
ItemProp* pItem = prj.GetItemProp( g_AddSMMode.dwSMItemID[SM_ESCAPE] );
                 
                    if( 
pItem && g_pPlayer )
                    {
                        
CTimeSpan ct( g_pPlayer->m_dwSMTime[SM_ESCAPE] );
                     
                        if( 
ct.GetTotalSeconds() )
                        {
                            
point.y -= 1;
                            
point.x += 1;
                            
RenderRadar( m_p2DRender, point, (DWORD)( pItem->dwCircleTime - ct.GetTotalSeconds() ), pItem->dwCircleTime );
                        }
                    }
                }
            } 
        }
        
point += CPoint( ICON_SIZE, 0 );
    }
    
// 아이템 아이콘 출력
    
point = POINT_ITEM;
    for( 
i = 0; i < MAX_SLOT_ITEM; i++ )
    {
        
LPSHORTCUT lpShortcut = &m_paSlotItem[ i ] ;
        if( !
lpShortcut->IsEmpty() )
        {
            if( 
lpShortcut->m_pTexture )
                
p2DRender->RenderTexture( point, lpShortcut->m_pTexture );
            if( 
lpShortcut->m_dwShortcut == SHORTCUT_ITEM )
            {
                
CItemBase* pItemBase = g_pPlayer->GetItemId( lpShortcut->m_dwId );
                
CItemElem* pItemElem = (CItemElem*)pItemBase;
                if( 
pItemElem  )
                {
                    if( 
pItemElem->GetProp()->dwPackMax > 1 )
                    {
                        
TCHAR szTemp[ 32 ];
#if __VER >= 8    // __JEFF_VER_8
                        
_stprintf( szTemp, "%d", g_pPlayer?g_pPlayer->m_Inventory.GetItemCount( pItemElem->m_dwItemId ): 0 );
#else    // __JEFF_VER_8
                        
_stprintf( szTemp, "%d", pItemElem->m_nItemNum );
#endif    // __JEFF_VER_8
                        
CSize size = m_p2DRender->m_pFont->GetTextExtent( szTemp );
                        
p2DRender->TextOut( point.x + 32 - size.cx, point.y + 32 - size.cy, szTemp, 0xfff6cc4d );
                        
p2DRender->TextOut( point.x + 31 - size.cx, point.y + 31 - size.cy, szTemp, 0xfff6cc4d );
                    }
                }

                
DWORD dwGroup = g_pPlayer->m_cooltimeMgr.GetGroup( pItemElem->GetProp() );
                if( 
dwGroup )
                {
                    
DWORD dwEnd = g_pPlayer->m_cooltimeMgr.GetTime( dwGroup );        // 이벤트 종료 시각
                    
if( dwEnd != 0 && dwEnd > dwCur )
                    {
                        
DWORD dwBase = g_pPlayer->m_cooltimeMgr.GetBase( dwGroup );    // 이벤트 시작 시각
                        
RenderRadar( p2DRender, point, dwCur - dwBase, dwEnd - dwBase );
                    }
                }
            }
            else if( 
lpShortcut->m_dwShortcut == SHORTCUT_SKILL && lpShortcut->m_dwType != 2 ) //극단스킬은 쿨타임 관련 Render를 하지 않는다.
            
{
                
RenderCollTime( point, lpShortcut->m_dwId, p2DRender );
            }
        
#if __VER >= 12 // __LORD
            
else if( lpShortcut->m_dwShortcut == SHORTCUT_LORDSKILL)
            {
                    
RenderLordCollTime( point, lpShortcut->m_dwId, p2DRender );
            }
        
#endif
            
else
            if( 
lpShortcut->m_dwShortcut == SHORTCUT_MOTION )
            {
                if( 
lpShortcut->m_dwId == MOT_BASE_ESCAPE )
                {
                    
ItemProp* pItem = prj.GetItemProp( g_AddSMMode.dwSMItemID[SM_ESCAPE] );

                    if( 
pItem && g_pPlayer )
                    {
                        
CTimeSpan ct( g_pPlayer->m_dwSMTime[SM_ESCAPE] );
                     
                        if( 
ct.GetTotalSeconds() )
                        {
                            
point.y -= 1;
                            
point.x += 1;
                            
RenderRadar( m_p2DRender, point, (DWORD)( pItem->dwCircleTime - ct.GetTotalSeconds() ), pItem->dwCircleTime );
                        }
                    }
                }
            }

             
        }
        
// hotkey 출력
        
CHAR cHotkey = ( i == 9 ) ? '0' : '1' + i;
        
CPoint ptHotkey( point.x + 8, point.y - 9 );
        
//DRAW_HOTKEY( p2DRender, ptHotkey, cHotkey );
        
point += CPoint( ICON_SIZE, 0 );
    }
 
    
point = CPoint( POINT_QUEUE_X - ICON_SIZE - 5, POINT_QUEUE_Y );
    
p2DRender->RenderTexture( point, m_pTexture );

    
// 스킬 큐
    
point = POINT_QUEUE;
    
//p2DRender->TextOut( point.x - 5, point.y - 16, "ACTION SLOT" );
    
for( i = 0; i < m_nCurQueueNum; i++ )
    {
        
LPSHORTCUT lpShortcut = &m_aSlotQueue[ i ] ;
        if( !
lpShortcut->IsEmpty() )
        {
            if( 
lpShortcut->m_pTexture )
            {
                
p2DRender->RenderTexture( point, lpShortcut->m_pTexture );
//                LPSKILL pSkill = g_pPlayer->GetSkill( lpShortcut->m_dwType, lpShortcut->m_dwId );
//                if( g_pPlayer->m_nReUseDelay[ lpShortcut->m_dwId ] > 0 )
//                    p2DRender->TextOut( point.x, point.y, g_pPlayer->m_nReUseDelay[ lpShortcut->m_dwId ] );

            
}
        }
        
point += CPoint( SKILL_SIZE, 0 );
    }

    if( !( 
g_pPlayer->IsSMMode( SM_ACTPOINT ) ) )
    {
    
#define LV2MAXAP    10        // 2단계 스킬이 다차는데 필요한 action point
    #define LV3MAXAP    25     
    #define LV4MAXAP    50
    #define LV5MAXAP    100

        
point = POINT_QUEUE;
        
point.x += SKILL_SIZE;    // 스킬 2번째캤壙� 쉐이드된다.
        
{
            
int nAP2Size;    // 액션포인트를 하이라이트양으로 변환한값.
            
if( m_nActionPoint >= LV4MAXAP )    // LV4MAXAP를 넘어섯� 5단계 시작.
                
nAP2Size = (SKILL_SIZE * 3) + (((m_nActionPoint - LV4MAXAP) * SKILL_SIZE) / (LV5MAXAP - LV4MAXAP));
            else if( 
m_nActionPoint >= LV3MAXAP )
                
nAP2Size = (SKILL_SIZE * 2) + (((m_nActionPoint - LV3MAXAP) * SKILL_SIZE) / (LV4MAXAP - LV3MAXAP));
            else if( 
m_nActionPoint >= LV2MAXAP )
                
nAP2Size = (SKILL_SIZE * 1) + (((m_nActionPoint - LV2MAXAP) * SKILL_SIZE) / (LV3MAXAP - LV2MAXAP));
            else
                
nAP2Size = (m_nActionPoint * SKILL_SIZE) / LV2MAXAP;
         
            
p2DRender->m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
            
p2DRender->m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
            
point.x += nAP2Size;
            
nAP2Size = (SKILL_SIZE * 4) - nAP2Size;
            
p2DRender->RenderFillRect( CRect(point.x, point.y,  point.x + nAP2Size, point.y + SKILL_SIZE + 2),
                                        
D3DCOLOR_ARGB( 0x7f, 0, 0, 0 ) );
         
            if( 
m_nCurQueueNum > 0 )
            {
                
int show = 1;
             
                if( 
m_nActionPoint >= LV2MAXAP )
                    
show = 2;
                if( 
m_nActionPoint >= LV3MAXAP )
                    
show = 3;
                if( 
m_nActionPoint >= LV4MAXAP )
                    
show = 4;
                if( 
m_nActionPoint >= LV5MAXAP )
                    
show = 5;
             
                if( 
m_nCurQueueNum <= show )
                    
show = m_nCurQueueNum;
             
                
CPoint Point = CPoint( POINT_QUEUE_X, POINT_QUEUE_Y+1 );

                
RenderOutLineLamp( POINT_QUEUE_X, POINT_QUEUE_Y+1, show, SKILL_SIZE );
            }
        }
    }

    
CWndButton* pWndButton = (CWndButton*)GetDlgItem( WIDC_UP );
    
rect = pWndButton->GetWindowRect( TRUE );
    
rect.top = rect.bottom - 2;
    
p2DRender->TextOut( rect.left, rect.top, m_nSlotIndex + 1, 0xffffffff );
    
p2DRender->SetFont( pOldFont );
} 

Dann noch sichergehen das m_nActionPoint in eurer WndTaskbar.h definiert ist und alles sollte funktionieren.
PHP Code:
int              m_nActionPoint; 
Credits : 100% Hostille
09/14/2014 07:10 wns24987#2
lol...thanke :)
09/14/2014 12:57 Sanctuary'#3
It's for the cooldown animation in the taskbar..
09/14/2014 13:30 .S0ulSeller#4
Danke, auch wenn das nicht deine Arbeit war...^^
09/14/2014 13:32 Burdenz2007#5
So basically the skill cooldown will rotate with this fix?
09/15/2014 03:08 Elusively#6
Thanks for giving credits ;)

As for those curious as to what this fixes, this fixes the display of the cooldown on items and(or) skills in the taskbar like retail.

All the public releases have this disabled for god knows what reason, but yea this will fix that.

As for activation problems it's more then likely due to the same reason. Simply keep following it, what i did find interesting when i "fixed" this is how the define was hidden between ifndef which shows this was done intentionally.
10/27/2014 14:53 Rodopushin#7
Quote:
Originally Posted by Sanctuary' View Post
Einfach die void CWndTaskBar::OnDraw Funktion in der WndTaskbar.h
Du meintest oben wohl WndTaskBar.cpp und nicht .h^^

Habe das gemacht (verwende derzeit Virtuos Files), allerdings spuckt er Errors aus, dass m_nActionPoint nicht definiert ist. Ich habe wie du beschrieben hattest in der WndTaskBar.h geschaut, ob es definiert ist und dort steht folgender Eintrag:


Wenn ich nun das #ifndef __NEW_TASKBAR_V19 rausnehme, dann sind die Fehlermeldungen weg. Jetzt k�nnte man meinen, ich h�tte __NEW_TASKBAR_V19 nicht definiert, ich habe das in allen relevanten VersionCommon.h gepr�ft und �berall ist es definiert.

Als ich das #ifndef �berall entfernt hatte, was mit der V19 Taskbar zutun hat, bekomme ich zwar keine Fehlermeldungen, aber im Spiel wird immernoch kein Cooldown angezeigt.

Kann mir jemand helfen?

EDIT: Er wird nur bei Skills nicht angezeigt!
10/28/2014 01:19 Spheromany#8
Quote:
Originally Posted by xXXKillianXXx View Post
Du meintest oben wohl WndTaskBar.cpp und nicht .h^^

Habe das gemacht (verwende derzeit Virtuos Files), allerdings spuckt er Errors aus, dass m_nActionPoint nicht definiert ist. Ich habe wie du beschrieben hattest in der WndTaskBar.h geschaut, ob es definiert ist und dort steht folgender Eintrag:


Wenn ich nun das #ifndef __NEW_TASKBAR_V19 rausnehme, dann sind die Fehlermeldungen weg. Jetzt k�nnte man meinen, ich h�tte __NEW_TASKBAR_V19 nicht definiert, ich habe das in allen relevanten VersionCommon.h gepr�ft und �berall ist es definiert.

Als ich das #ifndef �berall entfernt hatte, was mit der V19 Taskbar zutun hat, bekomme ich zwar keine Fehlermeldungen, aber im Spiel wird immernoch kein Cooldown angezeigt.

Kann mir jemand helfen?

EDIT: Er wird nur bei Skills nicht angezeigt!
Du weist schon das "#ifndef" f�r "if not defined" steht oder? Sprich: #wennnichtdefiniert __NEW_TASKBAR_V19

Auf gut deutsch: er benutzt die Variable/Pointer/whatever wenn die neue Taskbar NICHT definiert ist.
10/28/2014 01:39 Avalion#9
Quote:
Originally Posted by jayjei14 View Post
what does it mean for this fix?
it is for radar or for activation potion?
Activition potion, like this, is an extremely easy fix.


Anyway, this can't be exactly copied or pasted. Just analyze the differences with CWndTaskbarInterface and work with it. GG, fixed cooldown.
10/28/2014 02:56 Rodopushin#10
Quote:
Originally Posted by Spheromany View Post
Du weist schon das "#ifndef" f�r "if not defined" steht oder? Sprich: #wennnichtdefiniert __NEW_TASKBAR_V19

Auf gut deutsch: er benutzt die Variable/Pointer/whatever wenn die neue Taskbar NICHT definiert ist.
Ja, hab ich nichtmehr dran gedacht. Kleiner Denkfehler von mir, aber egal wie ich es mache, ob nun ifdef oder ifndef, ob mit oder ohne den Code, bei Skills wird der Cooldown tortzdem nicht angezeigt :D
10/28/2014 11:52 Burdenz2007#11
So anyone Tested this code? Does it really works?
10/30/2014 13:42 max982#12
There's a much easier way to do this.
02/04/2019 04:57 adeilson123#13
Code:
int	CUserTaskBar::SetNextSkill( CUser *pUser )
{
	m_nUsedSkillQueue ++;		// 큐인덱스 다음으로...
	
#ifdef __V19_TASKBAR
	int nAP = 100;
#else//__V19_TASKBAR
	int nAP = m_nActionPoint;
	if( !( pUser->IsSMMode( SM_ACTPOINT ) ) )
	{
		switch( m_nUsedSkillQueue )
		{
		case 1:	nAP -= 6;	break;		// 액션 포인트 소모량. 다음슬롯을 사용할수있는지 미리 알아보기 위함.
		case 2:	nAP -= 8;	break;
		case 3:	nAP -= 11;	break;
		case 4:	nAP -= 30;	break;
		}
	}
#endif//__V19_TASKBAR
	LPSHORTCUT pShortcut = &m_aSlotQueue[ m_nUsedSkillQueue ];
	BOOL bResult = nAP < 0;
	if( ( m_nUsedSkillQueue >= MAX_SLOT_QUEUE) || pShortcut->IsEmpty() || (nAP < 0) )	// 큐진행이 끝까지 갔거나 || 큐가 비었거나 || AP가 없거나.
	{
		OnEndSkillQueue( pUser );
		return 0;		// 큐실행 끝.
	} else
	{
#ifndef __V19_TASKBAR
		if( nAP < 0 )	nAP = 0;
		m_nActionPoint = nAP;
#endif//__V19_TASKBAR
		pUser->AddSetActionPoint( nAP );		// 액숀포인트 클라에 갱신.
		OBJID idTarget = pUser->m_idSetTarget;
		TRACE( "다음스킬사용 시도%d, ", pShortcut->m_dwId );
		if( pUser->CMD_SetUseSkill( idTarget, pShortcut->m_dwId, SUT_QUEUEING ) == 0 )		// 실행할 명령을 셋팅. 이동 + 스킬사용이 합쳐진 명령.
		{
			TRACE( "다음스킬사용 실패 %d, ", pShortcut->m_dwId );
			SetNextSkill( pUser );	// 스킬사용에 실패했다면 다음 스킬 사용하도록 넘어감.
		}
		return 1;
	}

	return 1;
}