P5R 模組製作


3樓貓 發佈時間:2025-02-07 14:25:44 作者:國境以南阿黑路西 Language

製作你的P5R模組

排版苦手,原文地址:P5R 模組製作筆記 - 飛書雲文檔

網站

  1. Amicitia Wiki

最全面的P系列模組製作百科。包括遊戲源文件解析,模組製作工具和ID表等。

Amicitia是ATLUS的JRPG的修改組織,特別是女神異聞錄系列遊戲。我們的目標是讓粉絲儘可能多的進行自定義。在這裡,您可以找到和編輯有關文件和工具的文檔,並修改它們。

  1. FearLess Cheat Engine

獲取最新的CT文件。為了測試模組,CE和CT文件是不可或缺的。

  1. Gamebanana

裝載其他人的遊戲模組,也可以在這裡獲取模組啟動器Reloaded-II及其運行環境。

  1. Reloaded II Documentation

瞭解Reloaded-II的使用方法。如果對本文中有關Reloaded-II的部分有疑問或操作時遇到困難,那麼你可以瀏覽這個網站尋求解決方法。

工具

  1. GARbro或CriPackGUI(或其他任意解包工具)

遊戲檔案文件解包工具,用以打開和提取CPK等格式的檔案文件。

  1. 010 Editor

十六進制文本編輯器,用以編輯TBL等格式的數據文件。

世界上最好的十六進制編輯器!

為了輕鬆看懂十六進制文件,當然需要模板010 Editor Templates,下載保存到路徑:

C:\Users\USERNAME\Documents\SweetScape\010 Templates\Repository

  1. Cheat Engine

進程內存修改工具,用以測試模組。

  1. 其他工具

  • Persona5NameTableEditor

    •   用以編譯或反編譯NAME.TBL. 可以修改遊戲中項目的名稱。

    • 要修改或添加以下項目的名稱,請下載本工具。

    • 阿爾卡納

    • 消耗道具

    • 重要道具

    • 材料

    • 近戰武器

    • 戰鬥行動

    • 服裝技能卡

    • 人物簡稱

    • 成員和協助人的姓氏

    • 成員和協助人的名字

    • 遠程武器

  • AtlusScriptCompiler和它的圖形用戶界面(直接解壓至前者的文件夾中即可使用)

    •   用以編譯或反編譯,以及編輯英文的BF和BMD格式的文件。可以修改戰鬥中的敵人行動AI等。

  • AtlusScriptCompilerGUI簡中版

    •   用以編譯或反編譯,以及編輯簡體中文的BF和BMD格式的文件。可以修改遊戲中的文本信息等。

    • 請一併下載網盤鏈接中的P5R漢字轉編碼&字庫. 來源於B站大佬:奇Sim的愛

  • PersonaEditor簡中版

    •   用以批量編輯BF和BMD格式的文件,並且可以編輯NAME.TBL. 可以修改遊戲中的文本信息和遊戲中項目的名稱等。

    • 來源於B站大佬:奇Sim的愛

  • GFD Studio

    •   用以查看和轉換GMD和GAP格式的文件。可以修改遊戲中的模型和模型的動畫動作。

前言 如何使用模組

Reloaded-II

功能強大的遊戲模組啟動器。P5R幾乎全部的模組都需要依賴它來運行。

手動安裝:Reloaded-II的運行環境

.NET 7.0 Desktop Runtime (v7.0.0) - Windows x64 Installer.NET 7.0 SDK (v7.0.100) - Windows x64 Installer.NET 7.0 Runtime (v7.0.0) - Windows x64 Installer

如何使用Reloaded-II

將P5R添加到啟動器

點擊窗口左側“⊕”圖標(Add an Application), 找到P5R.exe選中並保存。

P5R 模組製作-第0張

裝載必需模組

點擊窗口左上角“齒輪+”圖標(Download Mods), 搜索Persona Essentials並下載。

裝載本地模組文件

將模組壓縮包解壓到文件夾:

Reloaded-II\Mods

盡情享受吧!

點擊窗口左上角“齒輪+”圖標(Download Mods), 裝載你想要的模組!

製作模組

前置工作:解包

以工具GARbro為例,對遊戲檔案文件BASE.CPK和SC.CPK進行解包。

P5R 模組製作-第1張

對於解包出的文件,其目錄列表、文件類型和打開方式都可以在Amiticia Wiki查看。

建議備份解包出的文件,並且不要修改備份文件。

修改技能:以“大罪穿甲彈”為例

修改技能數據

如果你仔細閱讀過Amiticia Wiki裡的文件列表,就會知道技能的數據存儲在文件:

BASE\BATTLE\TABLE\SKILL.TBL

用010 Editor打開它。

P5R 模組製作-第2張

為了能夠簡明的看懂這個文件,需要運行模板。

依次點擊Tempaltes—>Open Templates—>p5r_tbl.bt, 然後再依次點擊Tempaltes—>Run Templates—>p5r_tbl.bt—>Run, 在界面下方可以看到模板運行的結果。

如果Template Results沒有出現,則用ALT+4查看。

P5R 模組製作-第3張

