Class CharacterQuestManager
MapleCharacter。
本類別封裝對角色任務狀態表 quests(MapleQuest → MapleQuestStatus)
與任務附帶資料表 questinfo(questid → 自訂字串,亦供組隊任務使用)的核心存取,涵蓋:
- 任務狀態的增刪查改——
getQuest(MapleQuest)/getQuestNoAdd(MapleQuest)/getQuestNAdd(MapleQuest)/setQuestAdd(MapleQuest, byte, String)/getQuestRemove(MapleQuest)/updateQuest(MapleQuestStatus)/getQuestStatus(int)/getNumQuest(); - 任務附帶資料(questinfo)的讀寫與封包推送——
getInfoQuest(int)/updateInfoQuest(int, String)/QuestInfoPacket(MaplePacketLittleEndianWriter); - 整張任務表的快照與列舉——
getQuest_Map()/getInfoQuest_Map()/getStartedQuests()/getCompletedQuests()/getCompletedMedals(); - 怪物擊殺對任務進度的回寫——
mobKilled(int, int); - 組隊任務(party quest)的開始/計分/排名——
startPartyQuest(int)/getOneInfo(int, String)/updateOneInfo(int, String, String)/recalcPartyQuestRank(int)/tryPartyQuest(int)/endPartyQuest(int)/havePartyQuest(int)(其附帶資料即存於questinfo,計時起點存於pqStartTime)。
MapleCharacter 以**逐字搬移**的方式把這些方法移入此處,並對每個對外公開方法保留
**簽名完全相同**的委派(delegate),因此所有 Java 呼叫端與 ~2,700 支腳本(皆透過 cm/
pi/qm 等腳本 API 轉呼)完全不受影響。協作者僅持有對所屬角色的回參考,透過同
package 存取其 quests/questinfo/changed_questinfo/pqStartTime/
client 等成員;quests/questinfo 這兩個欄位本身仍宣告並初始化於
MapleCharacter(載入/存檔/跨頻道搬移會直接存取),僅放寬為 package-private 供本協作者存取。
組隊任務方法建立在核心任務方法之上:在本類別內部以**裸名稱**互相呼叫(如 startPartyQuest 內呼叫
getQuestNAdd/updateQuest/updateInfoQuest),與搬移前在 MapleCharacter
內的裸呼叫逐位元組一致。
-
Method Summary
Modifier and TypeMethodDescriptionvoidendPartyQuest(int questid) 結算一次組隊任務的完成:記錄最佳耗時、累加完成次數與完成率,並重評等級。取得角色已完成且會頒發勳章(裝備類獎勵道具)的任務清單。final List<MapleQuestStatus> 取得角色目前所有已完成的(非自訂、未被封鎖)任務。final StringgetInfoQuest(int questid) 取得指定任務的附帶資料字串。取得角色任務附帶資料表questinfo的底層參考。final int計算角色已完成的(非自訂)任務數量。getOneInfo(int questid, String key) 從某組隊任務的附帶資料字串中,解析並取出單一欄位的值。final MapleQuestStatusgetQuest(MapleQuest quest) 取得指定任務的狀態物件,必要時回傳一個全新的「未開始」狀態。final Map<MapleQuest, MapleQuestStatus> 取得角色任務狀態表quests的底層參考。final MapleQuestStatusgetQuestNAdd(MapleQuest quest) 取得指定任務的狀態物件,缺少時建立一筆「未開始」狀態並放入quests表。final MapleQuestStatusgetQuestNoAdd(MapleQuest quest) 直接取得quests表中指定任務的狀態物件,缺少時不新增。final MapleQuestStatusgetQuestRemove(MapleQuest quest) 自quests表移除指定任務並回傳其原狀態物件。final bytegetQuestStatus(int quest) 取得指定任務(以 ID 指定)的狀態值。final List<MapleQuestStatus> 取得角色目前所有進行中的(非自訂、未被封鎖)任務。voidhavePartyQuest(int itemId) 依持有的特定 PQ 道具標記對應組隊任務的「持有」欄位。voidmobKilled(int id, int skillID) 將一次怪物擊殺回寫至所有相關的進行中任務的擊殺進度。final void將角色的任務附帶資料表questinfo(主要供組隊任務使用)序列化寫入指定封包寫入器。voidrecalcPartyQuestRank(int questid) 依某組隊任務目前的累計數據重新評定其等級(rank),達標時逐級晉升。final voidsetQuestAdd(MapleQuest quest, byte status, String customData) 在角色尚無此任務時,以指定狀態與自訂資料新增一筆任務狀態。booleanstartPartyQuest(int questid) 開始一個組隊任務(party quest),必要時建立其任務狀態與初始附帶資料。voidtryPartyQuest(int questid) 記錄一次組隊任務的「嘗試」:開始任務、記下計時起點並累加嘗試次數。final voidupdateInfoQuest(int questid, String data) 設定指定任務的附帶資料字串,並即時同步至客戶端。voidupdateOneInfo(int questid, String key, String value) 更新某組隊任務附帶資料字串中的單一欄位值,並同步至客戶端。final voidupdateQuest(MapleQuestStatus quest) 寫入/更新一筆任務狀態並同步至客戶端(非靜默模式)。final voidupdateQuest(MapleQuestStatus quest, boolean update) 寫入/更新一筆任務狀態,並(對非自訂任務)同步至客戶端。
-
Method Details
-
QuestInfoPacket
將角色的任務附帶資料表questinfo(主要供組隊任務使用)序列化寫入指定封包寫入器。先寫入項目數量(
short),再逐筆寫入 questid(short)與其對應字串; 值為null時改寫空字串。註:對應的 quest 須另行加入quests清單。- Parameters:
mplew- 目標封包寫入器,呼叫後其緩衝區會被附加上述資料
-
updateInfoQuest
設定指定任務的附帶資料字串,並即時同步至客戶端。副作用:寫入
questinfo、將changed_questinfo標記為待存檔(true), 並向客戶端送出InfoPacket.updateInfoQuest(int, String)封包。- Parameters:
questid- 任務 IDdata- 要儲存的附帶資料字串
-
getInfoQuest
取得指定任務的附帶資料字串。- Parameters:
questid- 任務 ID- Returns:
- 對應的附帶資料字串;若該任務尚無附帶資料則回傳空字串(不會回傳
null)
-
getNumQuest
public final int getNumQuest()計算角色已完成的(非自訂)任務數量。僅計入狀態為已完成(
status == 2)且非自訂(!isCustom())的任務。- Returns:
- 已完成的一般任務數量
-
getQuestStatus
public final byte getQuestStatus(int quest) 取得指定任務(以 ID 指定)的狀態值。採非新增(no-add)語意:若角色尚無此任務則回傳
0(未開始),不會在quests表中建立新項目。- Parameters:
quest- 任務 ID- Returns:
- 任務狀態(0=未開始、1=進行中、2=已完成);任務不存在時為
0
-
getQuest
取得指定任務的狀態物件,必要時回傳一個全新的「未開始」狀態。若角色
quests表中沒有此任務,回傳一個status == 0的全新MapleQuestStatus,但**不**將其放入quests(與getQuestNAdd(MapleQuest)不同—— 後者會放入;亦與getQuestNoAdd(MapleQuest)不同——後者直接回傳表中值、缺少時為null)。- Parameters:
quest- 任務定義- Returns:
- 對應的任務狀態;缺少時為新建的未開始狀態(永不為
null)
-
setQuestAdd
在角色尚無此任務時,以指定狀態與自訂資料新增一筆任務狀態。具「不覆寫」語意:僅當
quests表中尚不含此任務時才建立並放入新項目; 若已存在則不做任何更動。新項目的自訂資料會設為customData。- Parameters:
quest- 任務定義status- 初始狀態值(0=未開始、1=進行中、2=已完成)customData- 要附加的自訂資料字串
-
getQuestNAdd
取得指定任務的狀態物件,缺少時建立一筆「未開始」狀態並放入quests表。與
getQuest(MapleQuest)的差異在於:本方法在缺少時會把新建的狀態**寫入**quests(產生狀態變更副作用),而getQuest(MapleQuest)只回傳暫時物件、不寫入。- Parameters:
quest- 任務定義- Returns:
- 對應的任務狀態;缺少時為新建並已放入表中的未開始狀態(永不為
null)
-
getQuestNoAdd
直接取得quests表中指定任務的狀態物件,缺少時不新增。採純查詢(no-add)語意:直接回傳表中對應值,不會建立任何新項目。
- Parameters:
quest- 任務定義- Returns:
- 對應的任務狀態;若角色尚無此任務則為
null
-
getQuestRemove
自quests表移除指定任務並回傳其原狀態物件。副作用:直接從角色的任務表移除該項目。
- Parameters:
quest- 任務定義- Returns:
- 被移除的任務狀態;若原本就不存在則為
null
-
updateQuest
寫入/更新一筆任務狀態並同步至客戶端(非靜默模式)。等同呼叫
updateQuest(MapleQuestStatus, boolean)並傳入update == false, 因此進行中(status == 1)的任務會額外送出任務資訊更新封包。- Parameters:
quest- 要寫入的任務狀態
-
updateQuest
寫入/更新一筆任務狀態,並(對非自訂任務)同步至客戶端。副作用:將狀態放入
quests(覆寫同 key)。若任務非自訂(!isCustom()), 送出InfoPacket.updateQuest(MapleQuestStatus)封包;當任務為進行中(status == 1)且update為false時,另送出CField.updateQuestInfo(MapleCharacter, int, int, byte)接受任務動畫封包。- Parameters:
quest- 要寫入的任務狀態update-true表示僅更新(抑制進行中任務的接受動畫封包)
-
getInfoQuest_Map
-
getQuest_Map
取得角色任務狀態表quests的底層參考。回傳的是**實際的底層 Map**(非複本,主要供載入/存檔直接存取),對其修改會直接影響角色狀態。
- Returns:
MapleQuest→MapleQuestStatus的底層 Map
-
mobKilled
public void mobKilled(int id, int skillID) 將一次怪物擊殺回寫至所有相關的進行中任務的擊殺進度。逐一檢視角色的進行中(
status == 1)且具擊殺需求(hasMobKills())的任務; 若該怪物使進度增加,送出InfoPacket.updateQuestMobKills(MapleQuestStatus)封包,並在任務已可完成時 另送出CWvsContext.getShowQuestCompletion(int)完成提示封包。- Parameters:
id- 被擊殺怪物的 IDskillID- 觸發擊殺的技能 ID(用於特定技能限定的任務計數)
-
getStartedQuests
取得角色目前所有進行中的(非自訂、未被封鎖)任務。僅收錄狀態為進行中(
status == 1)、非自訂(!isCustom())且任務未被封鎖 (!isBlocked())者。- Returns:
- 進行中任務狀態的新清單(可能為空)
-
getCompletedQuests
取得角色目前所有已完成的(非自訂、未被封鎖)任務。僅收錄狀態為已完成(
status == 2)、非自訂(!isCustom())且任務未被封鎖 (!isBlocked())者。- Returns:
- 已完成任務狀態的新清單(可能為空)
-
getCompletedMedals
取得角色已完成且會頒發勳章(裝備類獎勵道具)的任務清單。在
getCompletedQuests()的篩選條件之上,進一步要求任務具勳章道具 (getMedalItem() > 0)且該道具屬於裝備類(MapleInventoryType.EQUIP)。- Returns:
- 每筆為(任務 ID,完成時間戳)的配對清單(可能為空)
-
startPartyQuest
public boolean startPartyQuest(int questid) 開始一個組隊任務(party quest),必要時建立其任務狀態與初始附帶資料。僅當指定任務存在且為組隊任務(
MapleQuest.isPartyQuest())時才處理。若角色尚未持有此任務 (quests或questinfo缺少對應項目),則:透過getQuestNAdd(MapleQuest)取得狀態、設為 進行中(1)、updateQuest(MapleQuestStatus),並依 questid 以updateInfoQuest(int, String)寫入該 PQ 的初始 附帶資料字串(不同 PQ 的欄位格式不同,例如嘉年華/鬼屋/藥草鎮/精靈使用各自的模板,其餘走預設模板)。副作用:可能變更
quests/questinfo並送出任務相關封包。本方法可重複呼叫; 若任務已開始則為無作用並回傳false。- Parameters:
questid- 組隊任務 ID- Returns:
true表示本次呼叫實際開始了任務;false表示任務無效、非組隊任務或已開始
-
getOneInfo
-
updateOneInfo
更新某組隊任務附帶資料字串中的單一欄位值,並同步至客戶端。解析既有的
key=value欄位串,將符合key者的值改為value(其餘原樣保留), 再透過updateInfoQuest(int, String)寫回(因而觸發其存檔標記與封包送出副作用)。若任務無附帶資料、key或value為null、任務不存在或非組隊任務,則為無作用。- Parameters:
questid- 任務 IDkey- 欲更新的欄位鍵value- 欄位的新值
-
recalcPartyQuestRank
public void recalcPartyQuestRank(int questid) 依某組隊任務目前的累計數據重新評定其等級(rank),達標時逐級晉升。僅處理有效的組隊任務。先呼叫
startPartyQuest(int)(確保任務已建立);唯有任務先前已開始 (該呼叫回傳false)時才進行評定。將目前等級向上推進一階(F→D→C→B→A→S;已是 S 則不動), 並檢查新等級在任務定義中(MapleQuest.getInfoByRank(String))的所有門檻條件(less/more/equal)。只有**全部**條件皆通過,才透過updateOneInfo(int, String, String)將rank欄位寫為新等級。任一門檻欄位缺值或無法解析為整數時,會保守地中止本次評定(不晉升)。
- Parameters:
questid- 組隊任務 ID
-
tryPartyQuest
public void tryPartyQuest(int questid) 記錄一次組隊任務的「嘗試」:開始任務、記下計時起點並累加嘗試次數。僅處理有效的組隊任務。呼叫
startPartyQuest(int)後,將pqStartTime設為目前時間 (供endPartyQuest(int)計算耗時),並把try欄位 +1。整段流程包覆於 try/catch, 發生例外時記錄錯誤日誌而不向外拋出。- Parameters:
questid- 組隊任務 ID
-
endPartyQuest
public void endPartyQuest(int questid) 結算一次組隊任務的完成:記錄最佳耗時、累加完成次數與完成率,並重評等級。僅處理有效的組隊任務。呼叫
startPartyQuest(int)後,若pqStartTime > 0:依 目前時間與起點算出耗時(分、秒),當其優於既有最佳(min欄位)時更新min/sec/date;接著把cmp(完成次數)+1、重算CR(完成率=cmp/try 取整),呼叫recalcPartyQuestRank(int)重評等級,最後把pqStartTime歸零。全程包覆於 try/catch, 發生例外時記錄錯誤日誌而不向外拋出。- Parameters:
questid- 組隊任務 ID
-
havePartyQuest
public void havePartyQuest(int itemId) 依持有的特定 PQ 道具標記對應組隊任務的「持有」欄位。將已知的 PQ 證明道具 ID 映射到其組隊任務 ID(部分道具還對應一個欄位索引
index, 例如藥草鎮、精靈、鬼屋的多件道具);不在映射表中的道具 ID 直接返回。確認任務有效且為組隊任務後, 呼叫startPartyQuest(int),再以updateOneInfo(int, String, String)將have(或have+索引) 欄位設為"1"。- Parameters:
itemId- 觸發的 PQ 道具 ID
-