3.1 KiB
3.1 KiB
主线任务完成卷 (贡献者: Trim)
首先我们先在dp_s文件夹中建立一个项目文件夹 MyProject 方便管理
然后我们建立一个新文件 主线任务完成卷.nut 用于编写我们的代码
然后我们在主线任务完成卷.nut中写入以下代码
//本例子由 Trim 提供
//主线任务完成卷ID
CrossoverId <- 7577;
Cb_Use_Item_Sp_Func[CrossoverId] <- function(SUser, ItemId) {
// 不需要完成的任务ID数组
local skippedQuestIDs = [674]; //将不要清理的任务ID写入数组内即可
// 获取角色任务信息和等级
local userQuest = SUser.GetQuest();
local questIsClear = NativePointer(userQuest).add(4);
local characLevel = SUser.GetCharacLevel();
local allClearQuest = 0;
// 获取 pvf 数据
local DataManager = Sq_CallFunc(S_Ptr("0x80CC19B"), "pointer", []);
// 判断任务是否需要跳过
function shouldSkip(questID) {
return skippedQuestIDs.find(questID) != null;
}
// 判断任务是否为主线并且角色等级符合要求
function isMainQuestAndLevelValid(pvfQuest, characLevel) {
local questGrade = NativePointer(pvfQuest).add(8).readInt();
local questLv = NativePointer(pvfQuest).add(0x20).readInt();
return questGrade == 0 && questLv <= characLevel;
}
// 判断任务是否已完成
function isQuestCleared(questID) {
return Sq_CallFunc(S_Ptr("0x808BAE0"), "bool", ["pointer", "int"], questIsClear.C_Object, questID);
}
// 设置任务为已完成
function clearQuest(questID) {
Sq_CallFunc(S_Ptr("0x808BA78"), "int", ["pointer", "int"], questIsClear.C_Object, questID);
}
// 循环处理任务
for (local questID = 1; questID< 30000; questID++) {
// 从 pvf 中获取任务数据
local pvfQuest = Sq_CallFunc(S_Ptr("0x835FDC6"), "pointer", ["pointer", "int"], DataManager, questID);
if (!pvfQuest || shouldSkip(questID)) continue; // 跳过空任务或不需要完成的任务
// 判断是否为主线任务且等级符合要求
if (!isMainQuestAndLevelValid(pvfQuest, characLevel)) continue;
// 判断任务是否已完成,若未完成则清理任务
if (!isQuestCleared(questID)) {
clearQuest(questID);
allClearQuest++;
}
}
local Pack = Packet();
//通知客户端刷新任务列表
Sq_CallFunc(S_Ptr("0x86ABBA8"), "int", ["pointer", "pointer"], userQuest, Pack.C_Object);
SUser.Send(Pack);
Pack.Delete();
// 发送通知
SUser.SendNotiPacketMessage("已清理:" + allClearQuest + "个主线任务!", 8);
}
最后我们回到dp_s文件夹中,打开Main.nut 加载我们刚才编写的逻辑
sq_RunScript("MyProject/主线任务完成卷.nut");
至此一个简单的主线任务完成卷的逻辑就写完了,然后我们就可以在游戏中使用道具7577来完成主线任务了



