Jump to content

Recommended Posts

If I`m not wrong robert installed this system for 2 servers, as I know but yeah it costs.

You have to adapt that pet render system cause it will not work exactly the same way, you have to send the index of the race to SetModel and the vnum of the item to SetArmor.

I didn`t have time to work on it but if I`m not wrong now is from python.

Link to comment
Share on other sites

  • 3 weeks later...
  • Contributor
On 3/10/2019 at 7:30 PM, Redeemed said:

Hey guys, i have this problem with the Render Target system:

renderproblem.thumb.png.758e9ea1034e78e40dcd735ce84e79fc.png

Things 've tried:

-Checked the scale functions several times

-Checked the layer part in the RegisterRenderTarget

This base is kinda clean the only thing what's in it is just the Acce and new emotion.

Thanks in advance for the answers!

I have your same problem when putting the game on resolution more than 800*600 with fullscreen , but works with specific configs , So weird ( Any solution ? )

Since the last time i changed the configs from config.exe and the above error occuring

My only accounts are here and on M2D, Don't trust anyone else from other shitty sites.
266868740522639360.png

Link to comment
Share on other sites

  • Contributor

Apparently it only works with this resolution
WIDTH                        1024
HEIGHT                        705
 other than this that problem occurs

My only accounts are here and on M2D, Don't trust anyone else from other shitty sites.
266868740522639360.png

Link to comment
Share on other sites

  • Contributor
Just now, ManiacRobert said:

works fine 1920x1080

you know what i mean it works only with some resolutions and this is a problem

I think this has something to do with it ?!
 

PyObject* renderTargetSetBackground(PyObject* poSelf, PyObject* poArgs)
{
	BYTE index = 0;
	if (!PyTuple_GetByte(poArgs, 0, &index))
		return Py_BadArgument();

	char * szPathName;
	if (!PyTuple_GetString(poArgs, 1, &szPathName))
		return Py_BadArgument();

	CRenderTargetManager::Instance().GetRenderTarget(index)->CreateBackground(
		szPathName, CPythonApplication::Instance().GetWidth(),
		CPythonApplication::Instance().GetHeight());
	return Py_BuildNone();
}


 

  • Love 1

My only accounts are here and on M2D, Don't trust anyone else from other shitty sites.
266868740522639360.png

Link to comment
Share on other sites

  • Contributor

Guys the main problem is here :

	if (!PERF_CHECKER_RENDER_GAME)
	{
		float fAspect=m_kWndMgr.GetAspect();
		float fFarClip=m_pyBackground.GetFarClip();

		m_pyGraphic.SetPerspective(30.0f, fAspect, 100.0, fFarClip);
		m_kRenderTargetManager.RenderBackgrounds();

		CCullingManager::Instance().Process();

it has something to do with :

Quote

m_pyGraphic.SetPerspective(30.0f, fAspect, 100.0, fFarClip);

 

My only accounts are here and on M2D, Don't trust anyone else from other shitty sites.
266868740522639360.png

Link to comment
Share on other sites

  • Bronze
On 3/10/2019 at 6:30 PM, Redeemed said:

Hey guys, i have this problem with the Render Target system:

renderproblem.thumb.png.758e9ea1034e78e40dcd735ce84e79fc.png

Things 've tried:

-Checked the scale functions several times

-Checked the layer part in the RegisterRenderTarget

This base is kinda clean the only thing what's in it is just the Acce and new emotion.

Thanks in advance for the answers!

screenshot_110.png.dba5816aece0adebade29eb3be31f681.png

  • Love 3
Link to comment
Share on other sites

  • 2 weeks later...
  • Premium
Am 7.4.2019 um 10:51 schrieb Morpheus™:

Hey all!

 

Can anyone help?

https://metin2.download/picture/VC8vbA1Ku8uC7k6X06zCO9sZGv4dR4WY/.gif

If there are monsters nearby, the render goes wrong o.O

 

Thanks!

Got the same poblem...found no solution

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 1
Link to comment
Share on other sites

help


 

Spoiler

Error    2    error LNK1120: 1 unresolved externals    C:\Users\andrea\Desktop\ZulaChams\Binario [email protected] 29-08-2018\Binario [email protected] 29-08-2018\binary\Metin2Distribute.exe    UserInterface
Error    1    error LNK2001: unresolved external symbol "void __cdecl initRenderTarget(void)" (?initRenderTarget@@YAXXZ)    C:\Users\andrea\Desktop\ZulaChams\Binario [email protected] 29-08-2018\Binario [email protected] 29-08-2018\vs_files\UserInterface\UserInterface.obj    UserInterface

 

Link to comment
Share on other sites

Hi i have problem with sethair / setweapon / setsash

e76eQRT.png

hair:

0428 02:57:16230 :: CGraphicThingInstance::RegisterModelThing(iModelThing=4, pModelThing=d:\ymir work\pc\assassin\hair\hair_1_1.gr2)
0428 02:57:16230 :: CGraphicThingInstance::SetModelInstance(iDstModelInstance=4, pModelThing=4, iSrcModel=0)
0428 02:57:16232 :: CGraphicThingInstance::SetMaterialImagePointer(ePart(4)<uPartCount(1), c_szImageName=d:\ymir Work\pc\assassin\assassin_hair_01.dds, pImage=d:\ymir work\pc\assassin\assassin_hair_01_brown.dds) - ePart OUT OF RANGE

weapon:

0428 02:59:47212 :: CGraphicThingInstance::SetModelInstance(iDstModelInstance=1, pModelThing=1, iSrcModel=0)
0428 02:59:47213 :: CGraphicThingInstance::AttachModelInstance(iDstModelInstance=0, c_szBoneName=equip_right, iSrcModelInstance=1)
0428 02:59:47214 :: CGraphicThingInstance::SetMaterialData(ePart(1)<uPartCount(1)) - ePart OUT OF RANGE
0428 02:59:48152 :: CGraphicThingInstance::RegisterModelThing(iModelThing=1, pModelThing=d:\ymir work\item\weapon\00010.gr2)

acce:

0428 02:59:43334 :: CGraphicThingInstance::SetModelInstance(iDstModelInstance=5, pModelThing=5, iSrcModel=0)
0428 02:59:43335 :: CGraphicThingInstance::AttachModelInstance(iDstModelInstance=0, c_szBoneName=Bip01 Spine2, iSrcModelInstance=5)
0428 02:59:43336 :: CGraphicThingInstance::SetMaterialData(ePart(5)<uPartCount(1)) - ePart OUT OF RANGE
0428 02:59:43763 :: CGraphicThingInstance::RegisterModelThing(iModelThing=5, pModelThing=d:\ymir work\item\wing\acce_easter_2k19_03.gr2)

I add function like @CxL'Mufuku & @ѕeмa™ write.

But work only setarmor.

Some suggestions? 

 

Solution:

in SelectModel:

change this:

kCreateData.m_bType = CActorInstance::TYPE_NPC;

to this:

kCreateData.m_bType = index > 8 ? CActorInstance::TYPE_NPC : CActorInstance::TYPE_PC;

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 1
Link to comment
Share on other sites

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Next bug.

fuzz-qrSc2wGX8QX7.gif 

Look for the shaman skills. When u far stay its this bug.

Some Solution?

 

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

  • Bot
28 minutes ago, h4c0k1 said:

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Next bug.

fuzz-qrSc2wGX8QX7.gif 

Look for the shaman skills. When u far stay its this bug.

Some Solution?

 

Search in EterLib/CRenderTarget.cpp:

	state_manager.SetRenderState(D3DRS_FOGENABLE, TRUE);

Replace with:

	state_manager.SetRenderState(D3DRS_FOGENABLE, FALSE);

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 1

english_banner.gif

Link to comment
Share on other sites

10 godzin temu, avertuss napisał:

@h4c0k1

Did you change or add something to sema code? I mean render armor/weapon/hair etc. or it works fine?

 

I use ChangeArmor / ChangeWeapon .. 

Not SetArmor

@avertuss

i add this horizontal scroll for set the camera:

 fuzz-guyS5m4MfFmn.png

 

And in code add functions:

fuzz-takGcjEuQWDb.png 

And view function:

fuzz-JopG4Ge3bLix.png

 

Like in PY:

renderTarget.View("costume", dwVnum)

 

That's it.

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Love 1
Link to comment
Share on other sites

5 hours ago, h4c0k1 said:

Show code. py + cpp

the code and what you see in this discussion

for the iupolites and this

Spoiler

#uitooltip.py Açýlýr

# Aratýlýr
class ItemToolTip(ToolTip):

# Altýna Eklenir

    ModelPreviewBoard = None
    ModelPreview = None
    ModelPreviewText = None


# Aratýlýr
def __AppendHairIcon(self, itemVnum):

# Altýna eklenir

    def __ModelPreview(self, Vnum):
        #if constInfo.DISABLE_MODEL_PREVIEW == 1:
        #    return

        RENDER_TARGET_INDEX = 1

        self.ModelPreviewBoard = ui.ThinBoard()
        self.ModelPreviewBoard.SetParent(self)
        self.ModelPreviewBoard.SetSize(190+10, 210+30)
        self.ModelPreviewBoard.SetPosition(-202, 0)
        self.ModelPreviewBoard.Show()

        self.ModelPreview = ui.RenderTarget()
        self.ModelPreview.SetParent(self.ModelPreviewBoard)
        self.ModelPreview.SetSize(190, 210)
        self.ModelPreview.SetPosition(5, 22)
        self.ModelPreview.SetRenderTarget(RENDER_TARGET_INDEX)
        self.ModelPreview.Show()

        self.ModelPreviewText = ui.TextLine()
        self.ModelPreviewText.SetParent(self.ModelPreviewBoard)
        self.ModelPreviewText.SetFontName(self.defFontName)
        self.ModelPreviewText.SetPackedFontColor(grp.GenerateColor(0.8824, 0.9804, 0.8824, 1.0))
        self.ModelPreviewText.SetPosition(0, 5)
        self.ModelPreviewText.SetText("Model Önizleme")
        self.ModelPreviewText.SetOutline()
        self.ModelPreviewText.SetFeather(False)
        self.ModelPreviewText.SetWindowHorizontalAlignCenter()
        self.ModelPreviewText.SetHorizontalAlignCenter()
        self.ModelPreviewText.Show()

        renderTarget.SetBackground(RENDER_TARGET_INDEX, "d:/ymir work/ui/game/myshop_deco/model_view_bg.sub")
        renderTarget.SetVisibility(RENDER_TARGET_INDEX, True)
        renderTarget.SelectModel(RENDER_TARGET_INDEX, Vnum)

    def __ModelPreviewClose(self):
        RENDER_TARGET_INDEX = 1

        if self.ModelPreviewBoard:
            self.ModelPreviewBoard.Hide()
            self.ModelPreview.Hide()
            self.ModelPreviewText.Hide()

            self.ModelPreviewBoard = None
            self.ModelPreview = None
            self.ModelPreviewText = None

            renderTarget.SetVisibility(RENDER_TARGET_INDEX, False)


# Aratýlýr
        self.__AdjustMaxWidth(attrSlot, itemDesc)
        self.__SetItemTitle(itemVnum, metinSlot, attrSlot, IsGlass)
        
# Altýna Eklenir

self.__ModelPreviewClose()


# Aratýlýr

            if bHasRealtimeFlag == 1:
                self.AppendMallItemLastTime(metinSlot[0])

        elif 0 != isCostumeItem:
            self.__AppendLimitInformation()
            self.__AppendAffectInformation()
            
            
# Üstüne Eklenir

            if itemSubType != item.PET_MOUNT:
                PetVnum = item.GetValue(0)

                if PetVnum != 0:
                    self.__ModelPreview(PetVnum)

            if itemSubType == item.PET_MOUNT:
                MountVnum = item.GetValue(4)
                if MountVnum != 0:
                    self.__ModelPreview(MountVnum)
 

Spoiler

import dbg
import player
import item
import grp
import wndMgr
import skill
import shop
import exchange
import grpText
import safebox
import localeInfo
import app
import background
import nonplayer
import chr

import ui
import mouseModule
import renderTarget
import constInfo
if app.ENABLE_SASH_SYSTEM:
    import sash
if app.ENABLE_CHANGELOOK_SYSTEM:
    import changelook
    
WARP_SCROLLS = [22011, 22000, 22010]
EXTRA_SLOT = [0,1,2,4,6,9,12,16]
DESC_DEFAULT_MAX_COLS = 26 
DESC_WESTERN_MAX_COLS = 35
DESC_WESTERN_MAX_WIDTH = 220

def chop(n):
    return round(n - 0.5, 1)

def pointop(n):
    t = int(n)
    if t / 10 < 1:
        return "0."+n
    else:        
        return n[0:len(n)-1]+"."+n[len(n)-1:]

def SplitDescription(desc, limit):
    total_tokens = desc.split()
    line_tokens = []
    line_len = 0
    lines = []
    for token in total_tokens:
        if "|" in token:
            sep_pos = token.find("|")
            line_tokens.append(token[:sep_pos])

            lines.append(" ".join(line_tokens))
            line_len = len(token) - (sep_pos + 1)
            line_tokens = [token[sep_pos+1:]]
        else:
            line_len += len(token)
            if len(line_tokens) + line_len > limit:
                lines.append(" ".join(line_tokens))
                line_len = len(token)
                line_tokens = [token]
            else:
                line_tokens.append(token)
    
    if line_tokens:
        lines.append(" ".join(line_tokens))

    return lines

###################################################################################################
## ToolTip
##
##   NOTE : ÇöÀç´Â Item°ú SkillÀ» »ó¼ÓÀ¸·Î Ưȭ ½ÃÄѵξúÀ½
##          ÇÏÁö¸¸ ±×´ÙÁö Àǹ̰¡ ¾ø¾î º¸ÀÓ
##
class ToolTip(ui.ThinBoard):

    TOOL_TIP_WIDTH = 190
    TOOL_TIP_HEIGHT = 10

    TEXT_LINE_HEIGHT = 17

    TITLE_COLOR = grp.GenerateColor(0.9490, 0.9058, 0.7568, 1.0)
    SPECIAL_TITLE_COLOR = grp.GenerateColor(1.0, 0.7843, 0.0, 1.0)
    NORMAL_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0)
    FONT_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0)
    PRICE_COLOR = 0xffFFB96D

    HIGH_PRICE_COLOR = SPECIAL_TITLE_COLOR
    MIDDLE_PRICE_COLOR = grp.GenerateColor(0.85, 0.85, 0.85, 1.0)
    LOW_PRICE_COLOR = grp.GenerateColor(0.7, 0.7, 0.7, 1.0)

    ENABLE_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0)
    DISABLE_COLOR = grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0)

    NEGATIVE_COLOR = grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0)
    POSITIVE_COLOR = grp.GenerateColor(0.5411, 0.7254, 0.5568, 1.0)
    SPECIAL_POSITIVE_COLOR = grp.GenerateColor(0.6911, 0.8754, 0.7068, 1.0)
    SPECIAL_POSITIVE_COLOR2 = grp.GenerateColor(0.8824, 0.9804, 0.8824, 1.0)

    SHOP_ITEM_COLOR = 0xfffff64e

    CONDITION_COLOR = 0xffBEB47D
    UNDER_LOOK_COLOR = 0xfffff64e
    BEFORE_LOOK_COLOR = 0xff9A9CDB
    CAN_LEVEL_UP_COLOR = 0xff8EC292
    CANNOT_LEVEL_UP_COLOR = DISABLE_COLOR
    NEED_SKILL_POINT_COLOR = 0xff9A9CDB

    def __init__(self, width = TOOL_TIP_WIDTH, isPickable=FALSE):
        ui.ThinBoard.__init__(self, "TOP_MOST")

        if isPickable:
            pass
        else:
            self.AddFlag("not_pick")

        self.AddFlag("float")

        self.followFlag = TRUE
        self.toolTipWidth = width

        self.xPos = -1
        self.yPos = -1

        self.defFontName = localeInfo.UI_DEF_FONT
        self.ClearToolTip()

    def __del__(self):
        ui.ThinBoard.__del__(self)

    def ClearToolTip(self):
        self.toolTipHeight = 12
        self.childrenList = []

    def SetFollow(self, flag):
        self.followFlag = flag

    def SetDefaultFontName(self, fontName):
        self.defFontName = fontName

    def AppendSpace(self, size):
        self.toolTipHeight += size
        self.ResizeToolTip()

    def AppendHorizontalLine(self):

        for i in xrange(2):
            horizontalLine = ui.Line()
            horizontalLine.SetParent(self)
            horizontalLine.SetPosition(0, self.toolTipHeight + 3 + i)
            horizontalLine.SetWindowHorizontalAlignCenter()
            horizontalLine.SetSize(150, 0)
            horizontalLine.Show()

            if 0 == i:
                horizontalLine.SetColor(0xff555555)
            else:
                horizontalLine.SetColor(0xff000000)

            self.childrenList.append(horizontalLine)

        self.toolTipHeight += 11
        self.ResizeToolTip()

    def AlignHorizonalCenter(self):
        for child in self.childrenList:
            (x, y)=child.GetLocalPosition()
            child.SetPosition(self.toolTipWidth/2, y)

        self.ResizeToolTip()

    def AutoAppendTextLine(self, text, color = FONT_COLOR, centerAlign = TRUE):
        textLine = ui.TextLine()
        textLine.SetParent(self)
        textLine.SetFontName(self.defFontName)
        textLine.SetPackedFontColor(color)
        textLine.SetText(text)
        textLine.SetOutline()
        textLine.SetFeather(FALSE)
        textLine.Show()

        if centerAlign:
            textLine.SetPosition(self.toolTipWidth/2, self.toolTipHeight)
            textLine.SetHorizontalAlignCenter()

        else:
            textLine.SetPosition(10, self.toolTipHeight)

        self.childrenList.append(textLine)

        (textWidth, textHeight)=textLine.GetTextSize()

        textWidth += 40
        textHeight += 5

        if self.toolTipWidth < textWidth:
            self.toolTipWidth = textWidth

        self.toolTipHeight += textHeight

        return textLine

    def AppendTextLine(self, text, color = FONT_COLOR, centerAlign = TRUE):
        textLine = ui.TextLine()
        textLine.SetParent(self)
        textLine.SetFontName(self.defFontName)
        textLine.SetPackedFontColor(color)
        textLine.SetText(text)
        textLine.SetOutline()
        textLine.SetFeather(FALSE)
        textLine.Show()

        if centerAlign:
            textLine.SetPosition(self.toolTipWidth/2, self.toolTipHeight)
            textLine.SetHorizontalAlignCenter()

        else:
            textLine.SetPosition(10, self.toolTipHeight)

        self.childrenList.append(textLine)

        self.toolTipHeight += self.TEXT_LINE_HEIGHT
        self.ResizeToolTip()

        return textLine

    def AppendDescription(self, desc, limit, color = FONT_COLOR):
        if localeInfo.IsEUROPE():
            self.__AppendDescription_WesternLanguage(desc, color)
        else:
            self.__AppendDescription_EasternLanguage(desc, limit, color)

    def __AppendDescription_EasternLanguage(self, description, characterLimitation, color=FONT_COLOR):
        length = len(description)
        if 0 == length:
            return

        lineCount = grpText.GetSplitingTextLineCount(description, characterLimitation)
        for i in xrange(lineCount):
            if 0 == i:
                self.AppendSpace(5)
            self.AppendTextLine(grpText.GetSplitingTextLine(description, characterLimitation, i), color)

    def __AppendDescription_WesternLanguage(self, desc, color=FONT_COLOR):
        lines = SplitDescription(desc, DESC_WESTERN_MAX_COLS)
        if not lines:
            return

        self.AppendSpace(5)
        for line in lines:
            self.AppendTextLine(line, color)
            

    def ResizeToolTip(self):
        self.SetSize(self.toolTipWidth, self.TOOL_TIP_HEIGHT + self.toolTipHeight)

    def SetTitle(self, name):
        self.AppendTextLine(name, self.TITLE_COLOR)

    def GetLimitTextLineColor(self, curValue, limitValue):
        if curValue < limitValue:
            return self.DISABLE_COLOR

        return self.ENABLE_COLOR

    def GetChangeTextLineColor(self, value, isSpecial=FALSE):
        if value > 0:
            if isSpecial:
                return self.SPECIAL_POSITIVE_COLOR
            else:
                return self.POSITIVE_COLOR

        if 0 == value:
            return self.NORMAL_COLOR

        return self.NEGATIVE_COLOR

    def SetToolTipPosition(self, x = -1, y = -1):
        self.xPos = x
        self.yPos = y

    def ShowToolTip(self):
        self.SetTop()
        self.Show()

        self.OnUpdate()

    def HideToolTip(self):
        self.Hide()

    def OnUpdate(self):

        if not self.followFlag:
            return

        x = 0
        y = 0
        width = self.GetWidth()
        height = self.toolTipHeight

        if -1 == self.xPos and -1 == self.yPos:

            (mouseX, mouseY) = wndMgr.GetMousePosition()

            if mouseY < wndMgr.GetScreenHeight() - 300:
                y = mouseY + 40
            else:
                y = mouseY - height - 30

            x = mouseX - width/2                

        else:

            x = self.xPos - width/2
            y = self.yPos - height

        x = max(x, 0)
        y = max(y, 0)
        x = min(x + width/2, wndMgr.GetScreenWidth() - width/2) - width/2
        y = min(y + self.GetHeight(), wndMgr.GetScreenHeight()) - self.GetHeight()

        parentWindow = self.GetParentProxy()
        if parentWindow:
            (gx, gy) = parentWindow.GetGlobalPosition()
            x -= gx
            y -= gy

        self.SetPosition(x, y)

class ItemToolTip(ToolTip):

    ModelPreviewBoard = None
    ModelPreview = None
    ModelPreviewText = None

    if app.ENABLE_SEND_TARGET_INFO:
        isStone = False
        isBook = False
        isBook2 = False

    CHARACTER_NAMES = ( 
        localeInfo.TOOLTIP_WARRIOR,
        localeInfo.TOOLTIP_ASSASSIN,
        localeInfo.TOOLTIP_SURA,
        localeInfo.TOOLTIP_SHAMAN,
#        localeInfo.TOOLTIP_WOLFMAN    
    )        

    CHARACTER_COUNT = len(CHARACTER_NAMES)
    WEAR_NAMES = ( 
        localeInfo.TOOLTIP_ARMOR, 
        localeInfo.TOOLTIP_HELMET, 
        localeInfo.TOOLTIP_SHOES, 
        localeInfo.TOOLTIP_WRISTLET, 
        localeInfo.TOOLTIP_WEAPON, 
        localeInfo.TOOLTIP_NECK,
        localeInfo.TOOLTIP_EAR,
        localeInfo.TOOLTIP_UNIQUE,
        localeInfo.TOOLTIP_SHIELD,
        localeInfo.TOOLTIP_ARROW,
    )
    WEAR_COUNT = len(WEAR_NAMES)

    AFFECT_DICT = {
        item.APPLY_MAX_HP : localeInfo.TOOLTIP_MAX_HP,
        item.APPLY_MAX_SP : localeInfo.TOOLTIP_MAX_SP,
        item.APPLY_CON : localeInfo.TOOLTIP_CON,
        item.APPLY_INT : localeInfo.TOOLTIP_INT,
        item.APPLY_STR : localeInfo.TOOLTIP_STR,
        item.APPLY_DEX : localeInfo.TOOLTIP_DEX,
        item.APPLY_ATT_SPEED : localeInfo.TOOLTIP_ATT_SPEED,
        item.APPLY_MOV_SPEED : localeInfo.TOOLTIP_MOV_SPEED,
        item.APPLY_CAST_SPEED : localeInfo.TOOLTIP_CAST_SPEED,
        item.APPLY_HP_REGEN : localeInfo.TOOLTIP_HP_REGEN,
        item.APPLY_SP_REGEN : localeInfo.TOOLTIP_SP_REGEN,
        item.APPLY_POISON_PCT : localeInfo.TOOLTIP_APPLY_POISON_PCT,
        item.APPLY_STUN_PCT : localeInfo.TOOLTIP_APPLY_STUN_PCT,
        item.APPLY_SLOW_PCT : localeInfo.TOOLTIP_APPLY_SLOW_PCT,
        item.APPLY_CRITICAL_PCT : localeInfo.TOOLTIP_APPLY_CRITICAL_PCT,
        item.APPLY_PENETRATE_PCT : localeInfo.TOOLTIP_APPLY_PENETRATE_PCT,

        item.APPLY_ATTBONUS_WARRIOR : localeInfo.TOOLTIP_APPLY_ATTBONUS_WARRIOR,
        item.APPLY_ATTBONUS_ASSASSIN : localeInfo.TOOLTIP_APPLY_ATTBONUS_ASSASSIN,
        item.APPLY_ATTBONUS_SURA : localeInfo.TOOLTIP_APPLY_ATTBONUS_SURA,
        item.APPLY_ATTBONUS_SHAMAN : localeInfo.TOOLTIP_APPLY_ATTBONUS_SHAMAN,
        item.APPLY_ATTBONUS_MONSTER : localeInfo.TOOLTIP_APPLY_ATTBONUS_MONSTER,

        item.APPLY_ATTBONUS_HUMAN : localeInfo.TOOLTIP_APPLY_ATTBONUS_HUMAN,
        item.APPLY_ATTBONUS_ANIMAL : localeInfo.TOOLTIP_APPLY_ATTBONUS_ANIMAL,
        item.APPLY_ATTBONUS_ORC : localeInfo.TOOLTIP_APPLY_ATTBONUS_ORC,
        item.APPLY_ATTBONUS_MILGYO : localeInfo.TOOLTIP_APPLY_ATTBONUS_MILGYO,
        item.APPLY_ATTBONUS_UNDEAD : localeInfo.TOOLTIP_APPLY_ATTBONUS_UNDEAD,
        item.APPLY_ATTBONUS_DEVIL : localeInfo.TOOLTIP_APPLY_ATTBONUS_DEVIL,
        item.APPLY_STEAL_HP : localeInfo.TOOLTIP_APPLY_STEAL_HP,
        item.APPLY_STEAL_SP : localeInfo.TOOLTIP_APPLY_STEAL_SP,
        item.APPLY_MANA_BURN_PCT : localeInfo.TOOLTIP_APPLY_MANA_BURN_PCT,
        item.APPLY_DAMAGE_SP_RECOVER : localeInfo.TOOLTIP_APPLY_DAMAGE_SP_RECOVER,
        item.APPLY_BLOCK : localeInfo.TOOLTIP_APPLY_BLOCK,
        item.APPLY_DODGE : localeInfo.TOOLTIP_APPLY_DODGE,
        item.APPLY_RESIST_SWORD : localeInfo.TOOLTIP_APPLY_RESIST_SWORD,
        item.APPLY_RESIST_TWOHAND : localeInfo.TOOLTIP_APPLY_RESIST_TWOHAND,
        item.APPLY_RESIST_DAGGER : localeInfo.TOOLTIP_APPLY_RESIST_DAGGER,
        item.APPLY_RESIST_BELL : localeInfo.TOOLTIP_APPLY_RESIST_BELL,
        item.APPLY_RESIST_FAN : localeInfo.TOOLTIP_APPLY_RESIST_FAN,
        item.APPLY_RESIST_BOW : localeInfo.TOOLTIP_RESIST_BOW,
        item.APPLY_RESIST_FIRE : localeInfo.TOOLTIP_RESIST_FIRE,
        item.APPLY_RESIST_ELEC : localeInfo.TOOLTIP_RESIST_ELEC,
        item.APPLY_RESIST_MAGIC : localeInfo.TOOLTIP_RESIST_MAGIC,
        item.APPLY_RESIST_WIND : localeInfo.TOOLTIP_APPLY_RESIST_WIND,
        item.APPLY_REFLECT_MELEE : localeInfo.TOOLTIP_APPLY_REFLECT_MELEE,
        item.APPLY_REFLECT_CURSE : localeInfo.TOOLTIP_APPLY_REFLECT_CURSE,
        item.APPLY_POISON_REDUCE : localeInfo.TOOLTIP_APPLY_POISON_REDUCE,
        item.APPLY_KILL_SP_RECOVER : localeInfo.TOOLTIP_APPLY_KILL_SP_RECOVER,
        item.APPLY_EXP_DOUBLE_BONUS : localeInfo.TOOLTIP_APPLY_EXP_DOUBLE_BONUS,
        item.APPLY_GOLD_DOUBLE_BONUS : localeInfo.TOOLTIP_APPLY_GOLD_DOUBLE_BONUS,
        item.APPLY_ITEM_DROP_BONUS : localeInfo.TOOLTIP_APPLY_ITEM_DROP_BONUS,
        item.APPLY_POTION_BONUS : localeInfo.TOOLTIP_APPLY_POTION_BONUS,
        item.APPLY_KILL_HP_RECOVER : localeInfo.TOOLTIP_APPLY_KILL_HP_RECOVER,
        item.APPLY_IMMUNE_STUN : localeInfo.TOOLTIP_APPLY_IMMUNE_STUN,
        item.APPLY_IMMUNE_SLOW : localeInfo.TOOLTIP_APPLY_IMMUNE_SLOW,
        item.APPLY_IMMUNE_FALL : localeInfo.TOOLTIP_APPLY_IMMUNE_FALL,
        item.APPLY_BOW_DISTANCE : localeInfo.TOOLTIP_BOW_DISTANCE,
        item.APPLY_DEF_GRADE_BONUS : localeInfo.TOOLTIP_DEF_GRADE,
        item.APPLY_ATT_GRADE_BONUS : localeInfo.TOOLTIP_ATT_GRADE,
        item.APPLY_MAGIC_ATT_GRADE : localeInfo.TOOLTIP_MAGIC_ATT_GRADE,
        item.APPLY_MAGIC_DEF_GRADE : localeInfo.TOOLTIP_MAGIC_DEF_GRADE,
        item.APPLY_MAX_STAMINA : localeInfo.TOOLTIP_MAX_STAMINA,
        item.APPLY_MALL_ATTBONUS : localeInfo.TOOLTIP_MALL_ATTBONUS,
        item.APPLY_MALL_DEFBONUS : localeInfo.TOOLTIP_MALL_DEFBONUS,
        item.APPLY_MALL_EXPBONUS : localeInfo.TOOLTIP_MALL_EXPBONUS,
        item.APPLY_MALL_ITEMBONUS : localeInfo.TOOLTIP_MALL_ITEMBONUS,
        item.APPLY_MALL_GOLDBONUS : localeInfo.TOOLTIP_MALL_GOLDBONUS,
        item.APPLY_SKILL_DAMAGE_BONUS : localeInfo.TOOLTIP_SKILL_DAMAGE_BONUS,
        item.APPLY_NORMAL_HIT_DAMAGE_BONUS : localeInfo.TOOLTIP_NORMAL_HIT_DAMAGE_BONUS,
        item.APPLY_SKILL_DEFEND_BONUS : localeInfo.TOOLTIP_SKILL_DEFEND_BONUS,
        item.APPLY_NORMAL_HIT_DEFEND_BONUS : localeInfo.TOOLTIP_NORMAL_HIT_DEFEND_BONUS,
        item.APPLY_PC_BANG_EXP_BONUS : localeInfo.TOOLTIP_MALL_EXPBONUS_P_STATIC,
        item.APPLY_PC_BANG_DROP_BONUS : localeInfo.TOOLTIP_MALL_ITEMBONUS_P_STATIC,
        item.APPLY_RESIST_WARRIOR : localeInfo.TOOLTIP_APPLY_RESIST_WARRIOR,
        item.APPLY_RESIST_ASSASSIN : localeInfo.TOOLTIP_APPLY_RESIST_ASSASSIN,
        item.APPLY_RESIST_SURA : localeInfo.TOOLTIP_APPLY_RESIST_SURA,
        item.APPLY_RESIST_SHAMAN : localeInfo.TOOLTIP_APPLY_RESIST_SHAMAN,
        item.APPLY_MAX_HP_PCT : localeInfo.TOOLTIP_APPLY_MAX_HP_PCT,
        item.APPLY_MAX_SP_PCT : localeInfo.TOOLTIP_APPLY_MAX_SP_PCT,
        item.APPLY_ENERGY : localeInfo.TOOLTIP_ENERGY,
        item.APPLY_COSTUME_ATTR_BONUS : localeInfo.TOOLTIP_COSTUME_ATTR_BONUS,

        item.APPLY_MAGIC_ATTBONUS_PER : localeInfo.TOOLTIP_MAGIC_ATTBONUS_PER,
        item.APPLY_MELEE_MAGIC_ATTBONUS_PER : localeInfo.TOOLTIP_MELEE_MAGIC_ATTBONUS_PER,
        item.APPLY_RESIST_ICE : localeInfo.TOOLTIP_RESIST_ICE,
        item.APPLY_RESIST_EARTH : localeInfo.TOOLTIP_RESIST_EARTH,
        item.APPLY_RESIST_DARK : localeInfo.TOOLTIP_RESIST_DARK,
        item.APPLY_ANTI_CRITICAL_PCT : localeInfo.TOOLTIP_ANTI_CRITICAL_PCT,
        item.APPLY_ANTI_PENETRATE_PCT : localeInfo.TOOLTIP_ANTI_PENETRATE_PCT,
        item.APPLY_BLEEDING_PCT : localeInfo.TOOLTIP_APPLY_BLEEDING_PCT,
        item.APPLY_BLEEDING_REDUCE : localeInfo.TOOLTIP_APPLY_BLEEDING_REDUCE,
        item.APPLY_ATTBONUS_WOLFMAN : localeInfo.TOOLTIP_APPLY_ATTBONUS_WOLFMAN,
        item.APPLY_RESIST_WOLFMAN : localeInfo.TOOLTIP_APPLY_RESIST_WOLFMAN,
        item.APPLY_RESIST_CLAW : localeInfo.TOOLTIP_APPLY_RESIST_CLAW,
    }

    if app.ENABLE_ANTI_RESIST_MAGIC_BONUS_SYSTEM:
        AFFECT_DICT.update({
            item.APPLY_ANTI_RESIST_MAGIC : localeInfo.APPLY_ANTI_RESIST_MAGIC,
        })

    ATTRIBUTE_NEED_WIDTH = {
        23 : 230,
        24 : 230,
        25 : 230,
        26 : 220,
        27 : 210,

        35 : 210,
        36 : 210,
        37 : 210,
        38 : 210,
        39 : 210,
        40 : 210,
        41 : 210,

        42 : 220,
        43 : 230,
        45 : 230,
    }

    ANTI_FLAG_DICT = {
        0 : item.ITEM_ANTIFLAG_WARRIOR,
        1 : item.ITEM_ANTIFLAG_ASSASSIN,
        2 : item.ITEM_ANTIFLAG_SURA,
        3 : item.ITEM_ANTIFLAG_SHAMAN,
        4 : item.ITEM_ANTIFLAG_WOLFMAN,
    }

    FONT_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0)

    def __init__(self, *args, **kwargs):
        ToolTip.__init__(self, *args, **kwargs)
        self.itemVnum = 0
        self.isShopItem = FALSE
        self.isOfflineShopItem = FALSE

        # ¾ÆÀÌÅÛ ÅøÆÁÀ» Ç¥½ÃÇÒ ¶§ ÇöÀç ij¸¯ÅÍ°¡ Âø¿ëÇÒ ¼ö ¾ø´Â ¾ÆÀÌÅÛÀ̶ó¸é °­Á¦·Î Disable Color·Î ¼³Á¤ (ÀÌ¹Ì ±×·¸°Ô ÀÛµ¿ÇÏ°í ÀÖÀ¸³ª ²¨¾ß ÇÒ ÇÊ¿ä°¡ À־)
        self.bCannotUseItemForceSetDisableColor = TRUE 

    def __del__(self):
        ToolTip.__del__(self)

    def SetCannotUseItemForceSetDisableColor(self, enable):
        self.bCannotUseItemForceSetDisableColor = enable

    def CanEquip(self):
        if not item.IsEquipmentVID(self.itemVnum):
            return TRUE

        race = player.GetRace()
        job = chr.RaceToJob(race)
        if not self.ANTI_FLAG_DICT.has_key(job):
            return FALSE

        if item.IsAntiFlag(self.ANTI_FLAG_DICT[job]):
            return FALSE

        sex = chr.RaceToSex(race)
        
        MALE = 1
        FEMALE = 0

        if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE) and sex == MALE:
            return FALSE

        if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE) and sex == FEMALE:
            return FALSE

        for i in xrange(item.LIMIT_MAX_NUM):
            (limitType, limitValue) = item.GetLimit(i)

            if item.LIMIT_LEVEL == limitType:
                if player.GetStatus(player.LEVEL) < limitValue:
                    return FALSE
            """
            elif item.LIMIT_STR == limitType:
                if player.GetStatus(player.ST) < limitValue:
                    return FALSE
            elif item.LIMIT_DEX == limitType:
                if player.GetStatus(player.DX) < limitValue:
                    return FALSE
            elif item.LIMIT_INT == limitType:
                if player.GetStatus(player.IQ) < limitValue:
                    return FALSE
            elif item.LIMIT_CON == limitType:
                if player.GetStatus(player.HT) < limitValue:
                    return FALSE
            """

        return TRUE

    def AppendTextLine(self, text, color = FONT_COLOR, centerAlign = TRUE):
        if not self.CanEquip() and self.bCannotUseItemForceSetDisableColor:
            color = self.DISABLE_COLOR

        return ToolTip.AppendTextLine(self, text, color, centerAlign)

    def ClearToolTip(self):
        self.isShopItem = FALSE
        self.isOfflineShopItem = FALSE
        self.toolTipWidth = self.TOOL_TIP_WIDTH
        ToolTip.ClearToolTip(self)

    def SetInventoryItem(self, slotIndex, window_type = player.INVENTORY):
        itemVnum = player.GetItemIndex(window_type, slotIndex)
        if 0 == itemVnum:
            return

        self.ClearToolTip()
        if shop.IsOpen():
            if not shop.IsPrivateShop() or not shop.IsOfflineShop():
                item.SelectItem(itemVnum)
                self.AppendSellingPrice(player.GetISellItemPrice(window_type, slotIndex)*5)

        metinSlot = [player.GetItemMetinSocket(window_type, slotIndex, i) for i in xrange(player.METIN_SOCKET_MAX_NUM)]
        attrSlot = [player.GetItemAttribute(window_type, slotIndex, i) for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM)]

        if app.ENABLE_CHANGELOOK_SYSTEM:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, slotIndex)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)
            # self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, slotIndex)
        # else:
            # self.AddItemData(itemVnum, metinSlot, attrSlot)
        self.__AppendSealInformation(player.INVENTORY, slotIndex)
        
    def SetOfflineShopBuilderItem(self, invenType, invenPos, offlineShopIndex):
        itemVnum = player.GetItemIndex(invenType, invenPos)
        if (itemVnum == 0):
            return

        self.ClearToolTip()
        item.SelectItem(itemVnum)
        #self.AppendSellingPrice(shop.GetOfflineShopItemPrice2(invenType, invenPos))

        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(player.GetItemMetinSocket(invenPos, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(player.GetItemAttribute(invenPos, i))
        
        if app.ENABLE_CHANGELOOK_SYSTEM:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0, invenType, invenPos)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0)
            
        price = shop.GetOfflineShopItemPrice2(invenType, invenPos)
            
        if app.ENABLE_CHEQUE_SYSTEM:
            price_cheque = shop.GetOfflineShopItemPriceCheque2(invenType, invenPos)
            price_yang = shop.GetOfflineShopItemPrice2(invenType, invenPos)
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.CHEQUE_SYSTEM_SELL_PRICE, grp.GenerateColor(255./255, 246./255, 78./255, 1.0))
            if price_cheque > 0:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.NumberToWonString(price_cheque), grp.GenerateColor(0./255, 215./255, 255./255, 1.0))
            if price_yang > 0:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
        else:
            self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
        
    def SetOfflineShopItem(self, slotIndex, addprice = 0, waltype = 0):
        itemVnum = shop.GetOfflineShopItemID(slotIndex)
        if (itemVnum == 0):
            return
            
        price = shop.GetOfflineShopItemPrice(slotIndex)
        if app.ENABLE_CHEQUE_SYSTEM:
            price_cheque = shop.GetOfflineShopItemPriceCheque(slotIndex)
            price_yang = shop.GetOfflineShopItemPrice(slotIndex)
        self.ClearToolTip()
        self.isOfflineShopItem = TRUE
        
        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(shop.GetOfflineShopItemMetinSocket(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(shop.GetOfflineShopItemAttribute(slotIndex, i))
            
        if app.ENABLE_CHANGELOOK_SYSTEM:
            transmutation = shop.GetOfflineShopItemTransmutation(slotIndex)
            if not transmutation:
                self.AddItemData(itemVnum, metinSlot, attrSlot)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)
        if waltype == 0:
            if app.ENABLE_CHEQUE_SYSTEM:
                if shop.IsOfflineShop():
                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.CHEQUE_SYSTEM_SELL_PRICE, grp.GenerateColor(255./255, 246./255, 78./255, 1.0))
                    if price_cheque > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToWonString(price_cheque), grp.GenerateColor(0./255, 215./255, 255./255, 1.0))
                    if price_yang > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
                else:
                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.CHEQUE_SYSTEM_SELL_PRICE, grp.GenerateColor(255./255, 246./255, 78./255, 1.0))
                    if price_cheque > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToWonString(price_cheque), grp.GenerateColor(0./255, 215./255, 255./255, 1.0))
                    if price_yang > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
            else:
                self.AppendPrice(price)
        else:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToMoneyString(addprice)[:-5]), self.SPECIAL_TITLE_COLOR)

    def SetInventoryItemAttrTransfer(self, slotIndex_1, slotIndex_2, window_type = player.INVENTORY):
        itemVnum = player.GetItemIndex(window_type, slotIndex_1)
        itemVnum_2 = player.GetItemIndex(window_type, slotIndex_2)
        if itemVnum == 0 or itemVnum_2 == 0:
            return
        
        self.ClearToolTip()
        if shop.IsOpen():
            if not shop.IsPrivateShop() or not shop.IsOfflineShop():
                item.SelectItem(itemVnum)
                self.AppendSellingPrice(player.GetISellItemPrice(window_type, slotIndex_2))
        
        metinSlot = [player.GetItemMetinSocket(window_type, slotIndex_2, i) for i in xrange(player.METIN_SOCKET_MAX_NUM)]
        attrSlot = [player.GetItemAttribute(window_type, slotIndex_2, i) for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM)]
        self.AddItemDataAttrTransfer(itemVnum, itemVnum_2, metinSlot, attrSlot, 0, 0, window_type, slotIndex_2)

    def AddItemDataAttrTransfer(self, itemVnum, itemVnum_2, metinSlot, attrSlot = 0, flags = 0, unbindTime = 0, window_type = player.INVENTORY, slotIndex = -1):
        self.itemVnum = itemVnum
        item.SelectItem(itemVnum)
        itemType = item.GetItemType()
        itemSubType = item.GetItemSubType()
        itemDesc = item.GetItemDescription()
        itemSummary = item.GetItemSummary()
        
        self.__AdjustMaxWidth(attrSlot, itemDesc)
        self.__SetItemTitle(itemVnum, metinSlot, attrSlot)
        self.AppendDescription(itemDesc, 26)
        self.AppendDescription(itemSummary, 26, self.CONDITION_COLOR)
        self.__AppendLimitInformation()
        self.__AppendAffectInformation()
        
        item.SelectItem(itemVnum_2)
        self.__AppendAttributeInformation(attrSlot)
        
        item.SelectItem(itemVnum)
        self.AppendWearableInformation()
        bHasRealtimeFlag = 0
        for i in xrange(item.LIMIT_MAX_NUM):
            (limitType, limitValue) = item.GetLimit(i)
            if item.LIMIT_REAL_TIME == limitType:
                bHasRealtimeFlag = 1
        
        if 1 == bHasRealtimeFlag:
            self.AppendMallItemLastTime(metinSlot[0])
        
        self.ShowToolTip()

    def SetShopItem(self, slotIndex, addprice = 0, waltype = 0):
        import localeInfo
        itemVnum = shop.GetItemID(slotIndex)
        if 0 == itemVnum:
            return

        price = shop.GetItemPrice(slotIndex)
        if app.ENABLE_CHEQUE_SYSTEM:
            price_cheque = shop.GetItemPriceCheque(slotIndex)
            price_yang = shop.GetItemPrice(slotIndex)
        self.ClearToolTip()
        self.isShopItem = True
        item.SelectItem(itemVnum)
        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(shop.GetItemMetinSocket(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(shop.GetItemAttribute(slotIndex, i)) 
        if app.ENABLE_CHANGELOOK_SYSTEM:
            transmutation = shop.GetItemTransmutation(slotIndex)
            if not transmutation:
                self.AddItemData(itemVnum, metinSlot, attrSlot)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)
        if waltype == 0:
            if app.ENABLE_CHEQUE_SYSTEM and app.ENABLE_SHOP_SISTEM:
                if shop.IsPrivateShop():
                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.CHEQUE_SYSTEM_SELL_PRICE, grp.GenerateColor(255./255, 246./255, 78./255, 1.0))
                    if price_cheque > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToWonString(price_cheque), grp.GenerateColor(0./255, 215./255, 255./255, 1.0))
                    if price_yang > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
                else:
                    if item.IsAntiFlag(item.ANTIFLAG_SHOP_SECONDARY):
                        self.miktar(price)
                    elif item.IsAntiFlag(item.ANTIFLAG_SHOP_TRIPLE):
                        self.miktar2(price)
                    else:
                        if item.IsAntiFlag(item.ANTIFLAG_SHOP_SECONDARY):
                            self.miktar(price)
                        elif item.IsAntiFlag(item.ANTIFLAG_SHOP_TRIPLE):
                            self.miktar2(price)
                        else:
                            self.AppendPrice(price)
        else:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToMoneyString(addprice)[:-5]), self.SPECIAL_TITLE_COLOR)

    def SetShopItemBySecondaryCoin(self, slotIndex):
        itemVnum = shop.GetItemID(slotIndex)
        if 0 == itemVnum:
            return

        price = shop.GetItemPrice(slotIndex)
        self.ClearToolTip()
        self.isShopItem = TRUE

        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(shop.GetItemMetinSocket(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(shop.GetItemAttribute(slotIndex, i))

        if app.ENABLE_CHANGELOOK_SYSTEM:
            transmutation = shop.GetItemTransmutation(slotIndex)
            if not transmutation:
                self.AddItemData(itemVnum, metinSlot, attrSlot)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)
        self.AppendPriceBySecondaryCoin(price)

    def SetExchangeOwnerItem(self, slotIndex):
        itemVnum = exchange.GetItemVnumFromSelf(slotIndex)
        if 0 == itemVnum:
            return

        self.ClearToolTip()

        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(exchange.GetItemMetinSocketFromSelf(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(exchange.GetItemAttributeFromSelf(slotIndex, i))
        if app.ENABLE_CHANGELOOK_SYSTEM:
            transmutation = exchange.GetItemTransmutation(slotIndex, True)
            if not transmutation:
                self.AddItemData(itemVnum, metinSlot, attrSlot)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)

    def SetExchangeTargetItem(self, slotIndex):
        itemVnum = exchange.GetItemVnumFromTarget(slotIndex)
        if 0 == itemVnum:
            return

        self.ClearToolTip()

        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(exchange.GetItemMetinSocketFromTarget(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(exchange.GetItemAttributeFromTarget(slotIndex, i))
        if app.ENABLE_CHANGELOOK_SYSTEM:
            transmutation = exchange.GetItemTransmutation(slotIndex, False)
            if not transmutation:
                self.AddItemData(itemVnum, metinSlot, attrSlot)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)

    def SetPrivateShopBuilderItem(self, invenType, invenPos, privateShopSlotIndex):
        itemVnum = player.GetItemIndex(invenType, invenPos)
        if 0 == itemVnum:
            return

        item.SelectItem(itemVnum)
        self.ClearToolTip()

        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(player.GetItemMetinSocket(invenPos, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(player.GetItemAttribute(invenPos, i))

        if app.ENABLE_CHANGELOOK_SYSTEM:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0, invenType, invenPos)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0)

        price = shop.GetPrivateShopItemPrice(invenType, invenPos)

        if app.ENABLE_CHEQUE_SYSTEM:
            price_cheque = shop.GetPrivateShopItemPriceCheque(invenType, invenPos)
            price_yang = shop.GetPrivateShopItemPrice(invenType, invenPos)
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.CHEQUE_SYSTEM_SELL_PRICE, grp.GenerateColor(255./255, 246./255, 78./255, 1.0))
            if price_cheque > 0:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.NumberToWonString(price_cheque), grp.GenerateColor(0./255, 215./255, 255./255, 1.0))
            if price_yang > 0:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))
        else:
            self.AppendTextLine(localeInfo.NumberToGoldString(price), self.GetPriceColor(price))

    def SetSafeBoxItem(self, slotIndex):
        itemVnum = safebox.GetItemID(slotIndex)
        if 0 == itemVnum:
            return

        self.ClearToolTip()
        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(safebox.GetItemMetinSocket(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(safebox.GetItemAttribute(slotIndex, i))
        
        if app.ENABLE_CHANGELOOK_SYSTEM:
            self.AddItemData(itemVnum, metinSlot, attrSlot, safebox.GetItemFlags(slotIndex), player.SAFEBOX, slotIndex)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot, safebox.GetItemFlags(slotIndex))
        self.__AppendSealInformation(player.SAFEBOX, slotIndex)

    def SetMallItem(self, slotIndex):
        itemVnum = safebox.GetMallItemID(slotIndex)
        if 0 == itemVnum:
            return

        self.ClearToolTip()
        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(safebox.GetMallItemMetinSocket(slotIndex, i))
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append(safebox.GetMallItemAttribute(slotIndex, i))

        if app.ENABLE_CHANGELOOK_SYSTEM:
            self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.MALL, slotIndex)
        else:
            self.AddItemData(itemVnum, metinSlot, attrSlot)
        self.__AppendSealInformation(player.MALL, slotIndex)

    def SetItemToolTip(self, itemVnum):
        self.ClearToolTip()
        metinSlot = []
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlot.append(0)
        attrSlot = []
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            attrSlot.append((0, 0))

        self.AddItemData(itemVnum, metinSlot, attrSlot)

    if app.ENABLE_SEND_TARGET_INFO:
        def SetItemToolTipStone(self, itemVnum):
            self.itemVnum = itemVnum
            item.SelectItem(itemVnum)
            itemType = item.GetItemType()

            itemDesc = item.GetItemDescription()
            itemSummary = item.GetItemSummary()
            attrSlot = 0
            self.__AdjustMaxWidth(attrSlot, itemDesc)
            itemName = item.GetItemName()
            realName = itemName[:itemName.find("+")]
            self.SetTitle(realName + " +0 - +4")

            ## Description ###
            self.AppendDescription(itemDesc, 26)
            self.AppendDescription(itemSummary, 26, self.CONDITION_COLOR)

            if item.ITEM_TYPE_METIN == itemType:
                self.AppendMetinInformation()
                self.AppendMetinWearInformation()

            for i in xrange(item.LIMIT_MAX_NUM):
                (limitType, limitValue) = item.GetLimit(i)

                if item.LIMIT_REAL_TIME_START_FIRST_USE == limitType:
                    self.AppendRealTimeStartFirstUseLastTime(item, metinSlot, i)

                elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType:
                    self.AppendTimerBasedOnWearLastTime(metinSlot)

            self.ShowToolTip()

    def __AppendAttackSpeedInfo(self, item):
        atkSpd = item.GetValue(0)

        if atkSpd < 80:
            stSpd = localeInfo.TOOLTIP_ITEM_VERY_FAST
        elif atkSpd <= 95:
            stSpd = localeInfo.TOOLTIP_ITEM_FAST
        elif atkSpd <= 105:
            stSpd = localeInfo.TOOLTIP_ITEM_NORMAL
        elif atkSpd <= 120:
            stSpd = localeInfo.TOOLTIP_ITEM_SLOW
        else:
            stSpd = localeInfo.TOOLTIP_ITEM_VERY_SLOW

        self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_SPEED % stSpd, self.NORMAL_COLOR)

    def __AppendAttackGradeInfo(self):
        atkGrade = item.GetValue(1)
        self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_GRADE % atkGrade, self.GetChangeTextLineColor(atkGrade))

    if app.ENABLE_SASH_SYSTEM:
        def CalcSashValue(self, value, abs):
            if not value:
                return 0
            
            valueCalc = int((round(value * abs) / 100) - .5) + int(int((round(value * abs) / 100) - .5) > 0)
            if valueCalc <= 0 and value > 0:
                value = 1
            else:
                value = valueCalc
            
            return value

    def __AppendAttackPowerInfo(self, itemAbsChance = 0):
        minPower = item.GetValue(3)
        maxPower = item.GetValue(4)
        addPower = item.GetValue(5)
        
        if app.ENABLE_SASH_SYSTEM:
            if itemAbsChance:
                minPower = self.CalcSashValue(minPower, itemAbsChance)
                maxPower = self.CalcSashValue(maxPower, itemAbsChance)
                addPower = self.CalcSashValue(addPower, itemAbsChance)
        
        if maxPower > minPower:
            self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_POWER % (minPower + addPower, maxPower + addPower), self.POSITIVE_COLOR)
        else:
            self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_POWER_ONE_ARG % (minPower + addPower), self.POSITIVE_COLOR)

    def __AppendMagicAttackInfo(self, itemAbsChance = 0):
        minMagicAttackPower = item.GetValue(1)
        maxMagicAttackPower = item.GetValue(2)
        addPower = item.GetValue(5)
        
        if app.ENABLE_SASH_SYSTEM:
            if itemAbsChance:
                minMagicAttackPower = self.CalcSashValue(minMagicAttackPower, itemAbsChance)
                maxMagicAttackPower = self.CalcSashValue(maxMagicAttackPower, itemAbsChance)
                addPower = self.CalcSashValue(addPower, itemAbsChance)
        
        if minMagicAttackPower > 0 or maxMagicAttackPower > 0:
            if maxMagicAttackPower > minMagicAttackPower:
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER % (minMagicAttackPower + addPower, maxMagicAttackPower + addPower), self.POSITIVE_COLOR)
            else:
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER_ONE_ARG % (minMagicAttackPower + addPower), self.POSITIVE_COLOR)

    def __AppendMagicDefenceInfo(self, itemAbsChance = 0):
        magicDefencePower = item.GetValue(0)
        
        if app.ENABLE_SASH_SYSTEM:
            if itemAbsChance:
                magicDefencePower = self.CalcSashValue(magicDefencePower, itemAbsChance)
        
        if magicDefencePower > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_DEF_POWER % magicDefencePower, self.GetChangeTextLineColor(magicDefencePower))

    def __AppendAttributeInformation(self, attrSlot, itemAbsChance = 0):
        if 0 != attrSlot:
            for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
                type = attrSlot[0]
                value = attrSlot[1]
                if 0 == value:
                    continue
                
                affectString = self.__GetAffectString(type, value)
                if app.ENABLE_SASH_SYSTEM:
                    if item.GetItemType() == item.ITEM_TYPE_COSTUME and item.GetItemSubType() == item.COSTUME_TYPE_SASH and itemAbsChance:
                        value = self.CalcSashValue(value, itemAbsChance)
                        affectString = self.__GetAffectString(type, value)
                
                if affectString:
                    affectColor = self.__GetAttributeColor(i, value)
                    self.AppendTextLine(affectString, affectColor)

    def __GetAttributeColor(self, index, value):
        if value > 0:
            if index >= 5:
                return self.SPECIAL_POSITIVE_COLOR2
            else:
                return self.SPECIAL_POSITIVE_COLOR
        elif value == 0:
            return self.NORMAL_COLOR
        else:
            return self.NEGATIVE_COLOR

    def __IsPolymorphItem(self, itemVnum):
        if itemVnum >= 70103 and itemVnum <= 70106:
            return 1
        return 0

    def __SetPolymorphItemTitle(self, monsterVnum):
        if localeInfo.IsVIETNAM():
            itemName =item.GetItemName()
            itemName+=" "
            itemName+=nonplayer.GetMonsterName(monsterVnum)
        else:
            itemName =nonplayer.GetMonsterName(monsterVnum)
            itemName+=" "
            itemName+=item.GetItemName()
        self.SetTitle(itemName)

    def __SetNormalItemTitle(self):
        if app.ENABLE_SEND_TARGET_INFO:
            if self.isStone:
                itemName = item.GetItemName()
                realName = itemName[:itemName.find("+")]
                self.SetTitle(realName + " +0 - +4")
            else:
                self.SetTitle(item.GetItemName())
        else:
            self.SetTitle(item.GetItemName())

    def __SetSpecialItemTitle(self):
        self.AppendTextLine(item.GetItemName(), self.SPECIAL_TITLE_COLOR)

    def __SetItemTitle(self, itemVnum, metinSlot, attrSlot):
        if localeInfo.IsCANADA():
            if 72726 == itemVnum or 72730 == itemVnum:
                self.AppendTextLine(item.GetItemName(), grp.GenerateColor(1.0, 0.7843, 0.0, 1.0))
                return
            
        if self.__IsPolymorphItem(itemVnum):
            self.__SetPolymorphItemTitle(metinSlot[0])
        else:
            if self.__IsAttr(attrSlot):
                self.__SetSpecialItemTitle()
                return

            self.__SetNormalItemTitle()

    def __IsAttr(self, attrSlot):
        if not attrSlot:
            return FALSE

        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            type = attrSlot[0]
            if 0 != type:
                return TRUE

        return FALSE
    
    def AddRefineItemData(self, itemVnum, metinSlot, attrSlot = 0):
        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlotData=metinSlot
            if self.GetMetinItemIndex(metinSlotData) == constInfo.ERROR_METIN_STONE:
                metinSlot=player.METIN_SOCKET_TYPE_SILVER

        self.AddItemData(itemVnum, metinSlot, attrSlot)

    def AddItemData_Offline(self, itemVnum, itemDesc, itemSummary, metinSlot, attrSlot):
        self.__AdjustMaxWidth(attrSlot, itemDesc)
        self.__SetItemTitle(itemVnum, metinSlot, attrSlot)
        
        if self.__IsHair(itemVnum):    
            self.__AppendHairIcon(itemVnum)

        ### Description ###
        self.AppendDescription(itemDesc, 26)
        self.AppendDescription(itemSummary, 26, self.CONDITION_COLOR)

    def check_sigillo(self, item_vnum):
        for x in range(55701,55707):
            if x == item_vnum:
                return TRUE
        if item_vnum == 55801:
            return TRUE
        return FALSE

    def AddItemData(self, itemVnum, metinSlot, attrSlot = 0, flags = 0, window_type = player.INVENTORY, slotIndex = -1, transmutation = -1):
        self.itemVnum = itemVnum
        item.SelectItem(itemVnum)
        itemType = item.GetItemType()
        itemSubType = item.GetItemSubType()

        if 50026 == itemVnum:
            if 0 != metinSlot:
                name = item.GetItemName()
                if metinSlot[0] > 0:
                    name += " "
                    name += localeInfo.NumberToMoneyString(metinSlot[0])
                self.SetTitle(name)

                self.ShowToolTip()
            return

        ### Skill Book ###
        if app.ENABLE_SEND_TARGET_INFO:
            if 50300 == itemVnum and not self.isBook:
                if 0 != metinSlot and not self.isBook:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILLBOOK_NAME, 1)
                    self.ShowToolTip()
                elif self.isBook:
                    self.SetTitle(item.GetItemName())
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()                    
                return
            elif 70037 == itemVnum :
                if 0 != metinSlot and not self.isBook2:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0)
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()
                elif self.isBook2:
                    self.SetTitle(item.GetItemName())
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()                    
                return
            elif 70055 == itemVnum:
                if 0 != metinSlot:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0)
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()
                return
        else:
            if 50300 == itemVnum:
                if 0 != metinSlot:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILLBOOK_NAME, 1)
                    self.ShowToolTip()
                return
            elif 70037 == itemVnum:
                if 0 != metinSlot:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0)
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()
                return
            elif 70055 == itemVnum:
                if 0 != metinSlot:
                    self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0)
                    self.AppendDescription(item.GetItemDescription(), 26)
                    self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
                    self.ShowToolTip()
                return
        ###########################################################################################


        itemDesc = item.GetItemDescription()
        itemSummary = item.GetItemSummary()

        isCostumeItem = 0
        isCostumeHair = 0
        isCostumeBody = 0
        isCostumeMount = 0
        if app.ENABLE_SASH_SYSTEM:
            isCostumeSash = 0
        if app.ENABLE_COSTUME_WEAPON_SYSTEM:
            isCostumeWeapon = 0
            
        if app.ENABLE_COSTUME_SYSTEM:
            if item.ITEM_TYPE_COSTUME == itemType:
                isCostumeItem = 1
                isCostumeHair = item.COSTUME_TYPE_HAIR == itemSubType
                isCostumeBody = item.COSTUME_TYPE_BODY == itemSubType
                isCostumeMount = item.COSTUME_SLOT_MOUNT == itemSubType
            if app.ENABLE_SASH_SYSTEM:
                isCostumeSash = itemSubType == item.COSTUME_TYPE_SASH
            if app.ENABLE_COSTUME_WEAPON_SYSTEM:
                isCostumeWeapon = item.COSTUME_TYPE_WEAPON == itemSubType

                #dbg.TraceError("IS_COSTUME_ITEM! body(%d) hair(%d)" % (isCostumeBody, isCostumeHair))
                

        self.__AdjustMaxWidth(attrSlot, itemDesc)
        self.__SetItemTitle(itemVnum, metinSlot, attrSlot)
        self.__ModelPreviewClose()
        
        ### Hair Preview Image ###
        if self.__IsHair(itemVnum):    
            self.__AppendHairIcon(itemVnum)

        ### Description ###
        self.AppendDescription(itemDesc, 26)
        self.AppendDescription(itemSummary, 26, self.CONDITION_COLOR)

        if self.check_sigillo(itemVnum) or itemVnum == 55002:
            if attrSlot[0][1] != 0:
                self.AppendSpace(2)
                blackyas = (int(attrSlot[5][1])/60)/24
                petevobl = (int(attrSlot[6][1]))
                self.AppendTextLine("|cffffffffLivello: "+str(metinSlot[1]) + " (" + str(blackyas) + localeInfo.DAY + ")", self.NORMAL_COLOR)
                if (str(petevobl)) == "0":
                    self.AppendTextLine(localeInfo.PET_TEXTT_7, grp.GenerateColor(0, 78, 0, 1))
                elif (str(petevobl)) == "1":
                    self.AppendTextLine(localeInfo.PET_SYSTEM_EVO2, grp.GenerateColor(0, 78, 0, 1))
                elif (str(petevobl)) == "2":
                    self.AppendTextLine(localeInfo.PET_SYSTEM_EVO3, grp.GenerateColor(0, 78, 0, 1))
                elif (str(petevobl)) == "3":
                    self.AppendTextLine(localeInfo.PET_SYSTEM_EVO4, grp.GenerateColor(0, 78, 0, 1))
                self.AppendSpace(2)
                self.AppendTextLine("Hp: +"+pointop(str(attrSlot[0][1]))+"%", self.SPECIAL_POSITIVE_COLOR)
                self.AppendTextLine("Difesa: +"+pointop(str(attrSlot[1][1]))+"%", self.SPECIAL_POSITIVE_COLOR)
                self.AppendTextLine("Mp: +"+pointop(str(attrSlot[2][1]))+"%", self.SPECIAL_POSITIVE_COLOR)
                self.AppendSpace(5)
                if itemVnum != 55002:
                    days = (int(attrSlot[3][1])/60)/24
                    hours = (int(attrSlot[3][1]) - (days*60*24)) / 60
                    mins = int(attrSlot[3][1]) - (days*60*24) - (hours*60)
                    self.AppendTextLine(localeInfo.PET_TEXTT_1 % (days, hours, mins), self.SPECIAL_POSITIVE_COLOR)

        ### Weapon ###
        if item.ITEM_TYPE_WEAPON == itemType:
            self.__AppendLimitInformation()        
            self.AppendSpace(5)
            if item.WEAPON_FAN == itemSubType:
                self.__AppendMagicAttackInfo()
                self.__AppendAttackPowerInfo()
            else:
                self.__AppendAttackPowerInfo()
                self.__AppendMagicAttackInfo()
            
            self.__AppendAffectInformation()
            self.__AppendAttributeInformation(attrSlot)
            if app.ENABLE_CHANGELOOK_SYSTEM:
                self.AppendTransmutation(window_type, slotIndex, transmutation)

            self.AppendWearableInformation()
            bHasRealtimeFlag = 0
            for i in xrange(item.LIMIT_MAX_NUM):
                (limitType, limitValue) = item.GetLimit(i)
                if item.LIMIT_REAL_TIME == limitType:
                    bHasRealtimeFlag = 1
                    
            if bHasRealtimeFlag == 1:
                self.AppendMallItemLastTime(metinSlot[0])
            else:
                self.__AppendMetinSlotInfo(metinSlot)

        ### Armor ###
        elif item.ITEM_TYPE_ARMOR == itemType:
            self.__AppendLimitInformation()

            ## ¹æ¾î·Â
            defGrade = item.GetValue(1)
            defBonus = item.GetValue(5)*2 ## ¹æ¾î·Â Ç¥½Ã À߸ø µÇ´Â ¹®Á¦¸¦ ¼öÁ¤
            if defGrade > 0:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade+defBonus), self.GetChangeTextLineColor(defGrade))

            self.__AppendMagicDefenceInfo()
            self.__AppendAffectInformation()
            self.__AppendAttributeInformation(attrSlot)
            if app.ENABLE_CHANGELOOK_SYSTEM:
                self.AppendTransmutation(window_type, slotIndex, transmutation)

            self.AppendWearableInformation()

            if itemSubType in (item.ARMOR_WRIST, item.ARMOR_NECK, item.ARMOR_EAR):                
                self.__AppendAccessoryMetinSlotInfo(metinSlot, constInfo.GET_ACCESSORY_MATERIAL_VNUM(itemVnum, itemSubType))
            else:
                self.__AppendMetinSlotInfo(metinSlot)

        ### Ring Slot Item (Not UNIQUE) ###
        elif item.ITEM_TYPE_RING == itemType:
            self.__AppendLimitInformation()
            self.__AppendAffectInformation()
            self.__AppendAttributeInformation(attrSlot)

            #¹ÝÁö ¼ÒÄÏ ½Ã½ºÅÛ °ü·ÃÇؼ± ¾ÆÁ÷ ±âȹ ¹ÌÁ¤
            #self.__AppendAccessoryMetinSlotInfo(metinSlot, 99001)
            bHasRealtimeFlag = 0
            for i in xrange(item.LIMIT_MAX_NUM):
                (limitType, limitValue) = item.GetLimit(i)
                if item.LIMIT_REAL_TIME == limitType:
                    bHasRealtimeFlag = 1
            
            if bHasRealtimeFlag == 1:
                self.AppendMallItemLastTime(metinSlot[0])            

        ### Belt Item ###
        elif item.ITEM_TYPE_BELT == itemType:
            self.__AppendLimitInformation()
            self.__AppendAffectInformation()
            self.__AppendAttributeInformation(attrSlot)
            self.AppendTextLine("Slot inseribili : %s " % EXTRA_SLOT[item.GetValue(0)], self.SPECIAL_POSITIVE_COLOR)

            self.__AppendAccessoryMetinSlotInfo(metinSlot, constInfo.GET_BELT_MATERIAL_VNUM(itemVnum))

        ## ÄÚ½ºÃõ ¾ÆÀÌÅÛ ##
        elif 0 != isCostumeItem:
            self.__AppendLimitInformation()
            
            if itemSubType != item.COSTUME_SLOT_MOUNT:
                PetVnum = item.GetValue(0)

                if PetVnum != 0:
                    self.__ModelPreview(PetVnum)

            if itemSubType == item.COSTUME_SLOT_MOUNT:
                MountVnum = item.GetValue(4)
                if MountVnum != 0:
                    self.__ModelPreview(MountVnum)
            
            if app.ENABLE_SASH_SYSTEM:
                if isCostumeSash:
                    ## ABSORPTION RATE
                    absChance = int(metinSlot[sash.ABSORPTION_SOCKET])
                    self.AppendTextLine(localeInfo.SASH_ABSORB_CHANCE % (absChance), self.CONDITION_COLOR)
                    ## END ABSOPRTION RATE
                    
                    itemAbsorbedVnum = int(metinSlot[sash.ABSORBED_SOCKET])
                    if itemAbsorbedVnum:
                        ## ATTACK / DEFENCE
                        item.SelectItem(itemAbsorbedVnum)
                        if item.GetItemType() == item.ITEM_TYPE_WEAPON:
                            if item.GetItemSubType() == item.WEAPON_FAN:
                                self.__AppendMagicAttackInfo(metinSlot[sash.ABSORPTION_SOCKET])
                                item.SelectItem(itemAbsorbedVnum)
                                self.__AppendAttackPowerInfo(metinSlot[sash.ABSORPTION_SOCKET])
                            else:
                                self.__AppendAttackPowerInfo(metinSlot[sash.ABSORPTION_SOCKET])
                                item.SelectItem(itemAbsorbedVnum)
                                self.__AppendMagicAttackInfo(metinSlot[sash.ABSORPTION_SOCKET])
                        elif item.GetItemType() == item.ITEM_TYPE_ARMOR:
                            defGrade = item.GetValue(1)
                            defBonus = item.GetValue(5) * 2
                            defGrade = self.CalcSashValue(defGrade, metinSlot[sash.ABSORPTION_SOCKET])
                            defBonus = self.CalcSashValue(defBonus, metinSlot[sash.ABSORPTION_SOCKET])
                            
                            if defGrade > 0:
                                self.AppendSpace(5)
                                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade + defBonus), self.GetChangeTextLineColor(defGrade))
                            
                            item.SelectItem(itemAbsorbedVnum)
                            self.__AppendMagicDefenceInfo(metinSlot[sash.ABSORPTION_SOCKET])
                        ## END ATTACK / DEFENCE
                        
                        ## EFFECT
                        item.SelectItem(itemAbsorbedVnum)
                        for i in xrange(item.ITEM_APPLY_MAX_NUM):
                            (affectType, affectValue) = item.GetAffect(i)
                            affectValue = self.CalcSashValue(affectValue, metinSlot[sash.ABSORPTION_SOCKET])
                            affectString = self.__GetAffectString(affectType, affectValue)
                            if affectString and affectValue > 0:
                                self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue))
                            
                            item.SelectItem(itemAbsorbedVnum)
                        # END EFFECT
                        
                        item.SelectItem(itemVnum)
                        ## ATTR
                        self.__AppendAttributeInformation(attrSlot, metinSlot[sash.ABSORPTION_SOCKET])
                        # END ATTR
                    else:
                        # ATTR
                        self.__AppendAttributeInformation(attrSlot)
                        # END ATTR
                else:
                    self.__AppendAffectInformation()
                    self.__AppendAttributeInformation(attrSlot)
            else:
                self.__AppendAffectInformation()
                self.__AppendAttributeInformation(attrSlot)
            if app.ENABLE_CHANGELOOK_SYSTEM:
                self.AppendTransmutation(window_type, slotIndex, transmutation)
            self.AppendWearableInformation()
            bHasRealtimeFlag = 0
            for i in xrange(item.LIMIT_MAX_NUM):
                (limitType, limitValue) = item.GetLimit(i)
                if item.LIMIT_REAL_TIME == limitType:
                    bHasRealtimeFlag = 1
            
            if bHasRealtimeFlag == 1:
                self.AppendMallItemLastTime(metinSlot[0])

                
        ## Rod ##
        elif item.ITEM_TYPE_ROD == itemType:

            if 0 != metinSlot:
                curLevel = item.GetValue(0) / 10
                curEXP = metinSlot[0]
                maxEXP = item.GetValue(2)
                self.__AppendLimitInformation()
                self.__AppendRodInformation(curLevel, curEXP, maxEXP)

        ## Pick ##
        elif item.ITEM_TYPE_PICK == itemType:

            if 0 != metinSlot:
                curLevel = item.GetValue(0) / 10
                curEXP = metinSlot[0]
                maxEXP = item.GetValue(2)
                self.__AppendLimitInformation()
                self.__AppendPickInformation(curLevel, curEXP, maxEXP)

        ## Lottery ##
        elif item.ITEM_TYPE_LOTTERY == itemType:
            if 0 != metinSlot:

                ticketNumber = int(metinSlot[0])
                stepNumber = int(metinSlot[1])

                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_LOTTERY_STEP_NUMBER % (stepNumber), self.NORMAL_COLOR)
                self.AppendTextLine(localeInfo.TOOLTIP_LOTTO_NUMBER % (ticketNumber), self.NORMAL_COLOR);

        ### Metin ###
        elif item.ITEM_TYPE_METIN == itemType:
            self.AppendMetinInformation()
            self.AppendMetinWearInformation()

        ### Fish ###
        elif item.ITEM_TYPE_FISH == itemType:
            if 0 != metinSlot:
                self.__AppendFishInfo(metinSlot[0])
        
        ## item.ITEM_TYPE_BLEND
        elif item.ITEM_TYPE_BLEND == itemType:
            self.__AppendLimitInformation()

            if metinSlot:
                affectType = metinSlot[0]
                affectValue = metinSlot[1]
                time = metinSlot[2]
                self.AppendSpace(5)
                affectText = self.__GetAffectString(affectType, affectValue)

                self.AppendTextLine(affectText, self.NORMAL_COLOR)

                if time >= 0:
                    minute = (time / 60)
                    second = (time % 60)
                    timeString = localeInfo.TOOLTIP_POTION_TIME

                    if minute >= 0:
                        timeString += str(minute) + localeInfo.TOOLTIP_POTION_MIN
                    if second >= 0:
                        timeString += " " + str(second) + localeInfo.TOOLTIP_POTION_SEC

                    self.AppendTextLine(timeString)
                else:
                    self.AppendTextLine(localeInfo.BLEND_POTION_NO_TIME)
            else:
                self.AppendTextLine("BLEND_POTION_NO_INFO")

        elif item.ITEM_TYPE_UNIQUE == itemType:
            if 0 != metinSlot:
                bHasRealtimeFlag = 0
                
                for i in xrange(item.LIMIT_MAX_NUM):
                    (limitType, limitValue) = item.GetLimit(i)

                    if item.LIMIT_REAL_TIME == limitType:
                        bHasRealtimeFlag = 1
                
                if 1 == bHasRealtimeFlag:
                    self.AppendMallItemLastTime(metinSlot[0])        
                else:
                    time = metinSlot[player.METIN_SOCKET_MAX_NUM-1]

                    if 1 == item.GetValue(2): ## ½Ç½Ã°£ ÀÌ¿ë Flag / ÀåÂø ¾ÈÇصµ ÁØ´Ù
                        self.AppendMallItemLastTime(time)
                    else:
                        self.AppendUniqueItemLastTime(time)

        ### Use ###
        elif item.ITEM_TYPE_USE == itemType:
            self.__AppendLimitInformation()

            if item.USE_POTION == itemSubType or item.USE_POTION_NODELAY == itemSubType:
                self.__AppendPotionInformation()

            elif item.USE_ABILITY_UP == itemSubType:
                self.__AppendAbilityPotionInformation()


            ## ¿µ¼® °¨Áö±â
            if 27989 == itemVnum or 76006 == itemVnum:
                if 0 != metinSlot:
                    useCount = int(metinSlot[0])

                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.TOOLTIP_REST_USABLE_COUNT % (200 - useCount), self.NORMAL_COLOR)

            ## À̺¥Æ® °¨Áö±â
            elif 50004 == itemVnum:
                if 0 != metinSlot:
                    useCount = int(metinSlot[0])

                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.TOOLTIP_REST_USABLE_COUNT % (10 - useCount), self.NORMAL_COLOR)

            ## ÀÚµ¿¹°¾à
            elif constInfo.IS_AUTO_POTION(itemVnum):
                if 0 != metinSlot:
                    ## 0: È°¼ºÈ­, 1: »ç¿ë·®, 2: ÃÑ·®
                    isActivated = int(metinSlot[0])
                    usedAmount = float(metinSlot[1])
                    totalAmount = float(metinSlot[2])
                    
                    if 0 == totalAmount:
                        totalAmount = 1
                    
                    self.AppendSpace(5)

                    if 0 != isActivated:
                        self.AppendTextLine("(%s)" % (localeInfo.TOOLTIP_AUTO_POTION_USING), self.SPECIAL_POSITIVE_COLOR)
                        self.AppendSpace(5)
                        
                    self.AppendTextLine(localeInfo.TOOLTIP_AUTO_POTION_REST % (100.0 - ((usedAmount / totalAmount) * 100.0)), self.POSITIVE_COLOR)
                                
            ## ±Íȯ ±â¾ïºÎ
            elif itemVnum in WARP_SCROLLS:
                if 0 != metinSlot:
                    xPos = int(metinSlot[0])
                    yPos = int(metinSlot[1])

                    if xPos != 0 and yPos != 0:
                        (mapName, xBase, yBase) = background.GlobalPositionToMapInfo(xPos, yPos)
                        
                        localeMapName=localeInfo.MINIMAP_ZONE_NAME_DICT.get(mapName, "")

                        self.AppendSpace(5)

                        if localeMapName!="":                        
                            self.AppendTextLine(localeInfo.TOOLTIP_MEMORIZED_POSITION % (localeMapName, int(xPos-xBase)/100, int(yPos-yBase)/100), self.NORMAL_COLOR)
                        else:
                            self.AppendTextLine(localeInfo.TOOLTIP_MEMORIZED_POSITION_ERROR % (int(xPos)/100, int(yPos)/100), self.NORMAL_COLOR)
                            dbg.TraceError("NOT_EXIST_IN_MINIMAP_ZONE_NAME_DICT: %s" % mapName)

            #####
            if item.USE_SPECIAL == itemSubType:
                bHasRealtimeFlag = 0
                for i in xrange(item.LIMIT_MAX_NUM):
                    (limitType, limitValue) = item.GetLimit(i)

                    if item.LIMIT_REAL_TIME == limitType:
                        bHasRealtimeFlag = 1
        
                ## ÀÖ´Ù¸é °ü·Ã Á¤º¸¸¦ Ç¥½ÃÇÔ. ex) ³²Àº ½Ã°£ : 6ÀÏ 6½Ã°£ 58ºÐ 
                if 1 == bHasRealtimeFlag:
                    self.AppendMallItemLastTime(metinSlot[0])
                else:
                    # ... ÀÌ°Å... ¼­¹ö¿¡´Â ÀÌ·± ½Ã°£ üũ ¾ÈµÇ¾î Àִµ¥...
                    # ¿Ö ÀÌ·±°Ô ÀÖ´ÂÁö ¾ËÁö´Â ¸øÇϳª ±×³É µÎÀÚ...
                    if 0 != metinSlot:
                        time = metinSlot[player.METIN_SOCKET_MAX_NUM-1]

                        ## ½Ç½Ã°£ ÀÌ¿ë Flag
                        if 1 == item.GetValue(2):
                            self.AppendMallItemLastTime(time)
            
            elif item.USE_TIME_CHARGE_PER == itemSubType:
                bHasRealtimeFlag = 0
                for i in xrange(item.LIMIT_MAX_NUM):
                    (limitType, limitValue) = item.GetLimit(i)

                    if item.LIMIT_REAL_TIME == limitType:
                        bHasRealtimeFlag = 1
                if metinSlot[2]:
                    self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_PER(metinSlot[2]))
                else:
                    self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_PER(item.GetValue(0)))
         
                ## ÀÖ´Ù¸é °ü·Ã Á¤º¸¸¦ Ç¥½ÃÇÔ. ex) ³²Àº ½Ã°£ : 6ÀÏ 6½Ã°£ 58ºÐ 
                if 1 == bHasRealtimeFlag:
                    self.AppendMallItemLastTime(metinSlot[0])

            elif item.USE_TIME_CHARGE_FIX == itemSubType:
                bHasRealtimeFlag = 0
                for i in xrange(item.LIMIT_MAX_NUM):
                    (limitType, limitValue) = item.GetLimit(i)

                    if item.LIMIT_REAL_TIME == limitType:
                        bHasRealtimeFlag = 1
                if metinSlot[2]:
                    self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_FIX(metinSlot[2]))
                else:
                    self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_FIX(item.GetValue(0)))
        
                ## ÀÖ´Ù¸é °ü·Ã Á¤º¸¸¦ Ç¥½ÃÇÔ. ex) ³²Àº ½Ã°£ : 6ÀÏ 6½Ã°£ 58ºÐ 
                if 1 == bHasRealtimeFlag:
                    self.AppendMallItemLastTime(metinSlot[0])

        elif item.ITEM_TYPE_QUEST == itemType:
            for i in xrange(item.LIMIT_MAX_NUM):
                (limitType, limitValue) = item.GetLimit(i)

                if item.LIMIT_REAL_TIME == limitType:
                    self.AppendMallItemLastTime(metinSlot[0])
        elif item.ITEM_TYPE_DS == itemType:
            self.AppendTextLine(self.__DragonSoulInfoString(itemVnum))
            self.__AppendAttributeInformation(attrSlot)
        else:
            self.__AppendLimitInformation()

        for i in xrange(item.LIMIT_MAX_NUM):
            (limitType, limitValue) = item.GetLimit(i)
            #dbg.TraceError("LimitType : %d, limitValue : %d" % (limitType, limitValue))
            
            if item.LIMIT_REAL_TIME_START_FIRST_USE == limitType:
                self.AppendRealTimeStartFirstUseLastTime(item, metinSlot, i)
                #dbg.TraceError("2) REAL_TIME_START_FIRST_USE flag On ")
                
            elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType:
                self.AppendTimerBasedOnWearLastTime(metinSlot)
                #dbg.TraceError("1) REAL_TIME flag On ")


                
        self.ShowToolTip()

    def __DragonSoulInfoString (self, dwVnum):
        step = (dwVnum / 100) % 10
        refine = (dwVnum / 10) % 10
        if 0 == step:
            return localeInfo.DRAGON_SOUL_STEP_LEVEL1 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine)
        elif 1 == step:
            return localeInfo.DRAGON_SOUL_STEP_LEVEL2 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine)
        elif 2 == step:
            return localeInfo.DRAGON_SOUL_STEP_LEVEL3 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine)
        elif 3 == step:
            return localeInfo.DRAGON_SOUL_STEP_LEVEL4 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine)
        elif 4 == step:
            return localeInfo.DRAGON_SOUL_STEP_LEVEL5 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine)
        else:
            return ""


    ## Çì¾îÀΰ¡?
    def __IsHair(self, itemVnum):
        return (self.__IsOldHair(itemVnum) or 
            self.__IsNewHair(itemVnum) or
            self.__IsNewHair2(itemVnum) or
            self.__IsNewHair3(itemVnum) or
            self.__IsCostumeHair(itemVnum)
            )

    def __IsOldHair(self, itemVnum):
        return itemVnum > 73000 and itemVnum < 74000    

    def __IsNewHair(self, itemVnum):
        return itemVnum > 74000 and itemVnum < 75000    

    def __IsNewHair2(self, itemVnum):
        return itemVnum > 75000 and itemVnum < 76000    

    def __IsNewHair3(self, itemVnum):
        return ((74012 < itemVnum and itemVnum < 74022) or
            (74262 < itemVnum and itemVnum < 74272) or
            (74512 < itemVnum and itemVnum < 74522) or
            (74762 < itemVnum and itemVnum < 74772) or
            (45000 < itemVnum and itemVnum < 47000))

    def __IsCostumeHair(self, itemVnum):
        return app.ENABLE_COSTUME_SYSTEM and self.__IsNewHair3(itemVnum - 100000)
        
    def __ModelPreview(self, itemVnum):
        #if constInfo.DISABLE_MODEL_PREVIEW == 1:
        #    return

        RENDER_TARGET_INDEX = 1

        self.ModelPreviewBoard = ui.ThinBoard()
        self.ModelPreviewBoard.SetParent(self)
        self.ModelPreviewBoard.SetSize(190+10, 210+30)
        self.ModelPreviewBoard.SetPosition(-202, 0)
        self.ModelPreviewBoard.Show()

        self.ModelPreview = ui.RenderTarget()
        self.ModelPreview.SetParent(self.ModelPreviewBoard)
        self.ModelPreview.SetSize(190, 210)
        self.ModelPreview.SetPosition(5, 22)
        self.ModelPreview.SetRenderTarget(RENDER_TARGET_INDEX)
        self.ModelPreview.Show()

        self.ModelPreviewText = ui.TextLine()
        self.ModelPreviewText.SetParent(self.ModelPreviewBoard)
        self.ModelPreviewText.SetFontName(self.defFontName)
        self.ModelPreviewText.SetPackedFontColor(grp.GenerateColor(0.8824, 0.9804, 0.8824, 1.0))
        self.ModelPreviewText.SetPosition(0, 5)
        self.ModelPreviewText.SetText("Pre Visualizzazione")
        self.ModelPreviewText.SetOutline()
        self.ModelPreviewText.SetFeather(False)
        self.ModelPreviewText.SetWindowHorizontalAlignCenter()
        self.ModelPreviewText.SetHorizontalAlignCenter()
        self.ModelPreviewText.Show()

        renderTarget.SetBackground(RENDER_TARGET_INDEX, "d:/ymir work/ui/myshop_deco/view.sub")
        renderTarget.SetVisibility(RENDER_TARGET_INDEX, True)
        renderTarget.SelectModel(RENDER_TARGET_INDEX, itemVnum)

    def __ModelPreviewClose(self):
        RENDER_TARGET_INDEX = 1

        if self.ModelPreviewBoard:
            self.ModelPreviewBoard.Hide()
            self.ModelPreview.Hide()
            self.ModelPreviewText.Hide()

            self.ModelPreviewBoard = None
            self.ModelPreview = None
            self.ModelPreviewText = None

            renderTarget.SetVisibility(RENDER_TARGET_INDEX, False)
        
    def __AppendHairIcon(self, itemVnum):
        itemImage = ui.ImageBox()
        itemImage.SetParent(self)
        itemImage.Show()            

        if self.__IsOldHair(itemVnum):
            itemImage.LoadImage("d:/ymir work/item/quest/"+str(itemVnum)+".tga")
        elif self.__IsNewHair3(itemVnum):
            itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum))
        elif self.__IsNewHair(itemVnum): # ±âÁ¸ Çì¾î ¹øÈ£¸¦ ¿¬°á½ÃÄѼ­ »ç¿ëÇÑ´Ù. »õ·Î¿î ¾ÆÀÌÅÛÀº 1000¸¸Å­ ¹øÈ£°¡ ´Ã¾ú´Ù.
            itemImage.LoadImage("d:/ymir work/item/quest/"+str(itemVnum-1000)+".tga")
        elif self.__IsNewHair2(itemVnum):
            itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum))
        elif self.__IsCostumeHair(itemVnum):
            itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum - 100000))

        itemImage.SetPosition(itemImage.GetWidth()/2, self.toolTipHeight)
        self.toolTipHeight += itemImage.GetHeight()
        #self.toolTipWidth += itemImage.GetWidth()/2
        self.childrenList.append(itemImage)
        self.ResizeToolTip()

    ## »çÀÌÁî°¡ Å« Description ÀÏ °æ¿ì ÅøÆÁ »çÀÌÁ Á¶Á¤ÇÑ´Ù
    def __AdjustMaxWidth(self, attrSlot, desc):
        newToolTipWidth = self.toolTipWidth
        newToolTipWidth = max(self.__AdjustAttrMaxWidth(attrSlot), newToolTipWidth)
        newToolTipWidth = max(self.__AdjustDescMaxWidth(desc), newToolTipWidth)
        if newToolTipWidth > self.toolTipWidth:
            self.toolTipWidth = newToolTipWidth
            self.ResizeToolTip()

    def __AdjustAttrMaxWidth(self, attrSlot):
        if 0 == attrSlot:
            return self.toolTipWidth

        maxWidth = self.toolTipWidth
        for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
            type = attrSlot[0]
            value = attrSlot[1]
            if self.ATTRIBUTE_NEED_WIDTH.has_key(type):
                if value > 0:
                    maxWidth = max(self.ATTRIBUTE_NEED_WIDTH[type], maxWidth)

                    # ATTR_CHANGE_TOOLTIP_WIDTH
                    #self.toolTipWidth = max(self.ATTRIBUTE_NEED_WIDTH[type], self.toolTipWidth)
                    #self.ResizeToolTip()
                    # END_OF_ATTR_CHANGE_TOOLTIP_WIDTH

        return maxWidth

    def __AdjustDescMaxWidth(self, desc):
        if len(desc) < DESC_DEFAULT_MAX_COLS:
            return self.toolTipWidth
    
        return DESC_WESTERN_MAX_WIDTH

    def __SetSkillBookToolTip(self, skillIndex, bookName, skillGrade):
        skillName = skill.GetSkillName(skillIndex)

        if not skillName:
            return

        if localeInfo.IsVIETNAM():
            itemName = bookName + " " + skillName
        else:
            itemName = skillName + " " + bookName
        self.SetTitle(itemName)

    def __AppendPickInformation(self, curLevel, curEXP, maxEXP):
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_PICK_LEVEL % (curLevel), self.NORMAL_COLOR)
        self.AppendTextLine(localeInfo.TOOLTIP_PICK_EXP % (curEXP, maxEXP), self.NORMAL_COLOR)

        if curEXP == maxEXP:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE1, self.NORMAL_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE2, self.NORMAL_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE3, self.NORMAL_COLOR)


    def __AppendRodInformation(self, curLevel, curEXP, maxEXP):
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_LEVEL % (curLevel), self.NORMAL_COLOR)
        self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_EXP % (curEXP, maxEXP), self.NORMAL_COLOR)

        if curEXP == maxEXP:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE1, self.NORMAL_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE2, self.NORMAL_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE3, self.NORMAL_COLOR)

    def __AppendLimitInformation(self):

        appendSpace = FALSE

        for i in xrange(item.LIMIT_MAX_NUM):

            (limitType, limitValue) = item.GetLimit(i)

            if limitValue > 0:
                if FALSE == appendSpace:
                    self.AppendSpace(5)
                    appendSpace = TRUE

            else:
                continue

            if item.LIMIT_LEVEL == limitType:
                color = self.GetLimitTextLineColor(player.GetStatus(player.LEVEL), limitValue)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_LEVEL % (limitValue), color)
            """
            elif item.LIMIT_STR == limitType:
                color = self.GetLimitTextLineColor(player.GetStatus(player.ST), limitValue)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_STR % (limitValue), color)
            elif item.LIMIT_DEX == limitType:
                color = self.GetLimitTextLineColor(player.GetStatus(player.DX), limitValue)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_DEX % (limitValue), color)
            elif item.LIMIT_INT == limitType:
                color = self.GetLimitTextLineColor(player.GetStatus(player.IQ), limitValue)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_INT % (limitValue), color)
            elif item.LIMIT_CON == limitType:
                color = self.GetLimitTextLineColor(player.GetStatus(player.HT), limitValue)
                self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_CON % (limitValue), color)
            """

    def __AppendSealInformation(self, window_type, slotIndex):
        if window_type == player.SAFEBOX:
            if safebox.GetItemBind(slotIndex) <= 1:
                itemSoulTime = safebox.GetItemBind(slotIndex)
            else:
                itemSoulTime = max(0, safebox.GetItemBind(slotIndex) - app.GetGlobalTimeStamp())
        elif window_type == player.MALL:
            if safebox.GetMallItemBind(slotIndex) <= 1:
                itemSoulTime = safebox.GetMallItemBind(slotIndex)
            else:
                itemSoulTime = max(0, safebox.GetMallItemBind(slotIndex) - app.GetGlobalTimeStamp())
        elif window_type == player.INVENTORY:
            if player.GetItemBind(slotIndex) <= 1:
                itemSoulTime = player.GetItemBind(slotIndex)
            else:
                itemSoulTime = max(0, player.GetItemBind(slotIndex) - app.GetGlobalTimeStamp())
        else:
            return
            
        if itemSoulTime == 0:
            return
        elif itemSoulTime == 1:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_SEALED, self.NEGATIVE_COLOR)
        elif itemSoulTime > 1:
            self.AppendSpace(5)
            hrs = itemSoulTime / 3600
            itemSoulTime -= 3600 * hrs
            mins = itemSoulTime / 60
            itemSoulTime -= 60 * mins
            self.AppendTextLine(localeInfo.TOOLTIP_UNSEAL_LEFT_TIME % (hrs, mins), self.NEGATIVE_COLOR)

    def __GetAffectString(self, affectType, affectValue):
        if 0 == affectType:
            return None

        if 0 == affectValue:
            return None

        try:
            return self.AFFECT_DICT[affectType](affectValue)
        except TypeError:
            return "UNKNOWN_VALUE[%s] %s" % (affectType, affectValue)
        except KeyError:
            return "UNKNOWN_TYPE[%s] %s" % (affectType, affectValue)

    def __AppendAffectInformation(self):
        for i in xrange(item.ITEM_APPLY_MAX_NUM):

            (affectType, affectValue) = item.GetAffect(i)

            affectString = self.__GetAffectString(affectType, affectValue)
            if affectString:
                self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue))

    def AppendWearableInformation(self):
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_ITEM_WEARABLE_JOB, self.NORMAL_COLOR)
        flagList = (
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_WARRIOR),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_ASSASSIN),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_SURA),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_SHAMAN),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_WOLFMAN)
                )
        
        characterNames = ""
        for i in xrange(self.CHARACTER_COUNT):
            name = self.CHARACTER_NAMES
            flag = flagList
            if flag:
                characterNames += " "
                characterNames += name
        
        textLine = self.AppendTextLine(characterNames, self.NORMAL_COLOR, TRUE)
        textLine.SetFeather()
        if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE):
            textLine = self.AppendTextLine(localeInfo.FOR_FEMALE, self.NORMAL_COLOR, TRUE)
            textLine.SetFeather()
        
        if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE):
            textLine = self.AppendTextLine(localeInfo.FOR_MALE, self.NORMAL_COLOR, TRUE)
            textLine.SetFeather()

    def __AppendPotionInformation(self):
        self.AppendSpace(5)

        healHP = item.GetValue(0)
        healSP = item.GetValue(1)
        healStatus = item.GetValue(2)
        healPercentageHP = item.GetValue(3)
        healPercentageSP = item.GetValue(4)

        if healHP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_HP_POINT % healHP, self.GetChangeTextLineColor(healHP))
        if healSP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_SP_POINT % healSP, self.GetChangeTextLineColor(healSP))
        if healStatus != 0:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_CURE)
        if healPercentageHP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_HP_PERCENT % healPercentageHP, self.GetChangeTextLineColor(healPercentageHP))
        if healPercentageSP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_SP_PERCENT % healPercentageSP, self.GetChangeTextLineColor(healPercentageSP))

    def __AppendAbilityPotionInformation(self):

        self.AppendSpace(5)

        abilityType = item.GetValue(0)
        time = item.GetValue(1)
        point = item.GetValue(2)

        if abilityType == item.APPLY_ATT_SPEED:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_ATTACK_SPEED % point, self.GetChangeTextLineColor(point))
        elif abilityType == item.APPLY_MOV_SPEED:
            self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_MOVING_SPEED % point, self.GetChangeTextLineColor(point))

        if time > 0:
            minute = (time / 60)
            second = (time % 60)
            timeString = localeInfo.TOOLTIP_POTION_TIME

            if minute > 0:
                timeString += str(minute) + localeInfo.TOOLTIP_POTION_MIN
            if second > 0:
                timeString += " " + str(second) + localeInfo.TOOLTIP_POTION_SEC

            self.AppendTextLine(timeString)

    def GetPriceColor(self, price):
        if price>=constInfo.HIGH_PRICE:
            return self.HIGH_PRICE_COLOR
        if price>=constInfo.MIDDLE_PRICE:
            return self.MIDDLE_PRICE_COLOR
        else:
            return self.LOW_PRICE_COLOR

    def AppendPrice(self, price):
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE1 , self.SHOP_ITEM_COLOR)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price))
        
    def miktar(self, price):    
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE_NEW  % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price))
        
    def miktar2(self, price):    
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE_NEW_2  % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price))

    if app.ENABLE_SHOP_SISTEM:
        def miktar(self, price):
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE1 , self.SHOP_ITEM_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE_NEW  % (localeInfo.NumberToMoneyString2(price)), self.GetPriceColor(price))

        def miktar2(self, price):
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE1 , self.SHOP_ITEM_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE_NEW_2  % (localeInfo.NumberToMoneyString2(price)), self.GetPriceColor(price))

    def AppendPriceBySecondaryCoin(self, price):
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE1 , self.SHOP_ITEM_COLOR)
        self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE  % (localeInfo.NumberToSecondaryCoinString(price)), self.GetPriceColor(price))

    def AppendSellingPrice(self, price):
        if item.IsAntiFlag(item.ITEM_ANTIFLAG_SELL):
            self.AppendTextLine(localeInfo.TOOLTIP_ANTI_SELL, self.DISABLE_COLOR)
            self.AppendSpace(5)
        else:
            self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE1 , self.SHOP_ITEM_COLOR)
            self.AppendTextLine(localeInfo.TOOLTIP_SELLPRICE % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price))
            self.AppendSpace(5)

    def AppendMetinInformation(self):
        affectType, affectValue = item.GetAffect(0)
        #affectType = item.GetValue(0)
        #affectValue = item.GetValue(1)

        affectString = self.__GetAffectString(affectType, affectValue)

        if affectString:
            self.AppendSpace(5)
            self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue))

    def AppendMetinWearInformation(self):

        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_SOCKET_REFINABLE_ITEM, self.NORMAL_COLOR)

        flagList = (item.IsWearableFlag(item.WEARABLE_BODY),
                    item.IsWearableFlag(item.WEARABLE_HEAD),
                    item.IsWearableFlag(item.WEARABLE_FOOTS),
                    item.IsWearableFlag(item.WEARABLE_WRIST),
                    item.IsWearableFlag(item.WEARABLE_WEAPON),
                    item.IsWearableFlag(item.WEARABLE_NECK),
                    item.IsWearableFlag(item.WEARABLE_EAR),
                    item.IsWearableFlag(item.WEARABLE_UNIQUE),
                    item.IsWearableFlag(item.WEARABLE_SHIELD),
                    item.IsWearableFlag(item.WEARABLE_ARROW))

        wearNames = ""
        for i in xrange(self.WEAR_COUNT):

            name = self.WEAR_NAMES
            flag = flagList

            if flag:
                wearNames += "  "
                wearNames += name

        textLine = ui.TextLine()
        textLine.SetParent(self)
        textLine.SetFontName(self.defFontName)
        textLine.SetPosition(self.toolTipWidth/2, self.toolTipHeight)
        textLine.SetHorizontalAlignCenter()
        textLine.SetPackedFontColor(self.NORMAL_COLOR)
        textLine.SetText(wearNames)
        textLine.Show()
        self.childrenList.append(textLine)

        self.toolTipHeight += self.TEXT_LINE_HEIGHT
        self.ResizeToolTip()

    def GetMetinSocketType(self, number):
        if player.METIN_SOCKET_TYPE_NONE == number:
            return player.METIN_SOCKET_TYPE_NONE
        elif player.METIN_SOCKET_TYPE_SILVER == number:
            return player.METIN_SOCKET_TYPE_SILVER
        elif player.METIN_SOCKET_TYPE_GOLD == number:
            return player.METIN_SOCKET_TYPE_GOLD
        else:
            item.SelectItem(number)
            if item.METIN_NORMAL == item.GetItemSubType():
                return player.METIN_SOCKET_TYPE_SILVER
            elif item.METIN_GOLD == item.GetItemSubType():
                return player.METIN_SOCKET_TYPE_GOLD
            elif "USE_PUT_INTO_ACCESSORY_SOCKET" == item.GetUseType(number):
                return player.METIN_SOCKET_TYPE_SILVER
            elif "USE_PUT_INTO_RING_SOCKET" == item.GetUseType(number):
                return player.METIN_SOCKET_TYPE_SILVER
            elif "USE_PUT_INTO_BELT_SOCKET" == item.GetUseType(number):
                return player.METIN_SOCKET_TYPE_SILVER

        return player.METIN_SOCKET_TYPE_NONE

    def GetMetinItemIndex(self, number):
        if player.METIN_SOCKET_TYPE_SILVER == number:
            return 0
        if player.METIN_SOCKET_TYPE_GOLD == number:
            return 0

        return number

    def __AppendAccessoryMetinSlotInfo(self, metinSlot, mtrlVnum):        
        ACCESSORY_SOCKET_MAX_SIZE = 3        

        cur=min(metinSlot[0], ACCESSORY_SOCKET_MAX_SIZE)
        end=min(metinSlot[1], ACCESSORY_SOCKET_MAX_SIZE)

        affectType1, affectValue1 = item.GetAffect(0)
        affectList1=[0, max(1, affectValue1*10/100), max(2, affectValue1*20/100), max(3, affectValue1*40/100)]

        affectType2, affectValue2 = item.GetAffect(1)
        affectList2=[0, max(1, affectValue2*10/100), max(2, affectValue2*20/100), max(3, affectValue2*40/100)]

        mtrlPos=0
        mtrlList=[mtrlVnum]*cur+[player.METIN_SOCKET_TYPE_SILVER]*(end-cur)
        for mtrl in mtrlList:
            affectString1 = self.__GetAffectString(affectType1, affectList1[mtrlPos+1]-affectList1[mtrlPos])            
            affectString2 = self.__GetAffectString(affectType2, affectList2[mtrlPos+1]-affectList2[mtrlPos])

            leftTime = 0
            if cur == mtrlPos+1:
                leftTime=metinSlot[2]

            self.__AppendMetinSlotInfo_AppendMetinSocketData(mtrlPos, mtrl, affectString1, affectString2, leftTime)
            mtrlPos+=1

    def __AppendMetinSlotInfo(self, metinSlot):
        if self.__AppendMetinSlotInfo_IsEmptySlotList(metinSlot):
            return

        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            self.__AppendMetinSlotInfo_AppendMetinSocketData(i, metinSlot)

    def __AppendMetinSlotInfo_IsEmptySlotList(self, metinSlot):
        if 0 == metinSlot:
            return 1

        for i in xrange(player.METIN_SOCKET_MAX_NUM):
            metinSlotData=metinSlot
            if 0 != self.GetMetinSocketType(metinSlotData):
                if 0 != self.GetMetinItemIndex(metinSlotData):
                    return 0

        return 1

    def __AppendMetinSlotInfo_AppendMetinSocketData(self, index, metinSlotData, custumAffectString="", custumAffectString2="", leftTime=0):

        slotType = self.GetMetinSocketType(metinSlotData)
        itemIndex = self.GetMetinItemIndex(metinSlotData)

        if 0 == slotType:
            return

        self.AppendSpace(5)

        slotImage = ui.ImageBox()
        slotImage.SetParent(self)
        slotImage.Show()

        ## Name
        nameTextLine = ui.TextLine()
        nameTextLine.SetParent(self)
        nameTextLine.SetFontName(self.defFontName)
        nameTextLine.SetPackedFontColor(self.NORMAL_COLOR)
        nameTextLine.SetOutline()
        nameTextLine.SetFeather()
        nameTextLine.Show()            

        self.childrenList.append(nameTextLine)

        if player.METIN_SOCKET_TYPE_SILVER == slotType:
            slotImage.LoadImage("d:/ymir work/ui/game/windows/metin_slot_silver.sub")
        elif player.METIN_SOCKET_TYPE_GOLD == slotType:
            slotImage.LoadImage("d:/ymir work/ui/game/windows/metin_slot_gold.sub")

        self.childrenList.append(slotImage)
        
        if localeInfo.IsARABIC():
            slotImage.SetPosition(self.toolTipWidth - slotImage.GetWidth() - 9, self.toolTipHeight-1)
            nameTextLine.SetPosition(self.toolTipWidth - 50, self.toolTipHeight + 2)
        else:
            slotImage.SetPosition(9, self.toolTipHeight-1)
            nameTextLine.SetPosition(50, self.toolTipHeight + 2)

        metinImage = ui.ImageBox()
        metinImage.SetParent(self)
        metinImage.Show()
        self.childrenList.append(metinImage)

        if itemIndex:

            item.SelectItem(itemIndex)

            ## Image
            try:
                metinImage.LoadImage(item.GetIconImageFileName())
            except:
                dbg.TraceError("ItemToolTip.__AppendMetinSocketData() - Failed to find image file %d:%s" % 
                    (itemIndex, item.GetIconImageFileName())
                )

            nameTextLine.SetText(item.GetItemName())
            
            ## Affect        
            affectTextLine = ui.TextLine()
            affectTextLine.SetParent(self)
            affectTextLine.SetFontName(self.defFontName)
            affectTextLine.SetPackedFontColor(self.POSITIVE_COLOR)
            affectTextLine.SetOutline()
            affectTextLine.SetFeather()
            affectTextLine.Show()            
                
            if localeInfo.IsARABIC():
                metinImage.SetPosition(self.toolTipWidth - metinImage.GetWidth() - 10, self.toolTipHeight)
                affectTextLine.SetPosition(self.toolTipWidth - 50, self.toolTipHeight + 16 + 2)
            else:
                metinImage.SetPosition(10, self.toolTipHeight)
                affectTextLine.SetPosition(50, self.toolTipHeight + 16 + 2)
                            
            if custumAffectString:
                affectTextLine.SetText(custumAffectString)
            elif itemIndex!=constInfo.ERROR_METIN_STONE:
                affectType, affectValue = item.GetAffect(0)
                affectString = self.__GetAffectString(affectType, affectValue)
                if affectString:
                    affectTextLine.SetText(affectString)
            else:
                affectTextLine.SetText(localeInfo.TOOLTIP_APPLY_NOAFFECT)
            
            self.childrenList.append(affectTextLine)            

            if custumAffectString2:
                affectTextLine = ui.TextLine()
                affectTextLine.SetParent(self)
                affectTextLine.SetFontName(self.defFontName)
                affectTextLine.SetPackedFontColor(self.POSITIVE_COLOR)
                affectTextLine.SetPosition(50, self.toolTipHeight + 16 + 2 + 16 + 2)
                affectTextLine.SetOutline()
                affectTextLine.SetFeather()
                affectTextLine.Show()
                affectTextLine.SetText(custumAffectString2)
                self.childrenList.append(affectTextLine)
                self.toolTipHeight += 16 + 2

            if 0 != leftTime:
                timeText = (localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(leftTime))

                timeTextLine = ui.TextLine()
                timeTextLine.SetParent(self)
                timeTextLine.SetFontName(self.defFontName)
                timeTextLine.SetPackedFontColor(self.POSITIVE_COLOR)
                timeTextLine.SetPosition(50, self.toolTipHeight + 16 + 2 + 16 + 2)
                timeTextLine.SetOutline()
                timeTextLine.SetFeather()
                timeTextLine.Show()
                timeTextLine.SetText(timeText)
                self.childrenList.append(timeTextLine)
                self.toolTipHeight += 16 + 2

        else:
            nameTextLine.SetText(localeInfo.TOOLTIP_SOCKET_EMPTY)

        self.toolTipHeight += 35
        self.ResizeToolTip()

    def __AppendFishInfo(self, size):
        if size > 0:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_FISH_LEN % (float(size) / 100.0), self.NORMAL_COLOR)

    def AppendUniqueItemLastTime(self, restMin):
        restSecond = restMin*60
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(restSecond), self.NORMAL_COLOR)

    def AppendMallItemLastTime(self, endTime):
        leftSec = max(0, endTime - app.GetGlobalTimeStamp())
        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(leftSec), self.NORMAL_COLOR)
        
    def AppendTimerBasedOnWearLastTime(self, metinSlot):
        if 0 == metinSlot[0]:
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.CANNOT_USE, self.DISABLE_COLOR)
        else:
            endTime = app.GetGlobalTimeStamp() + metinSlot[0]
            self.AppendMallItemLastTime(endTime)        
    
    def AppendRealTimeStartFirstUseLastTime(self, item, metinSlot, limitIndex):        
        useCount = metinSlot[1]
        endTime = metinSlot[0]
        
        # ÇÑ ¹øÀÌ¶óµµ »ç¿ëÇß´Ù¸é Socket0¿¡ Á¾·á ½Ã°£(2012³â 3¿ù 1ÀÏ 13½Ã 01ºÐ °°Àº..) ÀÌ ¹ÚÇôÀÖÀ½.
        # »ç¿ëÇÏÁö ¾Ê¾Ò´Ù¸é Socket0¿¡ ÀÌ¿ë°¡´É½Ã°£(À̸¦Å׸é 600 °°Àº °ª. ÃÊ´ÜÀ§)ÀÌ µé¾îÀÖÀ» ¼ö ÀÖ°í, 0À̶ó¸é Limit Value¿¡ ÀÖ´Â ÀÌ¿ë°¡´É½Ã°£À» »ç¿ëÇÑ´Ù.
        if 0 == useCount:
            if 0 == endTime:
                (limitType, limitValue) = item.GetLimit(limitIndex)
                endTime = limitValue

            endTime += app.GetGlobalTimeStamp()
    
        self.AppendMallItemLastTime(endTime)

    if app.ENABLE_SASH_SYSTEM:
        def SetSashResultItem(self, slotIndex, window_type = player.INVENTORY):
            (itemVnum, MinAbs, MaxAbs) = sash.GetResultItem()
            if not itemVnum:
                return
            
            self.ClearToolTip()
            
            metinSlot = [player.GetItemMetinSocket(window_type, slotIndex, i) for i in xrange(player.METIN_SOCKET_MAX_NUM)]
            attrSlot = [player.GetItemAttribute(window_type, slotIndex, i) for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM)]
            
            item.SelectItem(itemVnum)
            itemType = item.GetItemType()
            itemSubType = item.GetItemSubType()
            if itemType != item.ITEM_TYPE_COSTUME and itemSubType != item.COSTUME_TYPE_SASH:
                return
            
            absChance = MaxAbs
            itemDesc = item.GetItemDescription()
            self.__AdjustMaxWidth(attrSlot, itemDesc)
            self.__SetItemTitle(itemVnum, metinSlot, attrSlot)
            self.AppendDescription(itemDesc, 26)
            self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
            self.__AppendLimitInformation()
            
            ## ABSORPTION RATE
            if MinAbs == MaxAbs:
                self.AppendTextLine(localeInfo.SASH_ABSORB_CHANCE % (MinAbs), self.CONDITION_COLOR)
            else:
                self.AppendTextLine(localeInfo.SASH_ABSORB_CHANCE2 % (MinAbs, MaxAbs), self.CONDITION_COLOR)
            ## END ABSOPRTION RATE
            
            itemAbsorbedVnum = int(metinSlot[sash.ABSORBED_SOCKET])
            if itemAbsorbedVnum:
                ## ATTACK / DEFENCE
                item.SelectItem(itemAbsorbedVnum)
                if item.GetItemType() == item.ITEM_TYPE_WEAPON:
                    if item.GetItemSubType() == item.WEAPON_FAN:
                        self.__AppendMagicAttackInfo(absChance)
                        item.SelectItem(itemAbsorbedVnum)
                        self.__AppendAttackPowerInfo(absChance)
                    else:
                        self.__AppendAttackPowerInfo(absChance)
                        item.SelectItem(itemAbsorbedVnum)
                        self.__AppendMagicAttackInfo(absChance)
                elif item.GetItemType() == item.ITEM_TYPE_ARMOR:
                    defGrade = item.GetValue(1)
                    defBonus = item.GetValue(5) * 2
                    defGrade = self.CalcSashValue(defGrade, absChance)
                    defBonus = self.CalcSashValue(defBonus, absChance)
                    
                    if defGrade > 0:
                        self.AppendSpace(5)
                        self.AppendTextLine(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade + defBonus), self.GetChangeTextLineColor(defGrade))
                    
                    item.SelectItem(itemAbsorbedVnum)
                    self.__AppendMagicDefenceInfo(absChance)
                ## END ATTACK / DEFENCE
                
                ## EFFECT
                item.SelectItem(itemAbsorbedVnum)
                for i in xrange(item.ITEM_APPLY_MAX_NUM):
                    (affectType, affectValue) = item.GetAffect(i)
                    affectValue = self.CalcSashValue(affectValue, absChance)
                    affectString = self.__GetAffectString(affectType, affectValue)
                    if affectString and affectValue > 0:
                        self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue))
                    
                    item.SelectItem(itemAbsorbedVnum)
                # END EFFECT
                
            item.SelectItem(itemVnum)
            ## ATTR
            self.__AppendAttributeInformation(attrSlot, MaxAbs)
            # END ATTR
            
            self.AppendWearableInformation()
            self.ShowToolTip()

        def SetSashResultAbsItem(self, slotIndex1, slotIndex2, window_type = player.INVENTORY):
            itemVnumSash = player.GetItemIndex(window_type, slotIndex1)
            itemVnumTarget = player.GetItemIndex(window_type, slotIndex2)
            if not itemVnumSash or not itemVnumTarget:
                return
            
            self.ClearToolTip()
            
            item.SelectItem(itemVnumSash)
            itemType = item.GetItemType()
            itemSubType = item.GetItemSubType()
            if itemType != item.ITEM_TYPE_COSTUME and itemSubType != item.COSTUME_TYPE_SASH:
                return
            
            metinSlot = [player.GetItemMetinSocket(window_type, slotIndex1, i) for i in xrange(player.METIN_SOCKET_MAX_NUM)]
            attrSlot = [player.GetItemAttribute(window_type, slotIndex2, i) for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM)]
            
            itemDesc = item.GetItemDescription()
            self.__AdjustMaxWidth(attrSlot, itemDesc)
            self.__SetItemTitle(itemVnumSash, metinSlot, attrSlot)
            self.AppendDescription(itemDesc, 26)
            self.AppendDescription(item.GetItemSummary(), 26, self.CONDITION_COLOR)
            item.SelectItem(itemVnumSash)
            self.__AppendLimitInformation()
            
            ## ABSORPTION RATE
            self.AppendTextLine(localeInfo.SASH_ABSORB_CHANCE % (metinSlot[sash.ABSORPTION_SOCKET]), self.CONDITION_COLOR)
            ## END ABSOPRTION RATE
            
            ## ATTACK / DEFENCE
            itemAbsorbedVnum = itemVnumTarget
            item.SelectItem(itemAbsorbedVnum)
            if item.GetItemType() == item.ITEM_TYPE_WEAPON:
                if item.GetItemSubType() == item.WEAPON_FAN:
                    self.__AppendMagicAttackInfo(metinSlot[sash.ABSORPTION_SOCKET])
                    item.SelectItem(itemAbsorbedVnum)
                    self.__AppendAttackPowerInfo(metinSlot[sash.ABSORPTION_SOCKET])
                else:
                    self.__AppendAttackPowerInfo(metinSlot[sash.ABSORPTION_SOCKET])
                    item.SelectItem(itemAbsorbedVnum)
                    self.__AppendMagicAttackInfo(metinSlot[sash.ABSORPTION_SOCKET])
            elif item.GetItemType() == item.ITEM_TYPE_ARMOR:
                defGrade = item.GetValue(1)
                defBonus = item.GetValue(5) * 2
                defGrade = self.CalcSashValue(defGrade, metinSlot[sash.ABSORPTION_SOCKET])
                defBonus = self.CalcSashValue(defBonus, metinSlot[sash.ABSORPTION_SOCKET])
                
                if defGrade > 0:
                    self.AppendSpace(5)
                    self.AppendTextLine(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade + defBonus), self.GetChangeTextLineColor(defGrade))
                
                item.SelectItem(itemAbsorbedVnum)
                self.__AppendMagicDefenceInfo(metinSlot[sash.ABSORPTION_SOCKET])
            ## END ATTACK / DEFENCE
            
            ## EFFECT
            item.SelectItem(itemAbsorbedVnum)
            for i in xrange(item.ITEM_APPLY_MAX_NUM):
                (affectType, affectValue) = item.GetAffect(i)
                affectValue = self.CalcSashValue(affectValue, metinSlot[sash.ABSORPTION_SOCKET])
                affectString = self.__GetAffectString(affectType, affectValue)
                if affectString and affectValue > 0:
                    self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue))
                
                item.SelectItem(itemAbsorbedVnum)
            ## END EFFECT
            
            ## ATTR
            item.SelectItem(itemAbsorbedVnum)
            for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM):
                type = attrSlot[0]
                value = attrSlot[1]
                if not value:
                    continue
                
                value = self.CalcSashValue(value, metinSlot[sash.ABSORPTION_SOCKET])
                affectString = self.__GetAffectString(type, value)
                if affectString and value > 0:
                    affectColor = self.__GetAttributeColor(i, value)
                    self.AppendTextLine(affectString, affectColor)
                
                item.SelectItem(itemAbsorbedVnum)
            ## END ATTR
            
            ## WEARABLE
            item.SelectItem(itemVnumSash)
            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_ITEM_WEARABLE_JOB, self.NORMAL_COLOR)
            
            item.SelectItem(itemVnumSash)
            flagList = (
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_WARRIOR),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_ASSASSIN),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_SURA),
                        not item.IsAntiFlag(item.ITEM_ANTIFLAG_SHAMAN)
            )
            
            flagList += (not item.IsAntiFlag(item.ITEM_ANTIFLAG_WOLFMAN),)
            
            characterNames = ""
            for i in xrange(self.CHARACTER_COUNT):
                name = self.CHARACTER_NAMES
                flag = flagList
                if flag:
                    characterNames += " "
                    characterNames += name
            
            textLine = self.AppendTextLine(characterNames, self.NORMAL_COLOR, True)
            textLine.SetFeather()
            
            item.SelectItem(itemVnumSash)
            if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE):
                textLine = self.AppendTextLine(localeInfo.FOR_FEMALE, self.NORMAL_COLOR, True)
                textLine.SetFeather()
            
            if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE):
                textLine = self.AppendTextLine(localeInfo.FOR_MALE, self.NORMAL_COLOR, True)
                textLine.SetFeather()
            ## END WEARABLE
            
            self.ShowToolTip()

    if app.ENABLE_CHANGELOOK_SYSTEM:
        def AppendTransmutation(self, window_type, slotIndex, transmutation):
            itemVnum = 0
            if transmutation == -1:
                if window_type == player.INVENTORY:
                    itemVnum = player.GetItemTransmutation(window_type, slotIndex)
                elif window_type == player.SAFEBOX:
                    itemVnum = safebox.GetItemTransmutation(slotIndex)
                elif window_type == player.MALL:
                    itemVnum = safebox.GetMallItemTransmutation(slotIndex)
                    #itemVnum = safebox.GetItemMallTransmutation(slotIndex)
            else:
                itemVnum = transmutation
            
            if not itemVnum:
                return
            
            item.SelectItem(itemVnum)
            itemName = item.GetItemName()
            if not itemName or itemName == "":
                return
            
            self.AppendSpace(5)
            title = "[ " + localeInfo.CHANGE_LOOK_TITLE + " ]"
            self.AppendTextLine(title, self.BEFORE_LOOK_COLOR)
            textLine = self.AppendTextLine(itemName, self.UNDER_LOOK_COLOR, True)
            textLine.SetFeather()

class HyperlinkItemToolTip(ItemToolTip):
    def __init__(self):
        ItemToolTip.__init__(self, isPickable=TRUE)

    def SetHyperlinkItem(self, tokens):
        minTokenCount = 3 + player.METIN_SOCKET_MAX_NUM
        if app.ENABLE_CHANGELOOK_SYSTEM:
            minTokenCount += 1
        maxTokenCount = minTokenCount + 2 * player.ATTRIBUTE_SLOT_MAX_NUM
        if tokens and len(tokens) >= minTokenCount and len(tokens) <= maxTokenCount:
            head, vnum, flag = tokens[:3]
            itemVnum = int(vnum, 16)
            metinSlot = [int(metin, 16) for metin in tokens[3:6]]

            rests = tokens[6:]
            transmutation = 0
            if app.ENABLE_CHANGELOOK_SYSTEM:
                rests = tokens[7:]
                cnv = [int(cnv, 16) for cnv in tokens[6:7]]
                transmutation = int(cnv[0])
            if rests:
                attrSlot = []

                rests.reverse()
                while rests:
                    key = int(rests.pop(), 16)
                    if rests:
                        val = int(rests.pop())
                        attrSlot.append((key, val))

                attrSlot += [(0, 0)] * (player.ATTRIBUTE_SLOT_MAX_NUM - len(attrSlot))
            else:
                attrSlot = [(0, 0)] * player.ATTRIBUTE_SLOT_MAX_NUM

            self.ClearToolTip()
            if app.ENABLE_CHANGELOOK_SYSTEM:
                if not transmutation:
                    self.AddItemData(itemVnum, metinSlot, attrSlot)
                else:
                    self.AddItemData(itemVnum, metinSlot, attrSlot, 0, player.INVENTORY, -1, transmutation)
            else:
                self.AddItemData(itemVnum, metinSlot, attrSlot)

            ItemToolTip.OnUpdate(self)

    def OnUpdate(self):
        pass

    def OnMouseLeftButtonDown(self):
        self.Hide()

class SkillToolTip(ToolTip):

    POINT_NAME_DICT = {
        player.LEVEL : localeInfo.SKILL_TOOLTIP_LEVEL,
        player.IQ : localeInfo.SKILL_TOOLTIP_INT,
    }

    SKILL_TOOL_TIP_WIDTH = 200
    PARTY_SKILL_TOOL_TIP_WIDTH = 340

    PARTY_SKILL_EXPERIENCE_AFFECT_LIST = (    ( 2, 2,  10,),
                                            ( 8, 3,  20,),
                                            (14, 4,  30,),
                                            (22, 5,  45,),
                                            (28, 6,  60,),
                                            (34, 7,  80,),
                                            (38, 8, 100,), )

    PARTY_SKILL_PLUS_GRADE_AFFECT_LIST = (    ( 4, 2, 1, 0,),
                                            (10, 3, 2, 0,),
                                            (16, 4, 2, 1,),
                                            (24, 5, 2, 2,), )

    PARTY_SKILL_ATTACKER_AFFECT_LIST = (    ( 36, 3, ),
                                            ( 26, 1, ),
                                            ( 32, 2, ), )

    SKILL_GRADE_NAME = {    player.SKILL_GRADE_MASTER : localeInfo.SKILL_GRADE_NAME_MASTER,
                            player.SKILL_GRADE_GRAND_MASTER : localeInfo.SKILL_GRADE_NAME_GRAND_MASTER,
                            player.SKILL_GRADE_PERFECT_MASTER : localeInfo.SKILL_GRADE_NAME_PERFECT_MASTER, }

    AFFECT_NAME_DICT =    {
                            "HP" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_POWER,
                            "ATT_GRADE" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_GRADE,
                            "DEF_GRADE" : localeInfo.TOOLTIP_SKILL_AFFECT_DEF_GRADE,
                            "ATT_SPEED" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_SPEED,
                            "MOV_SPEED" : localeInfo.TOOLTIP_SKILL_AFFECT_MOV_SPEED,
                            "DODGE" : localeInfo.TOOLTIP_SKILL_AFFECT_DODGE,
                            "RESIST_NORMAL" : localeInfo.TOOLTIP_SKILL_AFFECT_RESIST_NORMAL,
                            "REFLECT_MELEE" : localeInfo.TOOLTIP_SKILL_AFFECT_REFLECT_MELEE,
                        }
    AFFECT_APPEND_TEXT_DICT =    {
                                    "DODGE" : "%",
                                    "RESIST_NORMAL" : "%",
                                    "REFLECT_MELEE" : "%",
                                }

    def __init__(self):
        ToolTip.__init__(self, self.SKILL_TOOL_TIP_WIDTH)
    def __del__(self):
        ToolTip.__del__(self)

    def SetSkill(self, skillIndex, skillLevel = -1):

        if 0 == skillIndex:
            return

        if skill.SKILL_TYPE_GUILD == skill.GetSkillType(skillIndex):

            if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth:
                self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH
                self.ResizeToolTip()

            self.AppendDefaultData(skillIndex)
            self.AppendSkillConditionData(skillIndex)
            self.AppendGuildSkillData(skillIndex, skillLevel)

        else:

            if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth:
                self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH
                self.ResizeToolTip()

            slotIndex = player.GetSkillSlotIndex(skillIndex)
            skillGrade = player.GetSkillGrade(slotIndex)
            skillLevel = player.GetSkillLevel(slotIndex)
            skillCurrentPercentage = player.GetSkillCurrentEfficientPercentage(slotIndex)
            skillNextPercentage = player.GetSkillNextEfficientPercentage(slotIndex)

            self.AppendDefaultData(skillIndex)
            self.AppendSkillConditionData(skillIndex)
            self.AppendSkillDataNew(slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage)
            self.AppendSkillRequirement(skillIndex, skillLevel)

        self.ShowToolTip()

    def SetSkillNew(self, slotIndex, skillIndex, skillGrade, skillLevel):

        if 0 == skillIndex:
            return

        if player.SKILL_INDEX_TONGSOL == skillIndex:

            slotIndex = player.GetSkillSlotIndex(skillIndex)
            skillLevel = player.GetSkillLevel(slotIndex)

            self.AppendDefaultData(skillIndex)
            self.AppendPartySkillData(skillGrade, skillLevel)

        elif player.SKILL_INDEX_RIDING == skillIndex:

            slotIndex = player.GetSkillSlotIndex(skillIndex)
            self.AppendSupportSkillDefaultData(skillIndex, skillGrade, skillLevel, 30)

        elif player.SKILL_INDEX_SUMMON == skillIndex:

            maxLevel = 10

            self.ClearToolTip()
            self.__SetSkillTitle(skillIndex, skillGrade)

            ## Description
            description = skill.GetSkillDescription(skillIndex)
            self.AppendDescription(description, 25)

            if skillLevel == 10:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR)
                self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (skillLevel*10), self.NORMAL_COLOR)

            else:
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR)
                self.__AppendSummonDescription(skillLevel, self.NORMAL_COLOR)

                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel+1), self.NEGATIVE_COLOR)
                self.__AppendSummonDescription(skillLevel+1, self.NEGATIVE_COLOR)

        elif skill.SKILL_TYPE_GUILD == skill.GetSkillType(skillIndex):

            if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth:
                self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH
                self.ResizeToolTip()

            self.AppendDefaultData(skillIndex)
            self.AppendSkillConditionData(skillIndex)
            self.AppendGuildSkillData(skillIndex, skillLevel)

        else:

            if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth:
                self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH
                self.ResizeToolTip()

            slotIndex = player.GetSkillSlotIndex(skillIndex)

            skillCurrentPercentage = player.GetSkillCurrentEfficientPercentage(slotIndex)
            skillNextPercentage = player.GetSkillNextEfficientPercentage(slotIndex)

            self.AppendDefaultData(skillIndex, skillGrade)
            self.AppendSkillConditionData(skillIndex)
            self.AppendSkillDataNew(slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage)
            self.AppendSkillRequirement(skillIndex, skillLevel)

        self.ShowToolTip()

    def __SetSkillTitle(self, skillIndex, skillGrade):
        self.SetTitle(skill.GetSkillName(skillIndex, skillGrade))
        self.__AppendSkillGradeName(skillIndex, skillGrade)

    def __AppendSkillGradeName(self, skillIndex, skillGrade):        
        if self.SKILL_GRADE_NAME.has_key(skillGrade):
            self.AppendSpace(5)
            self.AppendTextLine(self.SKILL_GRADE_NAME[skillGrade] % (skill.GetSkillName(skillIndex, 0)), self.CAN_LEVEL_UP_COLOR)

    def SetSkillOnlyName(self, slotIndex, skillIndex, skillGrade):
        if 0 == skillIndex:
            return

        slotIndex = player.GetSkillSlotIndex(skillIndex)

        self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH
        self.ResizeToolTip()

        self.ClearToolTip()
        self.__SetSkillTitle(skillIndex, skillGrade)        
        self.AppendDefaultData(skillIndex, skillGrade)
        self.AppendSkillConditionData(skillIndex)        
        self.ShowToolTip()

    def AppendDefaultData(self, skillIndex, skillGrade = 0):
        self.ClearToolTip()
        self.__SetSkillTitle(skillIndex, skillGrade)

        ## Level Limit
        levelLimit = skill.GetSkillLevelLimit(skillIndex)
        if levelLimit > 0:

            color = self.NORMAL_COLOR
            if player.GetStatus(player.LEVEL) < levelLimit:
                color = self.NEGATIVE_COLOR

            self.AppendSpace(5)
            self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_LEVEL % (levelLimit), color)

        ## Description
        description = skill.GetSkillDescription(skillIndex)
        self.AppendDescription(description, 25)

    def AppendSupportSkillDefaultData(self, skillIndex, skillGrade, skillLevel, maxLevel):
        self.ClearToolTip()
        self.__SetSkillTitle(skillIndex, skillGrade)

        ## Description
        description = skill.GetSkillDescription(skillIndex)
        self.AppendDescription(description, 25)

        if 1 == skillGrade:
            skillLevel += 19
        elif 2 == skillGrade:
            skillLevel += 29
        elif 3 == skillGrade:
            skillLevel = 40

        self.AppendSpace(5)
        self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_WITH_MAX % (skillLevel, maxLevel), self.NORMAL_COLOR)

    def AppendSkillConditionData(self, skillIndex):
        conditionDataCount = skill.GetSkillConditionDescriptionCount(skillIndex)
        if conditionDataCount > 0:
            self.AppendSpace(5)
            for i in xrange(conditionDataCount):
                self.AppendTextLine(skill.GetSkillConditionDescription(skillIndex, i), self.CONDITION_COLOR)

    def AppendGuildSkillData(self, skillIndex, skillLevel):
        skillMaxLevel = 7
        skillCurrentPercentage = float(skillLevel) / float(skillMaxLevel)
        skillNextPercentage = float(skillLevel+1) / float(skillMaxLevel)
        ## Current Level
        if skillLevel > 0:
            if self.HasSkillLevelDescription(skillIndex, skillLevel):
                self.AppendSpace(5)
                if skillLevel == skillMaxLevel:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR)
                else:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR)

                #####

                for i in xrange(skill.GetSkillAffectDescriptionCount(skillIndex)):
                    self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillCurrentPercentage), self.ENABLE_COLOR)

                ## Cooltime
                coolTime = skill.GetSkillCoolTime(skillIndex, skillCurrentPercentage)
                if coolTime > 0:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), self.ENABLE_COLOR)

                ## SP
                needGSP = skill.GetSkillNeedSP(skillIndex, skillCurrentPercentage)
                if needGSP > 0:
                    self.AppendTextLine(localeInfo.TOOLTIP_NEED_GSP % (needGSP), self.ENABLE_COLOR)

        ## Next Level
        if skillLevel < skillMaxLevel:
            if self.HasSkillLevelDescription(skillIndex, skillLevel+1):
                self.AppendSpace(5)
                self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_1 % (skillLevel+1, skillMaxLevel), self.DISABLE_COLOR)

                #####

                for i in xrange(skill.GetSkillAffectDescriptionCount(skillIndex)):
                    self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillNextPercentage), self.DISABLE_COLOR)

                ## Cooltime
                coolTime = skill.GetSkillCoolTime(skillIndex, skillNextPercentage)
                if coolTime > 0:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), self.DISABLE_COLOR)

                ## SP
                needGSP = skill.GetSkillNeedSP(skillIndex, skillNextPercentage)
                if needGSP > 0:
                    self.AppendTextLine(localeInfo.TOOLTIP_NEED_GSP % (needGSP), self.DISABLE_COLOR)

    def AppendSkillDataNew(self, slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage):

        self.skillMaxLevelStartDict = { 0 : 17, 1 : 7, 2 : 10, }
        self.skillMaxLevelEndDict = { 0 : 20, 1 : 10, 2 : 10, }

        skillLevelUpPoint = 1
        realSkillGrade = player.GetSkillGrade(slotIndex)
        skillMaxLevelStart = self.skillMaxLevelStartDict.get(realSkillGrade, 15)
        skillMaxLevelEnd = self.skillMaxLevelEndDict.get(realSkillGrade, 20)

        ## Current Level
        if skillLevel > 0:
            if self.HasSkillLevelDescription(skillIndex, skillLevel):
                self.AppendSpace(5)
                if skillGrade == skill.SKILL_GRADE_COUNT:
                    pass
                elif skillLevel == skillMaxLevelEnd:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR)
                else:
                    self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR)
                self.AppendSkillLevelDescriptionNew(skillIndex, skillCurrentPercentage, self.ENABLE_COLOR)

        ## Next Level
        if skillGrade != skill.SKILL_GRADE_COUNT:
            if skillLevel < skillMaxLevelEnd:
                if self.HasSkillLevelDescription(skillIndex, skillLevel+skillLevelUpPoint):
                    self.AppendSpace(5)
                    ## HPº¸°­, °üÅëȸÇÇ º¸Á¶½ºÅ³ÀÇ °æ¿ì
                    if skillIndex == 141 or skillIndex == 142:
                        self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_3 % (skillLevel+1), self.DISABLE_COLOR)
                    else:
                        self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_1 % (skillLevel+1, skillMaxLevelEnd), self.DISABLE_COLOR)
                    self.AppendSkillLevelDescriptionNew(skillIndex, skillNextPercentage, self.DISABLE_COLOR)

    def AppendSkillLevelDescriptionNew(self, skillIndex, skillPercentage, color):

        affectDataCount = skill.GetNewAffectDataCount(skillIndex)
        if affectDataCount > 0:
            for i in xrange(affectDataCount):
                type, minValue, maxValue = skill.GetNewAffectData(skillIndex, i, skillPercentage)

                if not self.AFFECT_NAME_DICT.has_key(type):
                    continue

                minValue = int(minValue)
                maxValue = int(maxValue)
                affectText = self.AFFECT_NAME_DICT[type]

                if "HP" == type:
                    if minValue < 0 and maxValue < 0:
                        minValue *= -1
                        maxValue *= -1

                    else:
                        affectText = localeInfo.TOOLTIP_SKILL_AFFECT_HEAL

                affectText += str(minValue)
                if minValue != maxValue:
                    affectText += " - " + str(maxValue)
                affectText += self.AFFECT_APPEND_TEXT_DICT.get(type, "")

                #import debugInfo
                #if debugInfo.IsDebugMode():
                #    affectText = "!!" + affectText

                self.AppendTextLine(affectText, color)
            
        else:
            for i in xrange(skill.GetSkillAffectDescriptionCount(skillIndex)):
                self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillPercentage), color)
        

        ## Duration
        duration = skill.GetDuration(skillIndex, skillPercentage)
        if duration > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_SKILL_DURATION % (duration), color)

        ## Cooltime
        coolTime = skill.GetSkillCoolTime(skillIndex, skillPercentage)
        if coolTime > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), color)

        ## SP
        needSP = skill.GetSkillNeedSP(skillIndex, skillPercentage)
        if needSP != 0:
            continuationSP = skill.GetSkillContinuationSP(skillIndex, skillPercentage)

            if skill.IsUseHPSkill(skillIndex):
                self.AppendNeedHP(needSP, continuationSP, color)
            else:
                self.AppendNeedSP(needSP, continuationSP, color)

    def AppendSkillRequirement(self, skillIndex, skillLevel):

        skillMaxLevel = skill.GetSkillMaxLevel(skillIndex)

        if skillLevel >= skillMaxLevel:
            return

        isAppendHorizontalLine = FALSE

        ## Requirement
        if skill.IsSkillRequirement(skillIndex):

            if not isAppendHorizontalLine:
                isAppendHorizontalLine = TRUE
                self.AppendHorizontalLine()

            requireSkillName, requireSkillLevel = skill.GetSkillRequirementData(skillIndex)

            color = self.CANNOT_LEVEL_UP_COLOR
            if skill.CheckRequirementSueccess(skillIndex):
                color = self.CAN_LEVEL_UP_COLOR
            self.AppendTextLine(localeInfo.TOOLTIP_REQUIREMENT_SKILL_LEVEL % (requireSkillName, requireSkillLevel), color)

        ## Require Stat
        requireStatCount = skill.GetSkillRequireStatCount(skillIndex)
        if requireStatCount > 0:

            for i in xrange(requireStatCount):
                type, level = skill.GetSkillRequireStatData(skillIndex, i)
                if self.POINT_NAME_DICT.has_key(type):

                    if not isAppendHorizontalLine:
                        isAppendHorizontalLine = TRUE
                        self.AppendHorizontalLine()

                    name = self.POINT_NAME_DICT[type]
                    color = self.CANNOT_LEVEL_UP_COLOR
                    if player.GetStatus(type) >= level:
                        color = self.CAN_LEVEL_UP_COLOR
                    self.AppendTextLine(localeInfo.TOOLTIP_REQUIREMENT_STAT_LEVEL % (name, level), color)

    def HasSkillLevelDescription(self, skillIndex, skillLevel):
        if skill.GetSkillAffectDescriptionCount(skillIndex) > 0:
            return TRUE
        if skill.GetSkillCoolTime(skillIndex, skillLevel) > 0:
            return TRUE
        if skill.GetSkillNeedSP(skillIndex, skillLevel) > 0:
            return TRUE

        return FALSE

    def AppendMasterAffectDescription(self, index, desc, color):
        self.AppendTextLine(desc, color)

    def AppendNextAffectDescription(self, index, desc):
        self.AppendTextLine(desc, self.DISABLE_COLOR)

    def AppendNeedHP(self, needSP, continuationSP, color):

        self.AppendTextLine(localeInfo.TOOLTIP_NEED_HP % (needSP), color)

        if continuationSP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_NEED_HP_PER_SEC % (continuationSP), color)

    def AppendNeedSP(self, needSP, continuationSP, color):

        if -1 == needSP:
            self.AppendTextLine(localeInfo.TOOLTIP_NEED_ALL_SP, color)

        else:
            self.AppendTextLine(localeInfo.TOOLTIP_NEED_SP % (needSP), color)

        if continuationSP > 0:
            self.AppendTextLine(localeInfo.TOOLTIP_NEED_SP_PER_SEC % (continuationSP), color)

    def AppendPartySkillData(self, skillGrade, skillLevel):

        if 1 == skillGrade:
            skillLevel += 19
        elif 2 == skillGrade:
            skillLevel += 29
        elif 3 == skillGrade:
            skillLevel =  40

        if skillLevel <= 0:
            return

        skillIndex = player.SKILL_INDEX_TONGSOL
        slotIndex = player.GetSkillSlotIndex(skillIndex)
        skillPower = player.GetSkillCurrentEfficientPercentage(slotIndex)
        if localeInfo.IsBRAZIL():
            k = skillPower
        else:
            k = player.GetSkillLevel(skillIndex) / 100.0
        self.AppendSpace(5)
        self.AutoAppendTextLine(localeInfo.TOOLTIP_PARTY_SKILL_LEVEL % skillLevel, self.NORMAL_COLOR)

        if skillLevel>=10:
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_ATTACKER % chop( 10 + 60 * k ))

        if skillLevel>=20:
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_BERSERKER     % chop(1 + 5 * k))
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_TANKER     % chop(50 + 1450 * k))

        if skillLevel>=25:
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_BUFFER % chop(5 + 45 * k ))

        if skillLevel>=35:
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_SKILL_MASTER % chop(25 + 600 * k ))

        if skillLevel>=40:
            self.AutoAppendTextLine(localeInfo.PARTY_SKILL_DEFENDER % chop( 5 + 30 * k ))

        self.AlignHorizonalCenter()

    def __AppendSummonDescription(self, skillLevel, color):
        if skillLevel > 1:
            self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (skillLevel * 10), color)
        elif 1 == skillLevel:
            self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (15), color)
        elif 0 == skillLevel:
            self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (10), color)


if __name__ == "__main__":    
    import app
    import wndMgr
    import systemSetting
    import mouseModule
    import grp
    import ui
    
    #wndMgr.SetOutlineFlag(TRUE)

    app.SetMouseHandler(mouseModule.mouseController)
    app.SetHairColorEnable(TRUE)
    wndMgr.SetMouseHandler(mouseModule.mouseController)
    wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight())
    app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1)
    mouseModule.mouseController.Create()

    toolTip = ItemToolTip()
    toolTip.ClearToolTip()
    #toolTip.AppendTextLine("Test")
    desc = "Item descriptions:|increase of width of display to 35 digits per row AND installation of function that the displayed words are not broken up in two parts, but instead if one word is too long to be displayed in this row, this word will start in the next row."
    summ = ""

    toolTip.AddItemData_Offline(10, desc, summ, 0, 0) 
    toolTip.Show()
    
    app.Loop()
 

 

Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.