QoL: Real Timer for items / affect

Items must use REAL_TIME or REAL_TIME_FIRST_USE
This commit is contained in:
rtw1x1
2026-01-21 21:48:18 +00:00
parent c1d86c0613
commit c94c2e2394
4 changed files with 159 additions and 66 deletions

View File

@@ -762,18 +762,18 @@ class GameWindow(ui.ScriptWindow):
# UNKNOWN_UPDATE
def BINARY_NEW_AddAffect(self, type, pointIdx, value, duration):
self.affectShower.BINARY_NEW_AddAffect(type, pointIdx, value, duration)
if chr.NEW_AFFECT_DRAGON_SOUL_DECK1 == type or chr.NEW_AFFECT_DRAGON_SOUL_DECK2 == type:
self.interface.DragonSoulActivate(type - chr.NEW_AFFECT_DRAGON_SOUL_DECK1)
elif chr.NEW_AFFECT_DRAGON_SOUL_QUALIFIED == type:
self.BINARY_DragonSoulGiveQuilification()
def BINARY_NEW_RemoveAffect(self, type, pointIdx):
self.affectShower.BINARY_NEW_RemoveAffect(type, pointIdx)
if chr.NEW_AFFECT_DRAGON_SOUL_DECK1 == type or chr.NEW_AFFECT_DRAGON_SOUL_DECK2 == type:
self.interface.DragonSoulDeactivate()
# END_OF_UNKNOWN_UPDATE
def ActivateSkillSlot(self, slotIndex):

View File

@@ -381,3 +381,32 @@ def SecondToHM(time):
if minute > 0:
text += str(minute) + MINUTE
return text
# Convert seconds to Days-Hours-Minutes-Seconds in real time
def RTSecondToDHMS(time):
text = ""
d = time // (24 * 3600)
time %= (24 * 3600)
h = time // 3600
time %= 3600
m = time // 60
s = time % 60
if d or not text:
if d:
text += "%dd " % d
if h or not text:
if h:
text += "%dh " % h
if m or not text:
if m:
text += "%dm " % m
if s or not text:
if s:
text += "%ds " % s
return text.strip()

View File

