よくある質問
コンテンツの追加
モンスターの追加
- モンスターの定義を作成します。
data/json/monsters.jsonを直接編集するか、 新しい JSON ファイルを作成し、そこに新しいモンスターの定義を挿入します(通常は既存のエントリーをコピーして編集します)。 - 他のすべてのモンスタータイプと重複しない固有のIDであることを確認してくださ い。
- これでモンスタータイプはゲーム内で有効になりますが、この時点ではまだ出現しま
せん。類似のモンスター群の中に出現させたい場合は、
monstergroups.jsonを編集します。適切な配列を見つけ、そこにモンスターの識別子 (例:mon_zombie)を挿入します。cost_multiplierは、出現コストを高く設定します。コストが高いほど、その出現場所で占有する「スロット」が多くなります。freqは出現頻度です。詳細についてはmongroupdef.cppを参照してください。 - モンスターにアイテムをドロップさせたい場合は、
monster_drops.jsonを編集し ます。そのモンスタータイプ専用の新しい配列を作成し、モンスターが運ぶ可能性のあるすべてのマップアイテムグループと、それぞれの出現確率を定義します。 - モンスターは、特別な攻撃、すなわち
monattack::function参照を持つ場合があり ます。monattack.hを編集し、その関数をクラス定義に含めます。monstergenerator.cppを編集して翻訳を追加し、次にmonattack.cppを編集して関数を定義します。関数は異なるモンスタータイプ間で共有される場合があります。注意点として、モンスターがこの特殊攻撃を使用するかどうかを決定するための条件式を含める必要があります。また、攻撃を使用した場合は、モンスターの攻撃タイマーをリセットする必要があります。 - 攻撃と同様に、一部のモンスターは死亡時に特別な関数が呼び出される場合がありま
す。これは攻撃と同じ仕組みですが、関連ファイルは
mondeath.hとmondeath.cppです。 - モンスターにフラグを追加する場合は、
json_flags.mdとmtype.hにそれらを 記述し、文書化してください。必ず行ってください。さもないと、夜中にあなたの血液が酸に置き換えられてしまうかもしれません。
マップへの建造物の追加
ほとんどの「通常の」建造物は、都市(互いに比較的近くに位置する建造物の大きなクラスター)に出現します。
ファイル omdata.h の enum oter_id 構造体で、建造物の名前(コード識別子)を定義します。
建造物をオーバーマップ上で異なる方向で表示したい場合は、各方向に対応する4つの識別子 (south、east、west、north)を追加する必要があります。
同じファイル内の構造体 const oter_t oterlist[num_ter_types] で、これらの建造物がどのように表示されるか、どの程度視界を遮るか、どのエクストラセットを持つかを定義する必要があります。例:
{"mil. surplus", '^', c_white, 5, build_extras, false, false},
{"mil. surplus", '>', c_white, 5, build_extras, false, false},
{"mil. surplus", 'v', c_white, 5, build_extras, false, false},
{"mil. surplus", '<', c_white, 5, build_extras, false, false}
この構造体の冒頭にあるコメントは非常に役立ちます。まず、ファイル mapgen.cpp内 のサブルーチン draw_map(...); を見つけてください。その中に巨大なバリアント演算子(switch文)があるはずです。ここに新しい case ステートメントを追加し、新しい建造物を定義するコードを配置する必要があります。
ほとんどの建造物は、SEEX*2 x SEEY*2 タイルの正方形上に構築されることに留意してください。
建造物を都市の境界内だけでなく、より広いエリアにスポーンさせたい場合は、ファイル omdata.h 内の構造体 ( #define OMSPEC_FREQ 7から始まる行) を参照する必要があります。
これらの構造体もソースコード内に詳細にコメントされています。
enum omspec_id構造体内のNUM_OMSPECSの前に、新しい識別子を追加します。- 次に、
const overmap_special overmap_specials[NUM_OMSPECS]配列に新しい建造物のレコードを追加します。
{ot_toxic_dump, 0, 5, 15, -1, mcat_null, 0, 0, 0, 0, &omspec_place::wilderness,0}
構造体 struct overmap_special に付けられているソースコード内のコメントは、上記の例におけるこれらの定数の意味を説明しています。
バイオニックの追加
data/json/bionics.jsonを編集し、類似のバイオニクスの近くに新しいバイオニ クスの定義を追加します。個々のフィールドの詳細については、JSON_INFO.mdを参照してください。- そのバイオニクスをアイテムとしてゲームワールドで入手可能にしたい場合は、
item_groups.jsonに追加します。また、data/json/items/bionics.jsonにバイオニクスアイテムの定義を追加する必要があります。 - バイオニクスの効果を、適切なファイルに手動でコーディングします。起動型のバイ
オニクス(アクティベートして使用するタイプ)の場合は、
bionics.cpp内にあるplayer::activate_bionic関数を編集します。 - 遠隔武器として機能するバイオニクスの場合、
ranged.jsonにバイオニクス武器の 対応する定義を追加し、BIONIC_WEAPONフラグを付与します。 - 近接武器として機能するバイオニクスの場合、
data/json/items/melee.jsonにバ イオニクス武器の定義を追加し、少なくともNON_STUCKおよびNO_UNWIELDフラグを付与します。
アーマー保護の計算方法
- プレイヤーが特定の身体部位に被弾した場合、まずアーマー被覆率に基づいて、アー
マーが被弾したのか、あるいはアーマーで覆われていないプレイヤーの素肌が被弾したのかが決定されます(被覆率に対して1から100までの乱数(
1d100)をロールします)。 - 上記の乱数ロールが失敗した場合(すなわち、ロール値が被覆率を上回った場合)、 アーマーはその打撃によるダメージを吸収しません。同時に、アーマーも損傷を受けません。
- 上記の乱数ロールが成功した場合、アーマーが被弾したと見なされ、ダメージの一部 を吸収し、その結果アーマーが損傷を受ける可能性があります。
- 上記のステップ(被覆率による判定とダメージ処理)は、その身体部位に重ね着され ているアーマーの層ごとに繰り返されます。
- アーマーは、打撃ダメージおよび切断ダメージからプレイヤーを保護します。ダメー
ジ耐性は、
materials.jsonファイルで設定されている素材ごとの打撃/切断耐性係数に、アーマーの厚さをそれぞれ乗算することによって算出されます。 - アーマーが2種類の素材でできている場合、耐性係数は主要素材(
66%)と副次素材 (33%)の重み付け平均を取って計算されます。 - 素材の耐性係数は、
PAPER(紙)を基準としています(ただし、ゲームバランス調 整のために微調整が必要になる場合があります)。
iuse 関数の追加
- 新しいアイテム使用コードの作成:
iuse.cppとiuse.hに、新しく作成するアイテム使用コード(関数)を追加します。 - JSON フラグの設定と関数のリンク付け: アイテムに新しい JSON フラグを追加します。その後、
item_factory.cppで、そのJSONフラグを、ステップ1で作成したiuse関数にリンクさせます。 - 新しいフラグの文書化: 追加した新しい JSON フラグについて、
json_flags.mdに詳細を記述し、文書化します。
酸耐性
これは、アイテムが酸のフィールドにどのように反応するかを決定します。アイテムの酸耐性は、素材の酸耐性の重み付け平均です (item::acid_resistを参照)。
- アイテムの酸耐性がゼロの場合、毎ターン腐食します。
- アイテムの酸耐性がゼロより大きい場合、毎ターン腐食する可能性があります。
- アイテムの酸耐性が9より大きい場合、完全に酸性耐性があります(acidproof)。
酸耐性値は materials.jsonにあり、次のように定義されています。
- 0 - 酸に対する耐性がゼロ(金属など)
- 1 - 部分的に酸性耐性がある
- 2 - 非常に酸性耐性がある
- 3 - 完全に酸性耐性がある
FAQ
Q: アイテムが NPC のインベントリに表示されないようにするにはどうすればよいですか?
A: そのアイテムに TRADER_AVOID フラグを追加します。
Q: マップオブジェクトって一体何ですか?
A: 関連するマップオブジェクトは、サブマップ(submap)、マップバッファ(mapbuffer)、マップ(map)、およびオーバーマップ(overmap)です。
サブマップは、SEEX × SEEY のチャンクで構成され、実際のマップデータを含んでいます。乗り物とスポーンデータは比較的疎なため、ベクトルに格納されています。サブマップは、単一のグローバルなマップバッファである MAPBUFFER 内に存在します。
マップは、現在アクティブなプレイヤー周辺のエリアをカプセル化しています。これには、grid と呼ばれる MAPSIZE * MAPSIZE のサブマップポインターの配列が含まれています。これは2次元配列ですが、(インデックス作成の目的で)1次元配列にマッピングされています。
プレイヤーがあるサブマップから別のサブマップに移動すると、map::shift() が呼び出されます。この関数は、プレイヤーが中央に位置するように grid 内のポインターを移動します。grid の最前線は map::load() によって埋められます。サブマップが以前に訪問されたことがある場合は、MAPBUFFER からロードされます。そうでない場合は、対応するオーバーマップ地形タイプに基づいて、2x2 チャンクのサブマップが生成されます。
オーバーマップは、マップの大規模な構造、すなわち都市、森、川、道路などの位置とレイアウトをカプセル化します。オーバーマップの数は任意であり、プレイヤーが新しいエリアに入るたびに、追加のオーバーマップが生成されます。
Q: NPC/モンスターとマップの関係はどうなっていますか?どこに、どのように格納されていますか?
A: すべての NPCは現在、オーバーマップに格納されています。ただし、実際にアクティブな NPC のみ、現在アクティブな状態の NPC コンテナに含まれます。 NPC が持つアクティブな座標とオーバーマップ上の座標には違いがあります。そのため、NPCをセーブする際には、この座標を適切に変更する必要があります。そうしないと、NPCが間違った場所に保存されてしまうためです。 そして、ご質問の通り、NPCのデータはオーバーマップに格納されています。