466 lines
18 KiB
Plaintext
466 lines
18 KiB
Plaintext
|
||
|
||
ChaFuCustomDecompositionFixFlag <- false;
|
||
|
||
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){
|
||
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);
|
||
|
||
local equdata = Memory.alloc(1000); //装备数据
|
||
local needslot = Memory.alloc(4); //需要的空白格子
|
||
needslot.writeInt(0);
|
||
|
||
//初始化装备数据
|
||
Sq_CallFunc(S_Ptr("0x80CB854"), "void", ["pointer"], equdata.C_Object);
|
||
|
||
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);
|
||
|
||
local itemid = equdata.add(2).readS32(); //装备代码
|
||
local amptype = equdata.add(17).readS8(); //红字类型
|
||
local upgrade_level = equdata.add(6).readU8(); //强化等级
|
||
|
||
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)
|
||
local slot = MyUser.GiveItem(itemId, itemCount);
|
||
|
||
// 将物品信息写入数据包
|
||
PackObject.Put_Short(slot[1]); // 槽位
|
||
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());
|
||
|
||
local InvenObject = MyUser.GetInven();
|
||
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())];
|
||
} |