鋼鐵雄心4自定義界面官網教程

原帖鏈接:點擊這裡 ,歡迎指正(註:原帖需要登錄P社官網賬號並掛載已購買了正版鋼鐵雄心4的蒸汽賬號方能訪問。)

翻譯進度:100%


這是一款關於動態界面的概念與應用的深度教學。我會在這裡以我自己的Mod作為範本,您可以在以下鏈接下載本Mod。——譯註:點擊這裡

首先讓我們來解釋一下動態界面的概念吧,我從我們上次的開發日誌中引用如下段落。

動態界面是一種我們專門為Modder們定製的功能。這個新工具將會允許Modder們創建屬於他們自己的界面(亦或是將他們自己的界面關聯到現存的界面之中),並且將動態文本/條件應用於界面之中。以下是Modder們可足發揮之空間的Gif演示:

top_bar

selected_state

selected_country

national_focus

research

全部以上Gif中所演示的內容均為Mod,下面是範本Mod中所添加的功能:

- 元首威望,為德國添加的新資源類別- 一個將元首威望作為資源使用的「咒術」系統 - 通過點擊上方資源條中的元首威望,你可以針對你自己的國家使用「咒術」 - 通過點擊其敵國,你可以針對他們使用「咒術」 - 通過點擊己方省份,你可以對其使用「咒術」- 一個獨立於既存焦點的偽焦點系統,允許你生產自己的元首威望- 一個通過消耗元首威望來助推科研的辦法- 一個基本的AI也會利用元首威望

如果您想嘗試一下此款Mod,可以於創意工坊上訂閱亦或是通過文章開頭的鏈接下載。(安裝路徑:DocumentsParadox InteractiveHearts of Iron IVmod)我還添加了一個小小的作弊方式,右擊元首威望數值就會生成大量元首威望。


以下是動態界面的功能列表:

- 創建一個只有滿足指定條件方可顯現的界面(以Gif演示為例:只有玩家點擊資源槽/選擇國家/選擇省份時才會顯現)- 默認而言,新建的界面不會與任何既存界面關聯(正如前三張Gif)但您也可以設置關聯(第五張Gif的新建界面與國策界面相關聯)- 為新建界面添加具有效果的按鈕,當玩家點擊或右擊時執行,也可以設定ctrl/alt/shift與左/右鍵同時按下時的特殊效果- 為這些按鈕設置可以使其停用的條件(範本中當你燒光了威望,「咒術」將不再可用)- 為按鈕/圖標/文本設置使其隱藏/顯示的條件(範本中停用科研加速的按鈕只有當你啟用科研加速後才會顯現)- 在文本/說明/按鈕/其他中使用動態文本。你也可以使用說明來添加對效果的額外描述- 一個基於權重的AI系統,將會根據您預設的間隔和目標評估您的界面(範本中正如咒術「流星群」),並且根據您設定的權重按順序點擊按鈕。- 並且同樣在多人遊戲中可用!

現在我們可以開始教程了!總的來說,創建您自己的界面需要如下兩個步驟:於interface文件夾下創建一個.gui文件,於common/scripted_guis文件夾下創建一個.txt文件。

  • 為動態界面創建.gui文件

您的.gui文件於其他的gui文件並無二致。創建一個容器作為主窗口,並且為其添加您需要的UI元素即可。以下是元首威望Mod中上方資源槽的.gui文件(路徑:fuhrer_manainterfacefuhrer_mana.gui)

guiTypes = { containerWindowType = { name = "fuhrer_mana_container" position = { x = 900 y = 4 } buttonType ={ name ="fuhrer_mana_bg" spriteType = "GFX_generic_box_smallest" position = { x=0 y=0 } shortcut = "ctrl+k" } iconType = { name ="fuhrer_mana_icon" spriteType = "GFX_fuhrer_mana" position = { x= 7 y = 6 } } instantTextBoxType = { name ="fuhrer_mana_text" position = { x= 15 y = 4 } font = "hoi_18mbs" text = "[?fuhrer_mana]" format = center maxWidth = 46 maxHeight = 24 fixedsize = yes pdx_tooltip = "FUHRER_MANA_TOOLTIP" pdx_tooltip_delayed = "FUHRER_MANA_TOOLTIP_DELAYED" } }}

