dp-s_doc/Start/Example/5.md

3.1 KiB
Raw Blame History

主线任务完成卷 (贡献者: Trim)

首先我们先在dp_s文件夹中建立一个项目文件夹 MyProject 方便管理

Alt text

然后我们建立一个新文件 主线任务完成卷.nut 用于编写我们的代码

Alt text

然后我们在主线任务完成卷.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);
}

Alt text

最后我们回到dp_s文件夹中打开Main.nut 加载我们刚才编写的逻辑

sq_RunScript("MyProject/主线任务完成卷.nut");

Alt text

至此一个简单的主线任务完成卷的逻辑就写完了,然后我们就可以在游戏中使用道具7577来完成主线任务了