顯而易見,此文件分為四部分:

  1. 技能的元素

    1. 元素類型

    2. 主動/被動技能

    3. 繼承等級:0表示不可繼承的技能;相同繼承等級的技能,變異時可以互相轉變。

    4.   (最新版模板請忽略)注意!該部分的模板存在錯誤,模板中每個技能佔3字節,實際上每個技能佔8個字節。

  2. 主動技能的數據

    1. 魔法/物理技能

    2. 基礎傷害

    3. 目標數

    4. 命中率

    5. 暴擊率

    6. ……

    7.   該部分存儲了除技能元素類型外主動技能的幾乎全部數據。需格外關注。

  3. 未知的數據段

  4. 特性

    1.   詳見修改特性:以“空前絕後的天性”為例。

瞭解模板運行結果的結構後,著手修改“大罪穿甲彈”的技能數據。

在Amiticia Wiki的技能表中,查找“大罪穿甲彈”(Sinful Shell)的ID,為0662.

(網頁中使用CTRL+F查找關鍵字)

在Active Skill Data中找到Active Skill Data:[662], 即“大罪穿甲彈”的數據。

P5R 模組製作-第4張

可以看到Base Damage的值為0,這就是為什麼使用CE調出的”大罪穿甲彈”在遊戲中實際傷害只有1.

  • Physical or Magic?的Comment有誤,該項的值不決定技能是否被蓄力或專心致志影響,實際作用有待測試。而"Damage Stat"不僅決定技能被力或魔影響,而且決定技能被蓄力或是專心致志影響。

  • Base Damege不建議設置過大(超過30,000), 可能會發生越界錯誤,導致實際傷害變為1.

  • Crit Chance的Comment有誤,萬能魔法技能也可以暴擊。

  • 人格面具使用技能的動作由Damage Stat決定。以“撒旦耶爾”為例,如果Damege Stat的值為StrengthStat(1), 則該技能使用右手開槍動作,否則使用左手握拳動作。

此外,可對數據做出任意修改。

(最新版模板請忽略)擴展:修改技能元素類型

前文提到,在模板運行結果的第一部分Skill Elements中,模板存在錯誤。模板中每個技能佔3字節(冗餘位佔1字節),實際上每個技能佔8個字節(冗餘位佔6字節)。這就是為什麼該部分足有2816項之多。

為了能夠正確的修改技能元素類型,需要做一些準備工作,這裡給出兩種方法:

方法:找到數據的正確位置(急時抱佛腳)

因為模板存在錯誤,所以不能直接找Skill Elements[662].

  • 右鍵界面左側地址號,依次點擊Addresses—>Byte number (Decimal), 將行號改為十進制顯示。然後依次點擊Addresses—>Set Starting Addresses,並將起始地址改為0.

  • 右鍵界面上方列號,依次點擊Line Width—>Fixed 4 Bytes, 將行寬度改為4字節。

  • 注意到文件開頭含有佔4個字節的uint, 而你想要修改ID為622的技能,且每個技能的元素佔8字節,所以要找第5300(4+8*662)字節。右鍵界面上方列號,點擊Goto...,確保設置正確:

P5R 模組製作-第5張
  • 5300位決定技能元素類型,5301位決定主動/被動技能,5302-5307位是冗餘位字段。

P5R 模組製作-第6張

方法:更改冗餘位字段定義(一勞永逸)

  • 任意打開Skill Elements[x], 右鍵Redundant Bitfield, 點擊Goto Definintion, 在彈出的P5R_TBL.bt中,將高亮行改為:

b48 RedundantBitfield_ThanksATLUS <name = "Redundant Bitfield", comment = "Rightmost 4 bits of the bitfield don't do anything. Probably leftovers from early P5 coding.">;

  • 此時由於沒有定義過結構b48, 需要定義b48, 在代碼開頭插入:

typedef struct { u8 bit0 : 1; u8 bit1 : 1; u8 bit2 : 1; u8 bit3 : 1; u8 bit4 : 1; u8 bit5 : 1; u8 bit6 : 1; u8 bit7 : 1; u8 bit8 : 1; u8 bit9 : 1; u8 bit10 : 1; u8 bit11 : 1; u8 bit12 : 1; u8 bit13 : 1; u8 bit14 : 1; u8 bit15 : 1; u8 bit16 : 1; u8 bit17 : 1; u8 bit18 : 1; u8 bit19 : 1; u8 bit20 : 1; u8 bit21 : 1; u8 bit22 : 1; u8 bit23 : 1; u8 bit24 : 1; u8 bit25 : 1; u8 bit26 : 1; u8 bit27 : 1; u8 bit28 : 1; u8 bit29 : 1; u8 bit30 : 1; u8 bit31 : 1; u8 bit32 : 1; u8 bit33 : 1; u8 bit34 : 1; u8 bit35 : 1; u8 bit36 : 1; u8 bit37 : 1; u8 bit38 : 1; u8 bit39 : 1; u8 bit40 : 1; u8 bit41 : 1; u8 bit42 : 1; u8 bit43 : 1; u8 bit44 : 1; u8 bit45 : 1; u8 bit46 : 1; u8 bit47 : 1; } b48;

  • CTRL+S保存後,重新運行模板。如果Skill Elements變成了1056個,說明修改正確。此時Skill Elements[662]即為“大罪穿甲彈”的元素類型。

修改技能粒子效果

技能的粒子效果存儲在文件:

BASE\BATTLE\SKILL\0xxx.BED

SKILL文件夾並沒有0662.BED文件,即“大罪穿甲彈”沒有粒子效果。可以用其他技能的粒子效果替代。

例如,使用一槍斃命(ID:0226)的粒子效果。將0226.BED複製粘貼並重命名為0662.BED.

修改技能音效

技能的音效存儲在文件:

BASE\SOUND\SKILLSE\0xxx.ACB

與替換粒子效果同理,將0226.ACB複製粘貼並重命名為0662.ACB.

至此,你已經成功修改了“大罪穿甲彈”的數據,並使用了一槍斃命的粒子效果和音效。

修改特性:以“空前絕後的天性”為例

特性數據和技能數據存儲在相同的文件:

BASE\BATTLE\TABLE\SKILL.TBL

用010 Editor打開並運行模板。打開第四部分的任意特性,發現其構成如下:

P5R 模組製作-第7張

因為我對模板做了些許修正,所以你看到的名稱可能與圖片中略有不同。不過影響不大,還是可以照常修改。你也可以下載並運行我修改後的模板,請直接覆蓋原來的模板之後再運行。

  • 效果與觸發的條件:每個特性有獨特的數值。

  • 觸發的概率

  • 子特性:該特性可以發動數值所指向的子特性的效果。

    • 如:特性ID136為MONA第三次覺醒面具的特性“威風凜凜的風範”:增加友方的治療技能的效果,並偶爾減少其SP消耗。

    • 這實際上是兩個效果,前者是其子特性ID135“清高的風範”的效果,後者才是“威風凜凜的風範”的原本效果。

    • 換言之,子特性功能可以使特性疊加。

  • 效果的倍率

  • 合成新人格面具時的額外繼承特性:只對寶魔特性生效。

  • 特性的類別:普通特性為0或4,DLC即不可繼承特性為1或5,寶魔特性為2.

現在著手修改“空前絕後的天性”。

在Amiticia Wiki中,查找“空前絕後的天性”(Eccentric Temper)的ID,為133.

可以看到,其效果為:有25%的概率使友方物理技能傷害變為1.8倍。

選擇s32 effect_rate, 修改為100;

選擇s32 effect_size, 修改為3.

至此,“空前絕後的天性”的效果已修改為:使友方物理技能傷害變為3倍.

修改人格面具:以“撒旦耶爾”為例

人格面具的數據存儲在文件:

BASE\BATTLE\TABLE\PERSONA.TBL

用010 Editor打開並運行模板。發現此文件由四部分構成:

  1. 人格面具的數值

    1. 阿爾卡納類別

    2. 基礎等級

    3. 基礎數值

    4. 技能繼承類型

  2. 技能和數值成長

    1. 數值成長權重分配

    2. 技能

      • 學習該技能需要提升的等級

      • 是否可學習

      • 技能ID

  3. 隊伍成員等級提升所需經驗的閾值

  4. 隊伍成員的人格面具

    1. 角色

    2. 可達到的等級

    3. 人格面具技能

    4. 升級獲得的人格面具數值

現在著手修改“撒旦耶爾”。

在Amiticia Wiki中,查找“撒旦耶爾”(Satanael)的ID,為0170.

在模板運行結果的Skills & Stat Growths找到Skills & Stat Growths[170], 選擇Skill[9], 修改為:

P5R 模組製作-第8張

你的“撒旦耶爾”會在99級學會“大罪穿甲彈”。

如果你想修改人格面具的元素相性(屬性抗性),請參考下文:修改敵方單位:以“獵殺者”為例的前半部分。

修改敵方單位

修改敵人數據:以“獵殺者”為例

關於單位的數據存儲在文件:

BASE\BATTLE\TABLE\UNIT.TBL

打開並運行模板。這裡只看前三部分:

  1. 敵方單位的數值

    1. 阿爾卡納類別

    2. 等級

    3. HP和SP

    4. 數值(五維)

    5. 戰鬥技能

    6. 經驗和金錢獎勵

    7. 攻擊傷害

    8. ……

  2. 敵人的元素相性

  3. 人格面具的元素相性

第一部分的戰鬥技能(Battle Skills)中,只有設置的自動技能會生效,而敵人使用的主動技能由AI文件決定。

修改敵人的行動AI:以“LV.???自稱特別搜查隊的少年”為例

敵人的AI數據存儲在ELSAI.TBL中。

P5R 模組製作-第9張

如果某敵人的AI ID為0,則它只會使用AICAIL.TBL中對應的技能;如果AI ID為xxxx, 則它的AI數據存儲在文件:

BASE\BATTLE\SCRIPT\ENEMY\BTL_AIxxxx.BF

前者毫無intelligence可言。於是我們重點關注BTL_AIxxxx.BF文件。

現在著手修改“LV.???自稱特別搜查隊的少年”的行動AI。

關於BF格式文件的打開方式

“LV.???自稱特別搜查隊的少年”的AI文件為BTL_AI0745.BF, 使用原版AtlusScriptCompilerGUI.exe反編譯。對於生成的BTL_AI0745.BF.flow. 可以用記事本打開和編輯它。

  番長的AI代碼

