更新分解HOOK 更新分解机逻辑
This commit is contained in:
parent
4e311036aa
commit
54c9c9c004
|
|
@ -0,0 +1,464 @@
|
|||
|
||||
|
||||
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"), "pointer", ["pointer"], equdata.C_Object);
|
||||
Sq_CallFunc(S_Ptr("0x81F8BA1"), "int", ["pointer", "int", "int", "pointer", "pointer", "pointer", "int"], 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())];
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -676,6 +676,13 @@ Cb_Inter_AuctionResultBidding_Enter_Func <- {};
|
|||
Cb_Inter_AuctionResultBidding_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x84D6CA4", ["pointer", "pointer", "pointer", "int"], Cb_Inter_AuctionResultBidding_Enter_Func, Cb_Inter_AuctionResultBidding_Leave_Func);
|
||||
|
||||
|
||||
//分解
|
||||
Cb_MyDisPatcher_DisJointItem_disjoint_Enter_Func <- {};
|
||||
Cb_MyDisPatcher_DisJointItem_disjoint_Leave_Func <- {};
|
||||
_Hook_Register_Currency_Func_("0x81f92ca", ["pointer", "int", "int", "int", "pointer", "int", "int"], Cb_MyDisPatcher_DisJointItem_disjoint_Enter_Func, Cb_MyDisPatcher_DisJointItem_disjoint_Leave_Func);
|
||||
|
||||
|
||||
function _Hook_Register_Currency_DelayHook_() {
|
||||
//五国时的热点函数
|
||||
//获取Item Rarity
|
||||
|
|
|
|||
Loading…
Reference in New Issue