@@ -292,6 +292,9 @@ class AffectImage(ui.ExpandedImageBox):
self.endTime = 0
if duration > 0:
self.endTime = app.GetGlobalTimeStamp() + duration
leftTime = localeInfo.RTSecondToDHMS(self.endTime - app.GetGlobalTimeStamp())
self.toolTip.AppendTextLine("(%s : %s)" % (localeInfo.LEFT_TIME, leftTime))
self.toolTip.ResizeToolTip()
def UpdateAutoPotionDescription(self):
@@ -319,25 +322,14 @@ class AffectImage(ui.ExpandedImageBox):
def UpdateDescription(self):
if not self.isClocked:
self.__UpdateDescription2()
return
if not self.description:
return
toolTip = self.description
if self.endTime > 0:
leftTime = localeInfo.SecondToDHM(self.endTime - app.GetGlobalTimeStamp())
toolTip += " (%s : %s)" % (localeInfo.LEFT_TIME, leftTime)
self.SetToolTipText(toolTip, 0, 40)
#독일버전에서 시간을 제거하기 위해서 사용
def __UpdateDescription2(self):
if not self.description:
return
toolTip = self.description
self.SetToolTipText(toolTip, 0, 40)
leftTime = localeInfo.RTSecondToDHMS(self.endTime - app.GetGlobalTimeStamp())
self.toolTip.childrenList[-1].SetText("(%s : %s)" % (localeInfo.LEFT_TIME, leftTime))
def SetSkillAffectFlag(self, flag):
self.isSkillAffect = flag
@@ -404,7 +396,7 @@ class AffectShower(ui.Window):
chr.NEW_AFFECT_SKILL_BOOK_BONUS : (localeInfo.TOOLTIP_APPLY_SKILL_BOOK_BONUS, "d:/ymir work/ui/skill/common/affect/gold_premium.sub"),
chr.NEW_AFFECT_SKILL_BOOK_NO_DELAY : (localeInfo.TOOLTIP_APPLY_SKILL_BOOK_NO_DELAY, "d:/ymir work/ui/skill/common/affect/gold_premium.sub"),
# 자동물약 hp, sp
# <EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> hp, sp
chr.NEW_AFFECT_AUTO_HP_RECOVERY : (localeInfo.TOOLTIP_AUTO_POTION_REST, "d:/ymir work/ui/pattern/auto_hpgauge/05.dds"),
chr.NEW_AFFECT_AUTO_SP_RECOVERY : (localeInfo.TOOLTIP_AUTO_POTION_REST, "d:/ymir work/ui/pattern/auto_spgauge/05.dds"),
#chr.NEW_AFFECT_AUTO_HP_RECOVERY : (localeInfo.TOOLTIP_AUTO_POTION_REST, "d:/ymir work/ui/skill/common/affect/gold_premium.sub"),
@@ -424,7 +416,7 @@ class AffectShower(ui.Window):
MALL_DESC_IDX_START+player.POINT_PC_BANG_DROP_BONUS: (localeInfo.TOOLTIP_MALL_ITEMBONUS_P_STATIC, "d:/ymir work/ui/skill/common/affect/Item_Bonus_p_on.sub",),
}
if app.ENABLE_DRAGON_SOUL_SYSTEM:
# 용혼석 천, 지 덱.
# <EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD> õ, <20><> <20><>.
AFFECT_DATA_DICT[chr.NEW_AFFECT_DRAGON_SOUL_DECK1] = (localeInfo.TOOLTIP_DRAGON_SOUL_DECK1, "d:/ymir work/ui/dragonsoul/buff_ds_sky1.tga")
AFFECT_DATA_DICT[chr.NEW_AFFECT_DRAGON_SOUL_DECK2] = (localeInfo.TOOLTIP_DRAGON_SOUL_DECK2, "d:/ymir work/ui/dragonsoul/buff_ds_land1.tga")
@@ -449,7 +441,7 @@ class AffectShower(ui.Window):
self.affectImageDict={}
self.__ArrangeImageList()
def ClearAffects(self): ## 스킬 이펙트만 없앱니다.
def ClearAffects(self): ## <EFBFBD><EFBFBD>ų <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>۴ϴ<DBB4>.
self.living_affectImageDict={}
for key, image in self.affectImageDict.items():
if not image.IsSkillAffect():
@@ -475,7 +467,7 @@ class AffectShower(ui.Window):
if not self.AFFECT_DATA_DICT.has_key(affect):
return
## 용신의 가호, 선인의 교훈은 Duration 0 으로 설정한다.
## <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȣ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Duration <EFBFBD><EFBFBD> 0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if affect == chr.NEW_AFFECT_NO_DEATH_PENALTY or\
affect == chr.NEW_AFFECT_SKILL_BOOK_BONUS or\
affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY or\

View File