// // FlowScript decompiled using Atlus Script Tools by TGE (2017-2021) // In the unfortunate case of any bugs, please report them back to me. // // // Procedure declarations // // Procedure Index: 0 void AI_MAIN() { int var0; BIT_ON( 11550 ); var0 = GET_COUNT( 308 ); //將var0定義為GET_COUNT( 308 ), 這是切換人格面具的函數 if ( AI_CHK_MORE() == 1 ) //ONE MORE時 PUTS( "1more" ); //發動ONE MORE if ( var0 == 452 ) //人格面具為伊邪納岐時 { AI_SET_GLOBAL( 0, 0 ); //將全局變量0的值設置為0,全局變量0用以表示該輪的回合數 AI_ACT_SKILL( 705 ); //行動:使用技能十字文斬 AI_TAR_RND(); //目標:隨機 } else if ( var0 == 457 ) //人格面具為黃龍時 { AI_SET_GLOBAL( 0, 1 ); AI_ACT_SKILL( 337 ); //行動:使用技能斯庫卡加 AI_TAR_MINE(); //目標:自身 } else if ( var0 == 458 ) //人格面具為輝夜時 { AI_SET_GLOBAL( 0, 2 ); AI_ACT_ATTACK(); //行動:攻擊 AI_TAR_RND(); //目標:隨機 } else if ( var0 == 459 ) //人格面具為斯拉歐加時 { AI_SET_GLOBAL( 0, 3 ); AI_ACT_SKILL( 371 ); //行動:使用技能瑪卡拉康 AI_TAR_MINE(); //目標:自身 } else if ( var0 == 460 ) //人格面具為義經時 { AI_SET_GLOBAL( 0, 4 ); AI_ACT_SKILL( 338 ); //行動:使用技能灼熱奮起 AI_TAR_MINE(); //目標:自身 } else if ( var0 == 461 ) //人格面具為伊邪納岐大神時 { AI_SET_GLOBAL( 0, 4 ); AI_ACT_SKILL( 338 ); //行動:使用技能數萬真言 AI_TAR_MINE(); //目標:自身(群體技能目標為自身和目標為隨機是等效的) } else { AI_ACT_ATTACK(); //行動:攻擊 AI_TAR_RND(); //目標:隨機 } return; } //切換人格面具的元素相性,並更改本輪的回合數 if ( var0 == 461 ) //人格面具為伊邪納岐大神時 { SET_COUNT( 308, 452 ); //COUNT( 308 )的值設置為452 AI_SET_AFFINITY( 452 ); //元素相性設置為伊邪納岐 AI_SET_GLOBAL( 0, 1 ); //全局變量0的值設置為1,本輪的第一回合 } else if ( var0 == 452 ) //人格面具為伊邪納岐時 { SET_COUNT( 308, 457 ); AI_SET_AFFINITY( 457 ); AI_SET_GLOBAL( 0, 2 ); } else if ( var0 == 457 ) //人格面具為黃龍時 { SET_COUNT( 308, 458 ); AI_SET_AFFINITY( 458 ); AI_SET_GLOBAL( 0, 3 ); } else if ( var0 == 458 ) //人格面具為輝夜時 { SET_COUNT( 308, 459 ); AI_SET_AFFINITY( 459 ); AI_SET_GLOBAL( 0, 4 ); } else if ( var0 == 459 ) //人格面具為斯拉歐加時 { SET_COUNT( 308, 460 ); AI_SET_AFFINITY( 460 ); AI_SET_GLOBAL( 0, 5 ); } else if ( var0 == 460 ) //人格面具為義經時 { SET_COUNT( 308, 461 ); AI_SET_AFFINITY( 461 ); AI_SET_GLOBAL( 0, 5 ); } else { SET_COUNT( 308, 452 ); AI_SET_AFFINITY( 452 ); AI_SET_GLOBAL( 0, 0 ); } var0 = GET_COUNT( 308 ); //不同輪次、不同人格面具的行動 if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 452 ) ) //AI_GET_LOCAL_PARAM( 0 )用來獲得本地參數0,這是獲得輪次的函數 { AI_ACT_SKILL( 705 ); AI_TAR_ID( 1 ); //目標:JOKER } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 452 ) ) { AI_ACT_SKILL( 151 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 457 ) ) { AI_ACT_SKILL( 278 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 457 ) ) { AI_ACT_SKILL( 97 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 458 ) ) { AI_ACT_SKILL( 708 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 458 ) ) { AI_ACT_SKILL( 708 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 459 ) ) { AI_ACT_SKILL( 131 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 459 ) ) { AI_ACT_SKILL( 360 ); AI_TAR_MINE(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 460 ) ) { if ( AI_CHK_ENBAD( 2 ) == 1 ) //當有敵人陷入冰凍狀態時 { AI_ACT_ATTACK(); AI_TAR_BAD( 2 ); //目標:陷入冰凍狀態的敵人 } else { AI_ACT_ATTACK(); AI_TAR_RND(); } } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 460 ) ) { AI_ACT_SKILL( 215 ); AI_TAR_RND(); } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 0 ) && ( var0 == 461 ) ) { AI_ACT_SKILL( 713 ); AI_TAR_RND(); AI_SET_LOCAL_PARAM( 0, 1 ); //本輪結束,將輪次改為1 } else if ( ( AI_GET_LOCAL_PARAM( 0 ) == 1 ) && ( var0 == 461 ) ) { AI_ACT_SKILL( 713 ); AI_TAR_RND(); AI_SET_LOCAL_PARAM( 0, 0 ); //本輪結束,將輪次改為0 } else { AI_ACT_ATTACK(); AI_TAR_RND(); } }

