info_outline
# 光暈戰記 RPG 事件表模組(TwilightWarsRPGEvents)
此專案為 **[TwilightWarsLib](/edit/TwilightWarsLib)** 的 RPG 功能擴充模組。
大量自訂義的資料型態,搭配少量光暈本身的功能,主要是為了省略在光暈製作一個 RPG 任務時,還要先用一堆事件來製作相關系統、功能的步驟,而誕生的模組。
本專案的所有功能,皆是建立在任務為開放式房間、可多人遊玩,且可跨事件表的前提下製作,也就是說整個專案共用同一個玩家資料,故如果要製作更多不同的 RPG 任務,請另建新的專案製作。
有任何問題或 BUG,歡迎於討論區提出、回報。
<font color=red>**安裝此模組後,事件表會增加一些變數保留字,請避免在宣告全域變數時,使用下列名稱:**</font>
**itemInfo, questInfo, {玩家代碼}_quests, {玩家代碼}_inventories, {玩家代碼}_equipmentSlot, {玩家代碼}_datas**
<font color=red>**本模組不具備任何界面顯示功能,如有需要可直接安裝 [TwilightWarsRPGGUIEvents](https://code.gamelet.com/edit/TwilightWarsRPGGUIEvents) 模組,提供些許的 GUI 樣式可供使用。**</font>
# 主要功能介紹
- [存讀檔功能](#存讀檔功能) <font color=grey>*ps.自動存檔、本機存/讀檔*</font>
- [任務系統](#任務系統)
- [自訂道具](#自訂道具)
- [背包/裝備欄](#背包/裝備欄)
- [跨事件表傳送](#跨事件表傳送)
## 存讀檔功能
本專案所有會更動玩家資料的動作,在變更玩家資料後,皆會**自動將資料儲存到專案資料庫**中。
專案任務作者只需要在玩家進入戰場後,使用動作來讀取資料即可,原則上並不需要考慮存檔的問題。
若有需要,本模組也提供於本機存讀檔的功能,但不建議使用於多人遊戲中,且讓玩家可以於本機存讀檔,可能會增加玩家隨意更改資料的風險。
提供可自訂玩家資料的功能,可設定例如等級、經驗值、金錢、稱號等屬性,修改數值時會自動存檔,也可隨時使用變數讀取數值。
```typescript
// 假設儲存玩家的代碼為 instance
{instance.code}_datas // 使用此變數名稱可以得到該玩家的所有自訂資料。
// 若無設定資料類別,於後方加上 .資料名稱 即可取得該自訂資料的數值,例如:
{instance.code}_datas.level // 可以取得該玩家,自訂資料 level 的數值。
{instance.code}_datas.money // 可以取得該玩家,自訂資料 money 的數值。
// 若有設定資料類別,於後方加上 .資料類別.資料名稱 即可取得該自訂資料的數值,例如:
{instance.code}_datas.profile.level // 可以取得該玩家,資料類別 profile,裡面 level 的數值。
{instance.code}_datas.profile.money // 可以取得該玩家,資料類別 profile,裡面 money 的數值。
```
## 任務系統
提供可以**儲存玩家任務狀態**的功能,每個任務皆需要有不同的任務代碼,而主要的任務狀態有「未接取」、「進行中」、「已完成」。
每個任務在玩家進行中的狀態時,皆還可以**設定任務的進度**,進度的數量沒有限制,且也可以自訂進度的名稱,以及隨時更改進度的值,例如在設定某個玩家的任務狀態為「進行中」的同時,可以設定該任務的進度有「探索:0」,每當玩家到指定的地點探索後,可以讓該任務的探索進度增加,或是為擊殺型的任務時,在玩家擊殺目標對象後,使擊殺進度增加,最後在嘗試回報任務的事件中,可以在檢查的部分加上「檢查任務進度」,來檢查該任務的進度是否達到目標,以執行回報任務後會觸發的動作。
由於任務進度的數量並沒有限制,所以專案作者也可以為某個任務同時設定多個進度,並檢查所有的進度都要完成時,任務才會完成。
如在初始化時有執行過動作**「設置系統變數」**,可使用變數讀取任務資訊,可以參考下列格式:
```json
// 假設儲存任務資訊的變數名稱為 questInfo,它會儲存所有任務的預設資訊。※ 詳細請看動作「設置系統變數」
{questInfo.questCode} // 將 questCode 改為自訂的任務代碼,可以取得該任務的所有資料。
{questInfo.main_0.name} // 可以取得任務代碼為 main_0 的名稱。
{questInfo.main_0.description} // 可以取得任務代碼為 main_0 的描述。
{questInfo.main_0.category} // 可以取得任務代碼為 main_0 的類別。
{questInfo.main_0.datas} // 可以取得任務代碼為 main_0 的自訂屬性,於後方加上 .屬性名稱 即可取得該自訂屬性,例如:
{questInfo.main_0.datas.returnActor} // 可以取得該任務中,自訂屬性 returnActor 的資料。
```
如需要在事件表中,使用變數讀取玩家任務資料,可以參考下列格式:
```json
// 假設儲存玩家的代碼為 instance
{instance.code}_quests // 使用此變數名稱可以得到該玩家的所有任務資料。
{instance.code}_quests.questCode // 將 questCode 改為自訂的任務代碼,可以取得玩家對於該任務的資料。
// 若是讀取該玩家未曾接取過的任務,則會得到 undefined,也無法讀取下列資料。
{instance.code}_quests.main_0.state // 取得該玩家任務代碼為 main_0 的任務狀態。(數字)
// 0 - 未接取, 1 - 進行中, 2 - 已完成
{instance.code}_quests.main_0.progress // 取得該玩家任務代碼為 main_0 的當前進度資料。
// 預設為空物件 {},需使用動作「設置任務進度」設置進度後,才會有內容可以讀取。
{instance.code}_quests.main_0.progress.talk // 取得該玩家任務代碼為 main_0 的 talk 進度值。(數字)
{instance.code}_quests.main_1.progress.kills // 取得該玩家任務代碼為 main_1 的 kills 進度值。(數字)
```
## 自訂道具
提供可以**自定義道具**的動作,可設定道具的名稱、描述、最大堆疊數量、物品樣式,以及其他自訂屬性,例如傷害力、防禦力、恢復力、可否裝備等。
至於定義物品道具的部分,請專門開一個事件表,將所有定義物品道具的動作放在裡面,並在玩家進入專案時執行一次即可,不需要每個事件表都重新放置動作。
或是可以直接在專案的進入點,加上 new ItemInfo 來定義物品。
```typescript
/**
* @param {string} code 物品代碼
* @param {string} maxStack 最高堆疊數量
* @param {string} name 物品名稱
* @param {string} description 物品描述
* @param {string} stuffCode 物品外觀道具代碼
* @param {object} datas 自訂物品屬性
* @param {string} alias 物品圖示的資源別名
* @param {string} linkage 資源的鏈接名稱
*/
new ItemInfo(code: string, maxStack: number, name?: string, description?: string,
stuffCode?: string, datas?: { [key: string]: number }, alias?: string, linkage?: string)
// 例如以下,創建一個 apple,最高可堆疊 10 個,手持時的武器為拳頭,datas 包含了 health 為 10。
new ItemInfo('apple', 10, '蘋果', '香甜可口的水果,散發著一股淡淡的香味。', 'kongfu', datas: { 'health': 10 });
```
如在初始化時有執行過動作**「設置系統變數」**,可使用變數讀取物品資訊,可以參考下列格式:
```typescript
// 假設儲存物品資訊的變數名稱為 itemInfo,它會儲存所有物品道具的預設資訊。※ 詳細請看動作「設置系統變數」
{itemInfo.itemCode} // 將 itemCode 改為自訂的物品代碼,可以取得該物品的所有資料。
{itemInfo.apple.name} // 可以取得物品代碼為 apple 的名稱。
{itemInfo.apple.description} // 可以取得物品代碼為 apple 的描述。
{itemInfo.apple.datas} // 可以取得物品代碼為 apple 的自訂屬性,於後方加上 .屬性名稱 即可取得該自訂屬性,例如:
{itemInfo.apple.datas.health} // 可以取得該物品中,自訂屬性 health 的數值。
```
## 背包/裝備欄
提供以**陣列為架構的背包系統**,並且可以為每個玩家**設置多個不同的背包**,可用裝備不同種類的物品,或是其他用途。
每個背包都可以**設置容量**,來決定這個背包可以裝多少組物品,當給予玩家物品時,若該物品的數量超過最大堆疊數量,則無法在同一欄位填裝,會自動尋找空位放入,直到背包沒有容量,且沒有可以堆疊的物品為止,並且會回傳多餘的物品數量,讓專案作者自行決定多餘的物品要怎麼處裡,例如直接丟棄,或是詢問玩家是否要替換背包中的物品,又或者是新增一個暫存用的背包,當物品數量過多時會自動裝入等等。
除了給予物品以外,也可以移除物品,移除時可以決定要不要指定背包中的哪一格,或是不指定,直接移除背包中指定物品代碼的物品。
提供可以檢查玩家背包物品數量的功能,可用於檢查玩家是否持有指定物品,且數量是否有達到條件,除了指定物品代碼以外,也可以檢查該物品的屬性是否符合條件。
提供裝備欄系統,可以自訂玩家的裝備欄狀態,以及各部位的名稱,並且裝備上物品道具,並且提供檢查**「檢查裝備欄物品」**,可檢查玩家某個裝備欄的物品,是否符合條件,例如是否為背包上的某一物品,或是符合某些物品代碼、屬性等,也可以單純檢查該裝備欄是否存在物品道具。
裝備欄的資料是直接儲存於背包資料中,故讀取背包資料時,會自動建置裝備欄的資料。
另外也提供了簡易的整理背包功能,專案作者可以讓玩家自行使用,或是在背包物品改變時使用。
如需要在事件表中,使用變數讀取玩家背包資料,可以參考下列格式:
```typescript
// 假設儲存玩家的代碼為 instance
{instance.code}_inventories // 使用此變數名稱可以得到該玩家的所有背包資料。
{instance.code}_inventories.inventoryCode // 將 inventoryCode 改為自訂的背包代碼,可以取得該背包的所有資料。
{instance.code}_inventories.myBag.slots // 可以取得背包代碼為 myBag 的容量大小。
{instance.code}_inventories.myBag.items // 可以取得背包代碼為 myBag 的所有物品資料。
{instance.code}_inventories.myBag.items.index // 可以取得該背包中,第 index 格的所有資料,index 請改為數字。
// index 是從 0 開始計算,故第一格為 0,第二格為 1,依此類推。
{instance.code}_inventories.myBag.items.0.item // 可以取得該背包中,第 0 格的物品資料。
{instance.code}_inventories.myBag.items.0.quantity // 可以取得該背包中,第 0 格的物品數量。
{instance.code}_inventories.myBag.items.0.equipped // 可以取得該背包中,第 0 格物品是否被裝備。
{instance.code}_inventories.myBag.items.0.slot // 可以取得該背包中,第 0 格物品的裝備位置。
{instance.code}_inventories.myBag.items.0.item.name // 可以取得該背包中,第 0 格物品的名稱。
// 將 name 改成其他屬性可以取得其他資料,例如:
// code - 物品代碼, maxStack - 最大堆疊數量, stuffCode - 物品外型代碼, description - 物品描述
{instance.code}_inventories.myBag.items.0.item.datas // 可以取得該背包中,第 0 格物品的自訂屬性資料,於後方加上 .屬性名稱 即可取得該自訂屬性,例如:
{instance.code}_inventories.myBag.items.0.item.datas.damage // 可以取得該物品中,自訂屬性 damage 的數值。
```
```typescript
// 假設儲存玩家的代碼為 instance
{instance.code}_equipmentSlot // 使用此變數名稱可以得到該玩家的所有裝備欄資料。
{instance.code}_equipmentSlot.slotType // 將 slotType 改為自訂的欄位類型,可以取得該欄位的所有資料。
// 所有資料包含 item, quantity, equipped, slot
{instance.code}_equipmentSlot.mainHand.item // 可以取得裝備欄中,裝備類型 mainHand 的物品資料。
// item 後面可讀取的資料,如同讀取背包內的物品資料一樣。
{instance.code}_equipmentSlot.mainHand.item.name // 可以取得裝備欄中,裝備類型 mainHand 的物品名稱,其他依此類推。
```
## 跨事件表傳送
提供簡單的跨事件表傳送功能,可以**將玩家傳送到指定事件表的指定座標**上,只要在需要傳送玩家時,執行動作「傳送玩家」並填入事件表路徑,以及傳送座標,並且在目標事件表初始化玩家時,執行動作「讀取玩家位置」即可。
儲存玩家位置,實際上是將該**玩家目前所在的事件表路徑以及座標儲存於資料庫**,也就是說事件表的位置、名稱,即是玩家所在的地點,請在一開始就確定好事件表的位置以及名稱,並不要於日後隨意更改,否則可能會導致玩家的位置資料損壞。
傳送玩家,實際上就是一個會先執行「儲存玩家位置」,然後讓玩家執行目標事件表的動作。
而讀取玩家位置,則是會先讀取玩家位於資料庫中的位置,並且判斷當下所在的事件表是否為資料所存的事件表,若不是的話,會自動將該玩家轉移到目標事件表,如果是的話,就會傳送玩家到資料所儲存的座標。
此功能可以用於讓每張地圖都有自己的事件表,並使玩家可以在這些地圖間進行傳送,而非如同以往需要繪製一張大地圖,並使用分割區域來達成不同區域的效果,跨事件表可以有效的降低遊戲的負擔。
## 作者
**[module_cook1470](/profile/64897095@github)**