容器的名字是「fuhrer_mana_container」,容器的名字決不能重複。容器中有三樣東西。「fuhrer_mana_bg」既作為按鈕也作為背景;「fuhrer_mana_text」顯示當前的元首威望值;「fuhrer_mana_icon」是將其與其他資源區分開來的簡易圖標。

默認而言,僅是創建這樣一個.gui文件還不足以顯現出任何內容。這就要讓動態文本出馬了,在這邊我們將要定義這一容器所能顯現的具體條件。

  • 創建動態界面文件

動態界面文件是創建於common/scripted_guis文件夾下的.txt文件,它們看上去是這樣的:

scripted_gui = { fuhrer_mana = { window_name = "fuhrer_mana_container" context_type = player_context visible = { tag = GER } effects = { fuhrer_mana_bg_click = { set_temp_variable = { show = 1 } subtract_from_temp_variable = { show = show_fuhrer_powers } set_variable = { show_fuhrer_powers = show } } fuhrer_mana_bg_right_click = { add_to_variable = { fuhrer_mana = 10 } } } triggers = { fuhrer_mana_bg_click_enabled = { always = yes } } }}

所以呢,正是這樣一段名為fuhrer_mana的文本定義了動態界面,這段腳本定義了我們上面範本中界面的表現,下面讓我們來逐條分解。

window_name = "fuhrer_mana_container"

這一條定義是將要被創建之容器的名字,它將會告知遊戲程序去創建一個該容器與其子元素的實體。

context_type = player_context

這一條是我們所定義的「語境」。語境定義了您所設定之界面的作用域。默認而言,多半寫的是player_context,而您也無須去定義其他東西。player_context的作用域將永遠是玩家,這也意味著所有的條件/效果也將以玩家為作用域。其餘的語境有:

selected_state_context:沒有選定一個省份的時候界面將不會顯示。當您選定了一個省份,界面將會彈出,作用域為選定省份selected_country_context:與上面很相似,但是作用域為選定國家

範本中其餘所有界面均使用了player_context。

並且無論選定語境為哪種,ROOT的作用域將永遠是玩家。

visible = { tag = GER}

(這邊跟範本中不一樣,範本中使用了預設條件,但功效是相同的)

接下來就是可見條件了。這是一個決定界面能否顯現的條件。所以這裡很簡單地要求作用域為德國。正如我早先提到的,作用域取決於我們的語境和選擇。因為這一個界面應用了player_context,作用域將永遠為玩家。所以這一界面將總會當玩家是德國的時候出現。如果您使用了tag控制台指令轉移到其他國家,遊戲程序將會把這一界面元素隱藏。

effects = { fuhrer_mana_bg_click = { set_temp_variable = { show = 1 } subtract_from_temp_variable = { show = show_fuhrer_powers } set_variable = { show_fuhrer_powers = show } } fuhrer_mana_bg_right_click = { add_to_variable = { fuhrer_mana = 10 } }}

在「效果」下,您應該為您需要的按鈕定義效果。效果的名字(如fuhrer_mana_bg_click)定義了這一段語句將對哪一按鈕生效以及何時(取決於按鈕的狀況)它將被調用。

舉例來說,「fuhrer_mana_bg_click」意味著這一段語句將會關聯到「fuhrer_mana_bg」上,並且當該按鈕被點擊時效果將會被調用。所以在這個範例中,點擊我們的資源中的背景按鈕將會切換一個與其他內容相關的變數。(這是動態界面中各元素之間交互數據的好例子。只要給國家插個flag/變數然後在其他動態界面中調用即可)

這裡還有個「fuhrer_mana_bg_right_click」,只有當您右擊背景時才會調用,將會給予您額外的元首威望。這就是後門的開法。

您也可以設置當用戶按住Ctrl/Alt/Shift按鈕時才會調用的效果。舉個例子,比如「fuhrer_mana_bg_control_alt_shift_right_click」就只有在玩家同時按住三個按鈕並右擊背景時才會啟用。

triggers = { fuhrer_mana_bg_click_enabled = { always = yes }}

條件可以作用到多種元素上,最常見的是用於啟用/停用按鈕的效果。範本中「fuhrer_mana_bg_click」的效果只有滿足條件才能被調用。因為這一條件總是滿足的,所以您隨時都可以點擊按鈕(您不必為每一樣內容謄抄條件,如若一個元素沒有定義條件,那麼它就默認是啟用的。我這樣輸入只是作為一個範例。翻翻範本中的文件來了解更多細節吧)

這裡還有一些特例,「button_name_click_enabled」這一條件也用於啟用/停用一個按鈕。如果一個按鈕被停用了,您便不能再調用它。所以「fuhrer_mana_bg_click_enabled」生效時會停用這一按鈕的一切功能。如果您只想專門停用右擊功能,您可以使用「fuhrer_mana_bg_right_click_enabled」來滿足願望。

另一類您可以使用的條件是「_visible」條件。舉例來說,如果您添加了「fuhrer_mana_bg_visible」這一條件,按鈕便只會在條件滿足時顯現。不若其他條件,可見條件也可以作用於其他元素(文本與圖標)。

基礎知識已經講完了,現在您可以著手製作自己的動態界面了。不過讓我們更進一步吧!


  • 將動態界面與既存界面相關聯

有兩種辦法來將動態界面關聯到既存界面之中。

第一種是使用「parent_window_token」介面。我定義了一些對應多種既存界面的「token」。使用方式如下:

parent_window_token = technology_tab

所以當您添加了這一語句,便會將界面關聯到科研界面上。

其他的條目如下:

top_bar (關聯到上方資源顯示條上)##八種當您點擊國旗右側按鈕時顯示的界面decision_tab#決議technology_tab#科研trade_tab#貿易construction_tab#建設production_tab#生產deployment_tab#部署logistics_tab#後勤diplomacy_tab#外交 (這一個比較特殊,只有在未選定國家,即世界國家列表顯現的時候才會顯現)politics_tab #內政(點擊國旗時顯示的界面)#默認的科技樹tech_infantry_folder#步兵tech_support_folder#支援tech_armor_folder#裝甲tech_artillery_folder#炮兵tech_land_doctrine_folder#陸軍學說tech_naval_folder#艦船tech_naval_doctrine_folder#海軍學說tech_air_techs_folder#飛行器tech_air_doctrine_folder#空軍學說tech_electronics_folder#電子tech_industry_folder#工業#國策樹national_focusselected_state_view (當您左擊省份時顯示的窗口)selected_country_view (當您右擊省份時顯示的窗口)selected_country_view_info (外交界面對方國家詳情小窗口)selected_country_view_diplomacy (外交界面對方國家外交情況小窗口)

另一種方式是使用容器的名字。

parent_window_name = "tech_tree_my_modded_tree"

舉個例子,您設定了一個新科技樹,並且將容器命名為「tech_tree_my_modded_tree」,您便可以用如上方式將其關聯。

大多數時候,使用「player_context」完全合理。但是需要的話您仍然可以使用「selected_country_context」或「selected_state_context」,這一情況下,作用域將是玩家最後一次選定過的國家/省份。

有兩個例外:

selected_state_view(選定省份時彈出的窗口)selected_country_view(右擊選定國家抑或於外交界面選定國家時彈出的窗口,其他類似窗口同理)

這兩類情況下,作用域將取決於其母窗口。

  • 動態文本

動態文本可以應用於動態界面。

一個額外功能是,您可以令文本顯示按鈕所調用的效果,如下:

FUHRER_MANA_POWER_GAIN_XP_DELAYED:0 "[!fuhrer_mana_power_gain_xp_click]"

  • 編輯紋理

圖標與按鈕的紋理可以通過添加一個「屬性」來改變,如下:

properties = { icon_name = { image = "[get_icon_name_texture]" }}

該範例將會把名為icon_name的紋理根據名為get_icon_name_texture的動態文本介面而改變。

get_icon_name_texture這一動態文本應該調用gfx文件中的對象,您也可以通過添加冒號「:」來調用目標對象的某一幀。如下:

defined_text = { name = bet_amount_text text = { localization_key = "GFX_texture_name:4" }}

這樣便會把紋理替換為GFX_texture_name的第四幀。

另外,您可以使用如下方式來設定幀數架構:

icon_name = { image = "[get_icon_name_texture]" frame = variable_that_stores_frame}

在這一情況下,紋理的對應幀數將取決於該界面作用域下這一變數的值,您也不是必須定義「image」,沒有定義的情況下將會根據默認設定調用。

  • 元素重定位

您可以在屬性中定義x介面或y介面以重定位一個按鈕、文本或圖標:

properties = { icon_name = { image = "[get_icon_name_texture]" frame = variable_that_stores_frame x = x_position_of_icon_name y = y_position_of_icon_name }}

這段代碼將會把名為icon_name的圖標根據其作用域下的兩個變數移位。


  • AI

這一部分有點冗長而複雜。

總的來說,您需要定義AI什麼時候會關照您的界面以及它該做些什麼來觸發對應的效果。

定義「何時檢查」不會很難,您只要給AI一個間隔它便會在有條件的情況下定期查看界面,並且模擬點擊按鈕的動作。

定義「該點什麼」可就得花點功夫了。對於「player_context」語境下的情況,因為其作用域永遠為玩家,一般不再需要去定義什麼內容了。但是對於其他語境,您需要要求您的AI去思考哪些國家與省份應該檢查,不然的話它就會好奇地把每樣東西都把玩一遍,留下一堆爛攤子。

  • 教導AI何時查看界面

讓我們從教導AI檢查間隔說起吧:

ai_enabled = { tag = GER } ai_test_interval = 168 ai_test_variance = 0.1 ai_check = { check_variable = { fuhrer_mana > 10 } }

「ai_enabled」介面是您可用的最佳優化措施。初始化的AI,會查看每一個國家的每一個界面,以測試「ai_enabled」是否滿足對應的作用域。如果不滿足,AI便會徹底無視那個界面。我在這裡設定條件為德國是因為範本中的所有功能都是為德國定製的,如此以來就沒有其他國家會去檢查這些界面了。

ai_test_interval = 168ai_test_variance = 0.1

這兩樣東西定義了AI檢查界面的間隔。第一個是小時數,第二個是變動值。在這個例子中,AI將會以每7天(168小時)±5%(變動值的一半)的頻率檢查該界面。默認的間隔為1天(24小時),默認的變動值為±10%(0.2)。

然後我們再看看「ai_check」條件。它將會在您設定的間隔期間被調用,作用域為國家。如果條件不滿足,AI會暫時無視這一界面。例子中我們會檢查是否有充足的威望可以消費,如果威望過低,就沒有挑選後續行動的意義了。

  • 教導AI該選定哪些國家與省份

現在讓我們教導AI該點什麼吧。在作用域不是玩家的情況下,您應該告訴AI它會影響到哪一個作用域。您可以設想一下AI把每個國家和每個省份的每一個能點的按鈕都給點過一遍是個什麼樣子。

默認情況下,如果您沒有特意指定目標,AI會遍歷所有選項,為性能考慮的話可不太妙,您有幾種辦法來限制AI會查看的目標。對於其他語境,也有幾種辦法來限制AI檢查指定的國家。

player_context

在這一語境下,AI會認定作用域為它自己,所以沒有限定作用域的方法。

selected_country_context

在這一語境下,默認情況是AI會遍歷所有國家。這可能是您在優化過程中不太想見到的,下面有一些方法來限定AI只會選定幾個目標省份,您可以這樣做:

ai_test_scopes = test_enemy_countries

只要這麼寫了,AI就只會檢查敵國了。其他的語句還有:

test_self_countrytest_enemy_countriestest_ally_countriestest_neighbouring_countriestest_neighbouring_ally_countriestest_neighbouring_enemy_countries

並且如果您想要同時檢查多個目標,可以這樣寫:

ai_test_scopes = test_self_countryai_test_scopes = test_ally_countries

這樣AI就又會檢查自己也會檢查盟友了。

selected_state_context

跟選定國家差不多,不過語句並不一樣,有這些:

test_self_owned_statestest_enemy_owned_statestest_ally_owned_statestest_self_controlled_statestest_enemy_controlled_statestest_ally_controlled_statestest_neighbouring_statestest_neighbouring_enemy_statestest_neighbouring_ally_statestest_our_neighbouring_states (AI的邊境)test_our_neighbouring_states_against_allies (AI面向盟友的邊境)test_our_neighbouring_states_against_enemies (AI面向敵國的邊境)test_contesded_states (與敵國爭奪中的省份)

然後還有呢,您可以同時輸入多個這樣的限制。

還有關於「ai_test_scopes」的最後一件事兒。您也可以設定「ai_test_scopes = test_if_only_major」這樣AI就只會檢查主要國家(也就是說「test_ally_countries」只會檢查同時是主要國家還是盟友的國家,「test_enemy_controlled_states」只會檢查控制該省份的同時既是主要國家還是敵國的國家,諸如此類)。您也可以設定「ai_test_scopes = test_if_only_coastal」來限定只檢查沿海的省份與國家。

現在AI有了一串名單了,馬上就可以搞點真功夫了。但是呢,在那之前還要做一個最終檢查,對於每一個目標作用域,還要最後檢查一遍是否滿足「ai_check」的條件。

ai_check = { num_of_controlled_states > 8}

所以,這個例子中會檢查目標國家是否控制至少9個省份,這一條在範本中用於「流星群」咒術,AI不會把元首威望浪費在地狹人稠的國家。

並且玩家點不了的AI一樣點不了,如果一個按鈕連可見條件都沒有滿足,AI同樣會無視它。

  • 為AI設定優先度列表

假設AI有了一個目標作用域並且也有一個可見窗口,它就終於可以檢查這些按鈕能不能點了。要做到這點,您需要為每一個您希望AI查看的效果設定一個名為「ai_will_do」的參數比如假設我們有個可以點的按鈕「button_1」,並且也有一個檢測按鈕是否啟用的條件:

effects = { button_1_click = { add_manpower = 100000 subtract_from_variable = { fuhrer_mana = 5 } }}triggers = { button_1_click_enabled = { check_variable = { fuhrer_mana > 4.99 } }}ai_weights = { button_1_click = { ai_will_do = { factor = 1 } }}

所以這裡我們要創建一個名為「ai_weight」的列表。在這裡我們有「button_1_click」的介面,並且它的分數為1。因為分數大於0,AI會嘗試點擊按鈕(即調用效果)。

AI也會檢查它是否真的被允許去點擊按鈕,所以它也會檢查「button_1_click_enabled」是否滿足。

默認來說,AI每輪間隔後只能點擊至多一個按鈕。每次檢查後,它會生成一個可選項列表,並且會點下分數最高的。如果您希望AI會去同時點擊多個按鈕:

ai_max_weight_taken_per_test = 5

這樣AI就會點擊至多五個按鈕。

默認來說,每個效果的權重都為1,對於上面的例子,AI會點擊5個效果,如果您希望某些效果佔用更多的權重:

ai_max_weight_taken_per_test = 2ai_weights = { a_click = { weight = 2 ai_will_do = { factor = 1 } } b_click = { weight = 1 ai_will_do = { factor = 1 } } c_click = { weight = 1 ai_will_do = { factor = 1 } }}