其直觀表示為:

使用的技能

使用的人格面具

伊邪納岐

黃龍

輝夜

斯拉歐加

義經

伊邪納岐大神

ONE MORE

十字文斬

斯庫卡加

攻擊

瑪卡拉康

灼熱奮起

數萬真言

第一輪

十字文斬

碎腦擊

輝箭

大冰河時期

攻擊

數萬真言

第二輪

崇高聖戰

精神汙染

輝箭

蓄力

八艘跳躍

數萬真言

第三輪及以後

重複第一輪及第二輪

AI函數

以下列出部分重要AI函數的偽代碼定義。要想瀏覽P5R所有函數的信息,請在AtlusScriptCompiler的文件目錄中找到Modules文件夾:

Libraries\Persona5Royal\Modules

其各文件夾下的Functions.json中包含P5R所有函數的信息。

AI_SET函數:設置參數

void AI_SET_FRID_MAXSERIAL( EnemyID, int x ){ 設置EnemyID的每回合行動數為x; //EnemyID應與AI文件的ID一致 } void AI_SET_GLOBAL( int x, int y){ //y < 0x10 全局變量x = y; } void AI_SET_LOCAL_PARAM( int x, int y ){ //y < 0x10 局部參數x = y; } void AI_SET_AFFINITY( EnemyID ){ 自身的元素相性 = EnemyID的元素相性; }

AI_ACT函數:行動

void AI_ACT_SKILL( SkillID ){ 使用技能SkillID; } void AI_ACT_ATTACK(){ 攻擊; } void AI_ACT_TAKEOVER( EnemyID ){ 換手給EnemyID; } void AI_ACT_WAIT(){ 等待; } void AI_ACT_WAIT3( SkillID ){ 等待使用SkillID; }

AI_TAR函數:選取目標

return AI_TAR_RND(){ 目標 = 隨機; //使用群體技能時即以群體為目標 return 0; } void AI_TAR_MINE(){ 目標 = 自身; } void AI_TAR_DOWN(){ 目標 = 倒地的目標; } void AI_TAR_ID( MemberID or EnemyID ){ 目標 = ID為MemberID或EnemyID的目標; } void AI_TAR_NOTID( MemberID ){ 目標 = 成員ID不為MemberID的目標; } void AI_TAR_HOJO( BuffID ){ 目標 = 有BuffIDBuff的目標; } void AI_TAR_NOTHOJO( BuffID ){ 目標 = 沒有BuffIDBuff的目標; } void AI_TAR_BAD( AilmentID ){ 目標 = 陷入AilmentID異常狀態的目標; } void AI_TAR_NOTBAD( AilmentID ){ 目標 = 未陷入AilmentID異常狀態的目標; } void AI_TAR_WEAK_ST( ElementID ){ //AI_TAR_MUKOU_ST,AI_TAR_NOTWEAK_ST等也是合法函數名 目標 = ElementID屬性為弱點的目標; }

AI_CHK函數:檢查並返回數值

int AI_CHK_MORE(){ if <發生one more> then return 1; else return 0; } int AI_CHK_MYHP( int x ){ if <自身當前HP百分比 <= x%> then return 1; else return 0; } int AI_CHK_ID( MemberID EnemyID ){ if <MemberID or EnemyID存活> then return 1; else return 0; } /*int AI_CHK_ID_ENTARGET( int x ){ if < x > then return 1; else return 0; }*/ int AI_CHK_MYHOJO( BuffID ){ if <自身有BuffID的Buff> then return 1; else return 0; } int AI_CHK_NOTMYHOJO( BuffID ){ if <自身沒有BuffID的Buff> then return 1; else return 0; } int AI_CHK_MYBAD( AilmentID ){ if <自身陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_NOTMYBAD( AilmentID ){ if <自身未陷入AilmentI異常狀態> then return 1; else return 0; } int AI_CHK_MYUSESKIL( SkillID ){ if <自身使用過SkillID的技能> then return 1; else return 0; } int AI_CHK_MYUSEATTR( ElementID ){ if <自身使用過ElementID的屬性攻擊> then return 1; else return 0; } int AI_CHK_ENHOJO( BuffID ){ if <敵人有BuffID的Buff> then return 1; else return 0; } int AI_CHK_ENID( PartyID ){ if <PartyID存活> then return 1; else return 0; } int AI_CHK_ENIDHOJO( PartyID, BuffID ){ if <PartyID有BuffID的Buff> then return 1; else return 0; } int AI_CHK_NOTENHOJO( BuffID ){ if <敵人沒有BuffID的Buff> then return 1; else return 0; } int AI_CHK_ENBAD( AilmentID ){ if <有敵人陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_ENIDBAD( PartyID, AilmentID ){ if <PartyID陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_NOTENBAD( AilmentID ){ if <沒有敵人陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_ENWEAK( ElementID ){ if <有敵人ElementID屬性為弱點> then return 1; else return 0; } int AI_CHK_ENIDWEAK( PartyID, ElementID ){ if <PartyID的ElementID屬性為弱點> then return 1; else return 0; } int AI_CHK_ENHANSYA( ElementID ){ if <有敵人ElementID屬性為反彈> then return 1; else return 0; } int AI_CHK_ENIDHANSYA( PartyID, ElementID ){ if <PartyID的ElementID屬性為反彈> then return 1; else return 0; } int AI_CHK_ENKYUSYU( ElementID ){ if <有敵人ElementID屬性為吸收> then return 1; else return 0; } int AI_CHK_ENIDKYUSYU( PartyID, ElementID ){ if <PartyID的ElementID屬性為吸收> then return 1; else return 0; } int AI_CHK_ENMUKOU( ElementID ){ if <有敵人ElementID屬性為無效> then return 1; else return 0; } int AI_CHK_ENIDMUKOU( PartyID, ElementID ){ if <PartyID的ElementID屬性為無效> then return 1; else return 0; } int AI_CHK_ENCNT( int x ){ if <敵人數量 == x> then return 1; else return 0; } int AI_CHK_ENEMY_ABLEWEAK( EnemyID ){ if <EnemyID可以攻擊敵人的弱點> then return 1; else return 0; } int AI_CHK_FRIDHP( EnemyID, int x ){ if <EnemyID單位當前HP百分比 <= x%> then return 1; else return 0; } int AI_CHK_FRBAD( AilmentID ){ if <友方陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_FRIDBAD( EnemyID, AilmentID ){ if <EnemyID單位陷入AilmentID異常狀態> then return 1; else return 0; } int AI_CHK_FRHOJO( BuffID ){ if <友方有BuffID的Buff> then return 1; else return 0; } int AI_CHK_FRIDHOJO( EnemyID, BuffID ){ if <EnemyID單位有BuffID的Buff> then return 1; else return 0; } int AI_CHK_TURN_O( int x ){ if <當前回合數 >= x> then return 1; else return 0; }

AI_GET函數:獲取數值

int AI_GET_FIRST_ACTION(){ if <戰鬥開始時自身先行動> then return 2; else return 1; } int AI_GET_E_NUM(){ return 敵人的數量; } int AI_GET_ENHOJO_ON( BuffID ){ return 敵人BuffID的Buff的數量; } int AI_GET_ENBAD_ON( AilmentID ){ return 敵人陷入AilmentID異常狀態的數量; } int AI_GET_ENID_CURRENTSERIAL( EnemyID ){ return EnemyID當前行動數; } int AI_GET_BOSSDAMAGE(){ return 受到的總傷害; } int AI_GET_GLOBAL( int x ){ return 全局變量x; } int AI_GET_LOCAL_PARAM( int x ){ return 局部參數x; } /*int AI_GET_UNIHPMIN(){ return HP最低者的ID; }*/

BIT函數

int BIT_CHK( BitID ){ if <BitID處於ON狀態> then return 1; else return 0; } void BIT_ON( BitID ){ BitID ON; } void BIT_OFF( BitID ){ BitID OFF; }

其他函數

void AI_CLEAR_BOSSDAMAGE(){ 受到的總傷害 = 0; } void GET_COUNT( 308 ){ 使用人格面具; } void SET_COUNT( 308, PersonaID ){ 人格面具 = PersonaID; } int RND( int x ){ return >=0且<=x的隨機數; } int REM( int x, int y ){ return x%y; } PUTS( "1more" ) //給出ONE MORE

ID枚舉

enum MemberID{ JOKER = 1, SKULL = 2, MONA = 3, PANTHER = 4, FOX = 5, QUEEN = 6, NAVI = 7, NOIR = 8, CROW = 9, VIOLET = 10, }; enum ElementID{ 物理 = 0, 槍擊 = 1, 火焰 = 2, 冰凍 = 3, 電擊 = 4, 疾風 = 5, 核熱 = 6, 念動 = 7, 祝福 = 8, 咒怨 = 9, 萬能 = 10, }; enum AilmentID{ 燃燒 = 1, 冰凍 = 2, 觸電 = 4, 暈眩 = 11, 混亂 = 12, 恐懼 = 13, 遺忘 = 14, 飢餓 = 15, 睡眠 = 16, 狂怒 = 17, 絕望 = 18, 洗腦 = 19, // = 0x0200, 死亡 = 0x00080000, // = 0x00100000, /* 扭曲的嫉妒 = ?, 扭曲的色慾 = ?, 扭曲的貪婪 = ?, 扭曲的虛榮 = ?, 死亡行進 = ?, 恐慌 = ?, 老鼠化 = ?, */ }; enum BuffID{ 塔爾卡加 = 1, 塔倫達 = 2, 革命 = 3, 反叛 = 5, 斯庫卡加的命中率Buff = 4, 斯庫卡加的迴避率Buff = 0x40, 斯坤達的命中率Buff = 8, 斯坤達的迴避率Buff = 0x80, 拉庫卡加 = 0x10, 拉坤達 = 0x20, 蓄力 = 0x0100, 專心致志 = 0x0200, 提特拉康 = 0x4000, 瑪卡拉康 = 0x8000, //提特拉加 = ?, 防火之壁 = 0x10000, 防冰之壁 = 0x20000, 防電之壁 = 0x40000, 防嵐之壁 = 0x00080000, 防核之壁 = 0x00100000, 防念之壁 = 0x00200000, 汙穢空氣 = 0x00400000, 汙穢吐息 = 0x00400000, };

修改項目名稱

為了簡單化操作流程,請使用已擴充字符的簡體中文NAME.TBL進行編輯。

NAME.TBL的文本內容由其下的奇數號DAT文件決定。

修改主要項目的名稱:以技能名稱“哈米吉多頓”為例

主要項目包括:

  1. 技能

  2. 特性

  3. 敵方單位

  4. 人格面具

  5. 飾品

  6. 防具

它們對應的已擴充字符的奇數號DAT文件為:

newName(03).DAT: 技能,每項佔30字節;

newName(05).DAT: 技能(不完整),每項佔30字節;

newName(07).DAT: 敵方單位,每項佔25字節;

newName(09).DAT: 人格面具,每項佔20字節;

newName(11).DAT: 特性,每項佔20字節;

newName(13).DAT: 飾品,每項佔20字節;

newName(15).DAT: 防具,每項佔20字節。

現在著手修改技能名稱“哈米吉多頓”。

我的目的是將拉雯妲的“米吉多拉翁”(ID603)的名稱改為“哈米吉多頓”。

  • 首先調整010 editor的編輯器格式。使用010 editor打開技能名稱對應的DAT文件newName(03).DAT,將上側邊欄的行寬改為31(每項的所佔字節數+1 = 30 + 1),將左側邊欄的地址改為“行號(十進制)”;

    •   此時編輯器中的行號即為技能ID。

  • 生成漢字的十六進制編碼。打開P5R漢字轉編碼&字庫,在Sheet9的對應單元格分別輸入“哈米吉多頓”;

  • 在右側的單元格複製對應的十六進制編碼,並將其粘貼至任意窗口,然後複製其非零位編碼;

    •   注意不要截斷編碼!因為非零位末尾有可能出現"XX X0"這樣的編碼,所以你需要檢查複製的位數是否為4的倍數,如果不是就再複製非零位末尾的一個0;

  • 粘貼編碼。在010 editor中找到第604行的位置,選中前20(5×4) 位的編碼,依次點擊“編輯”—>“粘貼自”—>“粘貼自十六進制文本”;

  • 編碼已替換,保存;

  • 最後更新Name.TBL文件。打開PersonaEditor.exe並將Name.TBL移入左下側框中,右鍵其下的Name(03).DAT並點擊REPLACE,選擇newName(03).DAT替換並保存,保存的Name.TBL即為修改好的文件。

至此,拉雯妲的“米吉多拉翁”(ID603)的名稱已修改為“哈米吉多頓”。

另:批量生成簡體中文的十六進制編碼

  1. 用符號分隔原文本中的漢字;

  2. 全選,將文本轉換成表格,以符號作為分隔位置(列數21 = 1列符號 + 20列漢字);

  3. 複製生成的表格,粘貼到P5R漢字轉編碼&字庫Sheet9的對應單元格;

  4. 右側的單元格內已生成對應的十六進制編碼。

修改其他項目的名稱:以材料名稱“黑雪人之光”為例

對於簡體中文,此過程十分繁瑣!

  • 為了能夠理解該部分的操作流程的意義,需要先了解NAME.TBL的構成。

    • 打開PersonaEditor.exe並將NAME.TBL移入左下側框中,發現其下有38個dat格式的文件。

    • 它們前後每兩個為一組,前者儲存字符長度數據,後者儲存字符數據。

    • 如NAME(02).DAT儲存技能名稱的字符長度數據,後面的NAME(03).DAT儲存技能名稱的字符數據。

    • 以下列出所有奇數號文件所儲存的內容:

    • NAME(01).DAT: 塔羅牌名稱,

    • NAME(03).DAT: 技能名稱,

    • NAME(05).DAT: 技能名稱(不完整),

    • NAME(07).DAT: 敵方單位名稱,

    • NAME(09).DAT: 人格面具名稱,

    • NAME(11).DAT: 特性名稱,

    • NAME(13).DAT: 飾品名稱,

    • NAME(15).DAT: 防具名稱,

    • NAME(17).DAT: 消耗道具名稱,

    • NAME(19).DAT: 重要道具名稱,

    • NAME(21).DAT: 材料名稱,

    • NAME(23).DAT: 近戰武器名稱,

    • NAME(25).DAT: 戰鬥行動名稱,

    • NAME(27).DAT: 服裝名稱,

    • NAME(29).DAT: 技能卡名稱,

    • NAME(31).DAT: 人物簡稱,

    • NAME(33).DAT: 成員和協助人姓氏,

    • NAME(35).DAT: 成員和協助人名字,

    • NAME(37).DAT: 遠程武器名稱。

現在著手修改材料名稱“黑雪人之光”。

  1. 打開Persona5NameTableEditor.exe並將Name.TBL移入窗口中,自動反編譯生成17個txt格式的文件:

    1.   之所以生成17個而非19(38÷2)個文件,是因為Persona5NameTableEditor.exe完全兼容P5,但與P5R兼容性並不好。這也是為什麼生成的部分文件,其文件名與內容並不相符。而且它不支持簡體中文,這會導致所生成文件的內容是表面上的亂碼;

  2. 找到實際內容是材料名稱的文件(這裡是BattleActionNames.txt)並打開,找到第2行,這是“RESERVE”對應的亂碼;

  3. 每個空格、亂碼或漢字對應AA,用14個A替換掉亂碼並保存;

  4. 打開Persona5NameTableEditor.exe並輸入包含txt文件的文件夾路徑,自動編譯生成newName.tbl;

  5. 打開PersonaEditor.exe並將newName.tbl移入左下側框中,右鍵其下的newName(20).DAT並點擊Save As...另存為;

  6. 選擇newName(21).DAT,找到14個A並記錄其位置;

  7. 將原Name.TBL移入左下側框中,右鍵其下的Name(20).DAT並點擊REPLACE,選擇newName(20).DAT替換。這一步驟是為了使用正確的字符長度文件;

  8. 右鍵Name(21).DAT並點擊Save As...另存為,使用010 Editor打開,找到它對應的14個A(這個文件裡實際上沒有這10個A)的位置即第6步中所記錄的位置,改成“黑雪人之光”對應的編碼並保存;

  9. 在PersonaEditor.exe內右鍵Name(21).DAT並點擊REPLACE,選擇剛修改的Name(21).DAT替換。

  10. 點擊File—>Save As...,保存的Name.TBL即為修改好的文件。

至此,ID為2的材料的名稱已修改為“黑雪人之光”。

修改文本信息:以“亞基”的技能描述為例

技能的數據存儲在文件:

BASE\SC\INIT\DATMSG.PAK

使用PersonaEditor批量編譯或反編譯和替換BF和BMD等類型文件。

打開PersonaEditor.exe後,將DATMSG.PAK移入左下側框中,選擇其下的datSkillHelp.bmd並在右側進行如圖設置,可以看到所有技能描述。

P5R 模組製作-第10張

找到skill00A“亞基”,將其描述修改為:

P5R 模組製作-第11張

P5R 模組製作-第12張

進入遊戲測試後可見,超過3行的技能描述會超出窗口顯示範圍。

使用AtlusScriptCompiler單獨編譯或反編譯BF和BMD格式的文件。

對於不包含簡體中文的文件(如AI文件):打開原版AtlusScriptCompilerGUI.exe後,將BF或BMD文件移入左側框中,自動反編譯生成對應flow或msg文件(均可使用記事本直接編輯);保存後移入右側框中,自動編譯生成BF或BMD文件;重命名新生成的文件名使其與原名一致。

對於包含簡體中文的文件(如技能描述):請使用簡中版AtlusScriptCompilerGUI_DARK.exe.

至此,“亞基”的技能描述已變得更加詳細。

修改音樂、模型……

相信你已經有了足夠的信息蒐集能力和動手能力,請嘗試自己修改吧!

測試模組

需要在Reloaded-II中創建一個新的模組。

打開Reloaded-II, 點擊窗口左側第二個圖標(Manage Mods).

點擊New創建模組。

以下操作請自己命名,不要照搬圖例!

  • 模組Id, 這是你的模組文件夾名:

P5R 模組製作-第13張
  • 常規細節:

P5R 模組製作-第14張
  • 必需依賴模組,選擇Persona Essentials:

P5R 模組製作-第15張
  • 更新支持,根據自己需要選擇:

P5R 模組製作-第16張
  • 選擇可使用該模組的遊戲Persona 5 Royal:

P5R 模組製作-第17張
  • 此時,已經可以在P5R的模組列表中看到新創建的P5R MOD TEST.

P5R 模組製作-第18張
  • 右鍵該模組並點擊Open Folder, 發現文件夾中存在ModConfig.json, 這是自動生成的模組設置文件。

  • 新建若干個文件夾,確保其結構如下:

P5RPC.ModTest ├─P5REssentials │ └─CPK │ ├─BASE.CPK │ | ├─battle │ | │ ├─SCRIPT │ | │ ├─SKILL │ | │ └─TABLE │ | ├─sound │ | | └─SKILLSE │ | └─MODEL │ | └─CHARACTER | └─SC | ├─battle │ │ └─TABLE | └─INIT | └─ModConfig.json

  • 將你修改的文件複製進對應文件夾。

  • 點擊Launch Application啟動遊戲來調試你的模組。

發佈模組

打開Reloaded-II, 點擊窗口左側第二個圖標(Manage Mods).

選中模組並點擊Publish. 根據自己的需要編輯發佈設置:

P5R 模組製作-第19張

點擊Pulish後,你可以在輸出文件夾中看到模組壓縮包。


© 2022 3樓貓 下載APP 站點地圖 廣告合作:asmrly666@gmail.com