DP-S_Script/MyProject/分级机重写逻辑.nut

473 lines
18 KiB
Plaintext
Raw Permalink Normal View History

2025-12-28 12:53:40 +08:00
ChaFuCustomDecompositionFixFlag <- false;
2025-12-28 23:29:22 +08:00
2025-12-28 12:53:40 +08:00
Cb_MyDisPatcher_DisJointItem_disjoint_Enter_Func["茶服自定义分解机"] <- function(args) {
//原逻辑
if (args[3] != 239) {
return null;
} else {
// 检查玩家状态是否可以分解
if (Sq_CallFunc(S_Ptr("0x81F8A7C"), "int", ["pointer", "int", "int", "int"], args[0], args[3], args[2], args[1]) != 1) {
return null;
}
if (!args[4]) return;
local SelfUser = User(args[0]);
local OthersUser = User(args[4]);
if (!OthersUser.GetCurCharacExpertJob()) return null;
if (OthersUser.GetCurCharacExpertJobType() != 3) return null;
local InvenTypeFromItemSpace = Sq_CallFunc(S_Ptr("0x80F7845"), "int", ["int"], args[2]);
if (SelfUser.CheckItemLock(InvenTypeFromItemSpace, args[1])) return null;
if (args[5] != 0xFFFF) {
local v9 = Sq_Get_GameWorld();
if (Sq_CallFunc(S_Ptr("0x81424E8"), "int", ["pointer"], v9)) return null;
}
ChaFuCustomDecompositionFixFlag = true;
//跳过原逻辑
Sq_WriteByteArr(S_Ptr("0x81F92D0"), Haker.AsmGenerateMcd(
"pop ebx",
"pop esi",
"pop edi",
"pop ebp",
"ret"));
try {
HandleDisjointRequest(SelfUser, args[1], args[2], args[3], OthersUser, args[5]);
} catch (exception){
2025-12-31 15:27:22 +08:00
print("error:")
print(exception)
2025-12-28 12:53:40 +08:00
Sq_CallFunc(S_Ptr("0x0867bf42"), "int", ["pointer", "int", "char"], SelfUser.C_Object, args[3], 19);
Sq_CallFunc(S_Ptr("0x0867bf42"), "int", ["pointer", "int", "char"], OthersUser.C_Object, args[3], 19);
}
}
}
Cb_MyDisPatcher_DisJointItem_disjoint_Leave_Func["茶服自定义分解机"] <- function(args) {
if (ChaFuCustomDecompositionFixFlag) {
ChaFuCustomDecompositionFixFlag = false;
Sq_WriteByteArr(S_Ptr("0x81F92D0"), [0x81, 0xec, 0xbc, 0x02, 0x00, 0x00, 0x8B, 0x45, 0x1c]);
}
}
function CUser_SendCmdErrorPacket(MyUser, HeadId, id) {
Sq_CallFunc(S_Ptr("0x867BF42"), "int", ["pointer", "int", "int"], MyUser.C_Object, HeadId, id)
}
function api_InterfacePacketBuf_put_byte_p(packet_guard, index, cnt) {
Sq_CallFunc(S_Ptr("0x8110B28"), "int", ["pointer", "pointer", "int"], packet_guard, index, cnt)
return;
}
// 装备分解系统 - Squirrel版本
function HandleDisjointRequest(MyUser, EquStol, Inventype, HeadId, ObjUser, ChannelIdentification) {
local InvenTypeFromItemSpace = Sq_CallFunc(S_Ptr("0x80F7845"), "int", ["int"], Inventype);
// 创建数据包
local PackObject = Packet();
PackObject.Put_Header(1, HeadId);
PackObject.Put_Byte(1);
PackObject.Put_Short(EquStol);
PackObject.Put_Byte(Inventype);
// 保存当前位置用于后续写入物品数量
local index = Sq_CallFunc(S_Ptr("0x8110B4C"), "int", ["pointer"], PackObject.C_Object)
PackObject.Put_Byte(0);
2025-12-28 23:29:22 +08:00
// local equdata = Memory.alloc(1000); //装备数据
// local needslot = Memory.alloc(4); //需要的空白格子
// needslot.writeInt(0);
local InvenObject = MyUser.GetInven();
2025-12-28 12:53:40 +08:00
2025-12-28 23:29:22 +08:00
// //初始化装备数据
// Sq_CallFunc(S_Ptr("0x80CB854"), "void", ["pointer"], equdata.C_Object);
2025-12-28 23:29:22 +08:00
// print("MyUser.C_Object: " + MyUser.C_Object + "EquStol: " + EquStol + "InvenTypeFromItemSpace: " + InvenTypeFromItemSpace + "equdata.C_Object: " + equdata.C_Object + "needslot.C_Object: " + needslot.C_Object + "ObjUser.C_Object: " + ObjUser.C_Object + "ChannelIdentification: " + ChannelIdentification);
// Sq_CallFunc(S_Ptr("0x81F8BA1"), "int", ["pointer", "int", "int", "pointer", "pointer", "pointer", "short"], MyUser.C_Object, EquStol, InvenTypeFromItemSpace, equdata.C_Object, needslot.C_Object, ObjUser.C_Object, ChannelIdentification);
2025-12-28 12:53:40 +08:00
2025-12-28 23:29:22 +08:00
local ItemObject = InvenObject.GetSlot(InvenTypeFromItemSpace, EquStol);
local itemid = ItemObject.GetIndex(); //装备代码
local amptype = ItemObject.GetAmplification(); //红字类型
local upgrade_level = ItemObject.GetUpgrade(); //强化等级
2025-12-28 12:53:40 +08:00
local ItemData = PvfItem.GetPvfItemById(itemid);
local Rarity = ItemData.GetRarity();
local equ_Level = ItemData.GetUsableLevel();
local tmpuser = 0;
// 确定使用哪个玩家的分解机等级
local tmpuser = null;
if (MyUser == ObjUser) {
tmpuser = MyUser; // 使用自己的分解机
} else {
tmpuser = ObjUser; // 使用他人的分解机
}
// 获取分解机等级
local CurCharacExpertJobExp = Sq_CallFunc(S_Ptr("0x08375026"), "int", ["pointer"], tmpuser.C_Object);
local CurExpertJobLevel = Sq_CallFunc(S_Ptr("0x0868bc7c"), "int", ["pointer", "int"], tmpuser.C_Object, CurCharacExpertJobExp);
// 准备物品产出列表 [物品ID, 数量]
local itemlist = [];
// 获取对应品级的有色晶块ID
local CrystalBlock = GetColoredCrystalBlock(Rarity);
// 根据装备品级处理基础产出
switch (Rarity) {
case 1: // 蓝装:无色小晶块 + 有色晶块
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([CrystalBlock, SetLevelCnt(CrystalBlock, equ_Level, CurExpertJobLevel)]);
break;
case 2: // 紫装:无色小晶块 + 有色晶块 + 下级元素结晶
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([CrystalBlock, SetLevelCnt(CrystalBlock, equ_Level, CurExpertJobLevel)]);
itemlist.append([3166, SetLevelCnt(3166, equ_Level, CurExpertJobLevel)]);
break;
case 3: // 粉装
// 检查是否为特殊传说装备
if (CF_chuanshuoliebiao2.find(itemid) != null) {
local randnum = MathClass.Rand(0, 1000);
local wupinIndex = 10000205; // 默认时空之石
local wupinNum = 1;
// 根据随机数决定产出
if (randnum< 100) {
wupinNum = 2;
wupinIndex = 10000204; // 镇魂之石
} else if (randnum< 200) {
wupinNum = 1;
wupinIndex = 10000204; // 镇魂之石
} else if (randnum< 300) {
wupinNum = 5; // 时空之石x5
} else if (randnum< 500) {
wupinNum = 3; // 时空之石x3
} else if (randnum< 700) {
wupinNum = 2; // 时空之石x2
}
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([wupinIndex, wupinNum]);
}
// 检查是否为普通传说装备
else if (CF_chuanshuoliebiao.find(itemid) != null) {
local randnum = MathClass.Rand(0, 1000);
local chuanshuolinghunnum = 1; // 基础1个传说灵魂
// 10%概率额外获得1个传说灵魂
if (randnum< 100) {
chuanshuolinghunnum += 1;
}
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([10099775, chuanshuolinghunnum]); // 传说灵魂
}
// 检查是否为阿拉德陨石领主神器
else if (CF_lingzhushenqi_aladeyunshi.find(itemid) != null) {
local yunshinum = equ_Level * 3 / 10; // 装备等级 * 0.3
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([3338, yunshinum]); // 阿拉德陨石
}
// 检查是否为燃烧陨石领主神器
else if (CF_lingzhushenqi_ranshaoyunshi.find(itemid) != null) {
local yunshinum = equ_Level * 3 / 10; // 装备等级 * 0.3
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([3339, yunshinum]); // 燃烧陨石
}
// 普通粉装
else {
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([CrystalBlock, SetLevelCnt(CrystalBlock, equ_Level, CurExpertJobLevel)]);
itemlist.append([3167, SetLevelCnt(3167, equ_Level, CurExpertJobLevel)]); // 上级元素结晶
}
break;
case 4: // 史诗装备:无色小晶块 + 宇宙灵魂
local SoulId = GetSoulId(equ_Level); // 根据等级获取对应的灵魂ID
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([SoulId, SetLevelCnt(SoulId, equ_Level, CurExpertJobLevel)]);
break;
case 5: // 勇者装备
if (equ_Level< 70) {
// 低级勇者装备:无色小晶块 + 魔石
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([3228, 1]); // 魔石
} else {
// 70级及以上勇者装备
if (CF_yijietaozhuang.find(itemid) != null) {
// 异界套装分解
local randnum = MathClass.Rand(0, 1000);
local basenum = 5; // 基础5个荒古的记忆
// 根据概率增加数量
if (randnum< 20) {
basenum += 10;
} else if (randnum< 50) {
basenum += 8;
} else if (randnum< 100) {
basenum += 5;
} else if (randnum< 500) {
basenum += 2;
}
// 加上强化等级加成
basenum += 5 + (CF_upgradeSetNum.rawget(upgrade_level) ? CF_upgradeSetNum[upgrade_level] : 0);
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([3311, basenum]); // 荒古的记忆
} else {
// 普通勇者装备
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
itemlist.append([3299, 1]); // 勇者装备材料
}
}
break;
default: // 其他品级:只给无色小晶块
itemlist.append([3037, SetLevelCnt(3037, equ_Level, CurExpertJobLevel)]);
break;
}
// 处理分解机等级带来的额外产出(仅限紫装)
if (Rarity == 2) {
local randnum = MathClass.Rand(0, 1000);
local extraChance = 0;
// 根据分解机等级设置额外产出概率
switch (CurExpertJobLevel) {
case 1:
extraChance = 50;
break; // 5%
case 2:
extraChance = 70;
break; // 7%
case 3:
extraChance = 90;
break; // 9%
case 4:
extraChance = 110;
break; // 11%
case 5:
extraChance = 130;
break; // 13%
case 6:
extraChance = 150;
break; // 15%
case 7:
extraChance = 170;
break; // 17%
case 8:
extraChance = 190;
break; // 19%
case 9:
extraChance = 210;
break; // 21%
case 10:
extraChance = 230;
break; // 23%
case 11:
extraChance = 250;
break; // 25%
}
// 检查是否获得额外材料
if (randnum <= extraChance) {
itemlist.append([2610045, 1]); // 分解机额外材料
}
}
// 处理红字装备的额外产出需要分解机等级≥7
if (amptype != 0 && CurExpertJobLevel >= 7) {
local randnum = MathClass.Rand(0, 1000);
local chance = 0;
// 根据品级设置红字装备产出概率
switch (Rarity) {
case 2:
chance = 200;
break; // 20% 概率
case 3:
chance = 400;
break; // 40% 概率
case 4:
chance = 1000;
break; // 100% 概率
case 5:
chance = 200;
break; // 20% 概率
}
if (randnum< chance) {
local randnum2 = MathClass.Rand(0, 1000);
local amount = 1; // 默认1个矛盾
// 3%概率获得10个矛盾
if (randnum2< 30) {
amount = 10;
}
itemlist.append([3242, amount]); // 矛盾的结晶体
}
}
// 将产出的物品添加到玩家背包并写入数据包
for (local i = 0; i< itemlist.len(); i++) {
local itemId = itemlist[i][0];
local itemCount = itemlist[i][1];
// 分配内存存储物品空间信息
local item_space = Memory.alloc(4);
// 添加物品到玩家背包
// 参数说明:玩家对象, 物品ID, 数量, 类型(6=直接添加), 物品空间指针, 标志位(0)
2025-12-31 15:27:22 +08:00
// local slot = MyUser.GiveItem(itemId, itemCount);
local slot = Sq_CallFunc(S_Ptr("0x867B6D4"), "int", ["pointer", "int", "int", "int", "pointer", "int"], MyUser.C_Object, itemId, itemCount, 6, item_space.C_Object, 0);
2025-12-28 12:53:40 +08:00
// 将物品信息写入数据包
2025-12-31 15:27:22 +08:00
PackObject.Put_Short(slot); // 槽位
2025-12-28 12:53:40 +08:00
PackObject.Put_Int(itemId); // 物品ID
PackObject.Put_Int(itemCount); // 数量
}
local indexPointer = Memory.alloc(4);
indexPointer.writeInt(index);
Sq_CallFunc(S_Ptr("0x8110B28"), "int", ["pointer", "pointer", "int"], PackObject.C_Object, indexPointer.C_Object, itemlist.len());
2025-12-28 23:29:22 +08:00
2025-12-28 12:53:40 +08:00
if (Sq_CallFunc(S_Ptr("0x850400C"), "int", ["pointer", "int", "int", "int", "int", "int"], InvenObject.C_Object, InvenTypeFromItemSpace, EquStol, 1, 7, 1) != 1) {
Sq_CallFunc(S_Ptr("0x0867bf42"), "int", ["pointer", "int", "char"], MyUser.C_Object, HeadId, 19);
return 0;
}
// 如果使用了分解机(自己或他人的),执行分解完成逻辑
if (tmpuser != null) {
local CurCharacExpertJob = Sq_CallFunc(S_Ptr("0x822f8d4"), "pointer", ["pointer"], tmpuser.C_Object);
Sq_CallFunc(S_Ptr("0x85D31A0"), "int", ["pointer", "pointer", "pointer"], CurCharacExpertJob, MyUser.C_Object, PackObject.C_Object);
}
PackObject.Finalize(true);
MyUser.Send(PackObject);
PackObject.Delete();
return 0;
}
// 辅助函数:根据等级和分解机等级计算物品数量
function SetLevelCnt(itemId, equLevel, disjointerLevel) {
local randnum = MathClass.Rand(0, 1000);
local ret = 1;
// 根据不同物品类型设置基础数量
switch (itemId) {
//处理上下级的元素结晶 不需要考虑装备等级问题
case 3166:
case 3167: {
ret = MathClass.Rand(2, 20); //默认值
//当分解机等级小于3有10%的概率触发大结果
if (randnum <= 100) {
ret = MathClass.Rand(100, 300);
}
//当分解机等级4到7级有15%的概率触发大结果
if (3< disjointerLevel && disjointerLevel <= 7) {
if (randnum <= 150) {
ret = MathClass.Rand(100, 300);
}
}
//当分解机等级大于8级有15%的概率触发大结果
if (disjointerLevel >= 8) {
if (randnum <= 300) {
ret = MathClass.Rand(100, 300);
}
}
return ret;
}
//处理处理狗头 不考虑分解机等级 且不考虑大成功
case 3260:
case 3285: {
ret = MathClass.Rand(55, 80); //默认值
return ret;
}
//处理无色小晶体
case 3037: {
switch (equLevel) {
case 1:
return MathClass.Rand(5, 20);
case 5:
case 10:
case 15:
case 20:
return MathClass.Rand(10, 40);
case 25:
case 30:
case 35:
case 40:
return MathClass.Rand(40, 80);
case 45:
case 50:
case 55:
case 60:
return MathClass.Rand(70, 150);
case 65:
case 70:
case 75:
case 80:
case 85:
return MathClass.Rand(90, 200);
default:
return MathClass.Rand(10, 40);
}
}
//处理有色小晶体
default: {
ret = MathClass.Rand(2, 30); //默认值
//当分解机等级小于3有10%的概率触发大结果
if (randnum <= 100) {
ret = MathClass.Rand(100, 300);
}
//当分解机等级4到7级有15%的概率触发大结果
if (3< disjointerLevel && disjointerLevel <= 7) {
if (randnum <= 150) {
ret = MathClass.Rand(100, 300);
}
}
//当分解机等级大于8级有15%的概率触发大结果
if (disjointerLevel >= 8) {
if (randnum <= 300) {
ret = MathClass.Rand(100, 300);
}
}
return ret;
}
}
// 确保至少返回1个
return baseCount > 0 ? baseCount : 1;
}
// 辅助函数根据等级获取灵魂ID史诗灵魂
function GetSoulId(equLevel) {
switch (equLevel) {
case 70:
case 75:
case 80:
case 85:
return 3285;//透明
default:
return 3260//灿烂
}
}
// 辅助函数根据品级获取有色晶块ID
function GetColoredCrystalBlock(rarity) {
local item = null;
switch (rarity) {
case 2:
case 3:
item = [3033, 3036, 3035, 3034, 3262]; //金色
default:
item = [3033, 3036, 3035, 3034]; //无金色
}
return item[MathClass.Rand(0, item.len())];
}