Таймер для дебафов ИНТЕРЛЮД
qq all.
А как вообще четкие пасаны делают такую фичу? Если ничего не путаю, то нужно в либах ковыряться каких-то (nwindow.dll вроде). И чего там искать-то? И вообще КАК? там же всё а-ля
:??0FCustomTooltip@@QAE@XZ
Для меня это такой высший пилотаж, что даже и не мечтаю когда-нибудь допереть до всего этого...
Потому и делаю через костыль с анреалскриптами. грубо говоря - время жизни бафов и дебафов (ведь клиенту нужно же знать, сколько должен висеть этот красный квадратик) шлется от сервера для отображения их на панели скиллов в AbnormalStatusWnd.uc. А потом уже в ToolTip.uc начинаются свои нюансы.
if (!IsDeBuff(Item.ClassID, Item.Level) && Item.Reserved>=0)
{
код прорисовки тултипа чтобы при наведении на скилл показывался кулдаун. И как видно из условия, секция для отрисовки времени будет только для недебафов и, более того, эффектов, которые имеют int параметр >0. А дебафы, что самое печальное, в этом параметре всегда имеют -1.
}
и что я делаю сейчас:
добавляю 3 строчки в функцию HandleAddNormalStatus класса AbnormalStatusWnd.uc
то есть во время прорисовки бафов проверяется, дебаф ли это и в случае тру, посылаются три переменные (ClassID, Name, RemainTime) в функцию ShowMsg класса, который дополнительно создал.
В коде далее будет видно, что порядковый элемент массива = айди дебафа. а это четырехзначные числа...
Опять же повторюсь, это пока для тестирования и использование динамических массивов будет изменено на обычные массивы или вообще можно как-нибудь изъебнуться и обойтись только локальными переменными и одним-единственным массивом. Сколько вообще можно иметь максимально допустимо одновременно висящих на персе дебафов? Поди 10 штук наверное. Вот и можно ограничиться этим количеством [10]
т.е. в этом новом классе DebufTimeInformer.uc имеется функция ShowMsg( int tab, string name, int timer ), которая и содержит всю нужную инфу: айди дебафа, название, оставшееся время. Вот тут и напрашивается идея создать таймер с обратным отсчетом, чтобы выводить эту инфу на экран (в идеальном варианте - писать в тултип поверх скилла в абнормал статус)
пока что не идеальный вариант:
ну и вдобавок создается одноименный винд с текстбоксом info1 в interface.xdat. Как видно в видео, на экране показывается таймер только для последнего дебафа. Впрочем, еще раз повторюсь, код был набросан вчера вечером, чтобы убедиться работает ли. Теперь уже можно сделать показ всех дебафов и компоновать их в один блок или размещать один под другим, короче - реализаций полно. Вот с тултипом пока еще не разобрался, а точнее с ParamAdd(m_Info.Condition, "Type", "RemainTime"); Добавил в ToolTip.uc:
И без понятия, что вместо "RemainTime" нужно слать. Condition судя по UIEventManager.uc представляет из себя динамический тект. Даже не знаю, как это Пробовал так же слать и сюда string (Script.Gettooltip(Item.ClassID)), но эффект тот же - счетчик не отсчитывается. Только при добавлении/удалении бафов/дебафов происходит обновление счетчика.
Нид ХЭЛП по этому вопросу
[media]https://youtu.be/LQxoGH6TsMI[/media]
qq all.
А как вообще четкие пасаны делают такую фичу? Если ничего не путаю, то нужно в либах ковыряться каких-то (nwindow.dll вроде). И чего там искать-то? И вообще КАК? там же всё а-ля
:??0FCustomTooltip@@QAE@XZ
Для меня это такой высший пилотаж, что даже и не мечтаю когда-нибудь допереть до всего этого...
Потому и делаю через костыль с анреалскриптами. грубо говоря - время жизни бафов и дебафов (ведь клиенту нужно же знать, сколько должен висеть этот красный квадратик) шлется от сервера для отображения их на панели скиллов в AbnormalStatusWnd.uc. А потом уже в ToolTip.uc начинаются свои нюансы.
if (!IsDeBuff(Item.ClassID, Item.Level) && Item.Reserved>=0)
{
код прорисовки тултипа чтобы при наведении на скилл показывался кулдаун. И как видно из условия, секция для отрисовки времени будет только для недебафов и, более того, эффектов, которые имеют int параметр >0. А дебафы, что самое печальное, в этом параметре всегда имеют -1.
}
и что я делаю сейчас:
добавляю 3 строчки в функцию HandleAddNormalStatus класса AbnormalStatusWnd.uc
function HandleAddNormalStatus(string param)
{
local int i;
local int Max;
local int BuffCnt;
local StatusIconInfo info;
local DebufTimeInformer script;
script = DebufTimeInformer ( GetScript ( "DebufTimeInformer" ) );
ClearStatus(false, false);
info.Size = 24;
info.BackTex = "L2UI.EtcWndBack.AbnormalBack";
info.bShow = true;
info.bEtcItem = false;
info.bShortItem = false;
BuffCnt = 0;
ParseInt(param, "Max", Max);
for (i=0; i<Max; i++)
{
ParseInt(param, "SkillID_" $ i, info.ClassID);
ParseInt(param, "SkillLevel_" $ i, info.Level);
ParseInt(param, "RemainTime_" $ i, info.RemainTime);
ParseString(param, "Name_" $ i, info.Name);
ParseString(param, "IconName_" $ i, info.IconName);
ParseString(param, "Description_" $ i, info.Description);
if (IsDeBuff(info.ClassID, info.Level))
script.ShowMsg( info.ClassID, info.Name, info.RemainTime);
if (info.ClassID>0)
{
if (BuffCnt%NSTATUSICON_MAXCOL == 0)
{
m_NormalStatusRow++;
class'UIAPI_STATUSICONCTRL'.static.InsertRow("AbnormalStatusWnd.StatusIcon", m_NormalStatusRow);
}
class'UIAPI_STATUSICONCTRL'.static.AddCol("AbnormalStatusWnd.StatusIcon", m_NormalStatusRow, info);
BuffCnt++;
}
}
if (m_EtcStatusRow>-1)
{
m_EtcStatusRow = m_NormalStatusRow + 1;
}
if (m_ShortStatusRow>-1)
{
m_ShortStatusRow = m_NormalStatusRow + 1;
}
UpdateWindowSize();
}
{
local int i;
local int Max;
local int BuffCnt;
local StatusIconInfo info;
local DebufTimeInformer script;
script = DebufTimeInformer ( GetScript ( "DebufTimeInformer" ) );
ClearStatus(false, false);
info.Size = 24;
info.BackTex = "L2UI.EtcWndBack.AbnormalBack";
info.bShow = true;
info.bEtcItem = false;
info.bShortItem = false;
BuffCnt = 0;
ParseInt(param, "Max", Max);
for (i=0; i<Max; i++)
{
ParseInt(param, "SkillID_" $ i, info.ClassID);
ParseInt(param, "SkillLevel_" $ i, info.Level);
ParseInt(param, "RemainTime_" $ i, info.RemainTime);
ParseString(param, "Name_" $ i, info.Name);
ParseString(param, "IconName_" $ i, info.IconName);
ParseString(param, "Description_" $ i, info.Description);
if (IsDeBuff(info.ClassID, info.Level))
script.ShowMsg( info.ClassID, info.Name, info.RemainTime);
if (info.ClassID>0)
{
if (BuffCnt%NSTATUSICON_MAXCOL == 0)
{
m_NormalStatusRow++;
class'UIAPI_STATUSICONCTRL'.static.InsertRow("AbnormalStatusWnd.StatusIcon", m_NormalStatusRow);
}
class'UIAPI_STATUSICONCTRL'.static.AddCol("AbnormalStatusWnd.StatusIcon", m_NormalStatusRow, info);
BuffCnt++;
}
}
if (m_EtcStatusRow>-1)
{
m_EtcStatusRow = m_NormalStatusRow + 1;
}
if (m_ShortStatusRow>-1)
{
m_ShortStatusRow = m_NormalStatusRow + 1;
}
UpdateWindowSize();
}
В коде далее будет видно, что порядковый элемент массива = айди дебафа. а это четырехзначные числа...
Опять же повторюсь, это пока для тестирования и использование динамических массивов будет изменено на обычные массивы или вообще можно как-нибудь изъебнуться и обойтись только локальными переменными и одним-единственным массивом. Сколько вообще можно иметь максимально допустимо одновременно висящих на персе дебафов? Поди 10 штук наверное. Вот и можно ограничиться этим количеством [10]
т.е. в этом новом классе DebufTimeInformer.uc имеется функция ShowMsg( int tab, string name, int timer ), которая и содержит всю нужную инфу: айди дебафа, название, оставшееся время. Вот тут и напрашивается идея создать таймер с обратным отсчетом, чтобы выводить эту инфу на экран (в идеальном варианте - писать в тултип поверх скилла в абнормал статус)
пока что не идеальный вариант:
class DebufTimeInformer extends UICommonAPI;
var array<int> TimeOnStart;
var array<int> requiredTime;
var array<int> delta;
var array<string>msg;
var Color colorCyan;
var WindowHandle ME;
function OnLoad()
{
colorCyan.R = 7;
colorCyan.G = 222;
colorCyan.B = 215;
colorCyan.A = 255;
Me = GetHandle ( "DebufTimeInformer" );
}
function OnTimer ( int TimerId )
{
local int tab;
tab = int (Left(TimerId,4));
if ( TimerId == tab )
{
Me.KillTimer ( tab );
Countdown ( tab );
}
}
function int Gettooltip( int ID ) // в планах вызывать эту функцию из ToolTip.uc чтобы писать время так же как и обычных скиллов
{
local int i_time;
i_time = delta[id];
return i_time;
}
function ShowMsg( int tab, string name, int timer )
{
AddSystemMessage ( "ID "$ tab $ "\\n Name "$ name $ "\\n timer " $ timer, colorCyan );
Me.KillTimer( tab );
TimeOnStart[tab] = SystemTime();
requiredTime[tab] = timer;
msg[tab] = name;
class'UIAPI_TEXTBOX'.static.SetTextColor( "DebufTimeInformer.info1", colorCyan );
Countdown( tab );
}
function Countdown( int tab )
{
local string s_time, s_info;
delta[tab] = TimeOnStart[tab] - SystemTime() + requiredTime[tab];
if( delta[tab] <= 0 )
{
s_time = "00:00";
Me.KillTimer( tab );
HideWindow("DebufTimeInformer");
}
else
{
s_time = Time2Str( delta[tab] );
Me.SetTimer( tab,1000 );
ShowWindow("DebufTimeInformer");
UpdateWindowSize();
}
s_info = msg[tab] @ s_time;
class'UIAPI_TEXTBOX'.static. SetText ( "DebufTimeInformer.info1", s_info );
}
function string Time2Str(int time)
{
local string s_result, s_sec, s_min;
local int i_sec, i_min;
i_sec = time % 60;
i_min = time / 60;
if ( i_sec<10 )
s_sec = "0" $ string(i_sec);
else
s_sec = string(i_sec);
if( i_min<10 )
s_min = "0" $ string(i_min);
else
s_min = string(i_min);
s_result = s_min $ ":" $ s_sec;
return s_result;
}
function int SystemTime()
{
local string time;
local int i_time;
time = GetTimeString();
i_time = int(Left(time,2))*60*60+int(Mid(time,3,2))*60+int(Right(time,2));
return i_time;
}
defaultproperties
{
}
var array<int> TimeOnStart;
var array<int> requiredTime;
var array<int> delta;
var array<string>msg;
var Color colorCyan;
var WindowHandle ME;
function OnLoad()
{
colorCyan.R = 7;
colorCyan.G = 222;
colorCyan.B = 215;
colorCyan.A = 255;
Me = GetHandle ( "DebufTimeInformer" );
}
function OnTimer ( int TimerId )
{
local int tab;
tab = int (Left(TimerId,4));
if ( TimerId == tab )
{
Me.KillTimer ( tab );
Countdown ( tab );
}
}
function int Gettooltip( int ID ) // в планах вызывать эту функцию из ToolTip.uc чтобы писать время так же как и обычных скиллов
{
local int i_time;
i_time = delta[id];
return i_time;
}
function ShowMsg( int tab, string name, int timer )
{
AddSystemMessage ( "ID "$ tab $ "\\n Name "$ name $ "\\n timer " $ timer, colorCyan );
Me.KillTimer( tab );
TimeOnStart[tab] = SystemTime();
requiredTime[tab] = timer;
msg[tab] = name;
class'UIAPI_TEXTBOX'.static.SetTextColor( "DebufTimeInformer.info1", colorCyan );
Countdown( tab );
}
function Countdown( int tab )
{
local string s_time, s_info;
delta[tab] = TimeOnStart[tab] - SystemTime() + requiredTime[tab];
if( delta[tab] <= 0 )
{
s_time = "00:00";
Me.KillTimer( tab );
HideWindow("DebufTimeInformer");
}
else
{
s_time = Time2Str( delta[tab] );
Me.SetTimer( tab,1000 );
ShowWindow("DebufTimeInformer");
UpdateWindowSize();
}
s_info = msg[tab] @ s_time;
class'UIAPI_TEXTBOX'.static. SetText ( "DebufTimeInformer.info1", s_info );
}
function string Time2Str(int time)
{
local string s_result, s_sec, s_min;
local int i_sec, i_min;
i_sec = time % 60;
i_min = time / 60;
if ( i_sec<10 )
s_sec = "0" $ string(i_sec);
else
s_sec = string(i_sec);
if( i_min<10 )
s_min = "0" $ string(i_min);
else
s_min = string(i_min);
s_result = s_min $ ":" $ s_sec;
return s_result;
}
function int SystemTime()
{
local string time;
local int i_time;
time = GetTimeString();
i_time = int(Left(time,2))*60*60+int(Mid(time,3,2))*60+int(Right(time,2));
return i_time;
}
defaultproperties
{
}
ну и вдобавок создается одноименный винд с текстбоксом info1 в interface.xdat. Как видно в видео, на экране показывается таймер только для последнего дебафа. Впрочем, еще раз повторюсь, код был набросан вчера вечером, чтобы убедиться работает ли. Теперь уже можно сделать показ всех дебафов и компоновать их в один блок или размещать один под другим, короче - реализаций полно. Вот с тултипом пока еще не разобрался, а точнее с ParamAdd(m_Info.Condition, "Type", "RemainTime"); Добавил в ToolTip.uc:
local string kokoko;
local DebufTimeInformer script;
script = DebufTimeInformer ( GetScript ( "DebufTimeInformer" ) );
...
...
if (IsDeBuff(Item.ClassID, Item.Level) == true )
{
kokoko = string (Script.Gettooltip(Item.ClassID));
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.bLineBreak = true;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 163;
m_Info.t_color.G = 163;
m_Info.t_color.B = 163;
m_Info.t_color.A = 255;
m_Info.t_ID = 1199;
EndItem();
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 163;
m_Info.t_color.G = 163;
m_Info.t_color.B = 163;
m_Info.t_color.A = 255;
m_Info.t_strText = " : ";
EndItem();
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 176;
m_Info.t_color.G = 155;
m_Info.t_color.B = 121;
m_Info.t_color.A = 255;
m_Info.t_strText = MakeBuffTimeStr(Script.Gettooltip(Item.ClassID)); // тек время как раз и берется из DebufTimeInformer.uc
ParamAdd(m_Info.Condition, "Type", "RemainTime");
//ParamAdd(m_Info.Condition, "Type", kokoko);
EndItem();
local DebufTimeInformer script;
script = DebufTimeInformer ( GetScript ( "DebufTimeInformer" ) );
...
...
if (IsDeBuff(Item.ClassID, Item.Level) == true )
{
kokoko = string (Script.Gettooltip(Item.ClassID));
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.bLineBreak = true;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 163;
m_Info.t_color.G = 163;
m_Info.t_color.B = 163;
m_Info.t_color.A = 255;
m_Info.t_ID = 1199;
EndItem();
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 163;
m_Info.t_color.G = 163;
m_Info.t_color.B = 163;
m_Info.t_color.A = 255;
m_Info.t_strText = " : ";
EndItem();
StartItem();
m_Info.eType = DIT_TEXT;
m_Info.nOffSetY = 6;
m_Info.t_bDrawOneLine = true;
m_Info.t_color.R = 176;
m_Info.t_color.G = 155;
m_Info.t_color.B = 121;
m_Info.t_color.A = 255;
m_Info.t_strText = MakeBuffTimeStr(Script.Gettooltip(Item.ClassID)); // тек время как раз и берется из DebufTimeInformer.uc
ParamAdd(m_Info.Condition, "Type", "RemainTime");
//ParamAdd(m_Info.Condition, "Type", kokoko);
EndItem();
Нид ХЭЛП по этому вопросу
[media]https://youtu.be/LQxoGH6TsMI[/media]