/* 文件名:NewTitle.nut 路径:Project/NewTitle/NewTitle.nut 创建日期:2026-01-29 02:36 文件用途: */ NewTitleC_Img_Map <- {}; class NewTitleC extends LenheartNewUI_Windows { //调试模式 // DeBugMode = true; //不是窗口 // NoWindow = true; //是否可见 Visible = false; Img = Rindro_Image("interface2/titlebook/titlebook_ver2.img"); BackGroundAni = null; BackGroundAni2 = null; ImgT = Rindro_Image("newtitle/nangua.img"); //信息 Info = null; //数据信息 DataInfo = null; //渲染指导信息 ShowData = null; //称谓类别 CategoryTitle = null; //称谓按钮List TitleButtonList = null; //是否显示复选框 IsDisplayBtn = null; //层级输入框 InputObject = null; //当前类别 CurrentCategory = 0; // 当前类别索引 //当前页数 CurrentPage = 0; //当前选中称谓ID CurrentSelectId = 1; //当前选中称谓信息 CurrentSelectInfo = null; //是否拥有当前选中称谓 CurrentSelectHaveFlag = false; //当前选中缩放 CurrentSelectScale = 1.0; //当前选中X轴偏移 CurrentSelectXOffset = 0; //当前选中Y轴偏移 CurrentSelectYOffset = 0; function CheckBookInfo() { SendPackEx({ op = 21012001 }) } constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) { DataInfo = {}; Childrens = []; //读取PVF InitPvf(); //注册控件 RegisterWidget(); LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH); //初始化背景动画 local FrameArr = []; for (local i = 0; i< 16; i++) { local T = { ImgIndex = i, Delay = 120, Pos = [0, 0] } FrameArr.append(T); } BackGroundAni = Rindro_CustomAnimation("interface2/titlebook/titlebook_effects.img", FrameArr); local FrameArr2 = []; for (local i = 16; i< 32; i++) { local T = { ImgIndex = i, Delay = 120, Pos = [0, 0] } FrameArr2.append(T); } BackGroundAni2 = Rindro_CustomAnimation("interface2/titlebook/titlebook_effects.img", FrameArr2); //因为json在传输中会将数字Key转为字符串 所以需要转int Pack_Control.rawset(21012002, function(Chunk) { local Jso = Json.Decode(Chunk); foreach(index, value in Jso.Info) { DataInfo.rawset(index.tointeger(), value); } }.bindenv(this)); //接受需要渲染的称谓数据 Pack_Control.rawset(21012004, function(Chunk) { ShowData = {}; local Jso = Json.Decode(Chunk); foreach(index, value in Jso.ShowData) { foreach(DrawObj in value) { local PvfInfo = GetTitlePvfInfo(DrawObj.Id.tointeger()) DrawObj.Category <- PvfInfo.Category; DrawObj.Content <- Json.Decode(Json.Encode(PvfInfo.Content)); } ShowData.rawset(index.tointeger(), value); } }.bindenv(this)); CheckBookInfo(); WorldDrawVirtualCharacterCallBackFunc.rawset("NewTitleC", function(Layer, XPos, YPos, WorldId, Name) { if (ShowData) { if (ShowData.rawin(WorldId)) { foreach(ShowInfo in ShowData[WorldId]) { //图像 if (ShowInfo.Content.type == "img") { //没有添加缓存的先添加缓存 if (!NewTitleC_Img_Map.rawin(ShowInfo.Content.img)) { NewTitleC_Img_Map.rawset(ShowInfo.Content.img, Rindro_Image(ShowInfo.Content.img)); } //这里从展示框的左上角开始算起 展示框大小为 290 * 115 如果添加新的称谓 可以现在PS里缩放 并记录下针对左上角坐标的偏移 与 缩放值 NewTitleC_Img_Map[ShowInfo.Content.img].DrawExPng(ShowInfo.Content.index, XPos + ShowInfo.XOffset, YPos + ShowInfo.YOffset, 0, 0xffffffff, ShowInfo.Scale.tofloat(), ShowInfo.Scale.tofloat()) } //Ani else if (ShowInfo.Content.type == "ani") { local Ani = DrawAniEx(XPos + ShowInfo.XOffset, YPos + ShowInfo.YOffset, ShowInfo.Content.ani); Ani.setImageRateFromOriginal(ShowInfo.Scale.tofloat(), ShowInfo.Scale.tofloat()); Ani.setAutoLayerWorkAnimationAddSizeRate(ShowInfo.Scale.tofloat(), ShowInfo.Scale.tofloat()); } } } } }.bindenv(this)); } function RegisterWidget() { //关闭按钮 local CloseButton = LenheartNewUI_BaseButton(435, 4, 11, 12, "interface/lenheartwindowcommon.img", 276); CloseButton.OnClick = function() { this.Visible = false; }.bindenv(this); Childrens.append(CloseButton); //注册类别 RegisterCategoryTitle(); TitleButtonList = []; for (local i = 0; i< 9; i++) { local TitleButtonBuffer = NewTitleC_Button(14, 138 + (37 * i), Img); TitleButtonBuffer.OnClickEx = function(Btn) { CurrentSelectId = Btn.Id; CurrentSelectInfo = Btn.Info; local DataInfoObj = null; //如果有数据 if (DataInfo.rawin(CurrentSelectId)) { DataInfoObj = DataInfo[CurrentSelectId]; IsDisplayBtn.IsSelected = DataInfoObj.IsDisplay; if (IsDisplayBtn.IsSelected) IsDisplayBtn.State = 1; else IsDisplayBtn.State = 0; InputObject.SetStr(DataInfoObj.ZOrder.tostring()); CurrentSelectScale = DataInfoObj.Scale; CurrentSelectXOffset = DataInfoObj.XOffset; CurrentSelectYOffset = DataInfoObj.YOffset; CurrentSelectHaveFlag = true; } else { CurrentSelectHaveFlag = false; } }.bindenv(this); AddChild(TitleButtonBuffer); TitleButtonList.append(TitleButtonBuffer); } local CheckCurrentSelectIdFunc = function(Btn) { //如果没有选中 或者没有信息 或者没有拥有 if (!CurrentSelectId || !CurrentSelectInfo || !DataInfo.rawin(CurrentSelectId)) { Btn.Visible = false; } else { Btn.Visible = true; } }.bindenv(this); //是否显示复选框 IsDisplayBtn = NewTitleC_SwitchButton(252, 424); IsDisplayBtn.OnClickEx = function(Btn) { }.bindenv(this); IsDisplayBtn.SetCallBackFunc(CheckCurrentSelectIdFunc); AddChild(IsDisplayBtn); //层级输入框 InputObject = LenheartNewUI_BaseInput(360, 423, 50, 20); InputObject.SetCallBackFunc(CheckCurrentSelectIdFunc); AddChild(InputObject); // InputObject.SetStr("131232"); //保存按钮 local ConfirmButton = LenheartNewUI_ButtonText(364, 481, 15, " 保 存"); ConfirmButton.DWidth = 18; ConfirmButton.Width = 74; ConfirmButton.SetTextOffset(-4, 1); ConfirmButton.OnClickEx = function(Btn) { if (Btn.Visible) { local Order = 1; try { Order = InputObject.str.tointeger(); } catch (exception) { } SendPackEx({ op = 21012003, Id = CurrentSelectId, SendInfo = { IsDisplay = IsDisplayBtn.IsSelected, Scale = CurrentSelectScale, XOffset = CurrentSelectXOffset, YOffset = CurrentSelectYOffset, ZOrder = Order } }) CheckBookInfo(); } }.bindenv(this); ConfirmButton.SetCallBackFunc(CheckCurrentSelectIdFunc); AddChild(ConfirmButton); for (local i = 0; i< 3; i++) { local ControlObject = "CurrentSelectScale"; if (i == 1) ControlObject = "CurrentSelectXOffset"; if (i == 2) ControlObject = "CurrentSelectYOffset"; local BtnBuffer = LenheartNewUI_BaseButton(205, 440 + (i * 16), 20, 15, "interface/lenheartwindowcommon.img", 528); BtnBuffer.Data = ControlObject; BtnBuffer.OnClickEx = function(Btn) { if (Btn.Data == "CurrentSelectScale") { this[Btn.Data] -= 0.1; } else { this[Btn.Data] -= 10; } FixCustomData(); }.bindenv(this); BtnBuffer.SetCallBackFunc(CheckCurrentSelectIdFunc); Childrens.append(BtnBuffer); BtnBuffer = LenheartNewUI_BaseButton(232, 440 + (i * 16), 15, 15, "interface/lenheartwindowcommon.img", 34); BtnBuffer.Data = ControlObject; BtnBuffer.OnClickEx = function(Btn) { if (Btn.Data == "CurrentSelectScale") { this[Btn.Data] -= 0.01; } else { this[Btn.Data] -= 1; } FixCustomData(); }.bindenv(this); BtnBuffer.SetCallBackFunc(CheckCurrentSelectIdFunc); Childrens.append(BtnBuffer); BtnBuffer = LenheartNewUI_BaseButton(284, 440 + (i * 16), 15, 15, "interface/lenheartwindowcommon.img", 38); BtnBuffer.Data = ControlObject; BtnBuffer.OnClickEx = function(Btn) { if (Btn.Data == "CurrentSelectScale") { this[Btn.Data] += 0.01; } else { this[Btn.Data] += 1; } FixCustomData(); }.bindenv(this); BtnBuffer.SetCallBackFunc(CheckCurrentSelectIdFunc); Childrens.append(BtnBuffer); BtnBuffer = LenheartNewUI_BaseButton(311, 440 + (i * 16), 20, 15, "interface/lenheartwindowcommon.img", 532); BtnBuffer.Data = ControlObject; BtnBuffer.OnClickEx = function(Btn) { if (Btn.Data == "CurrentSelectScale") { this[Btn.Data] += 0.1; } else { this[Btn.Data] += 10; } FixCustomData(); }.bindenv(this); BtnBuffer.SetCallBackFunc(CheckCurrentSelectIdFunc); Childrens.append(BtnBuffer); } //初始默认0类别 ChangeCategoryTitle(0); } //更改页面 function ChangeCategoryTitle(ToCategory) { CurrentCategory = ToCategory; //得到对应分类的称谓List local ItemList = Info.ItemIndex[CurrentCategory]; local SetInfo = []; for (local i = (9 * CurrentPage); i< 9; i++) { //得到ID和Info 0 和 null 为没有数据 local TileId = 0; local TileInfo = null; if (i< ItemList.len()) { //将ID记录到数组 TileId = ItemList[i]; TileInfo = Info.Item[CurrentCategory][ItemList[i]]; } SetInfo.append({ TileId = TileId, TileInfo = TileInfo }); } //遍历数组将ID与Info 设置给按钮 for (local i = 0; i< 9; i++) { TitleButtonList[i].SetInfo(SetInfo[i].TileId, SetInfo[i].TileInfo); } } //修正数据 function FixCustomData() { if (this.CurrentSelectScale > 1.0) this.CurrentSelectScale = 1.0; if (this.CurrentSelectScale< 0.01) this.CurrentSelectScale = 0.01; if (this.CurrentSelectXOffset > 800) this.CurrentSelectXOffset = 800; if (this.CurrentSelectXOffset<(-800)) this.CurrentSelectXOffset = -800; if (this.CurrentSelectYOffset > 600) this.CurrentSelectYOffset = 600; if (this.CurrentSelectYOffset<(-600)) this.CurrentSelectYOffset = -600; } //注册类别 function RegisterCategoryTitle() { CategoryTitle = []; local LogicFunc = function(Btn) { foreach(Pos, obj in CategoryTitle) { if (obj != Btn) obj.State = 0; else { obj.State = 1; ChangeCategoryTitle(Pos); } } }; //遍历有多少个Boss foreach(Pos, Name in Info.category) { local Tabbars1 = LenheartNewUI_TabbarsText(10 + (Pos * 61), 110, Name); if (Pos == 0) Tabbars1.State = 1; Tabbars1.SetTextOffset(31 - LenheartTextClass.GetStringLength(Name) / 2, 4); AddChild(Tabbars1); Tabbars1.OnClickEx = LogicFunc.bindenv(this); CategoryTitle.append(Tabbars1); } } //绘制主界面 function DrawMain(obj) { //背景框 DrawNineBox(X, Y, 450, 518, "interface/lenheartwindowcommon.img", 213); //标题 DrawWindowTitle(452); //绘制标题名 L_sq_DrawCode("誉名录", X + 204, Y + 5, sq_RGBA(230, 200, 155, 255), 0, 1); //头部图像 Img.DrawPng(0, X + 5, Y + 26); L_sq_SetDrawImgModel(2, 0); BackGroundAni.Show(Duration, X + 150, Y + 35); BackGroundAni2.Show(Duration, X + 150, Y + 30); L_sq_ReleaseDrawImgModel(); //书本图像 Img.DrawPng(1, X + 184, Y + 46); L_sq_DrawCode("誉名录完成率", X + 188, Y + 98, sq_RGBA(202, 200, 194, 255), 0, 1); //左侧背景 Img.DrawPng(2, X + 9, Y + 132); //右侧背景 Img.DrawPng(3, X + 143, Y + 132); //详情页 if (CurrentSelectId && CurrentSelectInfo) { //展示文字 L_sq_DrawCode("效果展示:", X + 150, Y + 140, sq_RGBA(230, 200, 155, 255), 0, 1); //展示框 Img.DrawPng(11, X + 147, Y + 156); //图像 if (CurrentSelectInfo.Content.type == "img") { //没有添加缓存的先添加缓存 if (!NewTitleC_Img_Map.rawin(CurrentSelectInfo.Content.img)) { NewTitleC_Img_Map.rawset(CurrentSelectInfo.Content.img, Rindro_Image(CurrentSelectInfo.Content.img)); } //这里从展示框的左上角开始算起 展示框大小为 290 * 115 如果添加新的称谓 可以现在PS里缩放 并记录下针对左上角坐标的偏移 与 缩放值 NewTitleC_Img_Map[CurrentSelectInfo.Content.img].DrawExPng(CurrentSelectInfo.Content.index, X + 147 + CurrentSelectInfo.DisplayData.x, Y + 156 + CurrentSelectInfo.DisplayData.y, 0, 0xffffffff, CurrentSelectInfo.DisplayData.scale, CurrentSelectInfo.DisplayData.scale) } //Ani else if (CurrentSelectInfo.Content.type == "ani") { local Ani = DrawAniEx(X + 147 + CurrentSelectInfo.DisplayData.x, Y + 156 + CurrentSelectInfo.DisplayData.y, CurrentSelectInfo.Content.ani); Ani.setImageRateFromOriginal(CurrentSelectInfo.DisplayData.scale, CurrentSelectInfo.DisplayData.scale); Ani.setAutoLayerWorkAnimationAddSizeRate(CurrentSelectInfo.DisplayData.scale, CurrentSelectInfo.DisplayData.scale); } //描述文字 L_sq_DrawCode("称谓信息:", X + 150, Y + 276, sq_RGBA(230, 200, 155, 255), 0, 1); L_sq_DrawCode_ExRN(CurrentSelectInfo.Explain, X + 150, Y + 292, sq_RGBA(104, 213, 237, 255), 0, 1); //获取途径文字 L_sq_DrawCode("获取途径:", X + 150, Y + 336, sq_RGBA(230, 200, 155, 255), 0, 1); L_sq_DrawCode_ExRN(CurrentSelectInfo.Conditions, X + 150, Y + 352, sq_RGBA(124, 110, 82, 255), 0, 1); if (CurrentSelectHaveFlag) { //调整文字 L_sq_DrawCode("自定义调整:", X + 150, Y + 410, sq_RGBA(230, 200, 155, 255), 0, 1); //缩放大小 L_sq_DrawCode("是否启用称谓显示: ", X + 150, Y + 426, sq_RGBA(124, 110, 82, 255), 0, 1); //层级调整 L_sq_DrawCode("显示层级: ", X + 300, Y + 426, sq_RGBA(124, 110, 82, 255), 0, 1); L_sq_DrawCode("缩放大小:", X + 150, Y + 442, sq_RGBA(124, 110, 82, 255), 0, 1); local CurrentSelectScaleStr = format("%.2f", CurrentSelectScale); L_sq_DrawCode(CurrentSelectScaleStr, X + 266 - LenheartTextClass.GetStringLength(CurrentSelectScaleStr) / 2, Y + 442, sq_RGBA(230, 200, 155, 255), 0, 1); L_sq_DrawCode("X轴偏移:", X + 150, Y + 458, sq_RGBA(124, 110, 82, 255), 0, 1); local CurrentSelectXOffsetStr = CurrentSelectXOffset.tostring(); L_sq_DrawCode(CurrentSelectXOffsetStr, X + 266 - LenheartTextClass.GetStringLength(CurrentSelectXOffsetStr) / 2, Y + 458, sq_RGBA(230, 200, 155, 255), 0, 1); L_sq_DrawCode("Y轴偏移:", X + 150, Y + 474, sq_RGBA(124, 110, 82, 255), 0, 1); local CurrentSelectYOffsetStr = CurrentSelectYOffset.tostring(); L_sq_DrawCode(CurrentSelectYOffsetStr, X + 266 - LenheartTextClass.GetStringLength(CurrentSelectYOffsetStr) / 2, Y + 474, sq_RGBA(230, 200, 155, 255), 0, 1); } } for (local i = 0; i< 6; i++) { Img.DrawPng(21 + i, X + 152, Y + 160 + (i * 44)); } } function Show(obj) { DrawMain(obj); LenheartNewUI_Windows.Show(obj); } //逻辑入口 function Proc(obj) { LenheartNewUI_Windows.SyncPos(X, Y); } function OpenCallBack() { Visible = true; CurrentSelectId = 0; CurrentSelectInfo = null; CheckBookInfo(); } function InitPvf() { Info = {}; //读取基础配置 Rindro_Script.GetFileData("etc/rindro/newtitle/newtitle.etc", function(DataTable, Data) { while (!Data.Eof()) { local Fragment = Data.Get(); if (Fragment == "[category]") { Info.category <- []; while (true) { local Fbuf = Data.Get(); if (Fbuf == "[/category]") { break; } Info.category.append(Sq_ConvertWideChar(Fbuf, "big5")); } } } }.bindenv(this)); //读取称谓列表 local TitleInfoMap = Rindro_Script.GetFileData("etc/rindro/newtitle/title.lst", function(InfoMap, Data) { while (!Data.Eof()) { local Index = Data.Get(); local Path = "etc/" + Data.Get(); local TitleInfo = Rindro_Script.GetFileData(Path, function(DataTable, Data) { while (!Data.Eof()) { local Fragment = Data.Get(); if (Fragment == "[name]") { DataTable.Name <- Sq_ConvertWideChar(Data.Get(), "big5"); } else if (Fragment == "[icon]") { DataTable.Icon <- { img = Data.Get().tolower(), index = Data.Get() } } else if (Fragment == "[explain]") { DataTable.Explain <- Sq_ConvertWideChar(Data.Get(), "big5"); } else if (Fragment == "[conditions]") { DataTable.Conditions <- Sq_ConvertWideChar(Data.Get(), "big5"); } else if (Fragment == "[category]") { DataTable.Category <- Data.Get(); } else if (Fragment == "[content]") { local Type = Data.Get(); if (Type == "img") { DataTable.Content <- { type = Type, img = Data.Get().tolower(), index = Data.Get() } } else if (Type == "ani") { DataTable.Content <- { type = Type, ani = Data.Get().tolower(), } } } else if (Fragment == "[display data]") { DataTable.DisplayData <- { x = Data.Get(), y = Data.Get(), scale = Data.Get() } } } }); InfoMap.rawset(Index, TitleInfo); } InfoMap.rawdelete("filepath"); }.bindenv(this)); //遍历称谓列表分配到对应的种类页 并编制索引 Info.Item <- []; Info.ItemIndex <- []; foreach(value in Info.category) { Info.Item.append({}); Info.ItemIndex.append([]); } foreach(Index, Value in TitleInfoMap) { Info.Item[Value.Category].rawset(Index, Value); Info.ItemIndex[Value.Category].append(Index); } } function L_sq_DrawCode_Ex(str, x, y, rgba, mb, jc) { local strarr = []; if (str.find("\r\n") == null) L_sq_DrawCode(str, x, y, rgba, mb, jc); else { local Bpos = 0; while (true) { local Npos = str.find("\r\n", Bpos); if (!Npos) { local strbuff = str.slice(Bpos, str.len()); strarr.append(strbuff); break; } local strbuff = str.slice(Bpos, Npos); strarr.append(strbuff); Bpos = Npos + 2; } for (local z = 0; z< strarr.len(); z++) { L_sq_DrawCode(strarr[z], x, y + (z * 14), rgba, mb, jc); } } } function GetTitlePvfInfo(FindId) { local FindCategory = -1; foreach(GroupIndex, Group in Info.ItemIndex) { foreach(value in Group) { if (value == FindId) { FindCategory = GroupIndex; break; } } } if (FindCategory != -1) { return Info.Item[FindCategory][FindId]; } return null; } } L_Windows_List <- []; getroottable().rawdelete("LenheartPluginsInitFlag"); getroottable().rawdelete("EventList_Obj") getroottable().rawdelete("NewTitle_Obj"); getroottable().rawdelete("L_Each_Obj"); function Lenheart_NewTitle_Fun(obj) { local RootTab = getroottable(); if (!RootTab.rawin("NewTitle_Obj")) { RootTab.rawset("NewTitle_Obj", true); local Win = LenheartNewUI_CreateWindow(NewTitleC, "称谓系统窗口", ((getroottable().Rindro_Scr_Width - 450) / 2).tointeger(), 30, 450, 518, 22); EventList_Obj.AddEvent("誉名录", 109, Win); } } getroottable()["LenheartFuncTab"].rawset("NewTitleFuncN", Lenheart_NewTitle_Fun);