「Module System/Document by Jik (2)」の編集履歴(バックアップ)一覧はこちら
「Module System/Document by Jik (2)」(2009/02/15 (日) 17:05:12) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*M&B Module System Documentation PART4-6
PART1-3へ([[リンク>Module System/Document by Jik (1)]])
PART7-10へ([[リンク>Module System/Document by Jik (3)]])
----
#contents
-他の章へのリンク
--&link_anchor(part1,pageid=121){PART1 イントロダクション(Getting Started)}
--&link_anchor(part2,pageid=121){PART2 モジュールシステムの編集(Editing the Module System)}
--&link_anchor(part3,pageid=121){PART3 兵士(Module Troops)}
--&link_anchor(part3,pageid=123){PART7 シーン編集(Scene Editing)}
----
***&aname(part4){PART4} パーティ(Module Party Templates)
この章ではパーティテンプレートを扱います。
PART2で学んだパーティと混同しないように注意してください。
簡単に言うと、パーティテンプレートはmap上に出現するパーティのガイドラインです。
パーティはmap上のユニークな存在なのに対して、テンプレートはゲーム内では見えません。
パーティテンプレートIDが与えられている場合、そのパーティIDへ入力する操作は無効となります。
パーティテンプレートは&bold(){module_party_template.py}にあります。
****4.1 Module_Party_Templatesの意味
party_templates =[, で始まるパイソンのリストは、最初にいくつかのハードワイヤードなテンプレートを含みます。その部分は編集してはいけません。
module_party_templateのタプルはmodule_partiesのそれとよく似ています。
しかし互換性はありません。
パーティテンプレートの例を見てみます。
>("village_farmers","Village Farmers",icon_peasant,0,fac_innocents,merchant_personality,[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
このテンプレートのパーティは”famers”と呼ばれます。
(訳注:これはVillege Farmersのはず 。恐らくJIK氏が修正し忘れています。)
このパーティはfarmerとpeasant womanによって構成され、臆病に行動します。
またゲーム中に接触すると自動的にダイアログが始まります。
(フラグpf_auto_start_dialogが抜けていますが、全てのパーティが接触によって自動的にダイアログが始まるからでしょうか)
タプルの意味を見ていきます。
1)パーティテンプレートID。他のファイルからの参照に使います。
2)パーティテンプレートの名前。このテンプレートを使うパーティの名前になります。
3)フラグ。header_parties.pyに使用可能なフラグの表があります。
4)メニュー。module_partiesと同じく非推奨で、0を入れます。
5)ファクション。
6)パーソナリティ。map上でのパーティの行動を決めるフラグが入ります。
7)スタックリスト。最大6スタックまで可能です。
7.1)兵士ID。
7.2)最少人数。
7.3)最大人数。
7.4)メンバーフラグ(オプション)。メンバーに関するフラグを追加できます。
例:(trp_swadian_crossbowman,5,14,pmf_is_prisoner)
Villege Farmersのタプルを当てはめてみます。
1)パーティテンプレートID = "village_farmers"
2)パーティテンプレートの名前 = "Village Farmers"
3)フラグ = icon_peasant
4)メニュー = 0
5)ファクション = fac_innocents
6)パーソナリティ = merchant_personality
7)スタックリスト
7.1)兵士ID = trp_farmer, trp_peasant_woman
7.2)最少人数 = 11, 16(訳注:これも修正し忘れ。正しくは5, 3)
7.3)最大人数 = 22, 44(訳注:同上。10, 8)
7.4)メンバーフラグ = なし
もうタプルを読むのにも慣れてきたことでしょう。
この中で他と違うのは6番目、パーソナリティのフラグです。
次節ではこのフラグの役割を扱います。
****4.2 パーソナリティ
前の節で触れたとおり、パーソナリティはmap上でパーティの行動を決定します。
パーティの勇気(courage)と攻撃性(aggressiveness)を直接指定したり、
merchant_personalityのようなプリセットを指定できます。
プリセットは勇気と攻撃性を含む定数で、header_parties.pyの一番下で定義されています。
ex. merchant_personality = aggressiveness_0 | courage_7
攻撃性0のパーティは他のパーティを一切攻撃しません。
攻撃性8では、攻撃側と防御側の関係が悪く、また防御側が数で大きく勝っていない場合に攻撃します。
勇気はどれ位の大きさのパーティから逃げるかを決定します。
勇気が高いほどは数が多い相手からも逃走しにくくなります。
この値は0から15の範囲で自由に決められます。
しかしMODDING初心者にはプリセットの利用を薦めます。
プリセットは初めてのMODに使うには十分実用的です。
最後にフラグ banditnessについて触れておきます。
このフラグはパーティを盗賊として、近くのパーティに常に注意し、獲物が大量の金/交易品を持っている場合は攻撃するようにします。
盗賊が軍隊に襲い掛からないように、攻撃性を低くするかパーティの人数を少なく抑えたほうがよいでしょう。
****4.3 新しいテンプレートの作成
"farmers"のタプルをリストの最後尾にコピー&ペーストして手を加えます。
>(&bold(){"new_template","new_template"},icon_peasant,0,fac_innocents,merchant_personality,[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
Idを“farmers”を”new_template”に、名前も同様に変更しました。更に手を加えていきます。
まずファクションをfac_neutralに、パーソナリティをsoldier_personalityに変更します。
>("new_template","new_template",icon_peasant,0,&bold(){fac_neutral},&bold(){soldier_personality},[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
これにより中立勢力となり、また敵の部隊を攻撃するようになりました。
更に兵士の構成も変更します。
>("new_template","new_template",icon_peasant,0,fac_neutral,soldier_personality,[&bold(){(trp_npc17,1,1),(trp_new_troop,16,44)}]),
この例は幾つかの重要な変化を含んでいます。
特に重要なのは”(trp_npc17,1,1)”が入ったことで、PART3で作ったGeoffrey君がこの部隊に入りました。
ヒーローユニットは唯一無二なので当然その数は1です。
部下としてtrp_new_troopを追加します。これもPART3で作った兵士です。
最少で16人、最多44人の“new troop”がパーティに入ります。
セーブしてビルドします。成功すれば新しいテンプレートが利用可能になります。
しかし新しいテンプレートを利用するパーティが存在しないので、ゲームを起動してもGeoffrey君の部隊は出現しません。
後の章ではテンプレートの部隊の出現方法を学びますが、
とりあえず今はGeoffrey君とその仲間達は置いておいて、
PART5では新しいアイテムの作り方を学びます。
***&aname(part5){PART5} アイテム(Module Items)
PART3と4では新しい兵士とパーティテンプレート、そして装備させる方法を学びました。
これを踏まえて、この章では新しいアイテムの作り方を学びます。
****5.1 Module_Itemsの説明
module_items.pyは幾つかのアイテム修飾子(modifier)に関する定数で始まります。
修飾子はmodule_itemsのタプルからゲーム中で見る形のアイテムを生み出し、またアイテムの性能を上下させます。
ex. Bent polearm、chipped sword, heavy axe
これら定数は標準のアイテム修飾子を定義しています。商人のインベントリやlootで見るアイテムはこれらの定数から修飾子をランダムに選択します。
その選択ではリストにない修飾子は考慮されません。
しかし経験を積んだMODDERにとって、
演算&bold(){“troop_add_item”を利用すれば定数リストの中にない修飾子も利用されうる}という点は注意が必要です。
例えば、longbowは通常”plain”、”bent”、”cracked”の形のみをとります。
しかしプレイヤーのインベントリに修飾子”balanced”をつけて追加すれば、balanced longbowを入手できます。
定数の後にタプルのリストが始まります。
最初にある”practice_sword”を例として取り上げることにします。
>["practice_sword","Practice Sword", [("practice_sword",0)],
>itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|itp_wooden_attack, itc_longsword,
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),imodbits_none],
これはArenaやTraining fieldで使う練習用の武器です。
タプルの要素を見ていきます。
1)アイテムID。他のファイルからの参照に利用します。
2)アイテムの名前。インベントリ画面で表示される名前です。
3)メッシュのリスト。各メッシュは以下の要素を含むタプルです。
3.1)メッシュの名前。ゲームorモジュールのリソースファイル内の3Dモデルの名前。
3.2)このメッシュに適応する修飾子。
デフォルトの代わりにこのメッシュを利用するアイテム修飾子のリスト。
1つ目のメッシュがデフォルトになります。
4)アイテムのフラグ。
5)能力(capability)。アイテムが利用できるアニメーションを含みます。
6)価値。単位はdenar。Tradeスキルが10未満の場合、実際の価値はこれ以上になります。
7)ステータス。重さ、存在度、難易度、アーマーレートなど。
8)このアイテムが利用しうる修飾子。module_items.pyの最初にリストがあります。
9)トリガー(オプション)。このアイテムに関係するトリガーのリストです。
Practice_swordの例を当てはめてみます。
1)アイテムID = "practice_sword"
2)アイテムの名前 = "practice_sword"
3)メッシュのリスト
3.1)メッシュの名前 = "practice_sword"
3.2)メッシュの修飾子 = 0
4)フラグ = itp_type_one_handed_wpn|itp_melee|itp_primary|itp_secondary
5)能力= itc_longsword
6)価値 = 3
7)ステータス = weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt)
8)修飾子 = imodbits_none
9)トリガー = なし
これで“practice_sword”の性質について詳しく分かるようになりました。
・メッシュ”practice_sword”をデフォルトメッシュとして利用している
・フラグによってmelee武器になっている。”practice_sword”を装備した兵士は、インベントリからプライマリのmelee武器を選ぶときに”practice_sword”を選択肢として考えます。
(注意:セカンダリ武器の関数は不明瞭です。いつ使うのか、常に使うのかよく分かりません。しかし、melee兵士は戦闘中にmelee武器を切り替えることはありません)
・アニメーションは定数itc_longswordによって定義されており、longswordと同じ動きをします。
・重さ1.5kg、スピードレート103、武器の長さ90、殴打のベースダメージが振りで16、突きで10です。
・アイテム修飾子は使いません。常に同じアイテムです。
****5.2 ダメージタイプ
上のタプルの説明にあったとおり、”practice_sword”は殴打(Blunt)ダメージを与えます。
練習用武器だから、という理由ですが、これを機にM&Bでのダメージタイプを見てみます。
&bold(){Cut}ダメージ:剣など鋭利な刃物での切りつけによるダメージを表します。Cutダメージは鎧を装備していない、または軽装の敵にボーナスがあり、重装の敵にペナルティがあります。またCutダメージでhpを0にすると相手は死にます。
&bold(){Blunt}ダメージ:メイスやハンマーなど、刃の無い武器での殴打によるダメージを表します。重装の敵に50%のボーナスがありますが、全体に刃物よりも短くダメージも低いです。殴打武器の最大の長所は敵を殺さずに気絶させることです。気絶したときは奴隷として売ることが出来ます。馬の突撃もBluntダメージになります。
&bold(){Pierce}ダメージ:矢やボルトなどの突入によるダメージを表します。Pierceダメージは重装の敵に50%のボーナスがありますが、他のダメージタイプとのバランスを取るために、一般に他の武器よりもダメージが低いです。Pierceダメージは敵を殺害します。
****5.3 アイテムの作成
“practice_sword”のタプルをリストの最後尾にコピー&ペーストしてIDと名前を変更します。
>[&bold(){"new_mace","New Mace"}, [("practice_sword",0)], itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|itp_wooden_attack,
>itc_longsword, 3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),imodbits_none],
M&Bのファイルシステムはかなり柔軟です。少しの調整で剣がメイスになります。
“practice_sword”は元々Bluntダメージなので更に簡単です。
まず、アイテムの能力を"itc_longsword"から&bold(){"itc_scimitar"}に変更します。
定数”itc_scimitar”には突きが無いので、突きが使えなくなります。
更にメッシュを"practice_sword"から&bold(){"mace_pear"}に変更します。
このメッシュはNativeでは使われていないので、新鮮な見た目をしたメイスになります。
そして他のメイスには無い&bold(){フラグ"itp_wooden_attack"を消去}します。
>["new_mace","New Mace", [(&bold(){"mace_pear"},0)], itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry,&bold(){itc_scimitar,}
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),&bold(){imodbits_mace}],
メッシュを変更しただけでなく、修飾子を imodbits_none から imodbits_maceに変更しました。
これにより新しいメイスは定数 imodbits_maceの修飾子を使えるようになります。
更に二箇所に手を加えます。振りダメージの上昇とフラグの追加です。
>["new_mace",&bold(){"Geoffreys mace"}, [("mace_pear",0)] , itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|&bold(){itp_unique}, itc_scimitar,
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(&bold(){26},blunt)|thrust_damage(10,blunt),imodbits_mace],
振りダメージが16から26になりました。そしてより重要なことに、フラグ itp_uniqueが追加されました。
フラグ itp_uniqueの付いた装備は普通の戦闘後のloot画面では入手出来ません。
これはあまりにも早い入手を防ぐための措置です。
最後の調整として、名前を"Geoffreys mace"に変更します。
そしてGeoffrey君の持ち物にするために、module_troops.pyを開き、
彼のインベントリの itm_clubを itm_new_maceに変更します。
セーブしてビルドします。”itm_new_mace”は存在しないというエラーを吐くかもしれません。
これはファイルをコンパイルする順番が、編集の順番とは異なるというレッスンです。
module_troops.pyはおそらくmodule_items.pyより先にコンパイルされています。
このために、新しいメイスはコードの中で未登場となっているのです。
もう一度ビルドすると、エラーは起こりません。module_items.pyが先にコンパイルされたためです。
モジュールファイルを編集する、特に次に編集するモジュールで必要なものを先に追加している場合、編集が終わった後にコンパイルするように心がけましょう。
&bold(){おめでとうございます!}新しいアイテムを作り、兵士のインベントリに追加できました!
問題の兵士はヒーローユニットであり、なので常にnew maceをインベントリに持ち、
その中で最高の武器を装備します。
一方、一般兵はインベントリの中からランダムで装備します。
このために一般兵の装備はバリエーションを持っているのです。
次は様々なステータスの意味について見ていきます。
****5.4 アイテムのステータス
*****一般
abundance:パーセント値
商人のインベントリやlootにアイテムが出現する確率を表します。
100が標準で下限は0です。
weight:キログラム値
アイテムの重さをキログラムで定義します。
*****itp_type_horse
body_armor:値
馬のアーマーレートとHPを決定します。
difficulty:値
騎乗に必要なRidingスキルの高さを決定します。
horce_speed:値
戦闘マップでの馬のスピードを決定します。高いほど速くなります。
horce_maneuver:値
戦闘マップでの馬の機動性を決定します。
horce_charge:値
馬が歩兵に突撃した時のダメージの大きさ、歩兵に接触した時の減速の大きさを決定します。
高い値はダメージを大きく、歩兵の中を抜けやすくなります。
*****itp_type_one_handed_wpn
difficulty:値
装備に必要な最小STR値です。
spd_rtng:値
振り、突き両方での攻撃速度です。
weapon_length:センチメートル値
センチメートルで表した武器の長さです。
メッシュサイズとは無関係に武器のリーチを決定します。
swing_damage:値、ダメージタイプ
振り攻撃でのベースダメージとダメージタイプです。
thrust_damage:値、ダメージタイプ
突き攻撃でのベースダメージとダメージタイプです。
*****itp_type_two_handed_wpn
itp_type_one_handed_wpnと同じです。
*****itp_type_polearm
itp_type_one_handed_wpnと同じです。
*****itp_type_arrows
weapon_length:センチメートル値
センチメートルで表した矢の長さです。
thrust_damage:値、ダメージタイプ
弓のベースダメージに加算されるダメージ量とダメージタイプです。
max_ammo:値
1スタックに含まれる矢の数です。
*****itp_type_bolts
itp_type_arrowsと同じです。
*****itp_type_shield
hit_points:値
盾のHPのベース値です。
body_armor:値
盾への攻撃に対して軽減されるダメージの値です。
spd_rtng:値
盾が防御体勢に入るまでの速度です。
weapon_length:値
シールド範囲です。大きいほど体の多くの部分をカバーできます。
*****itp_type_bow
difficulty:値
弓を使うのに必要な最小のPower Drawスキル値です。
spd_rtng:値
弓の再装填速度です。
高いほど矢筒から引き出し、つがえ、放つまでの時間が短くなります。
shoot_speed:値
矢の飛ぶ速度です。高いほど速く飛びますが、あまりにも速い矢は近くの敵に当たらずに素通りします。
thrust_damage:値、ダメージタイプ
ベースダメージとダメージタイプです。
accuracy:パーセント値
矢がまっすぐ狙った場所に飛ぶ確率です。100は100%を示します。
Nativeでは利用されていませんが、追加できます。
*****itp_type_crossbow
difficulty:値
そのクロスボウを使うのに必要な最小STR値です。
spd_rtng:値
クロスボウの再装填速度です。
高いほど矢筒からボルトを抜き、つがえ、弦を引ききるまでの時間が短くなります。
shoot_speed:値
弓と同じです。
thrust_damage:値、ダメージタイプ
弓と同じです。
max_ammo:値
再装填が必要となるまでにボルトを何発撃てるかです。
accuracy:パーセント値
弓と同じです。
*****itp_type_thrown
difficulty:値
その武器を使うのに必要な最小Power Throwスキル値です。
spd_rtng :値
弓と同じです。
shoot_speed:値
弓と同じです。
thrust_damage :値、ダメージタイプ
弓と同じです。
max_ammo :値
1スタックに何個の武器が含まれているかです。
weapon_length:センチメートル値
武器の長さが何センチメートルあるかです。
*****itp_type_goods
food_quality
その食べ物のモラルへの影響です。50以上の場合、消費されるときにモラルを上昇させ、
50以下の場合はモラルを下げます。
max_ammo
その食べ物の消費可能な数です。
*****itp_type_head_armor
head_armor:値
兵士の頭へのダメージを防ぐ大きさです。
body_armor:値
兵士の体へのダメージを防ぐ大きさです。
leg_armor:値
兵士の足へのダメージを防ぐ大きさです。
difficulty:値
その装備を身につけるのに必要な最小STR値です。
*****itp_type_body_armor
itp_type_head_armorと同じです。
*****itp_type_foot_armor
itp_type_head_armorと同じです。
*****itp_type_hand_armor
itp_type_head_armorと同じです。
*****itp_type_pistol
difficulty:値
そのピストルを使うのに必要な最小STR値です。
difficulty:値
ピストルの再装填速度です。
shoot_speed:値
弾丸の速度です。
max_ammo:値
装填可能な弾の数です。
accuracy:パーセント値
弾が狙った場所に飛ぶ確率です。100で100%です。
*****itp_type_musket
itp_type_pistolと同じです。
*****itp_type_bullets
itp_type_pistolと同じです。
***&aname(part6){PART6} 定数、勢力、文章とクエスト(Module Constants, Factions, Strings and Quests)
このパートでは、モジュール内でもっとも小さく、全体への影響も少ないが、
しかし色々と便利なモジュールファイルを扱います。
****6.1 Module_Constants
&bold(){module_constants.py} はシンプルで、定数で埋め尽くされています。
module_constants内の定数は他の場所で宣言された定数と同じですが、
他の場所からの参照が容易なようにまとめられています。
例えば、定数 hero_escape_after_defeat_chanceの値を80から50にすると、
定数 hero_escape_after_defeat_chanceを使う演算はすべて50を投入するようになります。
このファイルはまた、kings_begin = “trp_kingdom_1_lord”や kings_end = “trp_knight_1_1”など
範囲マーカーも含んでいます。
定数セクションで定義されている他の重要なものとしてはスロット(Slot)があります。
スロットは兵士、ファクション、パーティに対して割り当てる事ができ、
そのグループの全員に特定の値を割り当てます。
例として街を街と定義しているスロットを見てみましょう
#slot_party_type values
##spt_caravan = 1
spt_castle = 2
spt_town = 3
spt_village = 4
module_script.py の中で spt_townを検索すると、spt_townの値と一緒にslot_party_typeが各街に割り当てられていることがわかります。
これはファイル内の他のタプルや後から参照することが出来ます。
spt_townの slot_party_typeを割り当てましたが、これ以外の他のスロットも追加できます。
複雑に聞こえますが、スロットの使い方が分かれば便利なツールとなるでしょう。
不幸にも私自身まだマスターしていませんが、Nativeのコードを読み込むうちに理解できると思います。
****6.2 Module_Factions
module_factions.pyはモジュールシステムとM&BのAIで使われる全てのファクションを含んでいます。
小さいファイルですが、いくつもの重要な設定に関わっています。
ファイルはPythonのリスト factions = [ で始まります。
他のモジュールファイルと同様、始めの幾つかのタプルはハードワイヤードなので編集不可です。
スクロールすると”deserters”のタプルが見つかります。
("deserters","Deserters", 0, 0.5,[("manhunters",-0.6),("merchants",-0.5),("player_faction",-0.1)], [], 0x888888),
このタプルは”deserters”というファクションを管理しています。
”deserters”の主な敵は”manhunters”、”merchants”、”player_faction”のファクションです。
”deserters”との関係がmodule_constantsで定義されていない場合、自動的に0にセットされます。
タプルの要素を見ていきます。
1)ファクションID。他のファイルからの参照に使います。
2)ファクションの名前。
3)フラグ。
4)一貫性(coherence)。このファクションのメンバー同士の関係を示します。
5)ファクション間の関係。
5.1)相手のファクション。
5.2)関係。2つのファクションの関係を示し、範囲は-1~1です。
6)ランク。
7)ファクションの色。デフォルトでグレイです。
例に当てはめてみます。
1)ファクションID = " deserters "
2)ファクションの名前 = "deserters"
3)フラグ = 0
4)一貫性 = 0.5
5)ファクション間の関係。
5.1)相手のファクション = "manhunters", “merchants”, "player_faction"
5.2)関係 = -0.6, -0.5, -0.1
6)ランク = 記述なし(JIK注:今のところこれが何なのか不明です)
7)色 = 0x888888(16進数)
このファクションはフラグを持っておらず、一貫性はニュートラル、3種の敵がいます。
他の場所に目を向けると、全ての”kingdom_#”ファクションは”deserters”に対して-0.02の関係を持っています。
これは関係の働き方が双方向なためです。
片方にセットされれば、両方のファクションでカウントされます。
新しいファクションを作ります。
“deserters”をリストの最後にコピー&ペーストします。
更にIDと名前を”geoffrey”にして、”player_faction”以外との関係を削除します。
> ("geoffrey","geoffrey", 0, 0.5,[("player_faction",-0.1)], [], 0x888888),
その後セーブしてビルドします。
ここで定義したファクションを他のモジュールファイルで利用します。
&bold(){module_party_templates.py} と &bold(){module_troops.py}を開き、
“new_template”と”npc17”のファクションを”fac_geoffrey”に変更します。
その後セーブしてビルドします。
成功すれば”new_template”のファクションが”Geoffrey”になり、プレイヤーに敵対するようになります。
****6.3 Module_Strings
&bold(){module_strings.py} はモジュールシステムの中でもっともシンプルなファイルです。
その中には文字列(strings)=テキストが入っています。
文字列は module_dialogsから module_questsまで、まとまったテキストを表示する必要のある全ての箇所で利用されています。
しかし module_stringsには、ひとつのファイルだけで利用されるのではない文字列が用意され、
モジュールシステム内の各所からの呼び出しに対応しています。
このファイルはmodule_fanctionsと同様にPythonのリスト strings = [ で始まります。
繰り返しになりますが、最初のいくつかのタプルはハードワイヤードです。
文字列の例を見てみます。
("bandits_eliminated_by_another", "The troublesome bandits have been eliminated by another party."),
("s5_s_party", "{s5}'s Party"),
タプルの要素を見ていきます。
1)文字列ID。参照に使います。
2)テキスト
重要な機能として、レジスタ値(register value)や他の文字列を投入出来ることが挙げられます。
例えば{reg0}を追加すると、reg(0)の現在値が表示されます。
同様に{reg10]ならばreg(10)の現在値が表示されます。
追加文字列として、普通のレジスタの代わりにに文字列レジスタ(string register)を利用できます。
これは文字列がレジスタとは別に格納されるためです。
例えば{s2]を追加した場合、reg{2}ではなく文字列レジスタ2が表示されます。
別々の事を示すために、同時にreg(2)と文字列レジスタ2が利用できます。
ダイアログにおいて、相手の性別によって違う文章を表示できます。
例えば、文字列に{sir/madam}を追加すると相手が男性のときsirを、女性のときmadamを表示します。
これらのオプションはいかなる文字列フィールドでも動作します。
一方、性別による分岐はダイアログでのみ有効です。
“display_message”のために、16進数コードを追加することで文字列の色を変更できます。
ex. (display_message,<string_id>,[hex_colour_code]),
色の16進数コードはRGBフォーマットで指定します。
例えば白は0xFFFFFFFF
0xFF(色指定はこれから始まる)FF(赤)FF(青)FF(緑)
各色の値はどれも0~256の16進数表示です。
赤を使いたければ0xFFFF0000になります。
色作りの方法を知っておくと便利でしょう。
****6.4 Module_Quest
これら小さいファイルの最後は&bold(){module_quests.py}です。
このファイルはクエストと、クエストに関連するテキストを含んでいます。
新しいクエストを追加すると、モジュールシステムはクエストの現在の状態を読みとり、
演算条件として利用します。
クエストの例を見てみます。
これは王からあなたに下される幾つかの配達命令のうちのひとつです。
("deliver_message", "Deliver Message to {s13}", qf_random_quest,
"{s9} asked you to take a message to {s13}. {s13} was at {s4} when you were given this quest."
),
タプルの要素を見ていきます。
1)クエストID = "deliver_message"
2)クエストの名前 = "Deliver Message"
3)クエストフラグ = qf_random_quest
4)クエストの説明 = "{s9} asked you to take a message to {s13}. {s13} was at {s4} when you were given this quest."
このクエストは文字列レジスタ{s9}、{s13}、{s4}を利用して、クエストの依頼者{s9}、請負人{s13}、
相手が最後に目撃された場所{s4}をあらわしています。
他のクエストを見ると、{s9}は常に依頼者、{s13}はターゲットの兵士/パーティ、そして{s4}はターゲットの最後の居場所のようです。
フラグ無しのクエストを作りたい場合、フラグには0を入れておきます。
我々の小さなクエストを作る第一歩を踏み出します。
下のクエストをコピーして、Pythonのリストの最後にある"quest_end"の前にペーストします。
>("speak_with_troublemakers", "Parley with the troublemakers", qf_random_quest,
>"Constible Haleck has asked you to deal with a bunch of young nobles making trouble around town.\
>How you want to tackle the problem is up to you; He has promised a purse of silver if you succeed."
>),
このタプルの構造について触れておきます。
見ての通り、新しいクエストを作るための変更点はわずかです。
しかし、それをゲームに組み込むためには他にも色々と手を出す必要があります。
注意:リストの全てのクエストはフラグ gf_random_questを持っています。
どうやら必要なフラグのようです。
まずクエストを受ける場所が必要です。次にクエストの中で役割を演じる”actors”が必要です。
最後に、クエストを面白くするダイアログが必要です。
旧チュートリアルはダイアログから取り組んでいましたが、
ここではまず”scene”から作ることにします。
”scene”はクエストを受諾し、その”target”に直面する場所です。
その後 module_dialogs.pyに取り掛かり、
新しいクエスト、兵士、テンプレートを組み込みます。
文字列の改行には'\'を用いていることに注意してください。
セーブしてビルドします。エラーが無ければPART7に進みましょう。
*M&B Module System Documentation PART4-6
PART1-3へ([[リンク>Module System/Document by Jik (1)]])
PART7-10へ([[リンク>Module System/Document by Jik (3)]])
----
#contents
-他の章へのリンク
--&link_anchor(part1,pageid=121){PART1 イントロダクション(Getting Started)}
--&link_anchor(part2,pageid=121){PART2 モジュールシステムの編集(Editing the Module System)}
--&link_anchor(part3,pageid=121){PART3 兵士(Module Troops)}
--&link_anchor(part3,pageid=123){PART7 シーン編集(Scene Editing)}
----
***&aname(part4){PART4} パーティ(Module Party Templates)
この章ではパーティテンプレートを扱います。
PART2で学んだパーティと混同しないように注意してください。
簡単に言うと、パーティテンプレートはmap上に出現するパーティのガイドラインです。
パーティはmap上のユニークな存在なのに対して、テンプレートはゲーム内では見えません。
パーティテンプレートIDが与えられている場合、そのパーティIDへ入力する操作は無効となります。
パーティテンプレートは&bold(){module_party_template.py}にあります。
****4.1 Module_Party_Templatesの意味
party_templates =[, で始まるパイソンのリストは、最初にいくつかのハードワイヤードなテンプレートを含みます。その部分は編集してはいけません。
module_party_templateのタプルはmodule_partiesのそれとよく似ています。
しかし互換性はありません。
パーティテンプレートの例を見てみます。
>("village_farmers","Village Farmers",icon_peasant,0,fac_innocents,merchant_personality,[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
このテンプレートのパーティは”famers”と呼ばれます。
(訳注:これはVillege Farmersのはず 。恐らくJIK氏が修正し忘れています。)
このパーティはfarmerとpeasant womanによって構成され、臆病に行動します。
またゲーム中に接触すると自動的にダイアログが始まります。
(フラグpf_auto_start_dialogが抜けていますが、全てのパーティが接触によって自動的にダイアログが始まるからでしょうか)
タプルの意味を見ていきます。
1)パーティテンプレートID。他のファイルからの参照に使います。
2)パーティテンプレートの名前。このテンプレートを使うパーティの名前になります。
3)フラグ。header_parties.pyに使用可能なフラグの表があります。
4)メニュー。module_partiesと同じく非推奨で、0を入れます。
5)ファクション。
6)パーソナリティ。map上でのパーティの行動を決めるフラグが入ります。
7)スタックリスト。最大6スタックまで可能です。
7.1)兵士ID。
7.2)最少人数。
7.3)最大人数。
7.4)メンバーフラグ(オプション)。メンバーに関するフラグを追加できます。
例:(trp_swadian_crossbowman,5,14,pmf_is_prisoner)
Villege Farmersのタプルを当てはめてみます。
1)パーティテンプレートID = "village_farmers"
2)パーティテンプレートの名前 = "Village Farmers"
3)フラグ = icon_peasant
4)メニュー = 0
5)ファクション = fac_innocents
6)パーソナリティ = merchant_personality
7)スタックリスト
7.1)兵士ID = trp_farmer, trp_peasant_woman
7.2)最少人数 = 11, 16(訳注:これも修正し忘れ。正しくは5, 3)
7.3)最大人数 = 22, 44(訳注:同上。10, 8)
7.4)メンバーフラグ = なし
もうタプルを読むのにも慣れてきたことでしょう。
この中で他と違うのは6番目、パーソナリティのフラグです。
次節ではこのフラグの役割を扱います。
****4.2 パーソナリティ
前の節で触れたとおり、パーソナリティはmap上でパーティの行動を決定します。
パーティの勇気(courage)と攻撃性(aggressiveness)を直接指定したり、
merchant_personalityのようなプリセットを指定できます。
プリセットは勇気と攻撃性を含む定数で、header_parties.pyの一番下で定義されています。
ex. merchant_personality = aggressiveness_0 | courage_7
攻撃性0のパーティは他のパーティを一切攻撃しません。
攻撃性8では、攻撃側と防御側の関係が悪く、また防御側が数で大きく勝っていない場合に攻撃します。
勇気はどれ位の大きさのパーティから逃げるかを決定します。
勇気が高いほどは数が多い相手からも逃走しにくくなります。
この値は0から15の範囲で自由に決められます。
しかしMODDING初心者にはプリセットの利用を薦めます。
プリセットは初めてのMODに使うには十分実用的です。
最後にフラグ banditnessについて触れておきます。
このフラグはパーティを盗賊として、近くのパーティに常に注意し、獲物が大量の金/交易品を持っている場合は攻撃するようにします。
盗賊が軍隊に襲い掛からないように、攻撃性を低くするかパーティの人数を少なく抑えたほうがよいでしょう。
****4.3 新しいテンプレートの作成
"farmers"のタプルをリストの最後尾にコピー&ペーストして手を加えます。
>(&bold(){"new_template","new_template"},icon_peasant,0,fac_innocents,merchant_personality,[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
Idを“farmers”を”new_template”に、名前も同様に変更しました。更に手を加えていきます。
まずファクションをfac_neutralに、パーソナリティをsoldier_personalityに変更します。
>("new_template","new_template",icon_peasant,0,&bold(){fac_neutral},&bold(){soldier_personality},[(trp_farmer,5,10),(trp_peasant_woman,3,8)]),
これにより中立勢力となり、また敵の部隊を攻撃するようになりました。
更に兵士の構成も変更します。
>("new_template","new_template",icon_peasant,0,fac_neutral,soldier_personality,[&bold(){(trp_npc17,1,1),(trp_new_troop,16,44)}]),
この例は幾つかの重要な変化を含んでいます。
特に重要なのは”(trp_npc17,1,1)”が入ったことで、PART3で作ったGeoffrey君がこの部隊に入りました。
ヒーローユニットは唯一無二なので当然その数は1です。
部下としてtrp_new_troopを追加します。これもPART3で作った兵士です。
最少で16人、最多44人の“new troop”がパーティに入ります。
セーブしてビルドします。成功すれば新しいテンプレートが利用可能になります。
しかし新しいテンプレートを利用するパーティが存在しないので、ゲームを起動してもGeoffrey君の部隊は出現しません。
後の章ではテンプレートの部隊の出現方法を学びますが、
とりあえず今はGeoffrey君とその仲間達は置いておいて、
PART5では新しいアイテムの作り方を学びます。
***&aname(part5){PART5} アイテム(Module Items)
PART3と4では新しい兵士とパーティテンプレート、そして装備させる方法を学びました。
これを踏まえて、この章では新しいアイテムの作り方を学びます。
****5.1 Module_Itemsの説明
module_items.pyは幾つかのアイテム修飾子(modifier)に関する定数で始まります。
修飾子はmodule_itemsのタプルからゲーム中で見る形のアイテムを生み出し、またアイテムの性能を上下させます。
ex. Bent polearm、chipped sword, heavy axe
これら定数は標準のアイテム修飾子を定義しています。商人のインベントリやlootで見るアイテムはこれらの定数から修飾子をランダムに選択します。
その選択ではリストにない修飾子は考慮されません。
しかし経験を積んだMODDERにとって、
演算&bold(){“troop_add_item”を利用すれば定数リストの中にない修飾子も利用されうる}という点は注意が必要です。
例えば、longbowは通常”plain”、”bent”、”cracked”の形のみをとります。
しかしプレイヤーのインベントリに修飾子”balanced”をつけて追加すれば、balanced longbowを入手できます。
定数の後にタプルのリストが始まります。
最初にある”practice_sword”を例として取り上げることにします。
>["practice_sword","Practice Sword", [("practice_sword",0)],
>itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|itp_wooden_attack, itc_longsword,
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),imodbits_none],
これはArenaやTraining fieldで使う練習用の武器です。
タプルの要素を見ていきます。
1)アイテムID。他のファイルからの参照に利用します。
2)アイテムの名前。インベントリ画面で表示される名前です。
3)メッシュのリスト。各メッシュは以下の要素を含むタプルです。
3.1)メッシュの名前。ゲームorモジュールのリソースファイル内の3Dモデルの名前。
3.2)このメッシュに適応する修飾子。
デフォルトの代わりにこのメッシュを利用するアイテム修飾子のリスト。
1つ目のメッシュがデフォルトになります。
4)アイテムのフラグ。
5)能力(capability)。アイテムが利用できるアニメーションを含みます。
6)価値。単位はdenar。Tradeスキルが10未満の場合、実際の価値はこれ以上になります。
7)ステータス。重さ、存在度、難易度、アーマーレートなど。
8)このアイテムが利用しうる修飾子。module_items.pyの最初にリストがあります。
9)トリガー(オプション)。このアイテムに関係するトリガーのリストです。
Practice_swordの例を当てはめてみます。
1)アイテムID = "practice_sword"
2)アイテムの名前 = "practice_sword"
3)メッシュのリスト
3.1)メッシュの名前 = "practice_sword"
3.2)メッシュの修飾子 = 0
4)フラグ = itp_type_one_handed_wpn|itp_melee|itp_primary|itp_secondary
5)能力= itc_longsword
6)価値 = 3
7)ステータス = weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt)
8)修飾子 = imodbits_none
9)トリガー = なし
これで“practice_sword”の性質について詳しく分かるようになりました。
・メッシュ”practice_sword”をデフォルトメッシュとして利用している
・フラグによってmelee武器になっている。”practice_sword”を装備した兵士は、インベントリからプライマリのmelee武器を選ぶときに”practice_sword”を選択肢として考えます。
(注意:セカンダリ武器の関数は不明瞭です。いつ使うのか、常に使うのかよく分かりません。しかし、melee兵士は戦闘中にmelee武器を切り替えることはありません)
・アニメーションは定数itc_longswordによって定義されており、longswordと同じ動きをします。
・重さ1.5kg、スピードレート103、武器の長さ90、殴打のベースダメージが振りで16、突きで10です。
・アイテム修飾子は使いません。常に同じアイテムです。
****5.2 ダメージタイプ
上のタプルの説明にあったとおり、”practice_sword”は殴打(Blunt)ダメージを与えます。
練習用武器だから、という理由ですが、これを機にM&Bでのダメージタイプを見てみます。
&bold(){Cut}ダメージ:剣など鋭利な刃物での切りつけによるダメージを表します。Cutダメージは鎧を装備していない、または軽装の敵にボーナスがあり、重装の敵にペナルティがあります。またCutダメージでhpを0にすると相手は死にます。
&bold(){Blunt}ダメージ:メイスやハンマーなど、刃の無い武器での殴打によるダメージを表します。重装の敵に50%のボーナスがありますが、全体に刃物よりも短くダメージも低いです。殴打武器の最大の長所は敵を殺さずに気絶させることです。気絶したときは奴隷として売ることが出来ます。馬の突撃もBluntダメージになります。
&bold(){Pierce}ダメージ:矢やボルトなどの突入によるダメージを表します。Pierceダメージは重装の敵に50%のボーナスがありますが、他のダメージタイプとのバランスを取るために、一般に他の武器よりもダメージが低いです。Pierceダメージは敵を殺害します。
****5.3 アイテムの作成
“practice_sword”のタプルをリストの最後尾にコピー&ペーストしてIDと名前を変更します。
>[&bold(){"new_mace","New Mace"}, [("practice_sword",0)], itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|itp_wooden_attack,
>itc_longsword, 3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),imodbits_none],
M&Bのファイルシステムはかなり柔軟です。少しの調整で剣がメイスになります。
“practice_sword”は元々Bluntダメージなので更に簡単です。
まず、アイテムの能力を"itc_longsword"から&bold(){"itc_scimitar"}に変更します。
定数”itc_scimitar”には突きが無いので、突きが使えなくなります。
更にメッシュを"practice_sword"から&bold(){"mace_pear"}に変更します。
このメッシュはNativeでは使われていないので、新鮮な見た目をしたメイスになります。
そして他のメイスには無い&bold(){フラグ"itp_wooden_attack"を消去}します。
>["new_mace","New Mace", [(&bold(){"mace_pear"},0)], itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry,&bold(){itc_scimitar,}
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(16,blunt)|thrust_damage(10,blunt),&bold(){imodbits_mace}],
メッシュを変更しただけでなく、修飾子を imodbits_none から imodbits_maceに変更しました。
これにより新しいメイスは定数 imodbits_maceの修飾子を使えるようになります。
更に二箇所に手を加えます。振りダメージの上昇とフラグの追加です。
>["new_mace",&bold(){"Geoffreys mace"}, [("mace_pear",0)] , itp_type_one_handed_wpn|itp_primary|itp_secondary|itp_wooden_parry|&bold(){itp_unique}, itc_scimitar,
>3,weight(1.5)|spd_rtng(103)|weapon_length(90)|swing_damage(&bold(){26},blunt)|thrust_damage(10,blunt),imodbits_mace],
振りダメージが16から26になりました。そしてより重要なことに、フラグ itp_uniqueが追加されました。
フラグ itp_uniqueの付いた装備は普通の戦闘後のloot画面では入手出来ません。
これはあまりにも早い入手を防ぐための措置です。
最後の調整として、名前を"Geoffreys mace"に変更します。
そしてGeoffrey君の持ち物にするために、module_troops.pyを開き、
彼のインベントリの itm_clubを itm_new_maceに変更します。
セーブしてビルドします。”itm_new_mace”は存在しないというエラーを吐くかもしれません。
これはファイルをコンパイルする順番が、編集の順番とは異なるというレッスンです。
module_troops.pyはおそらくmodule_items.pyより先にコンパイルされています。
このために、新しいメイスはコードの中で未登場となっているのです。
もう一度ビルドすると、エラーは起こりません。module_items.pyが先にコンパイルされたためです。
モジュールファイルを編集する、特に次に編集するモジュールで必要なものを先に追加している場合、編集が終わった後にコンパイルするように心がけましょう。
&bold(){おめでとうございます!}新しいアイテムを作り、兵士のインベントリに追加できました!
問題の兵士はヒーローユニットであり、なので常にnew maceをインベントリに持ち、
その中で最高の武器を装備します。
一方、一般兵はインベントリの中からランダムで装備します。
このために一般兵の装備はバリエーションを持っているのです。
次は様々なステータスの意味について見ていきます。
****5.4 アイテムのステータス
*****一般
abundance:パーセント値
商人のインベントリやlootにアイテムが出現する確率を表します。
100が標準で下限は0です。
weight:キログラム値
アイテムの重さをキログラムで定義します。
*****itp_type_horse
body_armor:値
馬のアーマーレートとHPを決定します。
difficulty:値
騎乗に必要なRidingスキルの高さを決定します。
horce_speed:値
戦闘マップでの馬のスピードを決定します。高いほど速くなります。
horce_maneuver:値
戦闘マップでの馬の機動性を決定します。
horce_charge:値
馬が歩兵に突撃した時のダメージの大きさ、歩兵に接触した時の減速の大きさを決定します。
高い値はダメージを大きく、歩兵の中を抜けやすくなります。
*****itp_type_one_handed_wpn
difficulty:値
装備に必要な最小STR値です。
spd_rtng:値
振り、突き両方での攻撃速度です。
weapon_length:センチメートル値
センチメートルで表した武器の長さです。
メッシュサイズとは無関係に武器のリーチを決定します。
swing_damage:値、ダメージタイプ
振り攻撃でのベースダメージとダメージタイプです。
thrust_damage:値、ダメージタイプ
突き攻撃でのベースダメージとダメージタイプです。
*****itp_type_two_handed_wpn
itp_type_one_handed_wpnと同じです。
*****itp_type_polearm
itp_type_one_handed_wpnと同じです。
*****itp_type_arrows
weapon_length:センチメートル値
センチメートルで表した矢の長さです。
thrust_damage:値、ダメージタイプ
弓のベースダメージに加算されるダメージ量とダメージタイプです。
max_ammo:値
1スタックに含まれる矢の数です。
*****itp_type_bolts
itp_type_arrowsと同じです。
*****itp_type_shield
hit_points:値
盾のHPのベース値です。
body_armor:値
盾への攻撃に対して軽減されるダメージの値です。
spd_rtng:値
盾が防御体勢に入るまでの速度です。
weapon_length:値
シールド範囲です。大きいほど体の多くの部分をカバーできます。
*****itp_type_bow
difficulty:値
弓を使うのに必要な最小のPower Drawスキル値です。
spd_rtng:値
弓の再装填速度です。
高いほど矢筒から引き出し、つがえ、放つまでの時間が短くなります。
shoot_speed:値
矢の飛ぶ速度です。高いほど速く飛びますが、あまりにも速い矢は近くの敵に当たらずに素通りします。
thrust_damage:値、ダメージタイプ
ベースダメージとダメージタイプです。
accuracy:パーセント値
矢がまっすぐ狙った場所に飛ぶ確率です。100は100%を示します。
Nativeでは利用されていませんが、追加できます。
*****itp_type_crossbow
difficulty:値
そのクロスボウを使うのに必要な最小STR値です。
spd_rtng:値
クロスボウの再装填速度です。
高いほど矢筒からボルトを抜き、つがえ、弦を引ききるまでの時間が短くなります。
shoot_speed:値
弓と同じです。
thrust_damage:値、ダメージタイプ
弓と同じです。
max_ammo:値
再装填が必要となるまでにボルトを何発撃てるかです。
accuracy:パーセント値
弓と同じです。
*****itp_type_thrown
difficulty:値
その武器を使うのに必要な最小Power Throwスキル値です。
spd_rtng :値
弓と同じです。
shoot_speed:値
弓と同じです。
thrust_damage :値、ダメージタイプ
弓と同じです。
max_ammo :値
1スタックに何個の武器が含まれているかです。
weapon_length:センチメートル値
武器の長さが何センチメートルあるかです。
*****itp_type_goods
food_quality
その食べ物のモラルへの影響です。50以上の場合、消費されるときにモラルを上昇させ、
50以下の場合はモラルを下げます。
max_ammo
その食べ物の消費可能な数です。
*****itp_type_head_armor
head_armor:値
兵士の頭へのダメージを防ぐ大きさです。
body_armor:値
兵士の体へのダメージを防ぐ大きさです。
leg_armor:値
兵士の足へのダメージを防ぐ大きさです。
difficulty:値
その装備を身につけるのに必要な最小STR値です。
*****itp_type_body_armor
itp_type_head_armorと同じです。
*****itp_type_foot_armor
itp_type_head_armorと同じです。
*****itp_type_hand_armor
itp_type_head_armorと同じです。
*****itp_type_pistol
difficulty:値
そのピストルを使うのに必要な最小STR値です。
difficulty:値
ピストルの再装填速度です。
shoot_speed:値
弾丸の速度です。
max_ammo:値
装填可能な弾の数です。
accuracy:パーセント値
弾が狙った場所に飛ぶ確率です。100で100%です。
*****itp_type_musket
itp_type_pistolと同じです。
*****itp_type_bullets
itp_type_pistolと同じです。
***&aname(part6){PART6} 定数、勢力、文章とクエスト(Module Constants, Factions, Strings and Quests)
このパートでは、モジュール内でもっとも小さく、全体への影響も少ないが、
しかし色々と便利なモジュールファイルを扱います。
****6.1 Module_Constants
&bold(){module_constants.py} はシンプルで、定数で埋め尽くされています。
module_constants内の定数は他の場所で宣言された定数と同じですが、
他の場所からの参照が容易なようにまとめられています。
例えば、定数 hero_escape_after_defeat_chanceの値を80から50にすると、
定数 hero_escape_after_defeat_chanceを使う演算はすべて50を投入するようになります。
このファイルはまた、kings_begin = “trp_kingdom_1_lord”や kings_end = “trp_knight_1_1”など
範囲マーカーも含んでいます。
定数セクションで定義されている他の重要なものとしてはスロット(Slot)があります。
スロットは兵士、ファクション、パーティに対して割り当てる事ができ、
そのグループの全員に特定の値を割り当てます。
例として街を街と定義しているスロットを見てみましょう
#slot_party_type values
##spt_caravan = 1
spt_castle = 2
spt_town = 3
spt_village = 4
module_script.py の中で spt_townを検索すると、spt_townの値と一緒にslot_party_typeが各街に割り当てられていることがわかります。
これはファイル内の他のタプルや後から参照することが出来ます。
spt_townの slot_party_typeを割り当てましたが、これ以外の他のスロットも追加できます。
複雑に聞こえますが、スロットの使い方が分かれば便利なツールとなるでしょう。
不幸にも私自身まだマスターしていませんが、Nativeのコードを読み込むうちに理解できると思います。
****6.2 Module_Factions
module_factions.pyはモジュールシステムとM&BのAIで使われる全てのファクションを含んでいます。
小さいファイルですが、いくつもの重要な設定に関わっています。
ファイルはPythonのリスト factions = [ で始まります。
他のモジュールファイルと同様、始めの幾つかのタプルはハードワイヤードなので編集不可です。
スクロールすると”deserters”のタプルが見つかります。
("deserters","Deserters", 0, 0.5,[("manhunters",-0.6),("merchants",-0.5),("player_faction",-0.1)], [], 0x888888),
このタプルは”deserters”というファクションを管理しています。
”deserters”の主な敵は”manhunters”、”merchants”、”player_faction”のファクションです。
”deserters”との関係がmodule_constantsで定義されていない場合、自動的に0にセットされます。
タプルの要素を見ていきます。
1)ファクションID。他のファイルからの参照に使います。
2)ファクションの名前。
3)フラグ。
4)一貫性(coherence)。このファクションのメンバー同士の関係を示します。
5)ファクション間の関係。
5.1)相手のファクション。
5.2)関係。2つのファクションの関係を示し、範囲は-1~1です。
6)ランク。
7)ファクションの色。デフォルトでグレイです。
例に当てはめてみます。
1)ファクションID = " deserters "
2)ファクションの名前 = "deserters"
3)フラグ = 0
4)一貫性 = 0.5
5)ファクション間の関係。
5.1)相手のファクション = "manhunters", “merchants”, "player_faction"
5.2)関係 = -0.6, -0.5, -0.1
6)ランク = 記述なし(JIK注:今のところこれが何なのか不明です)
7)色 = 0x888888(16進数)
このファクションはフラグを持っておらず、一貫性はニュートラル、3種の敵がいます。
他の場所に目を向けると、全ての”kingdom_#”ファクションは”deserters”に対して-0.02の関係を持っています。
これは関係の働き方が双方向なためです。
片方にセットされれば、両方のファクションでカウントされます。
新しいファクションを作ります。
“deserters”をリストの最後にコピー&ペーストします。
更にIDと名前を”geoffrey”にして、”player_faction”以外との関係を削除します。
> ("geoffrey","geoffrey", 0, 0.5,[("player_faction",-0.1)], [], 0x888888),
その後セーブしてビルドします。
ここで定義したファクションを他のモジュールファイルで利用します。
&bold(){module_party_templates.py} と &bold(){module_troops.py}を開き、
“new_template”と”npc17”のファクションを”fac_geoffrey”に変更します。
その後セーブしてビルドします。
成功すれば”new_template”のファクションが”Geoffrey”になり、プレイヤーに敵対するようになります。
****6.3 Module_Strings
&bold(){module_strings.py} はモジュールシステムの中でもっともシンプルなファイルです。
その中には文字列(strings)=テキストが入っています。
文字列は module_dialogsから module_questsまで、まとまったテキストを表示する必要のある全ての箇所で利用されています。
しかし module_stringsには、ひとつのファイルだけで利用されるのではない文字列が用意され、
モジュールシステム内の各所からの呼び出しに対応しています。
このファイルはmodule_fanctionsと同様にPythonのリスト strings = [ で始まります。
繰り返しになりますが、最初のいくつかのタプルはハードワイヤードです。
文字列の例を見てみます。
("bandits_eliminated_by_another", "The troublesome bandits have been eliminated by another party."),
("s5_s_party", "{s5}'s Party"),
タプルの要素を見ていきます。
1)文字列ID。参照に使います。
2)テキスト
重要な機能として、レジスタ値(register value)や他の文字列を投入出来ることが挙げられます。
例えば{reg0}を追加すると、reg(0)の現在値が表示されます。
同様に{reg10]ならばreg(10)の現在値が表示されます。
追加文字列として、普通のレジスタの代わりにに文字列レジスタ(string register)を利用できます。
これは文字列がレジスタとは別に格納されるためです。
例えば{s2]を追加した場合、reg{2}ではなく文字列レジスタ2が表示されます。
別々の事を示すために、同時にreg(2)と文字列レジスタ2が利用できます。
ダイアログにおいて、相手の性別によって違う文章を表示できます。
例えば、文字列に{sir/madam}を追加すると相手が男性のときsirを、女性のときmadamを表示します。
これらのオプションはいかなる文字列フィールドでも動作します。
一方、性別による分岐はダイアログでのみ有効です。
“display_message”のために、16進数コードを追加することで文字列の色を変更できます。
ex. (display_message,<string_id>,[hex_colour_code]),
色の16進数コードはRGBフォーマットで指定します。
例えば白は0xFFFFFFFF
0xFF(色指定はこれから始まる)FF(赤)FF(青)FF(緑)
各色の値はどれも0~256の16進数表示です。
赤を使いたければ0xFFFF0000になります。
色作りの方法を知っておくと便利でしょう。
****6.4 Module_Quest
これら小さいファイルの最後は&bold(){module_quests.py}です。
このファイルはクエストと、クエストに関連するテキストを含んでいます。
新しいクエストを追加すると、モジュールシステムはクエストの現在の状態を読みとり、
演算条件として利用します。
クエストの例を見てみます。
これは王からあなたに下される幾つかの配達命令のうちのひとつです。
("deliver_message", "Deliver Message to {s13}", qf_random_quest,
"{s9} asked you to take a message to {s13}. {s13} was at {s4} when you were given this quest."
),
タプルの要素を見ていきます。
1)クエストID = "deliver_message"
2)クエストの名前 = "Deliver Message"
3)クエストフラグ = qf_random_quest
4)クエストの説明 = "{s9} asked you to take a message to {s13}. {s13} was at {s4} when you were given this quest."
このクエストは文字列レジスタ{s9}、{s13}、{s4}を利用して、クエストの依頼者{s9}、請負人{s13}、
相手が最後に目撃された場所{s4}をあらわしています。
他のクエストを見ると、{s9}は常に依頼者、{s13}はターゲットの兵士/パーティ、そして{s4}はターゲットの最後の居場所のようです。
フラグ無しのクエストを作りたい場合、フラグには0を入れておきます。
我々の小さなクエストを作る第一歩を踏み出します。
下のクエストをコピーして、Pythonのリストの最後にある"quest_end"の前にペーストします。
>(&bold(){"mod_trouble"}, "Parley with the troublemakers", qf_random_quest,
>"Constible Haleck has asked you to deal with a bunch of young nobles making trouble around town.\
>How you want to tackle the problem is up to you; He has promised a purse of silver if you succeed."
>),
(修正02/15/09:クエストの名前を修正しました)
このタプルの構造について触れておきます。
見ての通り、新しいクエストを作るための変更点はわずかです。
しかし、それをゲームに組み込むためには他にも色々と手を出す必要があります。
注意:リストの全てのクエストはフラグ gf_random_questを持っています。
どうやら必要なフラグのようです。
まずクエストを受ける場所が必要です。次にクエストの中で役割を演じる”actors”が必要です。
最後に、クエストを面白くするダイアログが必要です。
旧チュートリアルはダイアログから取り組んでいましたが、
ここではまず”scene”から作ることにします。
”scene”はクエストを受諾し、その”target”に直面する場所です。
その後 module_dialogs.pyに取り掛かり、
新しいクエスト、兵士、テンプレートを組み込みます。
文字列の改行には'\'を用いていることに注意してください。
セーブしてビルドします。エラーが無ければPART7に進みましょう。
表示オプション
横に並べて表示:
変化行の前後のみ表示: