スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スカイリム試作MOD rbAutoHarvest v0.7

近くの植物や死体から自動採集するMOD
(試作MODですので「動作確認に付き合ってやるかぁ」程度の感じでお願いします)

アップロード先:
Axfc UpLoader http://www1.axfc.net/uploader/File/so/77041.7z
4shared http://www.4shared.com/archive/mDcHdkVn/file.html

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
旧バージョンからバージョンアップして継続使用する場合には、必ず
「★本MODを削除する前、またはバージョンアップ前にクリーニングする手順」に
従った作業を行ってください! さもないと大変なことになるかもしれません。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

★更新履歴
v0.7
・今までループ処理をOnUpdate内でのスタック状態に近いぶん回し続け処理や
 RegisterForUpdateによる連続呼び出しにて行っていましたが、
 RegisterForSingleUpdateによる1回だけの呼び出しと
 処理終了後の次回RegisterForSingleUpdateの登録という方法へ変更しました
・上記仕様変更に伴い、
 「単一クエスト複数スクリプト」で行っていたマルチスレッド処理を
 「複数クエスト単一スクリプト」で行う方法へと変更しました
・各スクリプトで可能な限りの最適化を行いました
v0.6
・各種設定項目を大幅に増やしました
 (周辺の採集や死体からの回収をOffにすることも可能になりました)
v0.5
・OnUpdateイベントハンドラの中でループをぶん回し続けていると
 Papyrusが「これはスタック状態だ」と判定してしまうようなので、
 以前のようにOnUpdateを連続的に発生させて処理する方法に戻しました
v0.4
・設定ダイアログにおける「0/1」表示を「On/Off」表示に変更しました
・死体から回収した際のメッセージ簡易表示をOn/Off設定できるようにしました
・死体から「魂石」を回収できる設定を追加しました
・プレイヤーのアクティベートキーや視点切り替えキーや移動キーが
 無効化されている場合には自動採集を行わないようにしました
v0.3
・自動採集の指輪(試作)を装備した際、設定ウィンドウが表示されるようになりました
・死体からの回収でプレイヤー自身が対象にならないように対処しました
・Find処理を複数スクリプトの並列処理で行うようにアルゴリズムを改善しました
・メニューモード中には採集動作を保留するように仕様変更しました
v0.2
・初回起動時に自動採集の指輪が2個以上与えられてしまう不具合を修正
・周辺の死体からゴールドとロックピックを回収する機能を追加
 (共に重さが0で勝手に拾っても害にならないと判断しました)
 CK標準スクリプトでは「その品がクエストアイテムか?」を判定できない為、
 上記以外のアイテムを自動採集するのは危険な気がするので避けています
 OBSEなら「IsQuestItem」で一発判定できたのですが (´・ω・`)
v0.1
・とりあえず公開してみた
 
★概要
「自動採集の指輪(試作)」を装備すると、近くの植物や材料などを自動採集できます。
また、近くの死体からは指輪装備時に設定した種類のアイテムを自動回収できます。
※「自動採集の指輪(試作)」は装備品ですが、実際にはどのスロットも占有しません
※「自動採集の指輪(試作)」を装備してから自動採集が開始するまでに数秒かかります

★インストール方法
スカイリムのDataフォルダに
rbAutoHarvest.esp
rbAutoHarvest.bsa
を展開してください。
その後、rbAutoHarvest.espをアクティベート状態にしてください

★本MODを削除する前、またはバージョンアップ前にクリーニングする手順
1)「自動採集の指輪(試作)」を装備している場合は装備を外してからセーブする
2)rbAutoHarvest.espを非アクティベート化する
3)スカイリムのDataフォルダ以下に存在するファイル rbAutoHarvest*.* を全削除
 (.esp、.pex、.psc、.bsa、.txtなど該当するもの全て削除すること)
4)スカイリムを起動し、該当セーブデータをロードする
 (「このセーブデータに関連するデータが削除されています」と出るはず)
5)ロードが完了したら、特に何もせずにそのままセーブする
 (この時セーブしたデータがクリーニング済みのセーブデータとなります)
6)最新版のrbAutoHarvestを適切に導入してアクティベートする、
 もしくはrbAutoHarvestと永遠におさらばする

★採集や回収に対応しているもの
プレイヤー周辺にある以下の物を自動採集できます
 植物や材料の元
 ニルンルート
 魚や昆虫
 小銭入れ
プレイヤー周辺にある死体の所持品から以下のアイテムを自動回収できます
 ゴールド
 ロックピック
 矢
 回復薬(基本的な回復薬のみ、EditorIDの先頭がRestoreのもの)
 宝石
 魂石(アズラの星のようなクエストに関わる品は回収しません)

※MODで追加された新種アイテムに関しては自動採集に対応していません

★周辺の自動採集を行わない特別な条件(盗品回避)
・その品がプレイヤー以外の所有物である場合
・その品がプレイヤー未所属組織の所有物である場合
・そのセルがプレイヤー以外の所有物である場合
・そのセルがプレイヤー未所属組織の所有物である場合

★検索範囲について
範囲を広くすると採集済みオブジェクトが範囲内に複数存在する可能性が高くなる為、
採集対象物が密集する場所(畑など)で全て採集できるまでにかかる時間が増します。
(この動作仕様に関しては「仕様と不具合」に詳しく書いてあります)

★仕様と不具合:解決方法をご存じの方は是非教えてください(切実)
1)
その品がクエストアイテムなのかを判定する方法を教えてください (´・ω・`)
(OBSEならIsQuestItemで解決できるのですが…)
2)
その採集物が採集済みなのか?を調べる方法がわからないので、
(OBSEならIsHarvestedで解決できるのですが…)
すでに採集済みの採集物に対してもアクティベートを行ってしまいます。
何も起きないので、実質的な弊害があるわけではないのですが(多分!
3)
採集物が密集していると採集が遅かったり取りこぼしたりします。
バニラの標準スクリプトでは対象リファレンスを検索する際、
「範囲内の最寄りの1個だけ」か「範囲内のランダムで1個だけ」の
どちらかの方法でしか検索することができません。
(OBSEのGetFirstRef,GetNextRefであれば解決できるのですが…)
従って採集が遅い場合は「自分のランダム運が悪いんだっ」と
無理矢理納得するようにしてください。
4)
初回起動時に「自動採集の指輪(試作)」が2つ以上与えられてしまうバグ…
は直せました!検証してみた結果、OnInitイベントがまったく同じタイミングで
2スレッドから同時に呼ばれている?ような?奇妙な状態になっていました。
変数判定も各スレッドで同じ結果となってしまい判別が不可能、
プレイヤーの所持品判定も同じ結果になってしまい判別が不可能という
もはや私には理解できない領域の動作になっていました…。

★CKを使える方で採集対象物を自由に追加したい場合
※以下の改変を行った場合は動作の保証や不具合への対応はできません!
FormList→rbAutoHarvestListにセル周辺の採集対象物、
FormList→rbAutoHarvestListCorpseに死体から回収する基本対象物の
ベースオブジェクトを適当に追加してください。
ただし対象物が多くなればなるほど、指輪装備時の初期化や
実際の採集処理がどんどん遅くなっていきます。

★愚痴
1)
Find系関数もUtility.IsInMenuMode()関数もGame.IsXXXControlsEnabled()関数も
どれもこれもバニラのネイティブ関数は処理が遅すぎて大変です…。
MODを作成する際、バニラスクリプトのみで実現可能なことを模索するだけでなく、
その関数の遅さが実用に耐えられるかどうかも検証しなければならないのは、
スカイリムでMODを作る際の大きなハードルになっているような気がします (つД`;
2)
メッセージボックスの選択肢が横にずらっと並ぶのはやめて欲しい (´Д`;
オブリのように縦に並べてスッキリ表示して欲しい…。
オブリのようにメッセージ自体をそのままボタンとして押せるようにして欲しい…。

★謝辞
死体からの回収対象物が多くなりすぎると処理が遅すぎて実用不可能でしたが、
対象とするポーションの種類を絞り込むことで対処することができました。
掲示板にてアイディアをご提供くださったgadoさん、ありがとうございます。
死体からの回収対象物のベースIDをFormListからGetAtで1個1個取得していましたが、
RemoveItemの第一引数に直接FormListを渡せることを教えて頂きました。
掲示板にて教えてくださったGeneRichさん、ありがとうございます。
アクターの名前をメッセージとして表示する為にエイリアスを使用しました。
この概念および使い方はMadCompanionshipSpellsInSkyrimを参考にさせて頂きました。
ソース付きでMODを公開してくださった狂気太郎さん、ありがとうございます。
ぶん回しのループ処理に関するスカイリム流のやり方については、
掲示板にてtowawotさんからアドバイスを頂きました、ありがとうございます。

★その他
作者 : r_basilico
TwitterID : r_basilico
Blog : http://rbasilico.blog86.fc2.com/
スポンサーサイト

コメント

非公開コメント

No title

テキストエディタで作って、コマンドラインからコンパイルしてます

コメントありがとうございます

tyさん、コメントありがとうございます。

な、なんだってーーーーと思って調べてみたら、
ご丁寧にも参考用のbatファイルがあったんですね (゚∀゚; !!

秀丸マクロに組み込み、編集もコンパイルも秀丸でできるようになりました。
ものすっごい便利!情報ありがとうございました。

No title

ネクサスに似た自動収集がありますけど変な挙動とかして困ってた所この神MODを発見し使わせてもらってます!
収集が楽で大変快適です、skyrimは色々増えて良いんですけどやっぱりそのアイテムの近くに行って採取するのは面倒ですね

コメントありがとうございます

拙作MODを使って頂いてありがとうございます!
本当はもっと快適に採集できるようにしたかったのですが、
標準スクリプトでは実現が難しく、頓挫してしまい申し訳ありません (つД`;

将来的にSKSEの方でまともな処理速度の検索コマンドや
クエストアイテム判定コマンドなどが追加された際には、
リニューアルしたいと思っています。

便利すぎます

大変ありがたく使わせてもらってます
蝶やトンボを自動でむしってくれるのが非常にありがたいです
馬に乗っていても山の花をむしってくれるのもありがたいです

薬や宝石や矢などを収集してくれるVerも作ってくれるとさらに
ありがたいのですがw

クエストアイテムか判定できないため危険とありましたが、
自己責任で使います。セーブデータ破損しても泣きません

ぜひご一考ください

コメントありがとうございます

ドヴァ禁さん、拙作MODを使って頂いてありがとうございます m(_ _)m

採集タイミングの高速化が思うように出来ずに諦め状態でしたが、
「採集対象を増やして追加する」という内容であれば対応できそうです。

設定方法をどうするのか等を含めて検討してみますので、
しばらくお待ち下さいませ~!

ありがとうございます!

まさか検討してもらえるとは・・・
じっくり待ち続けますので、よろしくお願いします!

使わせて頂きました

採集楽しいけれど、いちいち自分で取るのは面倒だなーって思っていたので、早速頂きました!
おまけに死体からまで!とっても便利で助かってます。

ただ、私も死体からだけでいいので宝石なども自動採集出来たらいいな、と思いました。
なので、勝手ながら、死体から採集するアイテムリストに宝石、矢、ソウルジェム、基本的なポーション類を
追加して使用させて頂いております。

余り多くすると処理で遅延したりするかな?と思いましたが、今のところは問題なく動作しております。

コメントありがとうございます

gadoさん、MODを使ってくださってありがとうございます。

ドヴァ禁さんにもご要望を頂いた件ですが、週末にいろいろと実験してみた所
「フィールドに落ちている」対象物の収集に関しては無理でした…

その辺に落ちている矢を自動的に拾う機能は自分自身も欲しい機能だったのですが
矢(Projectile)はスクリプトからアクティベートすることが出来ないという
どうしようもない仕様が判明したので、完全にお手上げです(´Д`;

落ちている宝石を自動採集する機能も実験してみたのですが、
コンソールから行う「Activate」と、スクリプトで行う「Activate」では
同じコマンド・同じ引数を使っても動作の結果が異なるという謎の状況で、
コンソールであれば正しく動作するが、スクリプトだと正常に動作しない為
残念ながらこちらもどうしようも出来ずにお手上げとなりました…

そんなこんなで、現実的なのは今回gadoさんからもコメントを頂いた
「死体からの」対象物の収集だけになりそうです。う~ん、不本意です (´;ω;`)

(´・ω・`)

バニラのポーション(含む毒)は全部で265個ほどありますが、
FormListから265要素をひとつずつGetAtで取得していくだけでも
2秒以上かかるのですが… (つД`;

何をやっても「スクリプト処理の遅さ」という壁にぶち当たってしまうのですが、
gadoさんはどのくらいの要素を追加しても処理が重くならずに普通に使えていますか?

FormListに設定する要素数

私が追加させて頂いたのは、本当に基本的なポーションのみで
RestoreHealth01 ~ 06
RestoreMagicka01 ~ 06
RestoreStamina01 ~ 06
CureDisease
の19種類です。

目的が死体からの取得であるため、雑魚NPCが持っている可能性が高いもののみ追加しています。
実はまだあんまりSkyrimをやり込んでいないため、序盤をやっていて必要性を感じたもののみです。

NPCが持たないようなものについては、そもそも設定の必要が無いと思います。
また、名前有りのNPCしか持っていないような物については、私の場合は自分で漁りに行くため、追加しないでいいかな、と。
あくまで私の場合なので、それも必要だという方もいると思いますが。
「NPCが持つ可能性のあるポーションがどれか」をちゃんと調べて、それを全て設定するのが
処理速度さえ許せば一番いいのだと思いますが、とりあえずは上記のものだけでいいかな・・・と。

他の矢や宝石など含め、rbAutoHarvestCorpseItemListに設定しているのは、全部で50種程度です。
個人的な物なので、とりあえず基本的なものだけ入れて、あとは必要に感じたものを随時追加していけばいく、という感じです。
公開するものだと、取捨選択が難しそうですね・・・。
使う側で簡単に設定できる仕組みとか出来ればいいのかもしれませんが。

スクロールとかも出来たらいいなーと思っていましたが、お話を聞く限り、処理速度的に無理そうですね・・・。

長々と失礼しました(´・ω・`)

No title

長文失礼いたします。

平素よりrbAutoHarvestMod利用させて頂いています。
貧乏症の私にとって、非常に嬉しいMODです。
ソースも付属していたので、とても参考になります。

私自身コーディングについて全くなのですが、
色々調べていた所スクリプト処理について気になる点があったので、
参考になればと思い書き込ませて頂いた次第です。

内容ですが、他のMODを見た時に「List参照後にRevert()」をしてロック(?)を解放している様に見えました。

実際にrbAutoHarvestを以下の様にした所、気持速くなった様な気がします(気のせいだったらすいません)
※ただし、畑の中とかはやっぱり遅い様な気がします…。

/*一部抜粋*/
Harvest( Game.FindClosestReferenceOfAnyTypeInListFromRef( HarvestList, Game.GetPlayer(), HarvestDistance ) );
+ HarvestList.Revert();

Harvest( Game.FindRandomReferenceOfAnyTypeInListFromRef( HarvestList, Game.GetPlayer(), HarvestDistance ) );
+ HarvestList.Revert();
/*ここまで*/

HarvestCorpseItem はどこに挟めばいいかわからなかったので、endFunction の前に入れてみました。

以上、参考になれば幸いです。

追:projectileも拾えるかと色々検索してみます。(前述通り貧乏症なので矢も拾いたくなってしまう…。)

コメントありがとうございます

gadoさん、お返事ありがとうございます。

なるほど、19種類ということは265種類に比べれば14倍ほど速くなる…はずですね!
次回リリースはgadoさんの設定なさっている種類のポーションに限定してみようと思うのですが、
真似しちゃってよろしいでしょうか?
矢の場合は種類が少ないので全種入れても問題なさそうなんですけどね~。
う~ん…。しかしどちらにしろ、対象物を増やせば増やすほど
便利になるけど遅くて使い物にならなくなるという、厳しすぎるジレンマ(´Д`;


Ryuさん、コメントおよび情報ありがとうございます m(_ _)m

FormListのRevert()に関しては、スクリプトからAddFormしたものを取り除いて
CSで作ったFormList初期状態に戻す関数のはずなので、
ロック解放?や処理速度の向上と関係あるのかはちょっと判断できないです…。
現在改変作業中の最新版では、取得したいアイテム種類の設定を変えた時に
Revert()で初期状態に戻してから追加するというRevert関数本来の使い方をしているので、
FormList参照後に毎回Revert()する…という使用はできない作りになっております (´・ω・`)

Projectileに関しては検証の時に判明している内容を以下に書いておきますね。
Find系の関数は戻り値がObjectReferenceなのにProjectileを拾えてしまいます。
(ProjectileはObjectReferenceを継承していないのでキャスト不可能にもかかわらず)
で、この戻ってきたProjectileのリファレンスに対して
(無理矢理ObjectReferenceの)Activate()メソッドを呼び出してみると、
なぜかちゃんとアクティベートを行ったことになり、拾えてしまいます。
ただしProjectileクラスにはActivateメソッドは存在しないので、
実行時のPapyrusログには「Error」とはっきり表示されています (´Д`;
また上記とは別の仕様上の問題として、
プレイヤーやNPCが普通に発射した矢=Projectileですから、
プレイヤーが発射した瞬間の矢を自動的に(手づかみのように)回収してしまいます。
タイミングが合えば、敵が撃って飛んできている矢も回収できると思いますw
先述のエラーと、後述の問題から、ちょっと実用にこぎ着けるのは難しいなぁと思っています。

う~ん、もしSKSEがスクリプト拡張コマンドを実装しても
バニラスクリプトと同じように遅い処理速度だったらスカイリムに絶望しちゃいそうです…

矢の収集に関して

初めまして、GeneRich(ジーンリッチ)と申します。
取得したいアイテムが盗品かどうか判断する方法を探してて、こちらのブログに辿り着きました。
なるほど、盗品かどうかは誰か(もしくはセルや組織)の所有物かどうかを判断すればいいわけですね。
大変参考になりました。

本日、たまたま矢の回収MODの作り方についてブログを更新していて、バジリコさんが取り組んでいる内容も似ていたのでコメントさせていただきました。
もしかしたら何か役に経つかもしれないので、URL貼らさせていただきます。

http://blog.generich-power.com/archives/1210

Projectile のアクティベートについて

すみません、気になってしまったので連投させていただきます。
基本的にワールドマップ上にある、アクティベート可能なものはObjectReferenceであると認識しております。
オブジェクト指向風にいうと、ProjectileがクラスでObjectReferenceがインスタンスの関係だと思ってます。
なので、マップ上に落ちているProjectileは実はObjectReferenceとして落ちているのでアクティベートできるのは、なんら不思議ではないと思います。
むしろ、ログにErrorと出てるのが不思議・・・。

自動収集対象

>次回リリースはgadoさんの設定なさっている種類のポーションに限定してみようと思うのですが、
>真似しちゃってよろしいでしょうか?
! 勿論ですっ。少しでも参考になったのであれば嬉しい限りです。

矢についても、少なくともNameが空の奴はゲーム内で見る機会は無いでしょうし、
boundArrowやCWArrowもたぶんNPCが持ってることは無いでしょうから、ある程度は絞れると思います。

No title

r_basilicoさん

返信を頂きありがとうございます。
こちらでもrevertを入れた場合と入れない場合で速度をきちんと検証し、結果変化なきことを確認いたしました。
誤った情報を書き込んでしまい大変申し訳ありませんでした。

(こちらの環境で色々(mod整理や改変、PCメンテなど)いじった後に拾うのが早くなっていたので、revertが関係している様に錯覚してしまいました。
確かにScriptReferenceにはr_basilicoさんのおっしゃる通りの記述があったことは事前に確認していたのでその時点で気付くべきでした。)

矢の収集についてr_basilicoさん、GeneRichさんお二方の情報を元に作成し、無事に回収することできました。
GeneRichさんの作成されたものを参考に作成してみましたが、r_basilicoさん情報の「Playerの矢を発射後すぐに回収してしまう動作」っぽい動きになりました。
うまい回避方法が思いつかなかったので1つ1つ座標をとって比較という簡易的なことで回避しました。

以上、色々とありがとうございました。

コメントありがとうございます

gadoさん、お返事ありがとうございます。
対象ポーションの絞り込みリスト、参考にさせて頂きますね。
死体から回収する矢(AMMO)に関してですが、Playableフラグが立っている=取得してもOK
だと思うので、それらだけを絞り込んだ結果「16種類」となりました。少な目でよかったですw

GeneRichさん、コメントありがとうございます。サイトも拝見させて頂きました。
クラスとインスタンスの関係についてですが… なるほど!!そういうことなのか (゚∀゚;
私は基本的な考え方として、アクターの「ActorBase」と「Actor」を参考にしていたので
 ・ActorBase(CSで設定したFormデータ) ※クラス
 ・Actor(ゲーム中に存在するObjectReference) ※インスタンス
これこそが標準だと思い込み、そう考えた場合「Projectile」は…
 ・ProjectileBase(CSで設定したFormデータ) ※なぜか存在しない
 ・Projectile(ゲーム中に存在するObjectReference) ※なぜかObjectReference継承ではない
こういう解釈で「なぜだ、おかしいぞぉぉ!」と悩んでいました (つД`;
ご助言ありがとうございます。危うく誤った解釈のまま行き詰まる所でした…

Ryuさん、コメントありがとうございます。
revert()に関しては検証までして頂いたんですね、感謝です (T_T)
あ、例のProjectileをFind系関数で拾ってきてObjectReferenceとして扱う件ですが、
Ryuさんの所でもPapyrusログにErrorは出力されずに普通に動いています?
座標を取得しているということは、Projectile対象のObjectReferenceを拾ってきて
GetPositionX()等で正常に座標を取得できているということですよね…

もしかして自分、やらかしちゃったのかな!? ((( ;゚Д゚)))
ProjectileをFind系関数で拾ってきてActivate()するとErrorログが出るという件に関しては
もう一度検証してみます、お騒がせしてすいません。

死体からのルート

死体のインベントリーから欲しいアイテム複数ルートする場合、
DeadActor.RemoveItem(WishItemFormList, 999999999, false, Game.GetPlayer())
このコードが最速だと思うので、これを基準に妥協点を見つければいいんではないでしょうか。
既知でしたゴメンナサイ。
(GetAt() でループ回してるって書いてあったもんで・・・)

Projectileの取得

特にエラーらしきものは出ていない様です。

不思議なことに、以前rbAutoHarvestに内包されている「rbAutoHarvestList」に自分でProjectileを追加した場合は取得できなかったのですが、
最近再度やったら取得できました。(以前~に関しては何かしら操作ミスをしていたのかもしれません。)
座標に関してはGeneRichさんのサンプルコード内で使われていたGetAngleX(),Y,Z を使いました。
値は返ってきたのでObjectReferenceは拾えて来てる様です。

しかし、着弾してから時間が経っている矢はProjectileでは拾えない様です。
これはこれで困りました…。
(AMMOでも拾えませんでした。←これはこれでよかったです。AMMOは自分が矢を落とすと何故か無限に拾い始めるので…)

コメントありがとうございます

GeneRichさん、コメントありがとうございます。
>DeadActor.RemoveItem(WishItemFormList, 999999999, false, Game.GetPlayer())
え… 第一引数Formに対してFormListを渡せるんですか!?
これって、FormListであるWishItemFormListの全内容(全Form)に対して
RemoveItemを繰り返す、ということになるのでしょうか。
ちょっと調べてみます、情報ありがとうございます。

Ryuさん、コメントありがとうございます。
エラーは出ずに普通にObjectReferenceとして扱えましたか。
となると、やっぱり自分のソースに問題があったんだと思います (つД`;
時間が経ったProjectileは拾えないんですか、それは気付きませんでした。
う~ん、相変わらず動作に謎が多いですね…。

それと「セルに落ちているAMMOを拾うと無限に拾い始める」件ですが、
実は私も同じ現象に陥っており、解決方法は見つかりませんでした。
いろいろ実験した結果、コンソールとスクリプトでは
同じActivateを呼んでも結果が違うような感じだったのですが、
Ryuさんの所ではいかがでしょうか。

スクリプトの場合はFind系関数で周辺のAMMOを検索して、見つかったら
ObjectReference.Activate( Game.GetPlayer(), false ) する
もしくは
ObjectReference.Activate( Game.GetPlayer(), true ) する
スクリプトの場合は上記どちらの処理でも結果は同じとなり、
一回目のアクティベートでAMMOの見た目は消えるものの、
何度でも無限に拾い続けてしまう。

コンソールの場合はセルに落としたAMMOをクリックして、
Activate Player 0 ←この場合はスクリプトの場合と同じく
一回目のアクティベートで見た目は消えるものの、
その後に同じコマンドを実行すると何度でも無限に拾えてしまう。
Activate Player 1 ←この場合は2度目以降は拾えなくなる(正常動作?)

上記のような感じでした (´・ω・`)

RemoveItem の件

RemoveItem の第一引数にFormListは渡せますよ^^
WikiマニュアルのRemoveItemの説明をよく読むと、Note の所に、
If you pass in a form list, it will remove aiCount of each item in the form list from the container. If there isn't aiCount of a particular item in the container, it will remove all of them.
って書いてあります。
ものすっごくわかりづらいですよねーー・・・。

AMMO

使い続けていた所、時間が経っても拾える場合と拾えない場合があるようです。

AMMOの件、情報ありがとうございます。
こちらでも、r_basilicoさんと同様にconsoleとscriptで動きが違う事を確認しました。

やはり全体を通して「謎が多い」ですね。

いろいろと

私の推測も多分に混じっているので、スルーしていただいても構わないのですが・・・
ワールドマップ上からAmmoを拾うのは危険だと思います。
というのも、CKのObject Window の Item ツリーの下の物は、そもそもインベントリー内で扱うものだからです。
例えば、ワールドマップ上に2本の矢が転がっているとすると、1本目の矢と2本目の矢は別物として識別できないといけないし、アクティベートできないといけないので Projectile と関連付いた ObjectReference 系のインスタンスとして転がっているわけです。
(物体にフォーカスした時に「Eキーで取得」とか表示されるのは全てObjectReference系のインスタンスと認識しています)
ところが、それを拾った瞬間、Ammo となってインベントリーに入るのです。
これは、インベントリー内では矢を一本一本識別する必要はなく、まとめてn本として扱えればいいわけですし、アクティベートする必要も無いからです。
その証拠に、OnItemAddedイベント内で受け取った矢に対して akForm as Ammo は変換できるが、 akForm as Projectile や Form as ObjectRefernce には変換できません。
つまり Find系メソッドに Projectile はOKだけど、AmmoはNGと言えると思います。
ワールドMAPから Ammo を Find できるというのが、そもそも謎ですが・・・
ひょっとして死体のインベントリーからのルートと混同してないでしょうか?

コメントありがとうございます

Ryuさん、コメントありがとうございます。
Activateの実験もしてくださってありがとうございます!
自分一人で検証をすると、勘違いや(これが多いw)環境固有の現象だったりすることもあるので
すごく助かります。んー、本当に謎が多いですね…。


GeneRichさん、コメントありがとうございます。
ほんとだ、説明が書いてある (´Д`;
form listが「FormList」のことだったとは… 機械翻訳任せのツケが!

あとAmmoの件に関してはどの辺のお話しなのかちょっとわからなかったのですが、
例えばセルに置いてある Ammo: EbonyArrow 000139BF を拾う場合、
Ammoである 000139BF 自体をアクティベートしているわけではなく、
「ベースオブジェクトが 000139BF の ObjectReference」をアクティベートしています。
Find系関数に渡すFormListの中にAmmoを含めた場合、そのAmmo自体が返ってくるわけではなく、
そのAmmoをベースとしている「ObjectReference」が返ってくるので、アクティベートできます。

OnItemAddedイベントに渡される引数ですが、例えばセルに置いてあるAmmoが
 ObjectReference: FF123456 ベースオブジェクトは Ammo: EbonyArrow 000139BF で10個セット
だった場合…
 Form akBaseItem = 139BF
 int aiItemCount = 10
 ObjectReference akItemReference = FF123456
 ObjectReference akSourceContainer = None
このakBaseItemはベースオブジェクトなので、as ObjectReferenceにキャストすることはできないです。

こちらの勘違いで、全然違う話をしていたら申し訳ないです (つД`;

頂きました

バージョンアップお疲れ様です。早速使用させて頂きましたっ。
以前のバージョンですと、MODを沢山入れた場合に採集速度の低下が気になっていたのですが、
今回のバージョンでは、採集速度がかなり改善致しました。

また、使用開始時に採集対象を選択出来るのはとても便利ですね。
これならもう少し選択対象を増やしてもいいかと思います。
他に軽くてNPCが持っていそうなものだと、指輪、ネックレス、魂石、スクロール、食品系(ワインとか)というところでしょうか。

No title

はじめまして
30分ほど使ってみた個人的な感想です

ここが便利
そこにあるのに気づいてなくても、偶然近くを通るだけで彩集できる
トンボやちょうちょ等うろちょろする対象に接近するだけで彩集できる
川に入れば魚も彩集できる
騎乗中でも彩集できる

ここが気になった(1点だけ
死体からルートした時に、「○種類のアイテムを確保しました(文面うろ覚えです)」
と一括りで表示されるので、何を何個拾ったのかわからない
各アイテムの名称ごとに順番に表示されたらいいなぁ
(取得対象のアイテム類だと、そんなに大量にログが出続ける状況もないだろうと思うので

と、プログラムやスクリプトが全くわからないのに生意気な事を言ってみます
[電柱]ω・`)チラッ

コメントありがとうございます

gadoさん、最新版を使って頂いてありがとうございます。
マルチスレッド化による処理速度改善の効果があったようで安心しました…。
採集対象の区分を増やすことに関しては、以前のポーションと同じように
例えば「指輪」という一区分を追加する場合でも
「バニラに存在する全ての指輪」を追加&チェックする必要が起きる都合上、
再び処理速度の問題が起きちゃうんですよね…。
Ringという文字が含まれるArmorはざっと150ありました (つД`; 多っ!
ソウルジェムは全種でも15ぐらいなので、
こちらは大きな処理速度低下にはならないような気がします。
なので「ソウルジェム」は次回更新にて追加してみようと思います。
今回も貴重なご意見をありがとうございます。

影技さん、拙作MODを使ってくださってありがとうございます。
騎乗中にも採集できてしまうのはちょっと気になっていたのですが、
便利ということで気に入って頂けるようでしたらこのままで行きます!w
メッセージの簡略化に関しては、過去バージョンと同じ動作で
「普通にアイテム追加のメッセージが表示される設定」を追加してみようと思います。
貴重なご意見をありがとうございます。

No title

指輪とネックレスについては、ポーションと同様の考え方で、基本的なもののみ追加というのはどうでしょう?
具体的には、IDが「Jewelry」で始まるものです。
それだけであれば指輪とネックレスが8種類ずつ、合計16種類で済みます。
宝石の延長線上、という感じですね。

ソウルジェムについても、IDが「SoulGem」で始まる物のみでいい気がします。
「Azura's Star」とか「The Black Star」とかを自動収集したいという需要はほとんど無いと思いますし・・・。

いっそReadmeとかに「CKを使って自分で収集物を編集する方法」とかの解説を載せるとかもアリかもしれません。

ver3

いつもありがたく使わせてもらっています。
最新版を導入させてもらってから発生する現象です。
矢・宝石・薬自動rooton。
英語版を日本語化し、固有名詞英語化しています。

左上にログが出るタイプの取得発生時に奇妙な現象が起きています。
①Gold
クエストの報酬でGoldが取得できる場合、または商人に対して投資をする場合。
Goldの取得に対してかなり遅延が発生します。投資の状況はすぐ反映されるのですが、500goldの支払いはかなり遅れます。
スキルトレーナーの支払いは通常通り発生します。

商人の在庫や資金、スキルトレーナーの拡張は手を入れていません。
クラフトmodは多数入れているので何とも言えませんが・・・。

②採掘
採掘時に鉱石・宝石の取得に遅延が起きます。
鉱石にアクティベートしても無反応だったり、採掘モーションが途中で解除されたり、取得に遅延が起きたりと様々です。
この状況が発生すると、自動採取が停止します。
少々困るのが採掘遅延が発生すると、採掘終了し先へ進むと、
時間差(数秒~1.2分?)で採掘していた鉱脈に引き戻されることがあります。
枯渇した鉱脈に対して採掘モーションが発生したりします。
フォロワーが戻ってくるのを見ると、PCのみ巻き戻り?が発生しているようです。

指輪の付け外しをすると設定ログが出ますが、2回目以降の設定変更を行おうとすると自動採取そのものがうまく働かなくなったりと少々不安定さを感じました。

長文で分かりにくい表現が多いと自分でも思いますが、今後の発展を期待しています。


コメントありがとうございます

gadoさん、コメントありがとうございます。
指輪は装備品なので、自動回収したいという場合は
エンチャントされていて高かったり自分が装備したくなるような品を
求める傾向が強いような気がするんですよね…。
「エンチャされていない基本的ないくつかの一般品だけ回収」だと
(装備品の場合に限っては)あまり意味がないんじゃないかな?と思っています。
ソウルジェムに関しては、すでに対応作業が完了しました。
当初よりクエストに関わる品は危険なので扱わないという方向性ですので、
「アズラの星」などは回収の対象にしていません。
CKを使って採集対象物をユーザーで自由に編集する方法ですが、
それを行うことにより処理速度が想定外にまで遅くなったり
何らかの編集ミスで正常に動作しなくなるリスクがあるので、
「編集した場合は動作保証できない」とした上で簡単な情報を追記してみようと思います。

mishelanさん、拙作MODを使ってくださってありがとうございます。
今回ご報告頂いた不具合に関してですが、
①は当方のセーブデータですぐに確認できる状態ではなかった為、検証できませんでした。
②はバニラモーションの場合でも、採掘が早くなる差し替えモーションの場合でも
今回ご連絡を頂いた不具合を再現させることはできず、正常に動作しました。
また「指輪の2回目以降の装備で採集が行われなくなる」という現象に関しましても、
こちらでは再現することができず、正常に採集が行われました。

mishelanさんと同じような不具合が起きている方、
または同じ状況でも不具合が起きていない方は、コメントにて教えて頂けませんでしょうか?
情報収集にご協力よろしくお願いします m(_ _)m

続き

r_basilico さん

返信ありがとうございます。
MOD制作やCK使用経験はなく、以下の記載について曖昧な表現になってしまい申し訳ありません。

左上にログが表示される動作について、遅延・もしくは処理待ち?が起きているように思えます。
採掘の取得について以前書きましたが、SoulTrapの処理についても同様のことが起きます。
Soul封入時には問題ないのですが、大きさに合うGemが無いときに遅延が起きています。
魂縛成功時には問題ないのですが、「魂の大きさに合うGemが見当たりません~」というログは
採掘遅延時や採取やrootを繰り返すとログの表示遅延が発生しているようです。
自動採取停止と以前書きましたが、時間経過やFTをすることにより、指輪脱着やクライアント再起動をしなくても再び動作を始めました。
以上のことから処理待ち?の可能性もあるのかなと感じています。
クリーンセーブをして再度ver3を導入しても状況は変わらず、ver2に戻すと全く動作しなくなります。
ニューゲームでは動作するようですが・・・。
①のGoldですが、100gpを賭けての殴り合いに関しても動作しないNPCが居ました。モーサルのベノアです。

18日にver3を導入後以上の現象が発生、ver2では問題なく動作していました。
前3日は別のMOD導入やアップデートをしていないとはいえ、当方DeadlyDragonやWarInSkyrim、ElysUncapper等の
バランス調整MODも導入しているため相性で不具合が出ている可能性も十分にあると考えます。
特にWISはプレイするにつれセーブデータに不具合も出る可能性があるようです。
上記MODを外してクリーンセーブして試してみても変化はありませんでした。

長文コメですが当方の環境の可能性も高いので、あまりお気になさらず、今後のMOD制作を期待しております。

コメントありがとうございます

mishelanさん、コメントありがとうございます。

連続処理の実装方法を以前のやり方に戻してみましたので、
v0.5を試して頂けませんでしょうか?

またバージョンアップの際には、ドキュメント内に記載してある手順で
旧バージョンのMODデータのクリーニングを行ってみてください。

お手数おかけしますが、よろしくお願いします。

No title

愛用してます。公開ありがとうございます。
取得範囲の半径があと3フィート伸びたら嬉しいです。
取得範囲変更オプションとかあってもいいかも。

No title

使わせていただいております。

勝手な意見ではありますが、出来れば植物の自動採取もON,OFFできるようにして頂けないでしょうか?

死体からのアイテム取得を主な目的として使って居まして、逆に現在は錬金をしていないため植物の採取はオフにできたら良いなと思っているのです。

AutoRooterというScriptDragonのasiを使っていたのですが、こちらはSDのdllの更新がどうにも遅く、Skyrimのバージョンアップごとに無効化されるという面がありまして>_<;

ご考慮頂けますようお願いいたしますm(_ _)m

コメントありがとうございます

おめがさん、こちらこそ拙作MODを使って頂いてありがとうございます。
検索範囲に関して、次バージョンから設定可能にしてみます。
ただ範囲を広くするとそれだけ採集済みのオブジェクトも範囲内に含まれる可能性が増え
採集の精度(?)が落ちると思います。
(野菜がたくさん植えてある畑の中だとなかなか全てを採集できなかったりする現象です)

Cosmoさん、拙作MODを使ってくださってありがとうございます。
確かにおっしゃる通りですね。
本MODは「周辺の植物を採集する」という形から生まれて、
後になって「死体からの回収」という機能が追加されたので、
なんとなく「周辺からの採集は絶対に使うもの」という思い込みが発生していました…。
次バージョンからはOn/Off可能にしますので、よろしくお願いします。

以下は独り言ですが、スカイリムのMODはバージョンアップ改変でいろいろな内容を
追加しただけ(削除はしていない)でも、正常に動作しなくなることが多々ありますね。
オブリではそういう現象は起きなかったのに…。
すごく面倒ですが、rbAutoHarvestに関しても旧バージョンを使っていた場合には
一度セーブデータのクリーニングを行ってMODに関するデータを除去しておかないと
正常に動作しない可能性が高いです (´Д`;

あとメッセージボックスの選択肢が横に並べられていくのが、すごく納得いかない(´Д`;
オブリの時は選択肢が縦に並べられていたのでスッキリしていたし、
表示したメッセージ内容をそのままボタンとして押せたのに…。
なぜスカイリムではこんなデザインになってしまったのだろう

ver5

ver5ですが、クリーンセーブ等を試してみても全く動かない状況ですね。
指輪を装備したときに設定メニューは出るのですが、採取・root共に働きません。
だいぶ古いデータ(ver2使用時)をver5入れた状態でロードすると自動採取は動きます。
設定メニューは文字化けしてますし、指輪脱着後は動かなくなりますが・・・。
「休息を感じた~」「100gpRemoved」等のupdate前の左上ログが残っているようなので、30分ほど放置してログを出し切って?も変わらず。

本日1.5導入の関係で問題が発生可能性も捨てきれませんが。
話題になっているENB系は導入したことがなく、テクスチャ関連はWATERとSkyrimHDのみです。
WATERとkillmove関係は外しましたが、update以降プチフリが発生するようになってしまいました。

正直クリーンインストールも試すべきだと感じていますが、名詞英語化パッチが最新stringsに対応していないようです。
後日ニューゲームから暫くプレイしてみようと思います。セーブに色々ゴミが発生してそうですしね。

No title

使わせてもらってます
v0.5→v0.6でほとんど拾えなくなりました。
時間がかなりかかります。
キャベツの上で10秒静止して待っても拾ってくれない時は拾ってくれないです。
ご報告まで。

No title

確かに0.5→0.6で処理が重くなってますね。
同じデータで歩きながら採れてた所が0.6では素通りしてしまいました。
せっかく捜索範囲が広げられると思ったんですが、そっと0.5に戻しました。

コメントありがとうございます

mishelanさん、コメントありがとうございます。
当方の環境(1.5パッチ適用済み)でニューゲームで試してみましたが、普通に動作しました。
環境によって併用しているMODとの相性が原因かもしれないので、
ちょっと私の方ではこれ以上対処はできなさそうです…。ごめんなさい m(_ _)m

ありがとうさん、おめがさん、コメントありがとうございます。
v0.6では処理族度に関係するような改変は行っていないんですけどね、なぜでしょう…。
スカイリムのスクリプトMODはいじればいじるほどうまくいかずに問題が山積していくので、
なんだかもう疲れてきました…(つД`;
オブリ+OBSEの恵まれていた環境が懐かしいです。

v0.5は4sharedに残してあるのでリンクを追記しておきます。

No title

今見たら0.6がある様なので0.5とは違うかも知れないのですが・・・

現状のonupdate()で処理をしつづけると重度のスタックが発生して
処理しない時が出てくると思うので(他のmodも遅くなるそうです)
処理方法の変更をしたほうが良いと思います。
フォーラムにその辺が纏められていたので紹介しようと思ったのですが
今見たらフォーラム模様替えしたみたいで何処か分からないので覚えてる範囲で書きだしてみます。

game.getplayer()等は同event内で多用しない。player=game.getplayer()等使う
ifは深く掘らない
無駄な変数を作らない可能ならevent/function内で処理をする
onupdateまわしはスタックの元なのでsingleupdateをつかって繋げる

event oninit()
registerforsingleupdate(1)
endevent

event onupdate()
fuss()
registerforsingleupdate(1)
endevent

確かこんな感じだったはず
Quest3個にして重ねないようにしながら回せって事でしょうかね

No title

追記
ただ個人的な感想ではif に && || 加えると目に見えて遅くなるので
どうしても同処理が必要な場合で深くすることで&&||を回避できるなら
積極的に使ったほうが良いと思ってます。

edit:
あと、単にesp外しただけではscript消えないからクリーンにしたいなら
このmodだと指輪を外すことで完全にupdate処理が消えるようにしたほうが良いって書いてありました

コメントありがとうございます

towawotさん、コメントありがとうございます。
具体的な内容のアドバイスが非常に参考になりました。

「無駄な変数を作らない」というのは、
propertyなどの静的記憶変数が増えるだけでも処理が遅くなるのでしょうか?
それとも特定スコープ内で一時変数を作ると処理が遅くなるということでしょうか。

以前検証したことがあるのですが、例えば…
 float data = GetData()
 bool flag = GetFlag()
 SampleFunction( data, flag )
こんな感じ↑で一時変数を使った処理を↓こうやってまとめると…
 SampleFunction( GetData(), GetFlag() )
無駄な変数が作られずに最適化されるような気がするのですが、
実際にコンパイルしたpexファイルをscriptdump.exeでデコンパイルすると…
 float ::temp00 = GetData() as float
 bool ::temp01 = GetFlag() as bool
 SampleFunction( ::temp00, ::temp01 )
こんな感じ↑のコードが出来上がっていて、
何の意味もないという結果になりました (つД`;

以前if文を減らして最適化をというアドバイスを頂いた時に検証してみたのですが、
 if ( bool型変数 )
 endif
こんな感じ↑の判定を1000回行った時の平均処理時間は約 0.000017秒だったので、
無理に最適化する意味はないと判断したんですよね~。
今回さらにif文の処理時間に関して検証したのですが、長文過ぎてここには書けなかったので
記事としてアップしてみます。

espを外しただけではスクリプトが消えないって本当ですか!?
そんな動作仕様では、一度導入したMODを外すことがあまりにも危険な行為になりますね…。
rbAutoHarvestの場合は「自動採集の指輪(試作)」を外すと
必ず UnRegisterForUpdate() が行われるようになっていますが、
MODを外す前に必ずそうするように注意書きした方がよさそうですね。

う~ん、スカイリムは些細なMODをひとつ作るのにも本当に大変ですね (つД`;

No title

>propertyなどの静的記憶変数が増えるだけでも処理が遅くなるのでしょうか?
>それとも特定スコープ内で一時変数を作ると処理が遅くなるということでしょうか。
前者です

>espを外しただけではスクリプトが消えないって本当ですか!?
ソース見つけたので読み返してみたら記憶違いがあったので訂正します。
espだけ消してもpexが残ってたら保持するって意味だったようです。
そら、そうよって思うんだけどdataにぶっ込んだ人なんかはpexがどれかサッパリだろうし
アナウンスは必要かもしれませんね。

以前自分のmodで外国人に使えない使えないって言われて詳しい説明も出来ずハマったことがあります
script名が同じ物が動いてるセーブデータだとそのまま動くのでとても分かりにくいです…

http://forums.bethsoft.com/topic/1359724-on-the-run-time-of-skyrims-papyrus-scripts/
Borgut1337はDeadly Combatの作者。詳しくはpdf読んでください。
自分英語は苦手なので間違ってることがあるかもしれませんので。

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

コメントありがとうございます

>2012-03-23 18:19さんへ

スクリプトが残り続ける件に関してですが… なるほど!!

オブリの場合、スクリプトは必ずどれかのesp/esmの中に内包されていたので、
そのesp/esmをディアクティベートするだけで消えてなくなっていましたが、
スカイリムの場合、esp/esmとスクリプト(pex)は完全に別物になってしまい、
場合によっては単一のpexファイルを複数のesp/esmから
参照している場合なんかも考えられますね…。

MOD削除時に全てのpexファイルも削除しなければならないのは面倒だと思うので、
複数のpexファイルは単一のbsaファイルにひとまとめにしておいて、
「MODを削除する際はespとbsaの両ファイルとも消せばOKです」
とした方が簡単に扱えそうですね。
更新したり管理するのが面倒になりますが…。

その他の情報もありがとうございます。
私は英文を見ていると意識が遠のいてしまう体質なもので(?)、
概要を教えて頂けるだけでも非常に助かっています。
しかし静的変数を増やすだけで動作が遅くなるってヒドイ (つД`;

コメントありがとうございます

>2012-03-23 23:02さんへ
4sharedは、アップロード後の反映が遅すぎる怪現象がしょっちゅう起きたり
ダウンロードするだけでもサインアップとログインが必要になったりで、
私の方でも別のアップローダーを探して移転すべきかなぁ…と悩んでいました。

今回教えて頂いたaxfcというアップローダーさんは
「小さいファイルは数年間保存が可能」とのことなので、
次回から試験的にそちらへアップロードさせて頂こうかと思っています。

あと私は、自分宛の英文メッセージを見ていると
何だかすごく怒られているような強迫観念を受けるので、
Nexusへアップロードする予定はありませんw

No title

こんばんわ
0.7を試してみたのですが自分の環境だと重度のstackのままでした。
普段 20kbとかのPapyrus.0.logが10000超えします。
event onupdate()
;
endevent
であったり、questをstopですぐに止めたりしたのですが
何故か指輪の装備の有無関係なく起こってます。
導入直後 questをself.stopで3個とも止めても起こってて理解不能です。

何が悪いのか検証しようと0.3まで遡ってみたのですが多少エラーの内容は変わるものの
stackは変わらずで0.2にしてやっとautohervestのstacエラーはなくなりました。
とりあえず動作はしてるのですがgame.pscのエラーが出てるみたいなのでfind関数でしょうか?

0.2は試しにQuestでのloopを辞めた物しか手元になかったので情報としては不良なのですが
中身は弄ってないので多分オリジナルと一緒だと思うのです…スミマセン

上の0.2と0.3の違いは
>・Find処理を複数スクリプトの並列処理で行うようにアルゴリズムを改善しました
>・メニューモード中には採集動作を保留するように仕様変更しました
並列処理がキツイのでしょうか?
解決までは出来ませんでしたが報告します。

長文失礼しました。

コメントありがとうございます

towawotさん、最新版を動作確認してくださってありがとうございます。

う~ん、うちの環境(ほぼバニラ)ではPapyrus.0.logにStack警告は出ないようになっており、
game.pscのエラーというのは今まで一度も見たことがないです…

過去にrbAutoHarvestを導入したセーブデータではなく、
ニューゲームで開始した場合でもrbAutoHarvestが原因のスクリプトエラーが出ますか?
あと、該当エラーのログ部分をコピペして見せて頂けると助かります。

ほんっとにスカイリムのMODは挙動が意味不明だ… (´Д`;

v0.7をしばらく使ってみて

v0.7を頂いて、しばらく使ってみていますが、とりあえず私の環境では特に問題は起きておりません。
採取速度も申し分無い程度に出ています。採取範囲はデフォルトのままです。

おかげで快適な冒険生活を送れておりますっヽ(´∀`)ノ

コメントありがとうございます

gadoさん、最新版を動作確認してくださってありがとうございます。

普通に動きましたか! よかった…
1人でMODを作って動作確認している限り、
もしかすると世界中で自分の環境でしか動かないMODになっている可能性もあるので、
「正常に動いた」というご報告をして頂けるのは本当に助かります。

もし何かおかしな点などありましたら教えてください~
また、ここをご覧の方で「普通に動いた」「正常に動作しないぞ!」などありましたら
お気軽にコメントして頂けますと助かります m(_ _)m

スタックの件

スタックや取りこぼしの件で気になったので・・・

PapyrusのAPIの中には、単体でスレッド処理されるものがあり、一見メソッドが処理を返してきてもバックエンドではまだ処理を続けているということがあります。
つい最近の現象で、自分の装備品のFormIDを一覧表示させるために以下のコードを書いたのですが、
(ある石碑をクリックすると着ている装備のFormIDを表示)

Event OnActivate(ObjectReference akActionRef)
Game.GetPlayer.Unequipall()
; この後プレイヤーのOnObjectUnequippedで
; 装備のFormを取得してFormListへAddForm
ShowDialogEquippedFormIDs() ; FormListの内容を表示する
EndEvent

これを実行すると、実際5つ装備しているのに、3つだけとか4つだけしか表示されない現象が発生します。
原因はUnequipall()がスレッドで起動するためで(ひょっとするとAddFormも)、処理がまだ途中でもメソッド自体は返ってきて、ShowDialogEquippedFormIDs()が実行されてしまうのです。

これを回避するには、
Game.GetPlayer.Unequipall()
Utility.Wait(1)
と、Wait()処理をいれてUnequipall()の処理が完全に終わるまで適当な時間待つことです。

たったこれだけのコードでも、数秒待たねばならないのに、rbAutoHarvest ではRegisterForSingleUpdateの間隔が0.001秒とかなり短く、一部のスレッドはまだ実行中なのに、一見処理が終わっているように見えるので、次のRegisterForSingleUpdateを実行してしまうという流れになっているような気がします。
環境によってスタックしたり、取りこぼしがおきたり、取得済みのアイテムがなぜか再取得されたりといった現象は(そんなようなことが書いてあったような気がした・・・)ここに原因があるんではないでしょうか?

処理速度の改善からは逆行する内容ですが・・・

コメントありがとうございます

GeneRichさん、コメントありがとうございます。

実は先日rbAutoHarvestに新しく追加した処理において
同じような現象に見舞われたので、私の意見も書いちゃいますね。

Game.GetPlayer.Unequipall() の処理が非同期で行われていて
全ての装備を解除していないのに次の処理へ進んでしまう…のではなくて、
装備を解除したことによって発生すべきイベント処理は別スレッドの担当なので
そのスレッドの処理が遅れているのが原因ではないでしょうか?

例えば、イベント処理を含めてシングルスレッド的に考えると…
(プレイヤーが「頭」と「体」だけに装備をしていると仮定した場合)

OnActivate開始
 Game.GetPlayer.Unequipall()実行
 →プレイヤーの頭の装備が外される
  →プレイヤーが頭の装備を外したというイベントが発生
   →プレイヤーが頭の装備を外したイベントの処理が実行される
 →プレイヤーの体の装備が外される
  →プレイヤーが体の装備を外したというイベントが発生
   →プレイヤーが体の装備を外したイベントの処理が実行される
 ShowDialogEquippedFormIDs()実行
OnActivate終了

こんな感じのイメージだと思いますが、実際のイベント処理は
別スレッド(この場合はPlayerにAddされているスクリプトのスレッド)
が処理しているはずなので…

*** スレッド1 ***(石碑にAddされているスクリプト)
OnActivate開始
 Game.GetPlayer.Unequipall()実行
 →プレイヤーの頭の装備が外される
  →プレイヤーが頭の装備を外したというイベントを登録する
   (実際の処理は別スレッドの担当なので後は知らんぷり)
 →プレイヤーの体の装備が外される
  →プレイヤーが体の装備を外したというイベントを登録する
   (実際の処理は別スレッドの担当なので後は知らんぷり)
 ShowDialogEquippedFormIDs()実行
OnActivate終了

*** スレッド2 ***(PlayerにAddされているスクリプト)
→イベントが登録されていないかをチェックする
 →イベントが発生していたらその処理を行う

(スレッド1・2は別々のタイミングで走っているので、
 スレッド2がイベント発生を検知して処理を行うタイミングは不定)
…と、私の考え方としてはこんな感じでした。

ただどちらにしても、発生した(登録された)イベントがいつ処理完了するのか、
もしくは処理完了したのかを調べる方法がないのが厳しいですよね…

こういう突っ込んだ内容の意見交換ができてありがたいです (つД`)

スレッドについて

すばやい長文の返信があったのでビックリしました^^;

なるほど、イベント部分が別スレッドねぇ・・・。
それであれば、ShowDialogEquippedFormIDs()実行結果であるFormIDの表示順が毎回違うのも納得です。

ただ、魔法を撃つ Spell.cast() - (イベント記述なし)なんかは、火炎魔法とかを実行すると、マジカが枯渇するまで撃ちっぱなしになるのに、cast メソッド自体はソッコーで処理を返してくるし(止める場合はInterruptCast()を使う)、Debug.Notification()はいわずもがな。
RemoveAllItems()なんかもちょっと怪しい動きをする時があったので、なんとなく値を返さないメソッドはIf 文等の条件で使われることはないので、スレッド処理してるんじゃないかなぁとまだちょっと疑ってます。

コメントありがとうございます

GeneRichさん、コメントありがとうございます。

おっしゃるとおり、関数によって
 (1) 実際の処理を行って、処理が完了してから返ってくるタイプ(同期型)
 (2) 実際の処理は行わず、処理の手続き登録だけをして返ってくるタイプ(非同期型)
の2パターンがありますね…

Debug.Notificationに関してはオブリのMessageやMessageBoxと同じで(2)だと思われ、
その関数自体は「メッセージ用のバッファに文章を追加登録しておくだけ」で、
実際にそのバッファを調べて画面に表示させているのは別(システム内部?)だと思います。

モーションやサウンドの再生も基本的には非同期型かと思われ、
「再生させるように手続きはするけど、あとは知らないよ」という非同期型が
 PlayAnimation - ObjectReference
 Play - Sound
「再生させて特定の状態になるまで待つよ」という同期型が
 PlayAnimationAndWait - ObjectReference
 PlayAndWait - Sound
こんな感じで明確に関数が分かれているものもありますね。

厄介なのは「その関数が同期型なのか非同期型なのかユーザーはわからない」ことですね…。
正しいソースでスクリプトを書いたのに処理の順番がおかしくなっていることに気付いて、
初めて「この関数は非同期処理なのか!?」と知る(もしくは推測する)という状況で(´Д`;

No title

ずっとver3をつかっていて更新しようとクリーニング手順に従い関連ファイルを削除すると
ベゼスタロゴ画面直後に落ちてしまう(メニューが画面に出る前)ようになりました。
元のファイルを入れると起動し、動作します。

単純にアップデートすると既存のセーブデータでは設定メニューの表示がおかしい上に設定できません。
ニューゲームだと正常に動作します。
当方の環境では同様の現象がAKM - Advanced KillMovesでも発生しています。
環境依存現象だと思いますがご報告まで。

#とりあえず再インストールまではVer3を使わせていただきます。とても便利です。

No title

一度skyrimのmodを整理していたので遅くなりました
新規から以前の環境に近づけて行くとエラーだらけに。
aaaうんたらはdrop torchの物です。
ますたーりすととろぐをあげました。
modの競合とかなんでしょうか。
正直rbautohervestは問題ない気がしてきました

http://www1.axfc.net/uploader/Sc/so/335464&key=skyrim

禁止ワード強すぎ><

No title

素材採取関係で死体の熊の爪、等はなんとか追加できたのですが
シャウラスの卵、ハチの巣、などの巣?を漁る系のアイテムが上手くいきませんでした
あれらは死体とは別もの扱いということでしょうか?

私の導入方法が間違っているだけだったらごめんなさい

もう手放せない

Oblivionで採集を自動化していたので,もう手で拾うのがだるいよぅ…と思っていたところこちらのModを知り早速ありがたく使わせて頂いております(-人-)
もうバジリコさんに頭が上がりません…!

コメントありがとうございます

すいません、スカイリムへの興味が薄れてしまった影響で
MOD作りやBlogの更新を放置状態にしちゃっていました (つД`;

SKSEがバージョン1.5台となり拡張コマンドの実装が行われたようなので
本MODもSKSE 1.5以降専用として作り直そうかとも思っているのですが、
基本的なスクリプト処理の動作が遅かったり、
MODの入れ外しで(オブリでは起きないような)異常状態になったりするという
スカイリム本体の根本的な問題は解決のしようがないので、
また何かをやったとしても徒労に終わるのかなぁ…なんて
ネガティブな気持ちもあったりで、なんだかよくわからない心境です。

とりあえずこんな試作MODを使ってくださった皆様、ありがとうございます!
不具合が起きた皆様、ごめんなさい!

(´・ω・`)

SKSE最新β版を使って拡張スクリプトコマンドの動作検証など行ってみましたが、
やはりスカイリム本体の基本スクリプトの動作が遅すぎるので、
普通の手段で実用的な処理速度のMODを作ることは困難でした (´Д`;

スカイリムのスクリプト処理速度をオブリ並みに高速化できる
SkyScriptBoostなんていう感じのソフトがあったら嬉しいのですがw

…ないですね (´Д`;

No title

ありがたく使わせていただきます
神MODですね
プロフィール

r_basilico

バジリコ風味 (r_basilico)
Twitter: r_basilico
Steam: r_basilico
艦これ: 嫁艦は祥鳳

リンク
最新記事
最新コメント
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。