@@ -122,6 +122,8 @@ class ToolTip(ui.ThinBoard):
self.xPos = -1
self.yPos = -1
self.timeInfoList = []
self.defFontName = localeInfo.UI_DEF_FONT
self.ClearToolTip()
@@ -131,6 +133,7 @@ class ToolTip(ui.ThinBoard):
def ClearToolTip(self):
self.toolTipHeight = 12
self.childrenList = []
self.timeInfoList = []
def SetFollow(self, flag):
self.followFlag = flag
@@ -302,6 +305,12 @@ class ToolTip(ui.ThinBoard):
if not self.followFlag:
return
for timeText in self.timeInfoList:
if timeText["line"]:
leftSec = max(0, timeText["value"] - app.GetGlobalTimeStamp())
if not self.isShopItem:
timeText["line"].SetText(localeInfo.LEFT_TIME + ": " + localeInfo.RTSecondToDHMS(leftSec))
x = 0
y = 0
width = self.GetWidth()
@@ -549,6 +558,13 @@ class ItemToolTip(ToolTip):
return ToolTip.AppendTextLine(self, text, color, centerAlign)
def AppendTextLineTime(self, endTime, getLimit):
color = self.FONT_COLOR
if not self.CanEquip() and self.bCannotUseItemForceSetDisableColor:
color = self.DISABLE_COLOR
return ToolTip.AppendTextLineTime(self, endTime, getLimit, color)
def ClearToolTip(self):
self.isShopItem = False
self.toolTipWidth = self.TOOL_TIP_WIDTH
@@ -953,6 +969,20 @@ class ItemToolTip(ToolTip):
#Planning for the ring socket system has not yet been decided
#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 1 == bHasRealtimeFlag:
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
self.AppendSpace(5)
### Belt Item ###
elif item.ITEM_TYPE_BELT == itemType:
@@ -971,18 +1001,17 @@ class ItemToolTip(ToolTip):
self.AppendWearableInformation()
bHasRealtimeFlag = 0
# # Find out if there is limited time remaining
for i in xrange(item.LIMIT_MAX_NUM):
(limitType, limitValue) = item.GetLimit(i)
if item.LIMIT_REAL_TIME == limitType:
bHasRealtimeFlag = 1
## If exists, display related information. ex) Remaining time: 6 days 6 hours 58 minutes
if 1 == bHasRealtimeFlag:
self.AppendMallItemLastTime(metinSlot[0])
#dbg.TraceError("1) REAL_TIME flag On ")
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
## Rod ##
elif item.ITEM_TYPE_ROD == itemType:
@@ -1056,7 +1085,6 @@ class ItemToolTip(ToolTip):
elif item.ITEM_TYPE_UNIQUE == itemType:
if 0 != metinSlot:
bHasRealtimeFlag = 0
for i in xrange(item.LIMIT_MAX_NUM):
(limitType, limitValue) = item.GetLimit(i)
@@ -1064,12 +1092,18 @@ class ItemToolTip(ToolTip):
bHasRealtimeFlag = 1
if 1 == bHasRealtimeFlag:
self.AppendMallItemLastTime(metinSlot[0])
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
time = metinSlot[player.METIN_SOCKET_MAX_NUM-1]
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
else:
time = metinSlot[player.METIN_SOCKET_MAX_NUM - 1]
if 1 == item.GetValue(2): ## Real-time use flag / given even if not equipped
self.AppendMallItemLastTime(time)
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(time, item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(time, item.GetLimitValue(1))
else:
self.AppendUniqueItemLastTime(time)
@@ -1148,22 +1182,23 @@ class ItemToolTip(ToolTip):
if item.LIMIT_REAL_TIME == limitType:
bHasRealtimeFlag = 1
## If exists, display related information. ex) Remaining time: 6 days 6 hours 58 minutes
if 1 == bHasRealtimeFlag:
self.AppendMallItemLastTime(metinSlot[0])
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
else:
# ... This... This time isn't checked on the server...
# I don't know why this exists, but let's just leave it...
if 0 != metinSlot:
time = metinSlot[player.METIN_SOCKET_MAX_NUM-1]
time = metinSlot[player.METIN_SOCKET_MAX_NUM - 1]
## Real-time usage Flag
if 1 == item.GetValue(2):
self.AppendMallItemLastTime(time)
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(time, item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(time, item.GetLimitValue(1))
elif item.USE_TIME_CHARGE_PER == itemSubType:
bHasRealtimeFlag = 0
for i in xrange(item.LIMIT_MAX_NUM):
(limitType, limitValue) = item.GetLimit(i)
@@ -1175,9 +1210,11 @@ class ItemToolTip(ToolTip):
else:
self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_PER(item.GetValue(0)))
## If available, display relevant information. ex) Time remaining: 6 days, 6 hours, 58 minutes
if 1 == bHasRealtimeFlag:
self.AppendMallItemLastTime(metinSlot[0])
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
elif item.USE_TIME_CHARGE_FIX == itemSubType:
bHasRealtimeFlag = 0
@@ -1186,21 +1223,32 @@ class ItemToolTip(ToolTip):
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)))
## If exists, display related information. ex) Remaining time: 6 days 6 hours 58 minutes
if 1 == bHasRealtimeFlag:
self.AppendMallItemLastTime(metinSlot[0])
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
elif item.ITEM_TYPE_QUEST == itemType:
bHasRealtimeFlag = 0
for i in xrange(item.LIMIT_MAX_NUM):
(limitType, limitValue) = item.GetLimit(i)
if item.LIMIT_REAL_TIME == limitType:
self.AppendMallItemLastTime(metinSlot[0])
bHasRealtimeFlag = 1
if 1 == bHasRealtimeFlag:
if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0):
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0))
else:
self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1))
elif item.ITEM_TYPE_DS == itemType:
self.AppendTextLine(self.__DragonSoulInfoString(itemVnum))
self.__AppendAttributeInformation(attrSlot)
@@ -1209,17 +1257,13 @@ class ItemToolTip(ToolTip):
for i in xrange(item.LIMIT_MAX_NUM):
(limitType, limitValue) = item.GetLimit(i)
#dbg.TraceError("LimitType : %d, limitValue : %d" % (limitType, limitValue))
limitValue2 = item.GetLimitValue(i)
if item.LIMIT_REAL_TIME_START_FIRST_USE == limitType:
self.AppendRealTimeStartFirstUseLastTime(item, metinSlot, i)
#dbg.TraceError("2) REAL_TIME_START_FIRST_USE flag On ")
self.AppendRealTimeStartFirstUseLastTime(item, metinSlot, i, limitValue2)
elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType:
self.AppendTimerBasedOnWearLastTime(metinSlot)
#dbg.TraceError("1) REAL_TIME flag On ")
self.ShowToolTip()
@@ -1782,7 +1826,7 @@ class ItemToolTip(ToolTip):
self.toolTipHeight += 16 + 2
if 0 != leftTime:
timeText = (localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(leftTime))
timeText = (localeInfo.LEFT_TIME + " : " + localeInfo.RTSecondToDHMS(leftTime))
timeTextLine = ui.TextLine()
timeTextLine.SetParent(self)
@@ -1808,14 +1852,39 @@ class ItemToolTip(ToolTip):
self.AppendTextLine(localeInfo.TOOLTIP_FISH_LEN % (float(size) / 100.0), self.NORMAL_COLOR)
def AppendUniqueItemLastTime(self, restMin):
restSecond = restMin*60
if restMin > 0:
restSecond = restMin * 60
self.AppendSpace(5)
self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(restSecond), self.NORMAL_COLOR)
self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.RTSecondToDHMS(restSecond), self.NORMAL_COLOR)
def AppendMallItemLastTime(self, endTime):
leftSec = max(0, endTime - app.GetGlobalTimeStamp())
def AppendMallItemLastTime(self, endTime, getLimit):
if endTime > 0:
self.AppendSpace(5)
self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.SecondToDHM(leftSec), self.NORMAL_COLOR)
self.AppendTextLineTime(endTime, getLimit)
def AppendTextLineTime(self, endTime, getLimit, color=FONT_COLOR):
leftSec = max(0, endTime - app.GetGlobalTimeStamp())
timeTextLine = ui.TextLine()
timeTextLine.SetParent(self)
timeTextLine.SetFontName(self.defFontName)
timeTextLine.SetPackedFontColor(color)
if not self.isShopItem:
timeTextLine.SetText(localeInfo.LEFT_TIME + ": " + localeInfo.RTSecondToDHMS(leftSec))
timeTextLine.SetOutline()
timeTextLine.SetFeather(False)
timeTextLine.SetPosition(self.toolTipWidth / 2, self.toolTipHeight)
timeTextLine.SetHorizontalAlignCenter()
timeTextLine.Show()
self.timeInfoList.append({"line": timeTextLine, "value": endTime, "limit": getLimit})
self.toolTipHeight += self.TEXT_LINE_HEIGHT
self.ResizeToolTip()
return timeTextLine
def AppendTimerBasedOnWearLastTime(self, metinSlot):
if 0 == metinSlot[0]:
@@ -1823,9 +1892,9 @@ class ItemToolTip(ToolTip):
self.AppendTextLine(localeInfo.CANNOT_USE, self.DISABLE_COLOR)
else:
endTime = app.GetGlobalTimeStamp() + metinSlot[0]
self.AppendMallItemLastTime(endTime)
self.AppendMallItemLastTime(endTime, getLimit)
def AppendRealTimeStartFirstUseLastTime(self, item, metinSlot, limitIndex):
def AppendRealTimeStartFirstUseLastTime(self, item, metinSlot, limitIndex, getLimit):
useCount = metinSlot[1]
endTime = metinSlot[0]
@@ -1836,9 +1905,12 @@ class ItemToolTip(ToolTip):
(limitType, limitValue) = item.GetLimit(limitIndex)
endTime = limitValue
self.AppendUniqueItemLastTime(endTime / 60)
return
endTime += app.GetGlobalTimeStamp()
self.AppendMallItemLastTime(endTime)
self.AppendMallItemLastTime(endTime, getLimit)
class HyperlinkItemToolTip(ItemToolTip):
def __init__(self):