C343-147をデバッグしてみる

  • ちょうどプレイヤーを解放した怪物が魔法の罠で魅了された場合、ゲームがpanicする

expels() → spoteffects() → dotrap() → domagictrap() → tamedog() で怪物がペット化されると、ペット情報を追加するために怪物のmonst構造体は新しく確保されたメモリ上にコピーされ、古いmonst構造体が入っていたメモリは廃棄される。expels() やそれを呼んだ関数がローカル変数で保持している怪物へのポインタは無効なメモリを指しているため、ゴミを読んでpanic。

vanilla ではどう直したのか不明ですが、これをちゃんと直すのは結構面倒くさそうです。monst構造体を動かさないようにするか、動かした先を指すようにポインタを上位の呼び出し元までさかのぼって更新する(全部参照渡しにする?)必要があります。

そんなめんどくさいことはやってられないので、spoteffects(), dotrap(), domagictrap() に引数を追加して魅了効果を選ばないようにする、という泥臭い回避策を入れてみました。

根本的には、やはりmonst構造体を極力動かさないようにする必要がありそうです。edog などの追加データを monst構造体のサイズを拡張して入れるのではなく、怪物の所持品同様、別に確保したメモリに入れてそのポインタを保持する形式に変更すればいいのですが…。