20 Commits

Author SHA1 Message Date
b77e17c012 fix(FileConfig): 更新插件包缩略图URL并添加缺失的缩略图配置
将starter_bundle包的缩略图路径更新为外部URL,并为其他两个插件包添加相同的缩略图配置
2026-04-21 15:08:12 +08:00
ab3832e7a5 refactor(UI): 修复世界地图绘制索引问题并更新插件包配置
修复RepairWorldMap.nut中地图标记绘制索引问题,使用独立DrawIndex变量替代Pos
重构FileConfig.json,将CSBaseScript替换为PackageBundle配置,添加三种插件包方案
2026-04-21 14:55:51 +08:00
40ee8a01aa refactor: 将装备掉落函数重命名为更通用的物品掉落函数
重命名 sq_DropEquipmentUnique 为 sq_DropItemUnique 和 sq_DropEquipment 为 sq_DropItem,使函数命名更准确反映其实际功能,适用于更广泛的物品掉落场景
2026-04-14 13:26:07 +08:00
fe05643f72 feat(偷窃系统): 实现偷窃系统基础功能
- 添加偷窃系统配置文件及脚本入口
- 实现NPC交互菜单和偷窃功能逻辑
- 添加网络通信协议处理
- 初始化偷窃配置数据并注册NPC交互
- 完善偷窃解锁动画和状态管理
2026-04-14 13:20:57 +08:00
e6bb957d3d feat(Steal): 添加解锁成功动画和音效反馈
- 将密码框滚动速度从500ms调整为250ms提升用户体验
- 添加解锁成功动画序列和音效反馈
- 增加全部解锁后的处理逻辑和动画播放
- 优化宝箱动画显示比例
- 添加解锁失败音效提示
2026-04-10 00:54:37 +08:00
8c9c9d718a feat(Steal): 扩展密码框功能并改进锁定机制
- 增加密码字符集支持字母和数字
- 将线性锁定检测改为矩形区域检测
- 添加停止位置偏移量以优化视觉效果
- 实现解锁进度自动计算功能
- 调整默认参数和初始化逻辑
2026-04-09 05:40:23 +08:00
105c9c5d41 feat(Steal): 添加密码框锁定功能及正确锁定计数
实现密码框滚动停止和锁定功能,当用户按下空格时尝试锁定当前焦点密码框
新增正确锁定计数功能,用于追踪成功锁定的次数
添加相关状态变量和方法支持锁定逻辑
2026-04-08 23:36:24 +08:00
1faacb5464 feat(Steal): 为密码框添加滚动效果和相位偏移
实现密码数字序列的平滑滚动动画效果,支持不同密码框的相位偏移显示
修改密码框构造函数以接收相位参数,添加滚动相关属性和计算方法
优化数字显示逻辑,支持循环滚动和动态位置计算
2026-04-08 23:24:34 +08:00
feb316d882 feat: 添加偷窃系统和自己服装备功能
- 新增偷窃系统(Steal)模块及相关UI界面
- 添加自己服(MySelf)装备功能及显示界面
- 在folder-alias.json中添加新系统路径映射
- 为BaseTool_Class添加DrawNineBoxAlpha方法支持透明度
- 修改NewItemInfoWindow装备判断逻辑
- 在FileConfig.json中为多个系统添加Enabled配置项
- 在ObjectConvert.nut中添加装备掉落相关函数
2026-04-08 22:26:57 +08:00
fb1309b486 feat(换装系统): 更新配置并添加详细说明文档
- 将换装系统从私有改为公开并设置价格
- 更新项目作者信息
- 添加详细的换装系统使用说明文档
- 添加图片路径配置
2026-03-18 16:53:30 +08:00
1fb970488c 11 2026-03-15 20:07:29 +08:00
9c6f49d2ea feat(ObjectConvert): 添加攻击信息相关伤害率和暴击率操作函数
添加多个函数用于获取和设置攻击信息的不同伤害率(对人、建筑、怪物)和暴击率,以及获取伤害反应值。这些函数通过内存操作实现,为战斗系统提供更精细的控制能力。
2026-03-15 01:59:20 +08:00
be0725b52a feat: 添加攻击内存数据编解码功能及相关攻击信息操作
实现EncodeAttackMemoryData函数用于攻击内存数据的编解码
添加sq_GetCurrentAttackInfoBonusRate获取攻击奖励率
添加sq_GetCurrentAttackInfoChangeStatus和sq_SetCurrentAttackInfoChangeStatus用于获取和设置攻击状态变更信息
2026-03-15 01:54:53 +08:00
17792f354f lulu 2026-03-15 01:24:56 +08:00
d0822165e6 fix(ObjectConvert): 在读写攻击信息时重置blob指针位置
修复在读取和写入攻击信息时未重置blob指针位置的问题,确保数据读写正确
2026-03-15 01:10:58 +08:00
1194db30b3 feat: 添加获取和设置攻击信息伤害值的函数
添加 sq_GetCurrentAttackInfoDamage 和 sq_SetCurrentAttackInfoDamage 函数,用于读取和修改攻击信息的伤害值,扩展对象能力操作功能
2026-03-14 23:59:31 +08:00
2f20020a01 refactor(HudUi): 清理无用代码并优化内存修复逻辑
移除多余的return语句和注释掉的代码
清理全局变量并优化内存修复函数
2026-03-14 19:01:32 +08:00
85b66c2cb1 露露插件 2026-03-11 01:06:17 +08:00
f7d6d34c46 露露插件 2026-03-10 19:31:51 +08:00
9902eaa818 feat(OutfitSystem): 添加悬停说明功能并移除过时代码注释
添加InstructionsIsHover变量控制说明提示的显示
新增TopShow方法显示悬停时的操作说明
移除过时的装备偏移注释代码
2026-03-04 06:47:04 +08:00
14 changed files with 1459 additions and 117 deletions

View File

@@ -92,8 +92,173 @@ function L_drawMainCustomUI_All() {
// print(sq_GetObjectId(obj))
// print(Clock());
// Rindro_Image_GlobalMap["interface/newstyle/windows/popup/popup.img"].DrawExPng(138, 205, 0, 0, sq_RGBA(255, 255, 255, 250), 13.0, 13.0);
// local attackInfo = sq_GetCustomAttackInfo(obj, 0);
// sq_SetAttackInfoHitDelayRateDamager(attackInfo, 4.2);
// // sq_SetCurrentAttackBonusRate(attackInfo, 4812);
// // sq_SetCurrentAttacknUpForce(attackInfo, 41918);
// // sq_GetAttackInfoHitDelayRateDamager(attackInfo);
// local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
// sq_SetChangeStatusIntoAttackInfoWithEtc(attackInfo, 0, 10, 50, 150, 140, 49, 0);
// print(attackInfo["__ot"][28259608])
// for (local i = 0; i< 8000; i++) {
// local Ret = DATK(AtkC, i).readInt();
// if (Ret == 21567)
// {
// print("找到了! " + format("当前遍历: 0x%02x\n", i));
// }
// }
// for (local i = 0; i< 18000; i++) {
// local Ret = NativePointer(AtkC + i).readFloat();
// if (Ret == 41590.0)
// {
// print("找到了! " + format("当前遍历: 0x%02x\n", i));
// }
// }
//[human damage rate]
// print(DATK(AtkC, 0x294).readFloat());
//[fort damage rate]
// print(DATK(AtkC, 0x2A0).readFloat());
//[monster damage rate]
// print(DATK(AtkC, 0x2AC).readFloat());
//[critical hit]
// print(DATK(AtkC, 0x68).readFloat());
//[damage]
// print(DATK(AtkC, 0x0).readFloat());
//[damage bonus]
// print(DATK(AtkC, 0x24).readInt());
//[absolute damage]
// print(DATK(AtkC, 0x18).readInt());
//[damage reaction]
// print(NativePointer(AtkC + 0x4C).readInt());
//[knuck back]
// print(DATK(AtkC, 0x8C).readInt());
//ACTIVESTATUS_SLOW
// print(DATK(AtkC, 0x1c8).readFloat());
// print(DATK(AtkC, 0x1ec).readInt());
// print(DATK(AtkC, 0x234).readInt());
// print(NativePointer(AtkC + 0x1BC).readInt());
// print(NativePointer(AtkC + 4 * (3 * 0 + 444)).readInt());
// print(DATK(AtkC, 0x234 + 0x4 + 0x4 + 0x4).readInt());
// print(DATK(AtkC, 0x19C).readInt());
// print(DATK(AtkC, 0x1A4).readInt());
// local WriteIntData = Memory.alloc(4);
// WriteIntData.writeFloat(756.4);
// MemoryTool.EncodeMemoryData(AtkC + 0x294, WriteIntData.readInt());
// local Ret = MemoryTool.DecodeMemoryDataF(AtkC + 0x10c);
// print(Ret)
// // secondTable 是一个指针,需要先读取它的值
// local secondTablePtr = 0x1AF8D78 + 4 * tableIndex + 36;
// local secondTable = NativePointer(secondTablePtr).readInt();
// local verifyValueAddr = secondTable + 4 * entryIndex + 0x2114;
// local verifyValue = NativePointer(verifyValueAddr).readInt();
// print("verifyValue: " + verifyValue);
// local verifyValue = GetObjectVerifyValue(*this_ptr);
// print(attackInfo["__ot"][28259608]);
// local Ret = L_Sq_CallFunc(0x5AE1E0, "float", FFI_MS_CDECL, ["int"], AtkC);
// local result = Memory.alloc(4);
// L_Sq_CallFunc(0x1195EB0, "void", FFI_FASTCALL, ["int", "int", "int", "pointer"], AtkC + 0X104, 0, AtkC + 0x10c, result.C_Object);
// print(result.C_Object);
// L_Sq_CallFunc(0x1195E40, "int", FFI_FASTCALL, ["int", "int", "int", "pointer"], AtkC + 0x30, 0, AtkC + 0x38, result.C_Object);
// print(result.readShort());
// print(result.C_Object);
// print(result.readInt());
// local result = Memory.alloc(4);
// L_Sq_CallFunc(0x1195EB0, "void", FFI_FASTCALL, ["int", "int", "int", "pointer", "int"], AtkC + 0x330, 0, AtkC + 0x338, result.C_Object, 0);
// print(result.readInt());
// print(L_sq_Test(AtkC));
// local keyTable = NativePointer(tableBase + 4 * tableIdx + 36).readInt();
// print("keyLow: " + keyLow + " xorMask: " + xorMask + " decryptedValue: " + decryptedValue);
// print(NativePointer(decryptedValue).readFloat());
// local decryptedLow = decryptedValue & 0xFFFF;
// local decryptedHigh = (decryptedValue >> 16) & 0xFFFF;
// local checksum = keyLow ^ (decryptedLow + decryptedHigh);
// local resultPtr = Memory.alloc(4);
// L_Sq_CallFunc(0x1195EB0, "void", FFI_STDCALL, ["int", "pointer"], Data, resultPtr.C_Object);
// print(resultPtr.readFloat());
}
function DATK(AtkC, Offset) {
// 读取 ObjectId
local ObjectIdPtr = NativePointer(AtkC + Offset);
local ObjectId = ObjectIdPtr.readInt();
// 读取 base1 (全局表)
local base1Ptr = NativePointer(0x1AF8D78);
local base1 = base1Ptr.readInt();
// 计算并读取二级表
local offset_high = 4 * ((ObjectId >> 16) & 0xFFFF);
local addr1 = base1 + offset_high + 0x24;
local base2Ptr = NativePointer(addr1);
local base2 = base2Ptr.readInt();
// 计算并读取 verifyValue
local offset_low = 4 * (ObjectId & 0xFFFF);
local addr2 = base2 + offset_low + 0x2114;
local verifyValuePtr = NativePointer(addr2);
local verifyValue = verifyValuePtr.readInt();
// 读取输入值
local inputAddr = AtkC + Offset + 0x8;
local inputPtr = NativePointer(inputAddr);
local inputValue = inputPtr.readInt();
// 解密
local lowWord = verifyValue & 0xFFFF;
local expanded = (lowWord << 16) | lowWord;
local decrypted = inputValue ^ expanded;
local Res = Memory.alloc(4);
Res.writeInt(decrypted);
return Res;
}
// for (local i = 0; i < 42; i++) {

View File

@@ -171,6 +171,7 @@ class Rindro_EventList {
X = Jso.YosinEventIconInfoXpos;
Y = Jso.YosinEventIconInfoYpos;
getroottable()["LenheartEventOffset"] <- {
x = X - 456,
y = Y
@@ -228,30 +229,6 @@ function Lenheart_EventList_Fun(obj) {
}
}
//获取活动图标坐标 在活动图标变动时会被调用
function Sq_Get_Event_Pos_X() {
if (getroottable().rawin("LenheartEventOffset")) {
return getroottable()["LenheartEventOffset"].x;
} else {
getroottable()["LenheartEventOffset"] <- {
x = 277,
y = 530
};
return getroottable()["LenheartEventOffset"].x;
}
}
function Sq_Get_Event_Pos_Y() {
if (getroottable().rawin("LenheartEventOffset")) {
return getroottable()["LenheartEventOffset"].y;
} else {
getroottable()["LenheartEventOffset"] <- {
x = 277,
y = 530
};
return getroottable()["LenheartEventOffset"].y;
}
}

View File

@@ -312,6 +312,50 @@ class Rindro_BaseToolClass {
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 8, X + Width - LeftTopW, Y + Height - LeftTopH);
}
function DrawNineBoxAlpha(X, Y, Width, Height, Img, StartIndex, Alpha)
{
//如果没有载入img就载入
if (!Rindro_Image_GlobalMap.rawin(Img)) {
Rindro_Image_GlobalMap[Img] <- Rindro_Image(Img);
}
//绘制左上角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex, X, Y);
//获取左上角的图片宽高
local LeftTopW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex).GetWidth();
local LeftTopH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex).GetHeight();
//绘制上边
//获取上边的宽
local TopW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 1).GetWidth();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 1, X + LeftTopW, Y, 0, sq_RGBA(255, 255, 255, Alpha), (Width - LeftTopW * 2).tofloat() / TopW, 1.0);
//绘制右上角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 2, X + Width - LeftTopW, Y);
//绘制左边
//获取左边的高
local LeftH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 3).GetHeight();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 3, X, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, Alpha), 1.0, (Height - LeftTopH * 2).tofloat() / LeftH);
//绘制中间
//获取中间的宽高
local MiddleW = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 4).GetWidth();
local MiddleH = Rindro_Image_GlobalMap[Img].GetPng(StartIndex + 4).GetHeight();
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 4, X + LeftTopW, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, Alpha), (Width - LeftTopW * 2).tofloat() / MiddleW, (Height - LeftTopH * 2).tofloat() / MiddleH);
//绘制右边
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 5, X + Width - LeftTopW, Y + LeftTopH, 0, sq_RGBA(255, 255, 255, Alpha), 1.0, (Height - LeftTopH * 2).tofloat() / LeftH);
//绘制左下角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 6, X, Y + Height - LeftTopH);
//绘制下边
Rindro_Image_GlobalMap[Img].DrawExPng(StartIndex + 7, X + LeftTopW, Y + Height - LeftTopH, 0, sq_RGBA(255, 255, 255, Alpha), (Width - LeftTopW * 2).tofloat() / TopW, 1.0);
//绘制右下角
Rindro_Image_GlobalMap[Img].DrawPng(StartIndex + 8, X + Width - LeftTopW, Y + Height - LeftTopH);
}
//品级颜色
function GetRarityColor(rarity) {
switch (rarity) {

View File

@@ -106,6 +106,7 @@ class Rindro_Item {
function Show(X, Y) {
//背景框
Rindro_BaseToolClass.DrawNineBox(X, Y, 214, DrawInfo.Height + 30, "interface2/common/mypopup/popup.img", 0);
// Rindro_BaseToolClass.DrawNineBox(X, Y, 214, DrawInfo.Height + 30, "sjweapon/sjwindow.img", 0);
// local C_Object = Rindro_Image_GlobalMap["popup"].GetPng(134);
// print(C_Object);
// L_Sq_CallFunc(0x11DF050, "void", FFI_FASTCALL, ["pointer", "int", "int", "int", "int", "int"], C_Object, 0, 10, 10, 10, 10);

View File

@@ -154,6 +154,13 @@ class NativePointer {
}
function readInt() {
// if(L_sq_P2I(this.C_Object) < 0x7FFFFFFF && L_sq_P2I(this.C_Object) > 0x400000 && L_sq_P2I(this.C_Object) % 4 == 0) {
// if(L_sq_Test(L_sq_P2I(this.C_Object))){
// return read('i');
// }
// }
// return 0;
return read('i');
}

View File

@@ -30,48 +30,137 @@
"Base/UI/Lenheart_Character_Info_Class.nut",
"Base/Interface.nut"
],
"CSBaseScript": [
"CSBase/_ENUM/_ENUM_.nut",
"CSBase/_Tool/Json_Class.nut",
"CSBase/_Tool/Packet_Class.nut",
"CSBase/_Tool/BaseTool_Class.nut",
"CSBase/_Tool/MemoryClass.nut",
"CSBase/_Tool/Hacker_Class.nut",
"CSBase/_Tool/Hacker_RegApi.nut",
"CSBase/_Tool/Script_Class.nut",
"CSBase/_Tool/Image_Class.nut",
"CSBase/_Tool/Animation_Class.nut",
"CSBase/CallBack/PackControl.nut",
"CSBase/CallBack/DrawMain.nut",
"CSBase/CallBack/DrawHudMain.nut",
"CSBase/CallBack/PushDamage.nut",
"CSBase/CallBack/GetDamageRate.nut",
"CSBase/_Z_Data/CharacterInfoData.nut",
"CSBase/UI/Lenheart_Cursor_Class.nut",
"CSBase/UI/OldWindowsMap.nut",
"CSBase/UI/Lenheart_UI_Class.nut",
"CSBase/UI/Lenheart_Ani_Class.nut",
"CSBase/UI/Lenheart_Each_Class.nut",
"CSBase/UI/Lenheart_Event_Class.nut",
"CSBase/UI/Lenheart_Character_Info_Class.nut",
"CSBase/Interface.nut"
],
"PackageBundle": {
"gold_bundle": {
"PackageAlias": "黄金插件包",
"PackageAuthor": "官方",
"PackageVersion": "1.0",
"PackageDescribe": "包含常用双端插件的组合包,该插件包无包安装服务,需要一定基础自行安装。(如需远程安装需单独支付费用)",
"PackagePrice": 50,
"PackageThumb": "https://i.imgs.ovh/2026/04/21/ZwpyBC.png",
"Items": [
"世界BOSS",
"伤害控制",
"土罐",
"圣者遗物箱",
"战令",
"战力系统",
"换装系统",
"收集箱",
"皮肤仓库",
"累计奖励",
"荒古遗尘装备"
]
},
"diamond_bundle": {
"PackageAlias": "钻石插件包",
"PackageAuthor": "官方",
"PackageVersion": "1.0",
"PackageDescribe": "包含常用双端插件的组合包 + 一个团本插件,该插件包无包安装服务,需要一定基础自行安装。(如需远程安装需单独支付费用)",
"PackagePrice": 100,
"PackageThumb": "https://i.imgs.ovh/2026/04/21/ZwpyBC.png",
"Items": [
"世界BOSS",
"伤害控制",
"土罐",
"圣者遗物箱",
"战令",
"战力系统",
"换装系统",
"收集箱",
"皮肤仓库",
"累计奖励",
"荒古遗尘装备",
"安图恩"
]
},
"ultimate_bundle": {
"PackageAlias": "至臻插件包",
"PackageAuthor": "官方",
"PackageVersion": "1.0",
"PackageDescribe": "包含所有插件,该插件包无包安装服务,需要一定基础自行安装。(如需远程安装需单独支付费用)",
"PackagePrice": 200,
"PackageThumb": "https://i.imgs.ovh/2026/04/21/ZwpyBC.png",
"Items": [
"世界BOSS",
"伤害控制",
"土罐",
"圣者遗物箱",
"战令",
"战力系统",
"换装系统",
"收集箱",
"皮肤仓库",
"累计奖励",
"荒古遗尘装备",
"安图恩",
"卢克",
"超时空"
]
}
},
"ProjectScript": {
"换装系统": {
"Private": true,
"price": 20,
"Private": false,
"Enabled": false,
"Script": [
"Project/OutfitSystem/OutfitSystem_Component.nut",
"Project/OutfitSystem/OutfitSystem.nut"
],
"info": {
"ProjectAuthor": "官方 (期限:月)",
"ProjectAuthor": "20",
"ProjectVersion": "1.0.0",
"ProjectDescribe": "换装系统",
"ImageMini": "http://49.234.27.222:8651/dps/download2/Image:chengjiu.png"
"ImageMini": "http://49.234.27.222:8651/dps/download2/Image:chengjiu.png",
"ProjectDetails": [
{
"type": "str",
"content": "在赛利亚这里可以打开换装配置"
},
{
"type": "img",
"content": "0"
},
{
"type": "str",
"content": "点击上面的编号图标,然后点记录,就会记录当前的装备"
},
{
"type": "img",
"content": "1"
},
{
"type": "str",
"content": "输入//HZ 编号(如 //HZ 1)就能换上对应编号的装备,可以在快捷喊话中设置,这样按快捷喊话的键就能换上对应的装备"
},
{
"type": "img",
"content": "2"
},
{
"type": "str",
"content": "换装界面也有使用说明"
},
{
"type": "img",
"content": "3"
},
{
"type": "str",
"content": "换装超快完成"
},
{
"type": "img",
"content": "5"
}
]
},
"imgPath": "OutfitSystem"
},
"黄金哥布林袖珍罐": {
"Private": true,
"Enabled": false,
"Script": [
"Project/TreasureGoblin/TreasureGoblin.nut"
],
@@ -82,8 +171,21 @@
"ImageMini": "http://49.234.27.222:8651/dps/download2/Image:chengjiu.png"
}
},
"偷窃系统": {
"Private": true,
"Script": [
"Project/Steal/Steal.nut"
],
"info": {
"ProjectAuthor": "官方 (期限:月)",
"ProjectVersion": "1.0.0",
"ProjectDescribe": "偷窃系统",
"ImageMini": "http://49.234.27.222:8651/dps/download2/Image:chengjiu.png"
}
},
"异界装备升级": {
"Private": true,
"Enabled": false,
"Script": [
"Project/ItemTool/ItemOtherWolrdUpgrade/ItemOtherWolrdUpgrade.nut"
],
@@ -96,6 +198,7 @@
},
"誉名录": {
"Private": true,
"Enabled": false,
"Script": [
"Project/NewTitle/TitleButton.nut",
"Project/NewTitle/NewTitle.nut"
@@ -121,6 +224,7 @@
},
"灵魂救赎武器": {
"Private": true,
"Enabled": false,
"Script": [
"Project/SoulSalvation/SoulSalvation.nut",
"Project/SoulSalvation/SoulSalvation_Upgrade.nut",

View File

@@ -13,3 +13,303 @@ function sq_GetCNRDObjectToPassiveObject(obj) {
function sq_GetCNRDObjectToSQRPassiveObject(obj) {
return L_Sq_ObjectAddressToSqrObject(L_Sq_GetObjectAddress(obj), "CNSquirrelPassiveObject", 0);
}
function sq_GetObjectAbilityInteger(obj, ObjectAddressOffset) {
return NativePointer(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset).readInt();
}
function sq_SetObjectAbilityInteger(obj, ObjectAddressOffset, Value) {
NativePointer(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset).writeInt(Value);
}
function sq_GetObjectAbilityFloat(obj, ObjectAddressOffset) {
return NativePointer(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset).readFloat();
}
function sq_SetObjectAbilityFloat(obj, ObjectAddressOffset, Value) {
NativePointer(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset).writeFloat(Value);
}
function sq_GetObjectAbilityIntegerWithDecrypt(obj, ObjectAddressOffset) {
return MemoryTool.DecodeMemoryData(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset);
}
function sq_SetObjectAbilityIntegerWithDecrypt(obj, ObjectAddressOffset, Value) {
MemoryTool.EncodeMemoryData(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset, Value);
}
function sq_GetObjectAbilityFloatWithDecrypt(obj, ObjectAddressOffset) {
local Res = MemoryTool.DecodeMemoryData(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset);
local B = blob();
B.writen(Res, 'i');
return B.readn('f');
}
function sq_SetObjectAbilityFloatWithDecrypt(obj, ObjectAddressOffset, Value) {
local B = blob();
B.writen(Value, 'f');
MemoryTool.EncodeMemoryData(L_Sq_GetObjectAddress(obj) + ObjectAddressOffset, B.readn('i'));
}
//[human damage rate]
// print(DATK(AtkC, 0x294).readFloat());
//[fort damage rate]
// print(DATK(AtkC, 0x2A0).readFloat());
//[monster damage rate]
// print(DATK(AtkC, 0x2AC).readFloat());
//[critical hit]
// print(DATK(AtkC, 0x68).readFloat());
//[damage]
// print(DATK(AtkC, 0x0).readFloat());
//[damage bonus]
// print(DATK(AtkC, 0x24).readInt());
//[absolute damage]
// print(DATK(AtkC, 0x18).readInt());
//[damage reaction]
// print(NativePointer(AtkC + 0x4C).readInt());
//[knuck back]
// print(DATK(AtkC, 0x8C).readInt());
function EncodeAttackMemoryData(AtkC, Offset) {
// 读取 ObjectId
local ObjectIdPtr = NativePointer(AtkC + Offset);
local ObjectId = ObjectIdPtr.readInt();
// 读取 base1 (全局表)
local base1Ptr = NativePointer(0x1AF8D78);
local base1 = base1Ptr.readInt();
// 计算并读取二级表
local offset_high = 4 * ((ObjectId >> 16) & 0xFFFF);
local addr1 = base1 + offset_high + 0x24;
local base2Ptr = NativePointer(addr1);
local base2 = base2Ptr.readInt();
// 计算并读取 verifyValue
local offset_low = 4 * (ObjectId & 0xFFFF);
local addr2 = base2 + offset_low + 0x2114;
local verifyValuePtr = NativePointer(addr2);
local verifyValue = verifyValuePtr.readInt();
// 读取输入值
local inputAddr = AtkC + Offset + 0x8;
local inputPtr = NativePointer(inputAddr);
local inputValue = inputPtr.readInt();
// 解密
local lowWord = verifyValue & 0xFFFF;
local expanded = (lowWord << 16) | lowWord;
local decrypted = inputValue ^ expanded;
local Res = Memory.alloc(4);
Res.writeInt(decrypted);
return Res;
}
function sq_GetCurrentAttackInfoDamage(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x0);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoDamage(attackInfo, damage) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(damage, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x0, B.readn('i'));
}
function sq_GetCurrentAttackInfoAbsoluteDamage(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x18);
return Res;
}
function sq_SetCurrentAttackInfoAbsoluteDamage(attackInfo, damage) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
MemoryTool.EncodeMemoryData(AtkC + 0x18, damage);
}
function sq_GetCurrentAttackInfoBonusRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x24);
return Res;
}
// print(DATK(AtkC, 0x1c8).readFloat());
// print(DATK(AtkC, 0x1ec).readInt());
// print(DATK(AtkC, 0x234).readInt());
function sq_GetCurrentAttackInfoChangeStatus(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Info = [EncodeAttackMemoryData(AtkC, 0x1c8).readFloat(), EncodeAttackMemoryData(AtkC, 0x1ec).readInt(), EncodeAttackMemoryData(AtkC, 0x234).readInt()];
return Info;
}
function sq_SetCurrentAttackInfoChangeStatus(attackInfo, Data1, Data2, Data3) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(Data1, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x1c8, B.readn('i'));
B.seek(0);
B.writen(Data2, 'i');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x1ec, B.readn('i'));
B.seek(0);
B.writen(Data3, 'i');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x234, B.readn('i'));
}
function sq_GetCurrentAttackInfoHumanDamageRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x294);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoHumanDamageRate(attackInfo, rate) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(rate, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x294, B.readn('i'));
}
function sq_GetCurrentAttackInfoFortDamageRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x2A0);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoFortDamageRate(attackInfo, rate) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(rate, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x2A0, B.readn('i'));
}
function sq_GetCurrentAttackInfoMonsterDamageRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x2AC);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoMonsterDamageRate(attackInfo, rate) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(rate, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x2AC, B.readn('i'));
}
function sq_GetCurrentAttackInfoCriticalRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x68);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoCriticalRate(attackInfo, rate) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(rate, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x68, B.readn('i'));
}
function sq_GetCurrentAttackInfoDamageReaction(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x4C);
return Res;
}
function sq_GetCurrentAttackeHitStunTime(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x138);
return Res;
}
function sq_GetCurrentAttackInfoKnuckBackType(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x8C);
return Res;
}
function sq_SetCurrentAttackInfoKnuckBackType(attackInfo, type) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
MemoryTool.EncodeMemoryData(AtkC + 0x8C, type);
}
function sq_GetCurrentAttackInfoStuckRate(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x74);
local B = blob();
B.writen(Res, 'i');
B.seek(0);
return B.readn('f');
}
function sq_SetCurrentAttackInfoStuckRate(attackInfo, rate) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local B = blob();
B.writen(rate, 'f');
B.seek(0);
MemoryTool.EncodeMemoryData(AtkC + 0x74, B.readn('i'));
}
function sq_GetCurrentAttackUpForce(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x5c);
return Res;
}
function sq_GetCurrentAttackBackForce(attackInfo) {
local AtkC = L_sq_P2I(attackInfo["__ot"][28259608]);
local Res = MemoryTool.DecodeMemoryData(AtkC + 0x50);
return Res;
}
function sq_DropItemUnique(id, posX, posY) {
local T = {
op = 21016001,
id = id,
posX = posX,
posY = posY,
}
Rindro_BaseToolClass.SendPackEx(T);
}
function sq_DropItem(rarity, posX, posY)
{
local T = {
op = 21016003,
rarity = rarity,
posX = posX,
posY = posY,
}
Rindro_BaseToolClass.SendPackEx(T);
}

View File

@@ -53,30 +53,29 @@ class HudUiC extends LenheartNewUI_Windows {
L_sq_WAB(0x400E17, 7);
L_sq_WAB(0x400E18, 0);
return;
// 干掉nut初始化基础技能栏坐标
L_sq_WAB(0x4B3239, 0xEB);
//右上角绿色小圆球
L_sq_WA(0x00E6D873, 1000);
//广播黑条
L_sq_WA(0x01AF4968, 0);
//格兰背景
L_sq_WA(0x004CA0B3, 850);
L_sq_WA(0x004BB768, 850);
//副本名称
L_sq_WA(0x004BB872, 850);
L_sq_WA(0x004BB850, 850);
//城镇名称
L_sq_WA(0x004CA27C, 850);
// //右上角绿色小圆球
// L_sq_WA(0x00E6D873, 1000);
// //广播黑条
// L_sq_WA(0x01AF4968, 0);
// //格兰背景
// L_sq_WA(0x004CA0B3, 850);
// L_sq_WA(0x004BB768, 850);
// //副本名称
// L_sq_WA(0x004BB872, 850);
// L_sq_WA(0x004BB850, 850);
// //城镇名称
// L_sq_WA(0x004CA27C, 850);
//城镇过场Tips背景
L_sq_WA(0x004580FD, 400 + 133);
//城镇过场Tips文本
L_sq_WA(0x004581DD, 400 + 133);
// //城镇过场Tips背景
// L_sq_WA(0x004580FD, 400 + 133);
// //城镇过场Tips文本
// L_sq_WA(0x004581DD, 400 + 133);
//头顶滚动公告
L_sq_WAB(0x11FA640, 0xC3);
// //头顶滚动公告
// L_sq_WAB(0x11FA640, 0xC3);
@@ -99,7 +98,6 @@ class HudUiC extends LenheartNewUI_Windows {
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x84 + (i * 0x4)) + 0x14, 844 + (i * 17));
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x84 + (i * 0x4)) + 0x18, 561);
}
//拍卖行(删除)
L_sq_WA(L_sq_RA(L_sq_RA(0x01ADE0CC) + 0x84 + (4 * 0x4)) + 0x14, -5000);
@@ -193,7 +191,6 @@ class HudUiC extends LenheartNewUI_Windows {
LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
FixMemory();
return;
local BallFrameArr = [];
for (local i = 0; i< 120; i++) {
local T = {
@@ -213,7 +210,6 @@ class HudUiC extends LenheartNewUI_Windows {
L_sq_DrawImg("interface2/hud/hpmp_vessel.img", i, -5000, 508);
}
}
@@ -629,7 +625,6 @@ class HudUiC extends LenheartNewUI_Windows {
function TopShow(obj) {
return;
//血蓝球悬停逻辑
BallRectLogic(obj);
//经验条悬停逻辑
@@ -638,14 +633,12 @@ class HudUiC extends LenheartNewUI_Windows {
}
function BottomShow(obj) {
return;
DrawMain(obj);
LenheartNewUI_Windows.Show(obj);
}
//动态窗口设置逻辑
function Active_Windows_SyncPos() {
return;
//任务快捷导航窗口
{
local WindowAddress = L_sq_GetWindowById(1);
@@ -655,13 +648,44 @@ class HudUiC extends LenheartNewUI_Windows {
//逻辑入口
function Proc(obj) {
return;
LenheartNewUI_Windows.SyncPos(X, Y);
Active_Windows_SyncPos();
}
}
//获取活动图标坐标 在活动图标变动时会被调用
function Sq_Get_Event_Pos_X() {
if (getroottable().rawin("LenheartEventOffset")) {
return getroottable()["LenheartEventOffset"].x;
} else {
getroottable()["LenheartEventOffset"] <- {
x = 275,
y = 530
};
return getroottable()["LenheartEventOffset"].x;
}
}
function Sq_Get_Event_Pos_Y() {
if (getroottable().rawin("LenheartEventOffset")) {
return getroottable()["LenheartEventOffset"].y;
} else {
getroottable()["LenheartEventOffset"] <- {
x = 275,
y = 530
};
return getroottable()["LenheartEventOffset"].y;
}
}
L_Windows_List <- [];
getroottable().rawdelete("LenheartPluginsInitFlag");
getroottable().rawdelete("EventList_Obj")
getroottable().rawdelete("HudUi_Obj");
getroottable().rawdelete("L_Each_Obj");
function Lenheart_HudUi_Fun(obj) {
local RootTab = getroottable();
@@ -672,6 +696,7 @@ function Lenheart_HudUi_Fun(obj) {
getroottable()["LenheartFuncTab"].rawset("HudUiFuncN", Lenheart_HudUi_Fun);
// L_sq_Test(L_sq_RA(0x01AB7CDC), 0x3DB61400);
// local Ret = L_sq_Test(L_sq_RA(0x01AB7CDC), 10);
// local Ret = L_sq_Test(L_sq_RA(0x01A5FA88), 101020037);

View File

@@ -0,0 +1,198 @@
/*
文件名:Equip.nut
路径:Project/MySelf/Equip/Equip.nut
创建日期:2026-03-24 01:54
文件用途:
*/
class MySelfEquipC extends Rindro_BaseToolClass {
constructor() {
local ItemDrawControl = getroottable()["NewItemInfoWindow_Obj"];
ItemDrawControl.AddHookItemId(27572);
}
}
function Lenheart_MySelfEquipC_Fun(obj) {
local RootTab = getroottable();
if (!RootTab.rawin("MySelfEquipC_Obj")) {
RootTab.rawset("MySelfEquipC_Obj", MySelfEquipC());
}
}
getroottable()["LenheartFuncTab"].rawset("MySelfEquipCFuncN", Lenheart_MySelfEquipC_Fun);
L_Windows_List <- [];
getroottable().rawdelete("LenheartPluginsInitFlag");
getroottable().rawdelete("EventList_Obj")
getroottable().rawdelete("MySelfEquipC_Obj");
getroottable().rawdelete("L_Each_Obj");
class Rindro_Item_DrawInfo {
//Item对象
Item = null;
//指导信息 (原装备生成的信息)
GuidanceInformation = null;
//指导信息标志位
GuidanceInformationFlag = 0;
//分割线计数
GuidanceDivCount = 0;
//信息
InfoList = null;
Height = 0;
Padding = 8;
Img = Rindro_Image("sjweapon/sjwindow.img");
Img2 = Rindro_Image("soulweapon/main.img");
constructor(gItem) {
Item = gItem;
InfoList = [];
}
//添加指导信息
function AddGuidanceInformation(info) {
GuidanceInformation = info;
}
function Init() {
//读取强化等级
local UpgradeLevel = Item.GetUpgrade();
//读取名字
local Name = "天 · 狂暴之" + Item.GetName();
local UpgradeStr = UpgradeLevel > 0 ? ("+" + UpgradeLevel + " ") : "";
local NameStr = Name.len() > 0 ? (Name + " ") : "未定名";
AddContent((UpgradeStr + Name), Padding, Padding, Rindro_BaseToolClass.GetRarityColor(6));
AddContent("巨剑(英雄级)", Padding, 18, sq_RGBA(176, 138, 44, 250));
// if (isGm()) {
// //读取编号
// local Index = Item.GetIndex();
// //读取uuid
// local Uuid = Item.GetUuid();
// local IndexStr = Index > 0 ? ("编号: [" + Index + "] ") : "";
// local UuidStr = Uuid > 10000 ? ("uid: [" + Uuid + "] ") : "";
// AddContent((IndexStr + UuidStr), Padding, 15, 0xffffffff);
// }
AddDelegate(20, function(X, Y, Item) {
for (local i = 0; i< 10; i++) {
Img.DrawPng(0, X + 7 + i * 16, Y + 19);
}
}.bindenv(this));
AddDividing(26, 15);
AddContent("攻击力", Padding, 18, 0xffffffff);
AddContent("458", 215 - LenheartTextClass.GetStringLength("458") - Padding, 0, 0xffffffff);
AddContent("命中", Padding, 18, 0xffffffff);
AddContent("100", 215 - LenheartTextClass.GetStringLength("100") - Padding, 0, 0xffffffff);
AddContent("暴击", Padding, 18, 0xffffffff);
AddContent("150", 215 - LenheartTextClass.GetStringLength("150") - Padding, 0, 0xffffffff);
AddContent("格挡", Padding, 18, 0xffffffff);
AddContent("150", 215 - LenheartTextClass.GetStringLength("150") - Padding, 0, 0xffffffff);
AddDividing(26, 15);
// AddContent("灵魂刻印率", Padding, 18, sq_RGBA(244, 21, 79, 250));
AddDelegate(20, function(X, Y, Item) {
L_sq_DrawCode("灵魂刻印率", X + 6, Y + 15, sq_RGBA(244, 21, 79, 255), 0, 1);
local Rate = 0.56;
L_sq_DrawCode(format("%.1f%%", Rate * 100.0), X + 180, Y + 15, sq_RGBA(255, 119, 0, 255), 0, 1);
Img2.DrawPng(0, X + 70, Y + 19);
setClip(X + 72, Y + 21, X + 72 + (Rate * 97.0).tointeger(), Y + 40); //开始裁切
Img2.DrawPng(1, X + 72, Y + 21);
releaseClip(); //裁切结束
}.bindenv(this));
AddContent("※ 力量", Padding, 12, sq_RGBA(104, 213, 237, 255));
AddContent("150", 215 - LenheartTextClass.GetStringLength("150") - Padding, 0, sq_RGBA(104, 213, 237, 255));
AddContent("※ 武器伤害增幅", Padding, 18, sq_RGBA(104, 213, 237, 255));
AddContent("16.3", 215 - LenheartTextClass.GetStringLength("16.3") - Padding, 0, sq_RGBA(104, 213, 237, 255));
AddContent("※ 异常属性攻击", Padding, 18, sq_RGBA(104, 213, 237, 255));
AddContent("25", 215 - LenheartTextClass.GetStringLength("25") - Padding, 0, sq_RGBA(104, 213, 237, 255));
AddDividing(26, 15);
AddDelegate(64, function(X, Y, Item) {
local Str = ["生命铭刻 · 1级", "精准铭刻 · 2级", "寒冰铭刻 · 1级", "火焰铭刻 · 3级"]
local Color = [sq_RGBA(120, 255, 30, 255), sq_RGBA(255, 240, 20, 240), sq_RGBA(33, 131, 217, 240), sq_RGBA(230, 34, 34, 240)]
for (local i = 0; i< 4; i++) {
Img.DrawPng(1 + i, X + 7, Y + 19 + i * 18);
L_sq_DrawCode(Str[i], X + (215 - LenheartTextClass.GetStringLength(Str[i]) - Padding), Y + 18 + i * 18, Color[i], 1);
}
}.bindenv(this));
AddDividing(26, 26);
AddContent("激荡 : 生生不息", Padding, 28, sq_RGBA(60, 180, 0, 255));
AddContent("攻击时,以2%的概率使自身回复35%的", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddContent("生命值。", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddContent("效果发动冷却时间: 15秒", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddDividing(26, 15);
AddContent("回响 : 天行健", Padding, 18, sq_RGBA(60, 180, 0, 255));
AddContent("攻击时,以5%的概率使自身进入心流", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddContent("伤害增幅10%,效果持续时间5秒。", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddContent("效果发动冷却时间: 45秒", Padding, 18, sq_RGBA(230, 200, 155, 250));
AddDividing(26, 15);
AddContent("装备需求职业:", Padding, 18, sq_RGBA(255, 255, 255, 255));
AddContent("鬼剑士", 215 - LenheartTextClass.GetStringLength("鬼剑士") - Padding, 0, sq_RGBA(255, 255, 255, 255));
}
//增加内容
function AddContent(Content, X, Y, Color) {
InfoList.append({
Type = 0,
Content = Content,
X = X,
Y = Y + Height,
Color = Color
});
Height += Y;
}
//增加分割线
function AddDividing(X, Y) {
InfoList.append({
Type = 1,
X = X,
Y = Y + Height + 3,
});
Height += 8;
}
//增加自定义代理
function AddDelegate(Y, Func) {
InfoList.append({
Type = 2,
X = 0,
Y = Height,
Func = Func
});
Height += Y;
}
}

View File

@@ -146,7 +146,7 @@ class NewItemInfoWindowC extends Rindro_BaseToolClass {
local EquipmentAddress = NativePointer(Rindro_Haker.CpuContext.ecx).add(0x178).readInt();
//是装备才做这个事
local Id = NativePointer(EquipmentAddress).add(0x1c).readInt();
if (NativePointer(EquipmentAddress).add(0x4).readInt() == 2 || NeedDrawHookList.rawin(Id)) {
if (NeedDrawHookList.rawin(Id)) {
args[2] = 947330670;
args[3] = EquipmentAddress;
return args;

View File

@@ -14,34 +14,6 @@ class OutfitSystemC extends LenheartNewUI_Windows {
//是否可见
Visible = false;
/*
武器偏移 "3038"
称号偏移 "303C"
上衣偏移 "3040"
头肩偏移 "3044"
裤子偏移 "3048"
鞋子偏移 "304C"
腰带偏移 "3050"
项链偏移 "3054"
手镯偏移 "3058"
戒指偏移 "305C"
左曹偏移 "3060"
右曹偏移 "3064"
时装帽子偏移 "3008"
时装头部偏移 "300C"
时装脸部偏移 "3010"
时装上衣偏移 "3014"
时装下衣偏移 "3018"
时装鞋子偏移 "301C" 原来3020正确的是301C
时装胸部偏移 "3020"
时装腰带偏移 "3024"
时装皮肤偏移 "3028"
时装光圈偏移 "302C"
时装武器偏移 "3030"
宠物偏移 "3068"
*/
Img = Rindro_Image("interface2/buffswitching/buffswitching.img");
ItemSlotPos = [
@@ -76,6 +48,9 @@ class OutfitSystemC extends LenheartNewUI_Windows {
//当前选中
CurrentSelect = null;
//说明是否悬停
InstructionsIsHover = true;
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
Childrens = [];
@@ -206,6 +181,8 @@ class OutfitSystemC extends LenheartNewUI_Windows {
L_sq_DrawCode("时装槽位", X + 188, Y + 135, sq_RGBA(150, 150, 150, 255), 0, 1);
L_sq_DrawCode("宠物", X + 308, Y + 135, sq_RGBA(150, 150, 150, 255), 0, 1);
Rindro_Image_GlobalMap["lenheartui"].DrawPng(469 + (InstructionsIsHover ? 1 : 0), X + 335, Y + 266);
if (CurrentSelect != null) {
Rindro_Image_GlobalMap["lenheartui"].DrawPng(425, X + 12 + (CurrentSelect % 10) * 30, Y + 38 + (CurrentSelect / 10) * 30);
}
@@ -216,9 +193,29 @@ class OutfitSystemC extends LenheartNewUI_Windows {
LenheartNewUI_Windows.Show(obj);
}
function TopShow(obj)
{
if(InstructionsIsHover){
local XOffset = 8;
local YOffset = 192;
DrawNineBox(X + XOffset, Y + YOffset, 326, 80, "interface/lenheartwindowcommon.img", 213);
L_sq_DrawCode("①选择对应的标签以配置换装配置", X + XOffset + 8, Y + YOffset + 8, sq_RGBA(230, 200, 155, 255), 0, 1);
L_sq_DrawCode("②点击记录可以保存当前穿戴的装备,点击重置可以清除配置", X + XOffset + 8, Y + YOffset + 8 + 16, sq_RGBA(230, 200, 155, 255), 0, 1);
L_sq_DrawCode("③在对话窗口输入//HZ 1 可以换装1号标签的配置", X + XOffset + 8, Y + YOffset + 8 + 32, sq_RGBA(230, 200, 155, 255), 0, 1);
L_sq_DrawCode("④设置快捷喊话可以方便一键切换", X + XOffset + 8, Y + YOffset + 8 + 48, sq_RGBA(230, 200, 155, 255), 0, 1);
}
}
//逻辑入口
function Proc(obj) {
LenheartNewUI_Windows.SyncPos(X, Y);
if (sq_IsIntersectRect(IMouse.GetXPos(), IMouse.GetYPos(), 1, 1, X + 335, Y + 266, 16, 16)) {
InstructionsIsHover = true;
} else {
InstructionsIsHover = false;
}
}
//读取自身装备并显示在装备槽位
@@ -270,7 +267,6 @@ class OutfitSystemC extends LenheartNewUI_Windows {
}
L_Windows_List <- [];
getroottable().rawdelete("LenheartPluginsInitFlag");
getroottable().rawdelete("EventList_Obj")
@@ -278,7 +274,6 @@ getroottable().rawdelete("OutfitSystem_Obj");
getroottable().rawdelete("L_Each_Obj");
function Lenheart_OutfitSystem_Fun(obj) {
local RootTab = getroottable();
if (!RootTab.rawin("OutfitSystem_Obj")) {

View File

@@ -92,16 +92,18 @@ class RepairWorldMapC extends LenheartNewUI_Windows {
L_sq_DrawCode(Info[AreaId].Name, 135 + YosinWorldMapX, 10 + YosinWorldMapY, 0xFFFFFFFF, 1, 1);
if (TabbarFlag) {
local DrawIndex = 0;
foreach(Pos, Value in Info) {
L_sq_DrawImg("interface/minimap_minimap_town.img", 9, 131 + YosinWorldMapX, 25 + (Pos * 18) + YosinWorldMapY);
L_sq_DrawImg("interface/minimap_minimap_town.img", 9, 131 + YosinWorldMapX, 25 + (DrawIndex * 18) + YosinWorldMapY);
// L_sq_DrawWindow(128, 24 + (Pos * 18), 108, 10, "interface/lenheartwindowcommon.img", 97, 11, 12, 11, 13);
L_sq_DrawCode(Value.Name, 135 + YosinWorldMapX, 28 + (Pos * 18) + YosinWorldMapY, 0xFFFFFFFF, 1, 1);
if (sq_IsIntersectRect(IMouse.GetXPos(), IMouse.GetYPos(), 1, 1, 131 + YosinWorldMapX, 25 + (Pos * 18) + YosinWorldMapY, 108, 18)) {
L_sq_DrawCode(Value.Name, 135 + YosinWorldMapX, 28 + (DrawIndex * 18) + YosinWorldMapY, 0xFFFFFFFF, 1, 1);
if (sq_IsIntersectRect(IMouse.GetXPos(), IMouse.GetYPos(), 1, 1, 131 + YosinWorldMapX, 25 + (DrawIndex * 18) + YosinWorldMapY, 108, 18)) {
MarkFlag = Pos;
L_sq_SetDrawImgModel(2, 0);
L_sq_DrawImg("interface/minimap_minimap_town.img", 16, 131 + YosinWorldMapX, 25 + (Pos * 18) + YosinWorldMapY);
L_sq_DrawImg("interface/minimap_minimap_town.img", 16, 131 + YosinWorldMapX, 25 + (DrawIndex * 18) + YosinWorldMapY);
L_sq_ReleaseDrawImgModel();
}
DrawIndex++;
}
}
}

515
Project/Steal/Steal.nut Normal file
View File

@@ -0,0 +1,515 @@
/*
文件名:Steal.nut
路径:Project/Steal/Steal.nut
创建日期:2026-04-07 05:19
文件用途:
*/
class StealC_Password_Box extends LenheartNewUI_CommonUi {
NumberSeq = null;
ScrollPixelOffset = 0;
ScrollBaseIndex = 0;
InitBaseIndex = 0;
ScrollStartTimeMs = 0;
RowDurationMs = 250;
RowHeight = 24;
ColumnYOffset = 0;
CorrectIndex = 0;
IsStopped = false;
IsLockedCorrect = false;
StopSnapOffsetY = 0;
PassStr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
constructor(X, Y, ...) {
LenheartNewUI_CommonUi.constructor(X, Y, 30, 120);
local PhaseIndex = 0;
if (vargc > 0) {
PhaseIndex = vargv[0];
}
ColumnYOffset = -(PhaseIndex * 8);
NumberSeq = [];
for (local i = 0; i< 10; i++) {
local Info = {
num = PassStr[sq_getRandom(0, PassStr.len() - 1)],
CorrectFlag = false,
}
NumberSeq.append(Info);
}
CorrectIndex = sq_getRandom(0, 9);
NumberSeq[CorrectIndex].CorrectFlag = true;
local SeqLen = NumberSeq.len();
if (SeqLen > 0) {
local Phase = PhaseIndex % SeqLen;
if (Phase< 0) {
Phase += SeqLen;
}
ScrollBaseIndex = Phase;
InitBaseIndex = Phase;
}
ScrollStartTimeMs = Clock();
}
function GetLoopIndex(Index) {
local SeqLen = NumberSeq.len();
if (SeqLen <= 0) {
return 0;
}
local Value = Index % SeqLen;
if (Value< 0) {
Value += SeqLen;
}
return Value;
}
function UpdateScrollByClock() {
if (RowDurationMs <= 0) {
RowDurationMs = 1;
}
local RunTimeMs = Clock() - ScrollStartTimeMs;
if (RunTimeMs< 0) {
RunTimeMs = 0;
}
local PassedRows = (RunTimeMs / RowDurationMs).tointeger();
local CycleMs = RunTimeMs % RowDurationMs;
ScrollPixelOffset = sq_GetUniformVelocity(0, RowHeight - 1, CycleMs, RowDurationMs).tointeger();
ScrollBaseIndex = GetLoopIndex(InitBaseIndex - PassedRows);
}
function GetCorrectCenterY(RefY) {
local SeqLen = NumberSeq.len();
if (SeqLen <= 0) {
return Y;
}
local Delta = GetLoopIndex(CorrectIndex - ScrollBaseIndex);
local TextY = Y + 10;
local BaseY = TextY + Delta * RowHeight + ScrollPixelOffset + ColumnYOffset + 8;
local CycleHeight = SeqLen * RowHeight;
local BestY = BaseY;
local BestDist = abs(BestY - RefY);
for (local k = -2; k <= 2; k++) {
local CY = BaseY + (k * CycleHeight);
local Dist = abs(CY - RefY);
if (Dist< BestDist) {
BestY = CY;
BestDist = Dist;
}
}
return BestY;
}
function TryLockByRect(LockTopY, LockHeight, SnapExtraOffsetY) {
if (IsStopped) {
return false;
}
UpdateScrollByClock();
local LockCenterY = LockTopY + (LockHeight / 2).tointeger();
local CorrectCenterY = GetCorrectCenterY(LockCenterY);
if (CorrectCenterY >= LockTopY && CorrectCenterY <= (LockTopY + LockHeight)) {
StopSnapOffsetY = (LockCenterY - CorrectCenterY) + SnapExtraOffsetY;
IsStopped = true;
IsLockedCorrect = true;
return true;
}
return false;
}
function Show(obj) {
Parent.Img.DrawExPng(10, X, Y, 0, sq_RGBA(255, 255, 255, 90), 1.0, 1.0);
local SeqLen = NumberSeq.len();
if (SeqLen <= 0) {
return;
}
if (!IsStopped) {
UpdateScrollByClock();
}
local DrawCount = (Height / RowHeight).tointeger() + 4;
local TextY = Y + 10;
for (local i = -2; i< DrawCount - 2; i++) {
local Info = NumberSeq[GetLoopIndex(ScrollBaseIndex + i)];
local NumStr = Info.num.tostring();
local Color = Info.CorrectFlag ? sq_RGBA(157, 245, 10, 255) : sq_RGBA(150, 150, 150, 255);
local DrawY = TextY + i * RowHeight + ScrollPixelOffset + ColumnYOffset + StopSnapOffsetY;
L_sq_DrawCode(NumStr, X + 15 - LenheartTextClass.GetStringLength(NumStr) / 2, DrawY, Color, 0, 1);
}
}
}
class StealC extends LenheartNewUI_Windows {
//调试模式
// DeBugMode = true;
//不是窗口
// NoWindow = true;
//是否可见
Visible = false;
Img = Rindro_Image("steal/widget.img");
//解锁完成度
UnlockComplete = 0.0;
CorrectLockedCount = 0;
LockBoxHeight = 24;
LockSnapOffsetY = -6;
AllUnlockedTriggered = false;
AniQueue = null;
UnlockSuccessAni = null;
UnlockAniPlaying = false;
UnlockAniFinished = false;
UnlockFinalizeDone = false;
UnlockAniFrameDelay = 60;
NPCList = null;
RequestNpcId = -1;
NpcEachRegistered = false;
constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) {
Childrens = [];
AniQueue = QuestQueue();
//注册控件
RegisterWidget();
LenheartNewUI_Windows.constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH);
RefreshUnlockComplete();
InitStealConfig();
RegisterStealNpcEach();
RegisterPack(21017002, function(Chunk) {
local Jso = Json.Decode(Chunk);
if (Jso.rawin("ret") && Jso.ret == true) {
ResetStealSession();
Visible = true;
ResetFocus();
} else {
Visible = false;
}
}.bindenv(this));
}
function RegisterWidget() {
// //关闭按钮
// local CloseButton = LenheartNewUI_BaseButton(278, 0, 11, 12, "interface/lenheartwindowcommon.img", 276);
// CloseButton.OnClick = function() {
// this.Visible = false;
// }.bindenv(this);
// Childrens.append(CloseButton);
for (local i = 0; i< 8; i++) {
local PasswordBox = StealC_Password_Box(280 + i * 30, 268, i);
AddChild(PasswordBox);
}
}
//绘制主界面
function InitStealConfig() {
NPCList = [];
Rindro_Script.GetFileData("etc/steal.etc", function(DataTable, Data) {
while (!Data.Eof()) {
local Fragment = Data.Get();
if (Fragment == "[npc list]") {
while (true) {
local Value = Data.Get();
if (Value == "[/npc list]") {
break;
}
local NpcId = Value;
try {
NpcId = Value.tointeger();
} catch (exception) {}
NPCList.append(NpcId);
}
}
}
}.bindenv(this));
}
function RegisterStealNpcEach() {
if (NpcEachRegistered) {
return;
}
if (!NPCList || NPCList.len() <= 0) {
return;
}
local RootTab = getroottable();
local EachManager = null;
if (RootTab.rawin("L_Each_Obj")) {
EachManager = RootTab["L_Each_Obj"];
} else if (RootTab.rawin("Lenheart_Get_EachObj")) {
EachManager = RootTab["Lenheart_Get_EachObj"]();
}
if (!EachManager) {
return;
}
foreach(id in NPCList) {
EachManager.AddEachForNpc(id, function(SThis) {
local StealButton = LenheartNewUI_Each_BaseButton(0, 0, 100, 21, "interface2/popup_menu/popup_back.img", 3);
StealButton.Icon = "interface2/popup_menu/popup_icon_cn.img";
StealButton.IconIdx = 27;
StealButton.Str = "偷窃";
StealButton.OnClick = function(Button) {
local NpcId = Button.Parent.NPC_Index;
RequestNpcId = NpcId;
Button.Parent.CloseAllEach();
Button.Parent.CloseWindow();
SendPackEx({
op = 21017001,
npcid = NpcId
});
}.bindenv(this);
StealButton.SetCallBackFunc(function(Button) {})
SThis.AddChild(StealButton);
}.bindenv(this));
}
NpcEachRegistered = true;
}
function ResetStealSession() {
UnlockComplete = 0.0;
CorrectLockedCount = 0;
AllUnlockedTriggered = false;
UnlockAniPlaying = false;
UnlockAniFinished = false;
UnlockFinalizeDone = false;
UnlockSuccessAni = null;
AniQueue = QuestQueue();
Childrens = [];
RegisterWidget();
RefreshUnlockComplete();
}
function GetLockTopY() {
return Y + 268 + 60;
}
function GetFocusPasswordBox() {
foreach(Child in Childrens) {
if ((Child instanceof StealC_Password_Box) && !Child.IsStopped) {
return Child;
}
}
return null;
}
function GetPasswordBoxTotal() {
local Total = 0;
foreach(Child in Childrens) {
if (Child instanceof StealC_Password_Box) {
Total += 1;
}
}
return Total;
}
function RefreshUnlockComplete() {
local Total = GetPasswordBoxTotal();
if (Total <= 0) {
UnlockComplete = 0.0;
return;
}
UnlockComplete = CorrectLockedCount.tofloat() / Total.tofloat();
}
function BuildUnlockFrameArr() {
local FrameArr = [];
local Delay = UnlockAniFrameDelay;
if (Delay <= 0) {
Delay = 60;
}
for (local i = 0; i< 13; i++) {
FrameArr.append({
ImgIndex = i,
Delay = Delay,
Pos = [0, 0]
});
}
return FrameArr;
}
function StartUnlockSuccessSequence() {
if (UnlockAniPlaying || UnlockAniFinished) {
return;
}
local FrameArr = BuildUnlockFrameArr();
UnlockSuccessAni = Lenheart_Ani("", FrameArr, [X + 269, Y + 260]);
UnlockSuccessAni.ImgPath = "steal/unlock.img";
UnlockSuccessAni.LoopFlag = false;
UnlockSuccessAni.Reset();
UnlockAniPlaying = true;
UnlockAniFinished = false;
if (AniQueue) {
AniQueue.RemoveQuest("StealUnlockSuccessAni");
AniQueue.AddQuest("StealUnlockSuccessAni", function(Name, Time) {
if (!UnlockSuccessAni) {
UnlockAniPlaying = false;
UnlockAniFinished = true;
AniQueue.RemoveQuest(Name);
FinalizeUnlockSuccess();
return;
}
UnlockSuccessAni.X = X + 324;
UnlockSuccessAni.Y = Y + 109;
UnlockSuccessAni.Show(Duration);
if (UnlockSuccessAni.State == 0) {
UnlockAniPlaying = false;
UnlockAniFinished = true;
AniQueue.RemoveQuest(Name);
FinalizeUnlockSuccess();
}
}.bindenv(this));
} else {
UnlockAniPlaying = false;
UnlockAniFinished = true;
FinalizeUnlockSuccess();
}
}
function FinalizeUnlockSuccess() {
if (UnlockFinalizeDone) {
return;
}
UnlockFinalizeDone = true;
SendStealUnlockPack();
CloseWindow();
Visible = false;
}
function SendStealUnlockPack() {
if (RequestNpcId == null || RequestNpcId <= 0) {
return;
}
SendPackEx({
op = 21017003,
npcid = RequestNpcId
});
}
function OnAllUnlockedInternal() {
R_Utils.PlaySound("GAMBLE_RESULT_GOOD");
StartUnlockSuccessSequence();
}
function CheckAllUnlocked() {
if (AllUnlockedTriggered) {
return;
}
local Total = GetPasswordBoxTotal();
if (Total <= 0) {
return;
}
if (CorrectLockedCount >= Total) {
AllUnlockedTriggered = true;
OnAllUnlockedInternal();
}
}
function CheckSpaceLock() {
if (!Visible) {
return;
}
if (!KeyPressNB.isKeyPress(7, "StealC")) {
return;
}
local FocusBox = GetFocusPasswordBox();
if (!FocusBox) {
return;
}
if (FocusBox.TryLockByRect(GetLockTopY(), LockBoxHeight, LockSnapOffsetY)) {
R_Utils.PlaySound("TRADE_OK");
CorrectLockedCount += 1;
RefreshUnlockComplete();
CheckAllUnlocked();
} else {
R_Utils.PlaySound("ALERT_2");
}
}
function DrawMain(obj) {
//灰色背景
DrawNineBoxAlpha(X, Y, 800, 600, "interface2/common/mypopup/popup.img", 0, 150);
//宝箱动画
local Ani = DrawAniEx(X + 425, Y + 230, "npc/animation/storagediamond.ani");
Ani.setImageRateFromOriginal(1.7, 1.7);
//如果未解锁
if (UnlockComplete< 1.0) {
//宝箱锁图像
Img.DrawPng(12, X + 335, Y + 120);
}
//完成度文字
local StealCompleteStr = "解锁完成度: " + UnlockComplete * 100.0 + "%";
L_sq_DrawCode(StealCompleteStr, X + 410 - LenheartTextClass.GetStringLength(StealCompleteStr) / 2, Y + 406, sq_RGBA(255, 255, 255, 255), 0, 1);
//完成度进度条
Img.DrawPng(2, X + 162, Y + 425);
setClip(X + 168, Y + 429, X + 168 + (463 * UnlockComplete).tointeger(), Y + 429 + 6);
Img.DrawPng(3, X + 168, Y + 429);
releaseClip(); //裁切结束
//解锁界面
Img.DrawPng(9, X + 269, Y + 260);
//解锁锁定条
Img.DrawPng(11, X + 269 + 8, Y + 260 + 60);
}
function Show(obj) {
DrawMain(obj);
if (AniQueue) {
AniQueue.Run();
}
//裁切遮罩密码框
setClip(X + 280, Y + 268, X + 280 + 8 * 30, Y + 268 + 120);
LenheartNewUI_Windows.Show(obj);
releaseClip(); //裁切结束
}
//逻辑入口
function Proc(obj) {
LenheartNewUI_Windows.SyncPos(X, Y);
if (!NpcEachRegistered) {
RegisterStealNpcEach();
}
CheckSpaceLock();
}
}
L_Windows_List <- [];
getroottable().rawdelete("LenheartPluginsInitFlag");
getroottable().rawdelete("EventList_Obj")
getroottable().rawdelete("Steal_Obj");
getroottable().rawdelete("L_Each_Obj");
function Lenheart_Steal_Fun(obj) {
local RootTab = getroottable();
if (!RootTab.rawin("Steal_Obj")) {
RootTab.rawset("Steal_Obj", true);
LenheartNewUI_CreateWindow(StealC, "Steal_Window", 0, 0, 800, 600, 0);
}
}
getroottable()["LenheartFuncTab"].rawset("StealFuncN", Lenheart_Steal_Fun);

View File

@@ -256,5 +256,14 @@
},
"Project/CustomPlugins": {
"description": "定制插件"
},
"Project/OutfitSystem": {
"description": "换装系统"
},
"Project/MySelf": {
"description": "自己服"
},
"Project/Steal": {
"description": "偷窃系统"
}
}