在這個例子里,每個按鈕的分數是相同的,所以AI會按隨機順序點擊按鈕。而因為a的權重為2,所以如果優先點擊了a,AI會認為它剩餘的權重不足以點擊b或c。如果優先點擊了b或c,AI就還會點擊其他按鈕。這在您設定了一個不希望AI到處揮霍的資源種類時非常有用。

  • 禁止AI點擊低優先度按鈕以為暫時不能點擊的高優先度按鈕存儲資源

您能夠為AI權重使用的最後一個介面是「ignore_lower_weights」

effects = { button_1_click = { add_manpower = 100000 subtract_from_variable = { fuhrer_mana = 15 } } button_2_click = { add_political_power = 10 subtract_from_variable = { fuhrer_mana = 5 } }}triggers = { button_1_click_enabled = { check_variable = { fuhrer_mana > 14.99 } } button_2_click_enabled = { check_variable = { fuhrer_mana > 4.99 } }}ai_weights = { button_1_click = { ai_will_do = { factor = -1 modifier = { manpower < 50000 add = 3 } } ignore_lower_weights = { factor = 5 } } button_2_click = { ai_will_do = { factor = 1 } }}

所以這裡有兩個按鈕。其中一個給予您人力,另外一個給予您PP。人力值15威望,PP值5威望。

假設我們希望AI在缺乏人力的時候只買人力,而其他情況下購買PP,您應該給購買人力設定更高的分數並為之設定「ignore_lower_weights」。在這個例子中,如果「ai_will_do」大於0(即人力缺乏的情況),它將會禁止任何優先度低於「ignore_lower_weights」的按鈕(例子中為最高禁止優先度為5的按鈕)。反之,AI會一直點擊購買PP而不會特意為人力存儲威望。AI會禁止執行「button_2_click」的效果直到「button_1_click_enabled」已經被滿足,然後它會執行「button_1_click」,接著它便獲得了足夠的人力,購買人力按扭的「ai_will_do」便會暫時失效。

  • 將多個界面的AI邏輯相整合

默認來說,不同自定義界面的AI互不干涉。它會為不同界面分別生成優先度判斷。如果您希望AI以相同的間隔檢查不同的界面,並且也將其中的「ai_will_do」一起比較,您可以為其設定上級:

ai_test_parent = "fuhrer_mana_powers"

如果您為這個界面添加了如上介面,這一界面將會與「fuhrer_mana_powers」一同檢查,並且會在同一個優先度列表裡判斷效果。舉例來說,「fuhrer_enemy_country_spells」和「fuhrer_self_state_spells」定義「fuhrer_spells」為上級,AI就會在同一時間評估它們。能做到這一點是因為「fuhrer_enemy_country_spells」的AI有一個介面可以禁止一切按鈕,以為了對敵國使用「流星群」咒術而存儲威望。

如果您定義了上級,您不應該為子級定義「ai_test_interval」,「ai_test_variance」和「ai_max_weight_taken_per_test」,因為它會使用上級的。

  • AI日誌

Debug模式下,您可以使用「human_ai」控制台指令以獲取當前國家AI決策過程的日誌。日誌內容包括:它所檢查的經過過濾過的界面,它對其中每一項效果分數的評估。如果有任何問題,可以去檢查log/scripted_ai.log以獲取日誌信息。

——譯者註:我的文檔/Paradox Interactive/Hearts of Iron IV/logs,並且每次開啟啟動器後日誌會自動清空,檢查日誌之前請不要開啟啟動器,以及即便你寫了什麼蛇皮東西把遊戲搞跳出了也是可以去看看日誌有沒有留下東西的,日誌內容是隨時生成的,而非正常退出遊戲之後才會生成。

  • 警告

不要在自定義界面中使用「save_event_target_as」,用了它什麼鬼事都會發生。如有需要請使用變數系統代替。


這就是全部的教程了!教程沒有經過校對,有些匆忙,如果有任何令人困惑的地方,請聯繫我。

——譯者註:這一段是原文,這篇翻譯可是來來回回改過很多次的!而且Mod製作過程中有任何問題也可以聯繫我而不用聯繫蠢驢。


推薦閱讀:

TAG:界面 | 翻譯 | 鋼鐵雄心4遊戲 |