2013/02/01
■ [変愚蛮怒/スポイラー]ストリーマーの生成(変愚蛮怒 Ver2.1.1)
ストリーマーとは図のように、偏りつつも散らばって生成された壁地形のことである。
ストリーマーはダンジョン生成中に湖地形が作られていない場合を前提として、以下の処理で生成される。
- ダンジョン毎に定義された第2ストリーマー地形生成をbuild_streamer()関数で4回、レア度15で試みる。
- ダンジョン毎に定義された第1ストリーマー地形生成をbuild_streamer()関数で4回、レア度15で試みる。
- build_streamer()関数は以下の処理でストリーマーを生成する。
- ストリーマーの縦横の開始地点を中央から(ダンジョンの長さ/3)付近の範囲でランダムに決める。
- そこからストリーマーの伸びる方向を、8方向から決める。
- ストリーマーの各地点で5回に渡って以下の処理を繰り返す。ストリーマーの地点がフロア外にはみ出るまで繰り返す。
- ストリーマーの生成地点から周辺5マスのどこかを定める。
- その地点が床地形/水地形/溶岩地形ならキャンセル。
- 永久地形ならばキャンセル。
- ストリーマーが壁地形ならば、閉じたドアや、特別な生成で作られた地形にならばキャンセル。
- その地形にモンスターやアイテムが配置されていた場合は削除される。
- ストリーマーが財宝を含んだ地形ならば、1/(レア度)の確率で財宝を含ませ、そうでなければもう一度1/(レア度)の確率で隠された財宝を含ませる。
- ストリーマーの生成地点を伸びる方向に向けて1マス進める。
このような生成プロセスになっているので、ストリーマーの流れは特に大きなダンジョンを見ると、くっきりと太さ11マスの線のように見えたりする。不自然だけど仕方ないね。
2013/02/02
■ [変愚蛮怒/スポイラー]ストリーマーの生成(変愚蛮怒 Ver2.1.1 r3245)
やはり先日の記事でストリーマーが直線的に生成されるのが気になったので、マッチポンプ改良を行なってみた。
以下の通りである。
ストリーマーはダンジョン生成中に湖地形が作られていない場合を前提として、以下の処理で生成される。
- ダンジョン毎に定義された第2ストリーマー地形生成をbuild_streamer()関数で4回、レア度15で試みる。
- ダンジョン毎に定義された第1ストリーマー地形生成をbuild_streamer()関数で4回、レア度15で試みる。
- build_streamer()関数は以下の処理でストリーマーを生成する。
- ストリーマーの縦横の開始地点を中央から(ダンジョンの長さ/3)付近の範囲でランダムに決める。
- そこからストリーマーの伸びる方向を、8方向から決める。
- ストリーマーの各地点で5回に渡って以下の処理を繰り返す。ストリーマーの地点がフロア外にはみ出るまで繰り返す。
- ストリーマーの生成地点から周辺5マスのどこかを定める。
- その地点が床地形/水地形/溶岩地形ならキャンセル。
- 永久地形ならばキャンセル。
- ストリーマーが壁地形ならば、閉じたドアや、特別な生成で作られた地形にならばキャンセル。
- その地形にモンスターやアイテムが配置されていた場合は削除される。
- ストリーマーが財宝を含んだ地形ならば、1/(レア度)の確率で財宝を含ませ、そうでなければもう一度1/(レア度)の確率で隠された財宝を含ませる。
- ストリーマーの生成地点を伸びる方向に向けて1マス進める。
- (追加点)1/10の確率でストリーマーが伸びる方向を左右どちらか45度回転させる。
これでストリーマーが中々自然そうな形に蛇行するようになったと思う。(自己満足)
2013/02/03
■ [変愚蛮怒/スポイラー]プレイヤーのテレポート処理(変愚蛮怒 Ver2.1.1 rev3259)
プレイヤーのテレポート処理はteleport_player()関数を根幹とし、テレポート距離と各種フラグを指定して実行する。
- テレポートの実際処理をteleport_player_aux()関数で行う。
- 荒野の広域マップ中ではキャンセル
- 反テレポを装備で備えていればキャンセル。
- テレポート距離に200以上が指定されていれば200に留める。
- @さんを中心としたテレポート距離*2の正方形内を全て走査し、テレポート先候補内に入れるかを決定する。
- distance()関数で測った絶対距離がテレポート距離以上ならその地点は候補から外す
- cave_player_teleportable_bold()で定められたテレポート先地形でないなら候補から外す
- 候補が一つもなければテレポートキャンセル。
- テレポート距離をテレポート可能先の比に基づいた確率で決定する。ただし、テレポート先になる候補は絶対距離の長い順から並べていき、候補全体が50%を超えた時点で候補を打ち切る。例えば範囲5内で20件候補がああった場合先頭の10件だけが候補となり、距離3の確率1/10、距離4の確率6/10、距離5の確率3/10となる。
5554444443 3333322211 |--候補--|
- 実際のテレポート先を確定して飛ぶ。万一フロアの外に飛んでしまう場合はキャンセルされ、move_player_effect()が実行される。
- 以上の処理を行なった後、周囲1マスのモンスターを走査し、いた場合にテレポート追尾の判定を行う。
- テレポート追尾を行う前提は、モンスターが眠っておらず、長距離テレポートを持ち、なおかつ、テレポ耐性を持っていない時。
- teleport_monster_to()関数により、(敵レベル)%の確率で追尾が試みられる。
2013/02/04
■ [変愚蛮怒/スポイラー]teleport_monster_to関数の処理(変愚蛮怒 Ver2.1.1 rev3259)
teleport_monster_to()関数はモンスターを指定された地点にテレポートさせる関数である。以下の処理中で呼び出されている。
- 魔法の笛の発動(プレイヤーのいる地点へ確率100%のテレポート/PASSIVE)
- ものまねの「引き寄せる」(プレイヤーのいる地点へ確率100%のテレポート/PASSIVE)
- 青魔法の「引き寄せる」(プレイヤーのいる地点へ確率100%のテレポート/PASSIVE)
- 鷲系モンスターが他のモンスターに対して「特別な行動(掴みかかる)」(鷲系モンスターのいる地点へ確率100%のテレポート/PASSIVE/NON_MAGICAL)
- モンスターがモンスターに対して「引き寄せる」(プレイヤーのいる地点へ確率100%のテレポート/PASSIVE)
- プレイヤーがteleport_player関数で能動的にテレポートした場合の追尾(プレイヤーのいる地点へ確率(モンスターレベル)%のテレポート)
- プレイヤーがteleport_away関数でテレポートアウェイされた場合の追尾(プレイヤーのいる地点へ確率(モンスターレベル)%のテレポート)
追尾時に関数が呼び出される前提は双方とも、teleport_player()中で@さんがテレポートした際、その周囲の1マスのモンスターにTELEPORTフラグがあり、かつRES_TELEフラグがない場合である。
各関数にPASSIVEや、NON_MAGICALなどのフラグは指定されているが現在の実装中でこれらが処理の影響を及ぼすことはない。
teleport_monster_to()の処理の流れは以下の通りである。
- 引数で予め定められた成功率での判定が通らなければキャンセルされる。
- テレポート先候補の目標地点間との距離(dis)を1からスタートする。
- (dis)範囲内のマスを500回ランダムに拾い、そこがテレポート可能な地点であった時点でテレポート先確定。
- 500回試行して拾えなかった場合はdisを倍にして再度検索、ここまでの流れをさらに500回試行する。
- 以上を繰り返してもテレポート先が無かった場合はキャンセル。
- テレポート先が確定したならば、実際にモンスターの座標を当該に移し、各種更新を行う。
2013/02/05
■ [変愚蛮怒/スポイラー]★切り裂きの大鎌『ブラッディ・ムーン』の発動と理想的なスレイ確率について(変愚蛮怒 Ver2.1.1 rev3259)
★ブラッディ・ムーン専用の属性付加はget_bloody_moon_flags()関数で行われ、以下の通りである。
- 元のアーティファクトフラグで生成済オブジェクトのフラグを初期化する。
- 2d2回に渡り、いずれかの26種のスレイ特性いずれかを得る。
- 混沌武器
- 吸血
- 動物スレイ
- 邪悪スレイ
- アンデッドスレイ
- 悪魔スレイ
- オークスレイ
- トロルスレイ
- 巨人スレイ
- ドラゴンスレイ
- ドラゴン*スレイ*
- 切れ味
- 地震
- 毒殺
- 溶解
- 電撃
- 焼棄
- 凍結
- 人間スレイ
- 動物*スレイ*
- アンデッド*スレイ*
- 悪魔*スレイ*
- オーク*スレイ*
- トロル*スレイ*
- 巨人*スレイ*
- 人間*スレイ*
- 1d2回に渡って、one_resistance()関数で耐性を得る。
- 1/3の確率でone_ele_resistance()により元素耐性4種(火、冷気、電撃、酸)のいずれか一つを得る。
- 2/3の確率でone_high_resistance()により上位耐性12種(毒、混乱、盲目、閃光、暗黒、破片、轟音、地獄、カオス、因果混乱、劣化、恐怖)のいずれか一つを得る。
- いずれか11種の内2つのpvalを得る。
- +腕力
- +知力
- +賢さ
- +器用
- +耐久
- +魅力
- +隠密
- +探索
- +赤外
- +掘削
- +加速
各処理中、特性を重複して得た場合は全く無駄になる。
以上より、ブラッディムーンにとりあえず切れ味&対邪といった非常に汎用性の高いスレイがつく確率は
2d2で得られる各組み合わせ毎に割り振って計算して、 2回時:0.25*(2/26)*(1/26)≒0.07396% 3回時:0.50*((52+50+48)/26^3≒0.42672% 4回時:0.25*(24/26)*((52+50+48)*/26^3)*(2/26)((1/26)+(25/26)(1/26)+(25/26)(25/26)(1/26))≒0.41042% 総計:0.91110%
多項分布か何か使えばもっとスマートに計算できたっけ?ともあれこれは1%未満ですね…たまげたなあ。
2013/02/06
■ [変愚蛮怒/スポイラー]process_monster()関数によるモンスターの行動処理(変愚蛮怒 Ver2.1.1 rev3265)
process_monster()関数はモンスターにターンが回ってきた際の処理が非常に長々と書かれている。全仕様を詳細に述べるとややこしくなるので、とりあえず大まかな流れだけ今回にまとめて、重要度の高いものは別項にまとめる。
- モンスターにRIDINGフラグがないのに、@さんがそれに騎乗している状態なら、この時点で落馬処理が行われる(通常変身などの直後に落馬処理が行われるはずなので、恐らく保険としての処理)
- モンスターの正体が眠っていないカメレオンならば1/13の確率で別のモンスターに変身する。
- @さんが忍者の超隠密状態ならば、一定の確率でモンスターは「気づかない状態」(aware=FALSE)状態になり、以下の一部の行動を行わない。
- 召喚などによって生成されて、親元が存在しているモンスターならば、その親元のモンスターが既にフロア中から消滅していると同様に削除される。
- QUANTUM(量子生物)フラグを持っているモンスターはQUESTERでない限り一定確率で自然消滅する。(ペットならば@さんが悲しい気分になる)
- 手榴弾はダメージ1を無条件に受ける(0になれば爆発する仕様になっている)
- 場が闘技場でなく、ペットか友好的なユニークやナズグル(準ユニーク)はHPが最大の1/3未満に陥っている場合、危機を感じて撤退しようとする。
- @さんが騎乗中のモンスターの場合「束縛から逃れようとしている!」と警告が出て、2ターン後に消滅、落馬処理が発生する。
- 蛆虫爺の狗共(『くいつき』『きば』『おおかみ』)以外でCAN_SPEAK持ちのユニークならば、「ピンチだ!退却させてもらう!」と丁寧に断る。
- レベルテレポートの巻物を読んで撤退する。(実質は単なるフロアからの削除であってどこかの階に必ず再生成される訳ではない)
- 何故か騎乗中のモンスターならばまた落馬処理が発生する。
- モンスターがまだ眠っている場合、この時点で処理が終了する。
- @さんが反感を持っている場合はこの時点で無条件に目を覚ます。
- モンスターが朦朧としている状態なら1/2の確率で行動キャンセルで処理が終了する。
- @さんが反感持ちなら友好的なモンスターや、ペットのユニーク、ナズグル(準ユニーク)は即座に敵に回る。
- MULTIPLYモンスターの増殖処理。
- 闘技場でなければ、CAN_SPEAK持ちの場合会話メッセージが表示される。
- 魔法詠唱確率を通った場合の魔法選択、実行処理。(別の関数にすべきなほど長い、後日別記事)
- モンスターの移動処理(別の関数にすべきなほどクッソ長い、後日別記事)
2013/02/07
■ [変愚蛮怒/スポイラー]process_monster()内のモンスター移動処理(変愚蛮怒 Ver2.1.1 rev3265)
- ランダムに歩く確率を決める。具体的には後述している、移動方向の候補が第4候補まで全てランダムになる。
- モンスターが混乱しているか、@さんが超隠密状態だと100%
- RAND_25フラグ持ちなら+25%
- RAND_50フラグ持ちなら+50%
- NEVER_MOVEフラグ持ちの移動不可で、@さんと隣接していない場合100%(元より動かないので意味がないのだが、実装されている処理上の都合)
- ペットが特に視界内に敵を捉えておらず、命令に従った通りの距離関係を@さんとの間に確保している場合100%
- 友好的なモンスターが敵を捉えていない場合100%
- get_move()関数により移動を試みるべき方向を、基本、第4候補まで確定する。(詳細は別記事予定)
- 移動方向を、第1候補から順に以下の流れで解決する。
- 候補の移動先がフロア領域外なら次の候補を選ぶ。
- 移動先に@さんか、他のモンスターがいた場合、移動先確定。
- KILL_WALL及びPASS_WALL持ちで移動先が突破あるいはすり抜けられる壁なら移動先確定。
- 移動先がくさびのない閉じたドアならでOPEN_DOOR持ちのモンスターの場合、1d(モンスターHP / 10) - 1 > ドア地形のPOWERならば、開けることが可能で行動終了。
- 移動先がドアで、BUSH_DOOR持ちなら、ガラスのドアでないか、ガラスのドアでもSTUPIDなモンスターでHPが200以上か、HP1/3以上のどちらか大きい方以上残っていたなら、ドアへの体当たりを試みる。1d(モンスターHP / 10) - 1 > ドア地形のPOWERならばドアは破壊され、そのマスにモンスターは移動する。
- 移動先が守りのルーンで突破できたら、移動先確定。
- 移動先が爆発のルーンなら、爆発の処理を後で行うフラグを立てる。
- 壁を壊して進んだなら、ここで壁の種類に応じて、「ギシギシ」音がなるか、ガラスの砕けた音がする。
- 移動先にアイテムがあって、TAKE_ITEM持ちで拾うことが可能なら拾う。
- 移動先にアイテムがあって、KILL_ITEM持ちで破壊することが可能なら破壊する。
2013/02/08
■ [変愚蛮怒/スポイラー]process_monster()関数中のモンスターがアイテムを拾う/破壊する処理(変愚蛮怒 Ver2.1.1 rev3265)
TAKE_ITEM/KILL_ITEMフラグ持ちのモンスターは以下の流れでアイテムを手に入れるか破壊しようとする。
- 前提としてペットはアイテムを拾おうとしない。
- 金や、死体、骨、像は拾う対象にはしない。
- DRAGON/DEMON/UNDEAD/ORC/TROLL/GIANT/ANIMAL/HUMANのフラグを持つモンスターは各スレイ作用を持つ武器に手をつけられない。
- IM_FIRE/IM_COLD/IM_ELEC/IM_ACID/IM_POISの各元素耐性を持っていないと、焼棄、凍結、電撃、溶解、毒殺武器に手をつけられない。
- アーティファクトは無条件に手をつけられない。
- RES_ALLフラグ持ちの場合のみ、上記の条件を全て無視して手をつけることができる。
- 以上の条件でアイテムを拾うことができない場合でも、STUPIDフラグ持ちのモンスターはアイテムを拾おうとして必ず失敗する。
- 以上を満たしてアイテムを拾うことができたならば、アイテムをモンスターのストックに入れて終了する。
- 以上の流れでアイテムを拾えなかったか、元より、TAKE_ITEMを持っていない、KILL_ITEMフラグ持ちモンスターならばアイテムを破壊する。
2013/02/09
■ [変愚蛮怒/スポイラー]モンスターの特殊攻撃選択処理(変愚蛮怒 Ver2.1.1 rev3274)
モンスター毎に規定された特殊攻撃率を通った後、以下の処理を進める。
- 予め属性や、ペット関係で攻撃ターゲットにしている他のモンスターがいた場合、そいつが依然敵対関係であり、かつ射線の通る位置にいる場合、目標モンスター→@さんの順に特殊攻撃を試みる。
- そうでない場合@さん→目標モンスターの順に特殊攻撃を試みる。
- モンスターからモンスターへの特殊攻撃の場合monst_spell_monst()関数へ移行。
- モンスターから@さんへの特殊攻撃の場合make_attack_spell()関数へ移行。
- ただし、@さんが忍者の超隠密でaware=FALSEでいる場合、特殊攻撃の目標対象にならない。
make_attack_spell()
- モンスターが混乱状態なら特殊攻撃は自動的に失敗する。
- @さんに対して敵意を抱いていないなら、自動的に失敗する。
- @さんが射程外(闘技場の時18、それ以外36)にいるなら自動的に失敗する。
- 閃光のブレスは、ガラス地形などで特殊な射線の通り方をするので、それで目標に届くがどうかをチェックする。閃光でも基本的に通らない状態ならば閃光のブレスを特殊攻撃の選択対象から最初から除外する。
- 射線が通るものの、@さんが壁抜けや幽体化などにより、壁にこもっている状態の場合、以下の特殊攻撃を優先的に選ぶ。
- 分解のブレスをモンスターが使用可能で、射線を塞ぐ壁が溶解可能なら1/2の確率で分解のブレスに確定。
- さもなくば閃光のブレスをモンスターが使用可能で、射線を塞ぐ壁がガラス地形ならば1/2の確率で閃光のブレスに確定する。
- 射線が通ってない状態でも、以下の条件で優先的に以下の特殊攻撃を選ぶ。
- 分解のブレス持ちで、@さんが最大射程の半分以内におり、壁の分解作用範囲内にいた場合、@さんからモンスターへの射線が通り(つまりLOSられている状態)なら1/2の確率、そうでないなら1/20の確率で分解のブレスに確定。
- 閃光のブレス持ちで、@さんが最大射程の半分以内におり、ガラスの壁により特別な射線が通るなら1/5の確率で閃光のブレス確定。
- スター・バースト持ちで、@さんが最大射程の中におり、ガラスの壁により特別な射線が通るなら1/5の確率でスター・バースト確定。
- 射線が通らなくてもの意味のある特殊攻撃(叫ぶ、回復など)を持っていたなら、選択肢をそれらに狭める。
- ここでまだ完全な確定特殊攻撃がなくて、しかるべき射線が通っている上で閃光のブレス持ちなら、1/5の確率で閃光のブレスに確定。
- 1d100>魔法詠唱率*2を満たした場合、魔法的な特殊攻撃は全て選択肢から除外する。
- 暗闇生成持ちが、@が忍者の上、自分がHURT_LITEやHAS_DARK_1など暗闇をまとっているフラグを持っていない場合、暗闇生成を光生成に切り替える。
- STUPID持ちでないなら、DARKNESSフラグつきのダンジョンでは暗闇生成/光生成を使わない。
- STUPID持ちでないなら、@さんが忍者で先の事情で光生成が使えないなら、選択肢から除外する。
- 反魔法の洞窟でSTUPID持ちでないなら、この時点で魔法的な特殊攻撃は全て選択肢から除外される。
- モンスターのHPが1/10で、SMARTならば、1/2の確率で回復、レベルテレポートなどの、緊急回避的な特殊攻撃のみを選択肢に入れる。
- ただし、レベルテレポートが無意味な状態ならば、選択肢からは除外する。
- この時点で使える特殊攻撃の選択肢がなくなったら終了。
- STUPIDでなければ、以下のように選択肢を狭める。
- @さんがMPを持たない職か、完全にMPが尽きているなら魔力吸収は行わない。
- ボルト系特殊攻撃は途中に他のモンスターがいる場合にはフレンドリーファイアをやりかねないだけに終わるので選択肢から外す。
- @さんの位置が召喚可能地点でないなら召喚系特殊攻撃は選択肢から外す。
- 蘇生可能な死体が範囲内にないなら死者蘇生は選択肢から外す。
- 以上を踏まえて特殊攻撃が確定していないなら、選択肢内でさらに特殊攻撃を決める。
- STUPIDなら一様ランダムに一つ選ぶ。
- そうでなければさらに細かく優先順位を定めるが後日別記事で解説。
- 魔法的な特殊攻撃は25 - (敵レベル + 3) / 4%の失敗率を持つ、ただしSTUPID持ちは本能的な能力で特殊攻撃を行なっているということで無条件に成功する。
- 朦朧としているなら1/2の確率で無条件に失敗する。
- @さんが呪術で反魔法結界を展開しているなら(@さんのレベル * 3 / 2) > 1d(敵レベル)の時魔法的な特殊攻撃を封じる。
- 以上を通れば、実際の特殊攻撃処理が行われる。
2013/02/10
■ [変愚蛮怒/スポイラー]地形の状態フラグ(変愚蛮怒 Ver2.1.1 rev3274)
ダンジョンの各マスには地形(feature)の他に状態(cave)のフラグが保持される。
CAVE_MARK | 記憶済のマスである |
CAVE_GLOW | 地形自体が独自に光っているマスである |
CAVE_ICKY | Vaultなどによる特別な地形である(主にテレポート地点の対象にならない) |
CAVE_ROOM | 部屋として生成された地形である |
CAVE_LITE | 現在任意の手段で光があたっている状態のマスである |
CAVE_VIEW | 現在@さんの視界に入っているマスである |
CAVE_TEMP | 視界に入れたことのあるマスである |
CAVE_XTRA | "easily viewable"な地形である(内部処理上の意味は不明) |
CAVE_MNLT | モンスターの光源によって光っているマスである |
CAVE_MNDK | モンスターのまとっている暗闇によって暗くなっているマスである |
以下はフロア生成時の処理中に一時的な記憶に利用する(らしい)
CAVE_FLOOR | 床として生成されたマスである |
CAVE_EXTRA | 部屋外のマスである |
CAVE_INNER | 内壁として生成されたマスである |
CAVE_OUTER | 外壁として生成されたマスである |
CAVE_SOLID | 硬い地形である(ので部屋間のトンネル生成に加えない?) |
CAVE_VAULT | VAULTとして生成されたマスである |
2013/02/11
■ [ファンタジー]「懐古」的聖典の「昨今」の善悪事情
ビオ略のNetHack関連雑記「善悪なんてもともと存在しないんだよ。秩序混沌の方はあるけどね。」より引用
日本語で「善悪」という言葉を使うとその定義はあまりにも 抽象的であることを逆に利用して、そんなものはもともと 存在しないとか、定義を曖昧にする「思考停止キャンペーン」に 走ろうとする動きが多い。
英語のGood/Evilと日本語の「善」「悪」の間に語源的定義の差はあるだろうが、英語の方が具体的になっているのかどうかはそもそもはっきり良く分からん。が、ビオの人の脳内ではそういうことになっているらしい。
例えば、安手の神話かぶれのRPGやFT漫画などに、「善」の性質が あまりに強いとやらの理由で、異教になびく危険性を少しでも示した 村人を虐殺する「天使」などが頻出する。ゲームにおけるGOODの定義 にあてはめると、これはたとえアルコン(ここではLAWFUL-GOODの天使 を指す)であっても決して起こることではない。 たとえかれらが従う「法」が「処断を行わなくてはならない」という 結論を要求してくる法であるとしても、その「法」だけに従い、 村人への思いやりという「良心」を無視するならば、それは絶対にGOODではない。 もちろん、人間のLAWFUL-GOODなどであればGOODよりもLAWFULの方を重視する者 などもいるであろうが、アルコンは「LAWFULとGOODの両方の属性において極限」と 定義される存在であり、GOODをそれほどまでに明らかに軽視することはありえない。 (なお、真にLAWFUL-GOODのアルコンがこういう村人をどうするかといえば、 単に殺す必要のない解決策を探すという当たり前の解答が出て来るだけの話である。)
いつまでも終わらない『Bastard!』のことかー、もしれないが、とりあえず例によって的外れに国産ファンタジーをこき下ろしてるノリには昔からうんざりである。別に海外キリスト教圏の倫理観まですっぽり学んで、教条的にファンタジーを作る必然性など全くないだろうに。
少なくとも日本人の我々の眼からすれば、そういう『普遍的な善』を提唱している者の現実が、古くは十字軍だったり、最近だとイラクだったり、シーシェパードだったりする訳で、そういう物を横合いから見て来た立場として、懐疑的なテーマを盛り込む事は何らおかしなことではない。(勿論キリスト教に限らず、他の宗教でも普遍的な善の提唱と現実がどんなものかは皆様ご存知のはずである)
当の海外、それも系譜的にはビオ略の絶賛する指輪的世界観の別の継承者であるウルティマですら、とうの昔に4~6で、二元論に懐疑する世界観を築いている。結局、二元論を重視しようと、懐疑しようと、作品の質を分けるのはそれを筋道立てて各々の作品のメディアとしていかに書ききれているかに分かれるのであって、「安手」のものだけ引き出しにして話を進めるのは単なる藁人形を叩く行為に過ぎない。
題名の通りの本題としては、ここからになるが、例えばD&D3.5版のサプリメント『高貴なる行いの書』|などでは上方次元界の「善」の極致的存在である、セレスチャル、ガーディナル、エラドリンといった住人達は、秩序-混沌の属性差があっても、互いを尊重し、相争うことは決してないということが明記されている。この辺は下層次元界のデヴィルやデーモンのように秩序-混沌枠どころか、全く同じ属性同士ですら(一種合理的な)権力抗争を繰り広げるのとは対照的であり、確かに極致の例としてはビオ略の通りになっている。
だが、一方でD&D4版のサプリメント『ドラコノミコン:メタリック・ドラゴン』によれば、こんな事も書いてある。
3. 善のドラゴンでさえ恐ろしい敵になりうる。 この世界の善にその身を捧げている強力なメタリック・ドラゴンでさえ、 英雄キャラクターに脅威を与えうる。善のドラゴンはなんらかの場所やアーティファクトを 守るために、太古の誓いを果たすために、もしくは強大な悪を阻むために、英雄の グループを滅ぼそうと考えるかもしれない。 彼らは長命であり、自惚れと思い上がりに満ち溢れているため、ドラゴンは下級クリーチャーに とって厳しい選択を行なったり、多数の幸福のために少数を犠牲にしたりしても、 ほとんど気にしない。ドラゴン族が真に同情するのは極めて稀なことなのだ。
常に恩着せがましい態度を取る すべてのドラゴンは極めて高尚な自説を有している。彼らがかたじけなくも弱いクリーチャーと 会話して下さる場合、自分はなんて寛容なんだろうとドラゴンは考える。そして彼らが会った者 たちは自分の注意を引くことができたことを嬉しく思うに違いないと期待する。 ドラゴンと会話した人型クリーチャーはその名誉に対して深甚なる感謝の意を示すのが良い。 メタリック・ドラゴンは自身に対する賞賛が単に歌われるのみならず、大音声で触れ回って 欲しいと考えている。彼らが追認を必要としているのは、自信がないからではなく、 箔をつけたいからだ。 メタリック・ドラゴンが人間を支配したり捕食したりするのを控える場合、自身の真の本能に 反する選択を意図的に行なう。そのため、狩ったり日常的に食べたりしないという贈り物と 引き替えに、人型クリーチャーはメタリック・ドラゴンを褒め称えるべきであると、 彼らは信じている。一部のドラゴンは他でもない完全な崇拝を期待している。
ドラゴンはそりゃアルコンと比べりゃそんなものだろうと言う人もいるかも知れないが、基本的に善竜バハムートとその系譜をたどる全てのメタリックドラゴンはそれこそクラシックD&D初版の頃から設定されてきた、押しも押されぬ善玉サイドの一つである。その頃から描き方が大分変わっている可能性もあるかもしれないが、少なくとも最新版、そして属性が9属性から、秩序-善-中立-悪-混沌とさらに二元的になった世界観の中で善の最大勢力の一つの輩が基本こんな風に定義されているのである。
双方のサプリメントでそれぞれに描かれた善の実相の内、どれを実際の卓で適用するかはそれはGMとプレイヤー達の好みに分かれる訳であり、例えばシナリオ的なガチさを求め、善について極めて困難な見極めを要するようになれば、そこには必然懐疑的なテーマも出てくるだろう。少なくともD&D公式ですら、完全に揺ぎのない「普遍的な善」をご立派に体系づけて提唱しきっている訳ではなく、「自由」としてユーザーに託していることになる。
2013/02/12
■ [別記事追加予定][変愚蛮怒/スポイラー]cave_gen()関数による部屋間の生成処理(変愚蛮怒 Ver2.1.1 rev3274)
cave_gen()関数の処理中、generate_rooms()関数で生成された部屋の中央部分を基準に生成を行う。部屋中央座標は生成した順に配列に保管されているが、これを予めシャッフルする。
- 部屋間のドア数カウントを0にリセットする(各部屋の内部として生成されたドアはこれに含めない)
- 部屋の中でも最後のIDの中央座標を起点に生成開始。
- どの部屋も必ず繋がるよう、起点からIDの若い順に繋いでいく。ダンジョン毎に定義された確率に応じて、天然の洞窟らしい入り組んだ通路になるか、人工的な最短距離を通るものになるかが決まる。(build_tunnel2()/build_tunnel())この関数を一回行う毎に、配列に両部屋を結ぶ通路の座標が収められる。
- build_tunnel2()/build_tunnel()の違いは、再帰構造があってクランク状の数が増えやすいがそうでないかの違い。
- 途中に部屋があっても、普通に貫通する。これにより実質の通路数は処理を繰り返す回数(=部屋数)よりずっと多くなる。
- 通路生成経路が部屋の外壁であった場合、後でドア生成を行う地点として記憶する。
- 通路生成経路が既に通路を生成した場所であった場合、その周囲1マスに後でドアの生成を試みる。
- 通路配列をなぞる順に、通路を敷き詰めていく。
- 通路を敷き詰める地形が、移動可能地形(FF_MOVE)(=既に部屋が生成されている地形)でないか、水地形、溶岩地形(FF_WATER/FF_LAVA)でない場合のみ床にする。
- ダンジョンにNO_DOORフラグがない場合前述に記憶したドア生成地点に、確率に応じてドアを生成する。(詳細は別記事)
2013/02/13
■ [変愚蛮怒/スポイラー]try_door()/place_random_door()関数による通路のドア生成処理の流れ(変愚蛮怒 Ver2.1.1 rev3274)
generate.cの関数
static void try_door(int y, int x)
この関数の処理は、cave_gen()関数による部屋間の生成処理(変愚蛮怒 Ver2.1.1 rev3274)に記述してある通路生成中に三叉路や十字路ができた場合に、その周囲1マスにドアの生成を試みるものである。
下図の赤枠に囲まれた部分にあたる。
また、try_door()関数がさらに実際にドア生成や、上図の赤枠に囲まれていないドアは、place_random_door()を直接呼び出す形で実装されている。
void place_random_door(int y, int x, bool room)
roomはtry_door()で呼び出された場合のみFALSE、それ以外ではTRUEとなる。
try_door()の流れ
- 座標がフロア範囲内ならキャンセル
- 座標のマスが壁ならばキャンセル
- 座標のマスがCAVE_ROOMフラグを持っていたらキャンセル
- ダンジョンにNO_DOORSフラグがなく、壁の位置関係が不自然なドアでなければ、ダンジョン毎に計算された確率でplace_random_door()を呼び出す。
place_random_door()の流れ
- ダンジョンがNO_DOORSを持っていたら指定座標を床にして終了。
- ダンジョンがCURTAINフラグを持っていた場合、NO_CAVEを持っていると1/16、持っていないなら1/256の確率でドアはカーテンになる。
- そうでなければダンジョンにGLASS_DOORがあるとガラスのドア、そうでない場合通常のドアになる。
- ドアの状態は以下の確率の通り
- 300/1000の確率で開いている。
- 100/1000の確率で壊れて開いている。
- 200/1000の確率で隠しドアにしようと試みる。
- ただし、カーテンであった場合は単に閉じたカーテンになる。
- ダンジョンを構成する基本的な壁地形による偽装を試みるが、ドアが遮蔽を持たない地形であるか、偽装する壁が飛んで移動できる地形(竜窟の崖など)であった場合、偽装をキャンセルして、半々の確率で壁にするか床にする。
- 400/1000の確率で閉じたドアになる。
- 閉じたドアはplace_closed_door()によりさらに実装されている。この関数はカーテンでなければ、
- 300/400の確率で鍵がかからず閉じている。
- 99/400の確率で鍵がかかっている。
- 1/400の確率で完全に閉じている(くさびのかかったドアと同じ)
- 閉じたドアはplace_closed_door()によりさらに実装されている。この関数はカーテンでなければ、
- 以上のドア配置先にモンスターがいた場合削除する。
2013/02/14
■ [変愚蛮怒/スポイラー]add_river()関数による川生成の処理(変愚蛮怒 Ver2.1.1 rev3274)
ダンジョンでそれなりによく生成されるこういう地形である。
add_river()関数が「浅い地形」と「深い地形」のIDを受け取り、以下の流れで生成を行う。
add_river()
- 川の開始地点を、何故かフロアの右下半分のいずれかに偏らせて選んで開始する。
- 1d4を振って川の終着地点を決める。
- 1ならフロアの上端のいずれか。
- 2ならフロアの左端のいずれか。
- 3ならフロアの右端のいずれか。
- 4ならフロアの下端のいずれか。
- 川の基本幅の値を1d2で決める。
- recursive_river()関数に、川の開始地点、終着地点、地形、基本幅値を与えて再帰的な生成処理を開始する。
recursive_river()
- 開始地点と終着地点の距離が4を超えていたら、その2点を対頂点として、フロアに平行な長方形をの範囲内に中間地点を定める。
- 開始地点~中間地点、及び中間地点~終着地点の間でrecursive_river()を呼び出し再帰させる。
- 1/50の確率で、基本幅が0より大きいなら、川幅を一つ減らし、「中点」~「中点から中間地点のベクトルの8倍先の地点」にかけてrecursive_river()を呼び出し再帰させる。これは、支流を表現していることになる。
- 開始地点と終着地点の距離が4以内なら再帰を停めて、実際に川を生成する処理に入る。
- 開始地点から、終着地点の各地点を(川幅の値+1)分に当分する。
- 当分地点を中心(川幅の値-1)~(川幅の値+1)の長方形部分を川の地形で埋める。
- 既に該当の川地形で埋まっていたらキャンセル。
- その長方形の地点が長方形の中央から少し離れていると、生成キャンセルが起きやすい。具体て絹は距離>(川幅の値-1)~(川幅の値+1)の乱数
- 永久壁の地形はキャンセル。
- 距離>川幅の値なら浅い地形、そうでないなら深い地形を埋める。
- 地形に隠しドアなどのフラグが立っていたら、そのフラグを解除する。
- 川地形が溶岩系統なら、地形を光らせる。
- CAVE_ICKYフラグを立てて、テレポート先の対象にしない。
2013/02/15
■ [ゲーム論][翻訳]ローグライク的なゲームとは何かを考察する(Berlin Interpretation翻訳編)
とりあえず、出発点としてWikipedia日本語版の記事や英語版を適当に斜め読みしてみる。ああ、International Roguelike Development Conferenceなんてものがあるのか。と思って、参照リンクなんぞたどってみたら、おい、何か海外ではこういう「研究」とか随分と確立してるようではありませんか。
井の中な自分のチンケな考察を述べる前にこういったものをとりあえず、一通りさらっておいた方が、怪我も少なくて済むことは経験則的に分かっているつもりである。Berlin Interpretationとやらをとりあえず可能な限り翻訳(ほとんど意訳)してみることにした。ツッコミあれば是非プリーズ。
解説
この「ローグライク」定義はInternational Roguelike Development Conference 2008で作成され、参加者全員の議論を通じて得られたものである。http://www.roguetemple.com/roguelike-definition/での定義がその議論の端を発した。ほどんどの要素は(既存のものを)書き直したもので、それにいくつかを加えるなり、削るなりを行なった結果である。
一般原則
「ローグライク」はジャンルとして確立したもので、単なる「(初代)Rogueっぽいもの」とは異なる。このジャンルとしての呼び名は「カノン」と呼ばれるようになったのと同様で(狭義の「カノン砲」がその後広く大型の火器全般を指すようになったということか)、「カノン」にあたるのが、ADOM、Angband、Crawl、NethackそしてRogueなのである。
以下に示されたリストは「ローグライク」とは何かを決定づけるためのものである。いくつかその要素が欠落しているからといって、そのゲームが「ローグライク」でないとは言わない。ただ同様に、いくつか当てはまっているからといって必ず「ローグライク」である事を意味しない。
この定義の目的は「ローグライク」のコミュニティで研究していることをよりよく理解するためのものであり、「ローグライク」ゲームやその開発者を抑圧するものではないのである。
高位な要素
ランダムな環境の生成
繰り返し遊ぶことができるよう、世界はランダムに生成される。ただし、位置関係やアイテムがランダム生成される一方で、モンスターや話の筋書き、パズル要素、バルトなど、固定要素もある。
恒久的な死
最初のキャラクターで勝利を得られると思ってはいけない。死んだ時にはスタート地点に戻される。セーブはできるが、ロード時にデータは消去される。ランダムな要素はプレイヤーを苦痛にするものでなく楽しませるものである。
ターン制
一つのコマンドは一つの移動、動作とされる。「ローグライク」では焦ることなく、一つ一つのコマンド選択に慎重に時間をかけられる。
グリッドフィールド制
世界は統一されたタイルの格子で表現される。モンスターもプレイヤーも一個のマス目を占有し、サイズは問わない。
モード性がない(訳注:?原語Non-modal)
移動、戦闘や他の動作は常に同じ効果を産めるべきである。あらゆるアクションはゲームに有用な要素であるべきだ。ADOMのワールドマップや、AngbandやCrawlの店はそれらに反している(訳注:?)
複雑性
「ローグライク」は一つの目的に複数の解決法がある程度の複雑性を持っている。あらゆるアクションはゲームに有用な要素であるべきだ。ADOMのワールドマップや、AngbandやCrawlの店はそれらに反している(訳注:何故?)
資源管理
食料や回復薬といった限られた資源を管理し、それらを確保するための使い道を考えなければならない。
ハック&スラッシュ性
多くの「ローグライク」に見られることだが、モンスターの大量殺害は「ローグライク」の重要な要素の一つである。「ローグライク」はプレイヤーとゲーム世界の対決であって、モンスター同士には敵意や交渉事はない。
探索と発見
「ローグライク」はダンジョンの慎重な調査や、未鑑定なアイテムの用途の発見をプレイヤーに求める。プレイヤーが新しくゲームを始めるごとに、何か新しいものがなければならない。
低位な要素
単体のプレイヤー
プレイヤーは単体のキャラクターを操作する。ゲームはプレイヤーを中心に動き、一体のキャラクターによって世界が捉えられる。キャラクターが死ねばゲームは終わる。
モンスターはプレイヤーと同様であること
装備やアイテム、魔法など、各ルールがプレイヤーにもモンスターにも同様に適用される。
戦術的挑戦
満足する成果を得るためには戦術を学ばねばならない。それも反復を伴うもので、前持って得た情報は後の問題解決にはならない。(「ランダムな環境の生成」や「恒久的な死」により、「ローグライク」は常に新しいキャラクターでの挑戦を求める)このゲーム的方向性が戦術的挑戦を求め、大図面を見る戦略的なゲームやパズルとは性質を異にするのである。
ASCII表示
「ローグライク」は伝統的に、ASCII文字に敷き詰められた世界で表現される。
ダンジョン
「ローグライク」は、階段や回廊などによって結ばれたフロアによるダンジョンを持つ。
数値性
HPや属性などいった要素が数値的にはっきりと示される。
訳者としての小学生並の感想
どうも自分の翻訳の技量不足もありそうなのだが、それ以上に原文が今ひとつ綺麗にまとめられていないような印象がある。
一応「全部当てはまってないからといって、ローグライクでないとは限らないし、逆に一部合っていたってローグライクじゃないよね」と断っているものの、大半の面白い/認知度の高いローグライクはこの手の原則をむしろ破っているケースが多すぎてやはり参考にならない。
さらに印象を言えば、正直原始的なRogueの要素を表層的に抜粋しただけに過ぎないようだ。挙句、ADOMやAngband、Crawlが原則に反してるって仮にも客観的な定義にしつこく書くのは何故なんだw。
最初の断り書きの英語らしからぬ妙なしつこさも相まって、どうもこの定義はgdgdしたディスカッションをまとめ切れず、何となく原理主義的で未分化な公約数をなあなあで列挙したものではあるまいか?
正直翻訳して損したかも知れないと思いつつ、話を次回に続けようかなと思う。
2013/02/16
■ [変愚蛮怒/スポイラー]*破壊*の発動ケースとその処理の流れ(変愚蛮怒 Ver2.1.2 rev3303)
*破壊*の処理はdestroy_area()関数で行われる。
bool destroy_area(int y1, int x1, int r, bool in_generate)
この関数は以下のケースの時にそれぞれの引数を伴って呼び出される。
- *破壊*の巻物を読んだ時、プレイヤー中心に半径12+d5, ingenerate=FALSE
- *破壊*の杖を使った時、プレイヤー中心に半径12+d5(強力発動時17+d5), ingenerate=FALSE
- カオス魔法の「ワンダー」の魔法のランダム発動で*破壊*が選ばれた時、プレイヤー中心に半径12+d5, ingenerate=FALSE
- 暗黒魔法の「悪霊召喚」の魔法のランダム発動で*破壊*が選ばれた時、プレイヤー中心に半径12+d5, ingenerate=FALSE
- カオス魔法の「破壊の言葉」が発動した時、半径12+d4, ingenerate=FALSE
- 破邪魔法の「ハルマゲドン」が発動した時、半径12+d4, ingenerate=FALSE
- カオス魔法の「虚無招来」を壁に接触した状態で発動した時、665/666の確立で半径14+@レベル+d11,ingenerate=FALSE
- フロア生成処理中に、*破壊*の痕跡を作成するフラグが立った時、半径15, ingenerate=TRUE
- カオスパトロンの報酬で*破壊*が発動した場合、半径25, ingenerate=FALSE
bool destroy_area(int y1, int x1, int r, bool in_generate)
- 固定クエストか地上の場合はFALSEを返して終了。
- in_generate=TRUEなら、モンスターの光源一旦全て消す。
- 射程内かつ、フロア内の各マスについて以下の処理を施す。
- 該当のマスはCAVE_ROOM/CAVE_ICKY/CAVE_MARK/CAVE_GLOW/CAVE_KNOWNのフラグを失う。
- in_generate=FALSEならば該当のマスもCAVE_UNSAFEフラグを除く、@さんのある地点上では*破壊処理*をスキップする代わりに、プレイヤーが盲目になるフラグを立てる。
- 該当のマスに敵がいた場合、
- in_generate=TRUEなら無条件にその敵をdelete_monster()関数で消す。
- そうでなく、そのモンスターがクエストモンスターなら、HPを最大まで回復させた上で、*破壊*半径*2+1だけ、テレポートアウェイさせる。
- そうでない場合、delete_monster()関数で消す。ペットは消滅した旨を日記に記録される。
- ゲームオプションでアーティファクトの保存モードがオンになっているか、in_generate=TRUEの場合、フロア生成時の自然ドロップで配置されていた固定アーティファクトを救済し、また再生成されるチャンスを残す。
- 該当のマスのオブジェクトを全て消滅させる。
- 該当のマスが永久地形出ない場合、地形が変化する。
- in_generate=FALSEの場合、20/200で花崗岩の壁、50/200で石英の壁、30/200で溶岩の壁、100/200でダンジョン標準の床に変化する。
- in_generate=TRUEの場合、20/200で花崗岩の壁、30/200で石英の壁、50/200で溶岩の壁、100/200でダンジョン標準の床に変化する。
- in_generate=FALSEの場合、ダンジョンの明暗関係を更新する。
- @さんに盲目耐性か閃光耐性が内場合、10+d10ターンの盲目状態が追加される。
2013/02/18
■ [変愚蛮怒/スポイラー]fill_treasure()関数の処理の流れ(変愚蛮怒 Ver2.1.2 rev3303)
fill_treasure()関数はランダムVault生成時にその部屋内をアイテムとモンスターで埋め尽くす大盤振る舞いの関数である。
static void fill_treasure(int x1, int x2, int y1, int y2, int difficulty)
以下の(x1,y1)-(x2,y2)の矩形範囲に、難易度に従ったアイテムの生成を行う。difficultの値は各タイプのランダムVault毎に以下の通りになっている。
ランダムVaultタイプ | 難易度 |
"Bubble Vault" | 1d5 |
"Room Vault" | 1d5+5 |
"Cave Vault" | 1d5 |
"Maze Vault" | 1d5 |
"Mini Checker Board Vault" | 10 |
"Castle Vault" | 1d3 |
"Target Vault" | 1d3+3 |
"Elemental Vault" | 1d5 |
以上を踏まえた上で、以下の処理を行う。
fill_treasure()
- size値を部屋の縦+横の長さで定める。
- 矩形範囲内の各位置に以下の処理を行う。
- そのマスに配置されるモンスターorアイテムを定めるvalue値を (部屋中央からの距離)*100/size+1d10-難易度で算出。
- ただし1d100-難易度*3>50を満たした場合value値を20で固定。
- そのマスがCAVE_FLOORフラグをもつか、FF_PLACEとFF_DROPを併せ持っていた場合、value値に応じて以下の配置を行う。
- value < 0ならば、生成階+40のモンスターと生成階+20のGOODなアイテム
- 0 <= value < 5ならば生成階+20のモンスターと生成階+10のGOODなアイテム
- 5 <= value < 10ならば生成階+9のモンスター。
- 10 <= value < 17ならば何も配置しない。
- 17 <= value < 23ならば25%で生成階相応の通常アイテム、75%でトラップ
- 23 <= value < 30ならば生成階+5のモンスターとトラップ
- 30 <= value < 40ならば50%で生成階+3にモンスター、50%で生成階+7の通常アイテム
- 40 <= value < 50ならばトラップ
- 50 <= valueならば20%で生成階相応のモンスター、40%でトラップ、20%で生成階相応のアイテム、20%でなにもなし。
以上の処理を踏まえるに、ランダムVaultはどういう種別であれ、value値<5付近が見込める中央付近に一番おいしいアイテムが存在し得るようだ。逆にいうと、中央の数マス付近が壁や配置不能地形であった場合は刺激も恩恵もほとんどなく、トラップ処理だけの徒労に終わる可能性が多いと踏んだ方がいい。
筆者は、かなり昔に"Target Vault"とおぼしき、ほとんど十字路のような形状のランダムVaultに遭遇したことがある。中央にいた『サンタクロース』無事を平らげることが出来た上、中央5つに配置されたアイテムの内3つがアーティファクトという大当たりだった。この生成処理を裏付けるものとしてはかなり面白い例だったと思う。
2013/02/19
■ [変愚蛮怒/スポイラー]place_trap()/choose_random_trap()関数によるトラップ選択処理(変愚蛮怒 Ver2.1.2 rev3303)
void place_trap(int y, int x) int choose_random_trap(void)
place_trap()関数は指定のマスにランダムなトラップを配置する関数であり、cave_gen()系列の処理で頻繁に呼ばれる。座標のフロア範囲外を抑制し、指定のマスの罠IDをchoose_random_trap()が返した値で埋めた上で、地形を標準の床に偽装する。
choose_random_trap()関数は標準的に選択可能なトラップを一様乱数で1種類返すのみで、これもそんなに複雑な処理ではない。トラップの種類は以下の通りである。
"TRAP_TRAPDOOR" | トラップ・ドア |
"TRAP_PIT" | 落とし穴 |
"TRAP_SPIKED_PIT" | 落とし穴 |
"TRAP_POISON_PIT" | 落とし穴 |
"TRAP_TY_CURSE" | 邪悪なルーン |
"TRAP_TELEPORT" | 奇妙なルーン |
"TRAP_FIRE" | 焦げた場所 |
"TRAP_ACID" | 焦げた場所 |
"TRAP_SLOW" | ダーツ・トラップ |
"TRAP_LOSE_STR" | ダーツ・トラップ |
"TRAP_LOSE_DEX" | ダーツ・トラップ |
"TRAP_LOSE_CON" | ダーツ・トラップ |
"TRAP_BLIND" | ガス・トラップ |
"TRAP_CONFUSE" | ガス・トラップ |
"TRAP_POISON" | ガス・トラップ |
"TRAP_SLEEP" | ガス・トラップ |
"TRAP_TRAPS" | コンパクトルーン |
"TRAP_ALARM" | 警報装置 |
ただしトラップ・ドアのみは、
- 既にダンジョンの最深層にいる
- クエスト中のフロアである
- 闘技場内である
場合のみ振りなおして別のトラップが選択される。
2013/02/20
■ [変愚蛮怒/スポイラー]build_type16()の部屋生成プロセス(変愚蛮怒 Ver2.1.2 rev3327)
iksさんが実装してくれた新しい部屋生成処理「地下街」の処理の流れを追ってみることにした。コメントによれば、Vanilla 3.0.3からの流用らしい。
- 横サイズ:town_wid = 33~44 を設定
- 縦サイズ:town_hgt = 11~14 を設定
- 既に他の部屋生成でブラックマーケットの入口が生成されている場合には、ブラックマーケットの生成を抑制する。
- precalc_ugarcade()という関数で、生成がフロア上で可能かをチェックする。不可能ならキャンセル。
- この時点で店舗に当たる矩形状の永久壁地形を、全店舗分確定する。基本的に永久壁の矩形が他の矩形にくっつかないように領域を確保していき、どうしても店舗数分生成できない場合は失敗扱いになる。
- find_space関数でtown_wid+4, town_hgt+4のスペースが確保できるかをチェックする。不可能ならキャンセル。
- 確定した生成範囲を3x3分割し、その中央部分を部屋にする。
- build_stores()関数で実際に店舗を生成。
- 店舗永久壁から周囲2マスの壁は必ず床にする。
- 永久壁の東西南北いずれかの端に店舗入口を作成する。
結果は上図の通り、何となくVanillaTownらしい地形がランダムに生成されるようになっている。悪くない。
2013/02/21
■ [変愚蛮怒/スポイラー]通常トラップの効果一覧(変愚蛮怒 Ver2.1.2 rev3327)
同日修正
影分身の発動で回避できるペナルティを取り違えていたので修正。
"TRAP_TRAPDOOR"/トラップ・ドア
浮遊を持っていないと2d8のダメージを受けて、1階層か2階層下のフロアに落とされる。
"TRAP_PIT"/落とし穴
浮遊を持っていないと2d6のダメージを受ける。
"TRAP_SPIKED_PIT"/落とし穴
TRAP_PITの処理に加えて、50%の確率でダメージが倍になり、1d(ダメージ量)分傷値が増える。
"TRAP_POISON_PIT"/落とし穴
TRAP_SPIKED_PITに加えて、毒耐性がないとダメージがさらに倍になり、1d(ダメージ量)分毒値が増える。
"TRAP_TY_CURSE"/邪悪なルーン
2+1d3体の階層相応のモンスターを敵対的に召喚し、(階層)%の確率で太古の怨念が発動、一度発動すると1/6の確率で連続して発生し続ける。
"TRAP_TELEPORT"/奇妙なルーン
距離100のテレポート。
"TRAP_FIRE"/焦げた場所
4d6の火炎属性ダメージ、アイテム破壊処理あり。
"TRAP_ACID"/焦げた場所
4d6の酸属性ダメージ、アイテム破壊処理あり。
"TRAP_SLOW"/ダーツ・トラップ
命中力125の命中判定(打撃処理に使われているものなのでACが関わる)が通ると1d4のダメージ、19+1d20ターンの減速。影分身が発動すれば全て無効。
"TRAP_LOSE_STR"/ダーツ・トラップ
命中力125の命中判定(打撃処理に使われているものなのでACが関わる)が通ると1d4のダメージ、1回のSTR減少。影分身が発動すれば全て無効。
"TRAP_LOSE_DEX"/ダーツ・トラップ
命中力125の命中判定(打撃処理に使われているものなのでACが関わる)が通ると1d4のダメージ、1回のDEX減少。影分身が発動すれば全て無効。
"TRAP_LOSE_CON"/ダーツ・トラップ
命中力125の命中判定(打撃処理に使われているものなのでACが関わる)が通ると1d4のダメージ、1回のCON減少。影分身が発動すれば全て無効。
"TRAP_BLIND"/ガス・トラップ
盲目耐性がないと、49+1d25ターンの盲目状態追加。
"TRAP_CONFUSE"/ガス・トラップ
混乱耐性がないと、19+1d20ターンの混乱状態追加。
"TRAP_POISON"/ガス・トラップ
毒耐性がないと、9+1d20の毒値追加。
"TRAP_SLEEP"/ガス・トラップ
麻痺知らずがないと、4+1d10ターンの麻痺追加。悪夢モードなら即座に悪夢を見る。
"TRAP_TRAPS"/コンパクトルーン
周囲1マスにトラップ追加。
"TRAP_ALARM"/警報装置
周囲のモンスターを怒らせる。
■ [ヴィーヤウトゥムノ]ロムンクァリィ&ウディンダイ母子(と愛玩用えるふ)
バルログアーチャーとバルログ魔道具術師。
原初神話のお約束で夫婦関係でもある罠。ヴィーヤ=ウトゥムノ伯国民法で規定された「近親相姦新型免許」三型乙種保持者なので何も問題はない。
2013/02/22
■ [変愚蛮怒/スポイラー]箱トラップの効果一覧(変愚蛮怒 Ver2.1.2 rev3327)
CHEST_LOSE_STR/(毒針)
- 1d4ダメージを受けて、一回のSTR減少処理。
CHEST_LOSE_CON/(毒針)
- 1d4ダメージを受けて、一回のCON減少処理。
CHEST_POISON/(ガス・トラップ)
- 毒耐性が無ければ、9+1d20の毒値追加。
CHEST_PARALYZE/(ガス・トラップ)
- 麻痺知らずが無ければ、9+1d20ターンの麻痺追加。
CHEST_EXPLODE/(爆発装置)
- 5d8のダメージを受けて、箱のアイテム生成効果が失われる。
CHEST_SUMMON/(召喚のルーン)
- 2+1d3回、(階層)%の確率でactivate_hi_summon()。それでなければ箱の難度相応のモンスターを敵対的に召喚。
CHEST_SCATTER/(マルチ・トラップ)
- 従来のアイテム生成処理が行われるが、アイテムの生成される範囲が全フロア中のいずれかになる。
CHEST_E_SUMMON/(召喚のルーン)
- 5+1d3回、箱の難度相応の'E'シンボルモンスターを敵対的に召喚。
CHEST_BIRD_STORM/(召喚のルーン)
- 3+1d3回、プレイヤーの周辺にフォース属性の球をpval/5の威力で発生させ、1d5+pval/5回、箱の難度相応の'B'シンボルモンスターを敵対的に召喚。
CHEST_H_SUMMON/(召喚のルーン)
- いずれかの一つの効果が発動。
- 2+1d3回、周辺に威力10の火のボールを発生させながら、箱の難度相応のデーモンを敵対的に召喚。
- 2+1d3回、箱の難度相応のドラゴンを敵対的に召喚。
- 3+1d5回、箱の難度相応の'H'シンボルのモンスターを敵対的に召喚。
- 2+1d3回、箱の難度相応の'v'シンボルのモンスターを敵対的に召喚。
CHEST_RUNES_OF_EVIL/(邪悪なルーン)
- 3+1d3回に渡り、1d100+箱pval*2 > @さんの魔法防御 の判定を通るといずれかの効果が発動。
- 5d20の強制ダメージ
- 傷値+200
- 麻痺知らずを持ってないと1+1d6ターンの麻痺状態追加。もっていても、9+1d100の朦朧値追加。
- 装備品の劣化判定
- 全ステータス減少
- 自分を中心にダメージ150の地獄属性ダメージ。
CHEST_ALARM/(警報装置)
- 周辺のモンスターを怒らせる。
2013/02/23
■ [変愚蛮怒/スポイラー]aggravate_monsters()関数による「周囲のモンスターを怒らせる」処理(変愚蛮怒 Ver2.1.2 rev3327)
aggravate_monsters()関数で処理される。
void aggravate_monsters(int who)
引数のwhoは誰が発生させたかを指し、0なら@さんがトラップを踏んだか、自発的な魔法により引き起こしたもの、0以外ならモンスターが魔法で引き起こしたものであることを指す。
以下の場合に呼ばれる場合がある。
- ★拍子木の発動。
- 床トラップの「警報装置」
- 床トラップの「開門装置」
- 箱トラップの「警報装置」
- カオス魔法失敗時かシャッフル「運命の輪」を引いた時のランダム効果。
- 歌の失敗時
- エキサイト・モンスターの巻物
- 反感のロッド
- (今はコメントアウトされている)呪われているアーティファクトを発動した時。
- シャッフルで「不調和の剣」を引いた時
- 剣術「気迫の雄叫び」による轟音攻撃の副作用
- ものまねの「叫ぶ」
- 敵モンスターの「叫ぶ」
- 青魔法の「叫ぶ」
- 突然変異「叫ぶ」による轟音攻撃の副作用
- 悪魔魔法「血の呪い」の効果の一つ
- 太古の怨念の効果の一つ
予め断っておくと、この効果は@さんが意図的に発動したものであっても必ずデメリットしかない。
処理の流れは以下の通りである。
- フロア中の全モンスターを対象に以下の判定を行う。
- 怒らせる処理を発生させたモンスター自身ならキャンセル
- モンスターが@さんから距離39マス以内にいた場合、モンスターは即座に目を覚まし、ペット化に対する耐性を持つ。
- @さんの視界内にいるモンスターの場合、+100ターン加速する。
- 加速したモンスターが一体でもいた場合「付近で何かが突如興奮したような感じを受けた!」とメッセージを流す。
- 加速したモンスターはいないが、目を覚ましたモンスターがいた場合は「何かが突如興奮したような騒々しい音が遠くに聞こえた!」とメッセージを流す。
- 実害が何もなかった場合は一切メッセージが流れない。
2013/02/24
■ [ゲーム論]ローグライク的なゲームとは何かを考察する(持論/前書き編)
前回にBerlin Interpretationとやらを翻訳してローグライクとはなんぞやという問いについて参考例を得ようをした訳だが、このまとめ方が今ひとつ、体系的でもなければ表層的で不満に思わざるを得ないものだった。
それでも一応、ローグライク的な要素を段階的に分けるという発想そのものは筆者も、あるいは他の人々も持っている発想ではあると思う。日本語版Wikipediaのローグライクゲームの記事を見ていても、明確にローグライクなゲームであると見なせるものと、厳密には違うけど、一面的ながらも要素があるだろうと認められるものをそれぞれまとめている。という訳で筆者としても、
- 狭義なローグライク的要素
- 広義なローグライク的要素
- ローグライクの本質ではない要素
の三つに分けて、ローグライクの全体像を俯瞰できるよう考えてみたいと思う。
「狭義なローグライク的要素」とは、「ローグライク」というゲームの1ジャンルとして、ジャンルの大多数が持っている主要な約数をまとめたものとする。勿論全て満たす必要はないが、概ね大半は持っていていないと流石に厳密な「ローグライク」というジャンルには加えられないだろう。(勿論だからと言って「ローグライク」と全く無関係だとか、ましてや駄作と見る必要は断じてない。次項を参照)
「広義なローグライク的要素」は、前述の「狭義なローグライク要素」の実現が、そもそもより抽象的にいかなる本質に根ざしているかを述べたものである。他の「狭義なローグライク要素」にこそ含まれていなくても、そのゲームの諸要素が「広義なローグライク要素」に根ざしているものならば、少なくともそのゲームを狭義な「ローグライク」というジャンルの兄弟や従兄弟として認知し、そういう形でローグライクの源流が発展するしていることを好意的に見るべきである。
「ローグライクの本質ではない要素」とは、例えば初代Rogueの頃にはあったものの、そこからNetHack系、Moria/Angband系、Crawl系などと派生していくにつれて、スポイルされたり、変容していったものを指す。これらは、各ゲームの個性としては認められるべきであるが、それをローグライク全体の主要な要素と見間違えて高らかに語ると、各シリーズやバリアント同士の毀誉褒貶を招いて基本的に徒労か害にしかならない。このような項目で「そうでなければならない」と主張するのは了見を狭めるものでしかないので「そうでなくてもよい」という形でまとめていく。
「広義なローグライク的発想に基づいた、狭義にはローグライク的ではない要素」については、これからも生まれてくる発想であることも期待して、あまり具体的には論じない。それ以外を次回より順に論じてみたい。
2013/02/25
■ [変愚蛮怒/スポイラー]モンスターのNasty生成(変愚蛮怒 Ver2.1.2 rev3327)
この処理は変愚のバージョンを2.x系列へ移行させる前後に、自分(deskull)がほぼ最初に手を加えた部分であったりする。1.x系列の最終版付近の時点では、http://sourceforge.jp/ticket/browse.php?group_id=541&tid=20039で指摘された通り機能していなかった部分を能動的に仕様変更することで解決したものである。
Nasty生成とはget_mon_num()関数中に実装された仕様である。get_mon_num()関数は引数で受け取った生成階を元に、予め設定された条件フィルタを通しつつ、その範囲内のレベルのモンスターを一種指定する関数である。Nasty生成は一定の確率に応じて、この生成階にブーストをかけるもので、実質的にBEGINNERフラグつきのダンジョンであること以外にこの処理を抑止する要素はない。
クローン地獄といった佳境の固定クエストで対処不能なレベルの敵が配置されることがあるのはとりもなおさずこれが原因である。全体として深層生成の流れは、固定/ランダムVaultの地形指定によるものとこのNasty生成によるもの2つに集約される(はずである)
Nasty生成はget_mon_num()関数上で以下のように実装されている。
- Nasty生成の行われる確率を、以下の式で計算する。ただし、1/3以上にはならない。
1/(25 - ゲームターン / 25000 - √(従来生成階 * 10000) / 10)
- Nasty生成発動時の生成階上昇量を以下の式で計算する。ただし最大+25Fまでである。
3 + (フロア滞在分のゲームターン) / 200000 - √(従来生成階 * 10000) / 10) + MIN(5, 生成階/10)
- MAZEフラグのついているダンジョンならば、Nasty生成発動確率を-10%するか半分にするか、どちらか低い方に修正する。ただし、最低2%は確保する。また、その代わり通常の生成階に+3Fを加え、Nasty生成階を+2Fする。
- 闘技場でなくダンジョンにBEGINNERフラグがなければ、いよいよ本格的にNasty生成を試みる。
- 悪夢モードかつ、Nasty生成率を通った場合は、先程算出した生成階上昇量は無関係になり(絶望)生成階が強制的に以下の通りになる。ぶっちゃけ1Fでも秩序のユニコーンと出くわす可能性も微粒子レベルで存在する。
1 + (従来生成階 * 128 / 1d128)
- 悪夢モードでない状態でNasty生成率を通った場合は、生成階上昇量が単純に加算される。
以上の流れより、スカム行為などでゲーム時間にして数百日分の時間経過を経るとNasty生成率と上昇階が最大の1/3で+25Fになり、相当刺激的なダンジョン探索が約束されるようになった訳である。
また、ゲーム開始直後に辺境の地などの生成階0F相当の地上でも、1/25の確率で+8Fの生成可能性が約束されたため、堀にピラニア(Level3)が泳いでいたり、時にはギリギリラグドゥフおじさん(Level8)が部下を引き連れて、辺境の地へ慰安旅行に赴く事態も、報告はまだ来てないがおそらく有り得るようになったのである。実装した当人として今は反芻している。
2013/02/26
■ [変愚蛮怒/スポイラー]酸による装備劣化処理とダメージ緩衝(変愚蛮怒 Ver2.1.2 rev3327)
http://jbbs.livedoor.jp/bbs/read.cgi/game/9358/1359868107/489-495より
489 :名@無@し:2013/02/25(月) 23:59:26 ID:??? 酸のブレスのダメージがwikiだとHPの1/3だけど実際は1/6しかない気がする 490 :名@無@し:2013/02/26(火) 00:03:11 ID:??? そんだけしか無かったら偉大なる不浄様が雑魚に成り下がる 491 :名@無@し:2013/02/26(火) 00:09:27 ID:??? 鎧にステンレスって銘つけてたことあるよw 492 :名@無@し:2013/02/26(火) 00:20:33 ID:??? 酸のブレスは防具を劣化させる時威力が落ちるとか何とか 493 :名@無@し:2013/02/26(火) 00:22:30 ID:??? またひとつ賢くなってしまった 494 :名@無@し:2013/02/26(火) 00:34:36 ID:??? 加速スレのパート50 487から494あたりでその話が出てるな 495 :名@無@し:2013/02/26(火) 00:43:31 ID:??? そんな仕様があったのか… 早とちりしてしまってごめんなさい
あれ、そうだったっけ?と思った俺はメンテナの屑なので、鑑になるためにちょっとソースを追う。
酸による装備の劣化はminus_ac()関数上で実装されている。これは酸属性のダメージ処理を行うacid_dam()でのみ呼び出され、劣化属性などでの劣化は別に実装されている。そしてこのminus_ac()がTRUEを返した場合に、
/* If any armor gets hit, defend the player */ if (minus_ac()) dam = (dam + 1) / 2;
コメントが正しく仕事をしてくれている通り、ダメージを切り上げで半減させることが判明した。いやあ、知らなんだ、あるいはD'ang開発中に多分気づいていたかもしれないが忘れていた。
minus_ac()の処理は以下の通りである。
- 右手/左手/体/体の上/腕/頭/足の7種いずれかの装備を対象にする。その枠に装備がなかった場合キャンセルでFALSEを返す。
- その装備が防具でない場合はキャンセルでFALSEを返す。
- ACが基本値+修正値で既に0以下になっていた場合はキャンセルでFALSEを返す。
- IGNORE_ACIDつきの装備の場合「しかし[装備名]には効果がなかった!」のメッセージを表示、キャンセルでTRUEを返す。
- 以上までのキャンセルがなければ、「[装備名]がダメージを受けた!」のメッセージを表示、AC修正値を1減らして、ステータスの再計算を行う(アンドロイドも強化値を再計算する)
- TRUEを返す。
あら、防具にひっかかったらとにかくダメージ半減するのか。なんてこった。右手に武器は大抵の職業で常識である以上、1/7の確率で酸ブレスは1600通るが、それでもいつも通りに耐性さえ確保していれば期待値自体はほぼ毒ブレス(最大800)より少し強い程度と見て問題ないようだ。
もちろん、そんなものあてにして、酸耐性を一重しか張ってない時に限って533ダメージが来るお約束であろうことは言うまでもあるまいが。
2013/02/27
■ [変愚蛮怒/スポイラー]apply_disenchant()による装備劣化処理(変愚蛮怒 Ver2.1.2 rev3327)
前回に引き続き装備劣化処理をチェック。今回は主に劣化属性攻撃などに使われているapply_disenchant()関数上での処理を追う。
apply_disenchant()は以下の処理の際に呼ばれる。
- 箱のトラップ「邪悪なルーン」の処理の一つ(引数:0)
- カオス魔法失敗時のペナルティ効果の一つ(引数:1)
- トランプ魔法「シャッフル」の「運命の輪」の効果の一つ(引数:1)
- 敵モンスターのUN_BONUS効果打撃(引数:0)
- 魔法の劣化属性攻撃(引数:0)
apply_disenchant()の処理の流れは以下の通りである。
- 右手、左手、射撃、体、体の上、頭部、腕、脚のいずれか一つの装備を標的にする。
- 対象の部位に装備がなければキャンセル。
- モンスターボールなどの一時的に手に持つタイプの発動アイテムは劣化せずキャンセル。
- 命中、ダメージ、AC修正値(非基本値)が既に全て0でなおかつ、pvalも最低の1ならば、劣化しようがないのでキャンセル。
- アーティファクトならば71%の確率で劣化を跳ね返しキャンセル。
- 命中、ダメージ、AC修正値をそれぞれ、1以上ならば必ず1減らす。
- さらに、この時点でまだ命中、ダメージ、AC修正値が6以上ならば、それぞれ20%の確率でさらに1減らす。
- 関数引数が0でかつ、pvalが1より大きいならば、1/13の確率でpvalを1減らす。
- 劣化した要素があったらメッセージを「(装備品)はは劣化してしまった!」を表示。
- 「調」の徳-1、「秘」の徳+2。
全く個人的な話だが、自分はバルログ魔道具術師で浅層で手に入れたリンギルの命中/ダメージを、別のキャラで手に入れたばかりのつらぬき丸をpvalまでアルベリヒに劣化させられたことがあった。訴訟不可避。
2013/02/28
■ [変愚蛮怒/スポイラー]その他の装備劣化処理(変愚蛮怒 Ver2.1.2 rev3327)
よくよく調べてみれば、装備の劣化処理は前々回/前回で述べたminus_ac()やapply_enchant()だけではなかった。明らかに同機能の多重実装の毛が強くて、イマイチ好きになれない事態だが、ともかくも他の劣化処理を検証してみる。
呪術領域の「武器呪縛」/「防具呪縛」失敗時の効果
両者は独立した関数でなく、それぞれ個別に実装されている。
- アーティファクトの場合1/3の確率で、祝福された武器であるならば必ず、武器は呪いを跳ね返す。
- その際1/3の確率でダメージ、命中、ACの各修正値がそれぞれ毎に2/3の確率で1減少する。ただし修正値が+0未満になることはない。
- 実際に劣化はなくても劣化処理に入った時点で「[武器名]は劣化してしまった」のメッセージは必ず表示する。
善良な領域を持ったプリーストのレイシャル「武器祝福」
- 呪いのかかったアイテムは必ず祝福に失敗するが劣化はしない。
- 祝福しようとした武器が祝福されていないアーティファクトか、エゴ武器であった場合は2/3の確率で祝福が失敗して以下の劣化処理に移行する。
- 武器の命中修正、ダメージ修正、AC修正がそれぞれ必ず1減少し、減らした時点でまだ修正値が+6より大きければ33/100の確率でさらに1減少する。ただし+0未満になることはない
- 劣化した場合のみ必ず「周囲が凡庸な雰囲気で満ちた...」「[武器名]劣化した!」のメッセージが入る。
一応それぞれ毎に微妙に劣化の仕様が異なり、深刻さにも微妙な差がついいているのは認めざるを得ないものの、やはり大同小異でしかない。とりあえずapply_enchant()に全部移してしまっていいのではないかとメンテナとして思う。
■ Karakuriya [ちょっと受けたぞ,褒めて使わす]
■ deskull [お、こりゃどうもwネタがネタだけに直接的な反応は無いと思ってました。]