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

466 lines
18 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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())];
}