■ 1- 101- 201- 301- 401-
501- 601- 701- 801- 901- ■
ホムンクルスのAIを語るスレ その3
- 1 :(○口○*)さん :06/03/17 03:51
- ここはアルケミストのホムンクルスAIについて語るスレです。
■参考サイト
アルケミスレテンプレサイト
http://cgi.f31.aaacafe.ne.jp/~alchemi/pukiwiki.php?
RO未実装システム情報スレWiki
http://rofuture.s86.xrea.com/
LUA日本語リファレンス
ttp://www.uri.sakura.ne.jp/~cosmic/yuno/lab/lua5_manual_ja.html
LUAの参考書のオンライン版(英語)
ttp://www.lua.org/pil/
luaのFAQ
ttp://garage.sakura.ne.jp/yuno/html/lua5_faq_ja.html
luaユーザー会Wiki(英語)
ttp://lua-users.org/wiki/
lua日本語パッチ
ttp://www.water.sannet.ne.jp/sowwa/
2chプログラム技術板 プログラミング言語 Lua その2
http://pc8.2ch.net/test/read.cgi/tech/1063711237/
LuaEclipse(英語)
ttp://www.ideais.com.br/luaeclipse/
The Winter's Tale
ttp://www.sgv417.jp/~winter/
アルケミスト・クリエイター情報交換スレ第65巻
http://gemma.mmobbs.com/test/read.cgi/ragnarok/1142433555/
未実装システム情報スレ179
http://gemma.mmobbs.com/test/read.cgi/ragnarok/1142193624/
- 2 :(○口○*)さん :06/03/17 03:51
- >>1
乙〜
- 3 :(○口○*)さん :06/03/17 03:52
- これ忘れてる〜
ホムンクルスAIについての雑談・要望スレ
http://enif.mmobbs.com/test/read.cgi/livero/1142513331/
- 4 :(○口○*)さん :06/03/17 03:53
- >>1乙
テンプレに未実装スレはもういらんのでは無いかな?
ホムンクルスAIについての雑談・要望スレ
http://enif.mmobbs.com/test/read.cgi/livero/1142513331/
- 5 :(○口○*)さん :06/03/17 03:56
- わしゃ前スレ終了間際のテンプレコピペしただけだから知らんよ
モタモタしてるうちに誰かが「アルケミストのAI〜」でスレ立てしちまいそうだったから、
検分もせず焦ってそのまま立てた
- 6 :(○口○*)さん :06/03/17 03:56
- 被ったorz
ついでに前スレ
アルケミストのAIを語るスレ その2
http://enif.mmobbs.com/test/read.cgi/livero/1140506800/
- 7 :(○口○*)さん :06/03/17 04:01
- 不備ばからで申し訳ないでうs
飲みながらじゃダメだね。ごめんです。
あーホムが目の前ぐるぐるまわるー
そして>>1乙でしたありがとう
そして寝ます
- 8 :823 :06/03/17 04:10
- >>1
乙です!初心者レベルのプログラム知識しかないけどがんばるぞ〜
- 9 :(○口○*)さん :06/03/17 04:25
- >>1乙乙。
むかーし、BASICを雑誌のプログラム写したりちょこっと書き換えたりして段々覚えていったように
今回も既存のAIをいじくってったらだんだん分かってきた。
分からないって言ってる人はエラー10回出せば1回成功する、てぐらいの気持ちで頑張るんだー。
更に>>9ゲトズサー
- 10 :(○口○*)さん :06/03/17 04:31
- 昔Cをかじっただけの俺が10ゲトー
- 11 :(○口○*)さん :06/03/17 04:54
- デフォルトのAIの見難いtabの書き方に怒りを覚えた俺が11get
- 12 :(○口○*)さん :06/03/17 05:04
- 寝落ち対策に、前スレ972の人のを使わせて頂きましたが、
上手に動かせませんでした。
EXIT_TIME=60にして試しました。
1回目は問題無く安息を使用しましたが、
そのままコールして2回目を試すとスキル使用の間隔が長くなり、
3回目は使わなくなりました。
AI.luaの1番末尾にコピペして、
メイン処理のところにExitEvent()と書いただけなのですが、
それだけでは足りない事ってありますでしょうか?
- 13 :(○口○*)さん :06/03/17 05:17
- ALT+右クリックで移動先を指定して移動が終わったあとにホムがOwnerのところへ戻ってくるのが嫌な人向け
隣のセルに置いておきたいとか整列とか落ち着きが欲しいとか
function OnMOVE_CMD_ST () の
MyState = IDLE_ST
を
MyState = FOLLOW_CMD_ST
に変更
function OnFOLLOW_CMD_ST () を
function OnFOLLOW_CMD_ST ()
return
end
に変更
Ownerの近くへ戻すにはALT+Tで戻ってくると思う
- 14 :11=13 :06/03/17 05:19
- 12の人とID一緒・・( ゚д゚)?!
- 15 :(○口○*)さん :06/03/17 05:21
- デフォルトAIをずーっと眺めて
ようやく処理の流れがつかめてきた。
- 16 :(○口○*)さん :06/03/17 05:35
- アクティブと非アクティブをショートカット等で切り替え出来ませんでしょうか?
非アクティブ時にターゲティングする時、ALT+クリック+ALT+クリックの2度手間も何とかなりませんか…
>>13
それ欲しかったんです!ありがとうございます!
- 17 :(○口○*)さん :06/03/17 05:45
- >アクティブと非アクティブをショートカット等で切り替え出来ませんでしょうか?
いくつかのサイト見た感じでは簡易実装はできると思う
ただし
現状ではテレポ、再コールやマップ移動で
設定がデフォルトに戻ってしまうものになる
- 18 :1 :06/03/17 06:00
- ようやく前スレを最後まで読み終えた。
…スレタイ直さない方よかったのか?
- 19 :(○口○*)さん :06/03/17 06:02
- スレタイはこっちで良いと思う
些細な違いだけどこっちの方が突っ込まれにくいしな
- 20 :(○口○*)さん :06/03/17 06:14
- 乱戦時を考えると自動PPは凄く欲しい…
しかしそれってBOT寸前な罠。
- 21 :(○口○*)さん :06/03/17 06:24
- >>16
alt+Tの待機・休息のチェンジを利用すればいいんじゃ無いかな
デフォルトのスライム&鳥アクティブでも、alt+Tで休息にすれば殴らなくなる
それより、ケミが座ってるとホムがスキル使わない原因はケミとホムの区別ついてないからかよw
自動で宝剣ボルトやヒールするINTケミとか出そうだな
スキルしか使えないようだから、餌の問題で永久稼動は不可能だが
それと、Gv時に特定プレイヤーに自動アシデモとか(しかもクロキン無視w)、そういう使い方もされそう
- 22 :(○口○*)さん :06/03/17 06:30
- ボットニュース早すぎw
- 23 :(○口○*)さん :06/03/17 06:35
- 前スレの940のコードを使おうと思ったのですが、Settingsがどーのとエラーが出てよく分からなくなりました・・・
何か宣言とかしないとはいけないと思うのですが、宣言の方法がいまいち分かりません。
DifferentialCountの方でもエラーが出たのですが、こちらの方はglobal variableのトコにDifferentialCount=0としてみたらエラー出なくなりました。
この対処法でいいのか不安があるのですが、大丈夫でしょうか。
ご教授お願いします・・・orz
- 24 :(○口○*)さん :06/03/17 06:36
- >>22
他人のスキルは制御できないとかホムにヒールかけても結局回復しないとか
肝心な部分はあえて載せてないんだろうな、相変わらずというか何というか
- 25 :(○口○*)さん :06/03/17 06:38
- >>22
うはw
すごい早さだな
これでTSメマーが合法で出来るようになるんかね
ためにしコード書いてみていい?
- 26 :(○口○*)さん :06/03/17 06:43
- マスゴミと一緒だな。
都合のいいところだけ拡大して報道する。
まあそれはおいといて
スキル自動使用のAI貰って使ってみたんだが
視界内にMobいなくなったときにホムが高確率でその場に固まるんだ。
traceAIによるとずっとスキル使おうとしてるらしい。
この辺何とかできんものかね…
- 27 :(○口○*)さん :06/03/17 06:51
- >>26
アクティブ設定にしてると固まってALT+T押すと戻ってくるやつ?
それならケミの近くにいるMobしか攻撃しないってルーチン追加したら固まらないようにはなったけど
- 28 :(○口○*)さん :06/03/17 06:55
- >>25
成功すると対人で威力発揮しちゃいそうなのは微妙なんで
せめて連続製薬あたりに…
- 29 :(○口○*)さん :06/03/17 06:57
- function OnSKILL_OBJECT_CMD (level,skill,id)
TraceAI ("OnSKILL_OBJECT_CMD")
if (level == 1 and skill == 8009) then --Lv1ムーンライトが使われたら
local enemy = 0
local loop = 0
while (loop == 0) do
enemy = GetActor()
for i,v in ipiars(enemy) do --敵が周囲から見つからなくなったらループ脱出
if (v == id) then
loop = 1
break
end
end
SkillObject(MyID,1,(メマー),MyID) --メマー撃つ
end
return
end
end
即興で作ったが、これでメマー連射可能か?
- 30 :(○口○*)さん :06/03/17 06:57
- >>23
Settingは工体研究所さんのconfig.luaを参考に
DifferentialCountはそれでいい
個人的には使う
function OnFOLLOW_ST ()の上辺りで
- 31 :(○口○*)さん :06/03/17 07:02
- あ”、これじゃダメだな
SkillObject(MyID,1,(メマー),MyID) --メマー撃つ
じゃなくて
SkillObject(MyID,1,(メマー),id) --メマー撃つ
だね
>>28
製薬はスキル使用以外の操作が必要だから、この発見じゃ無理だと思う
- 32 :(○口○*)さん :06/03/17 07:19
- アシッドデモンストレーションも連射できるのか?
- 33 :(○口○*)さん :06/03/17 07:22
- >>32
メマーが可能ならそっちもできると思うけど、金掛かりそうだなぁ…
- 34 :(○口○*)さん :06/03/17 07:25
- >>30
ありがとうございます、早速工体研究所さんのところに行って見てきました。
試行錯誤の結果、ちゃんと動くようになりました。ホントにありがとうございます。(ノ-`)
- 35 :(○口○*)さん :06/03/17 07:25
- >>33
詠唱とスキルディレイがあるからTSのように連射はできないと思う
あと、コード書いといてなんだが、実験してないのでほんとにTSメマーできるかわからん
- 36 :(○口○*)さん :06/03/17 07:33
- BOTNEWSどうしようもねえな
自力でプログラム組める香具師は全員BOTer扱いかよ
- 37 :(○口○*)さん :06/03/17 07:38
- なんにせよ、このアホな穴を塞いで欲しい
ケミが座ったままでホムがスキル使ってくれるようになれば嬉しいし
- 38 :(○口○*)さん :06/03/17 07:41
- IDとか普通わかんなくね?
- 39 :(○口○*)さん :06/03/17 07:49
- 前スレの823です
前スレ996氏の発言をヒントに、いろいろ試した結果、
攻撃行動をキャンセルして逃げられるように修正しました
先行型のMob取得方法を流用して逃げるようにしているので、
ATTACK_STのみでの処理だとホムがMobに近寄ってしまうため
CHASE_STでも処理をするようにしホムの挙動不審を抑えてみました
無駄な記述がまだある気がするので
HPで公開するのは当分先にすることにしてこのスレで先行発表を
ttp://www.uzukisyou.nobody.jp/AI2.html
もっとスマートな書き方があるのかもしれませんが
私のスキルでは軽量化まで手が回りません(ノ∀`)
この修正だけで7回くらいエラー落ち…
さぁ次は草やキノコを無視するスクリプトだ
FD1|λ…
HP減った状態で広い場所でアクティブMobにたげられると
ホムがあたふたと逃げ回って可愛い(*´ω`)
- 40 :(○口○*)さん :06/03/17 08:13
- >>36
最近ネタ無いから困ってるんじゃないの?
- 41 :(○口○*)さん :06/03/17 08:15
- 追記:
前スレの864−865氏と996氏に感謝!
- 42 :(○口○*)さん :06/03/17 09:35
- リーフの治癒の手ってNPCやワープポイントにも使えるんだな、おもしれぇ
赤スリム(というかサボテンの針)がなかなか手に入らなくて、手軽に街中で連打できないのが残念
- 43 :(○口○*)さん :06/03/17 09:46
- >>13
デフォルトのAI使って変更したところ 543のendが引っかかりますた(´・ω・)
- 44 :(○口○*)さん :06/03/17 10:15
- 公式AIのOnHOLD_CMD_STの
local d = GetDistance(MyEnemy,MyID)
ってところ、正しくはGetDistance2だな
もともと呼ばれる事のない関数だからどうでもいいけどね
- 45 :(○口○*)さん :06/03/17 10:20
- んで>>13の機能だけど
>>44を修正した後にOnMOVE_CMD_STを
- MyState = IDLE_ST
+ ProcessCommand( { HOLD_CMD } )
の一行を差し替えでいけるっぽい
- 46 :(○口○*)さん :06/03/17 10:44
- 流れぶった切って質問だが許して
工体研究所さんの最新版つかわせてもらってるんですが
ここに、HP,SPが回復したら
ケミの周りをうろちょろする設定だけ追加しようと思ったら
どこをいじったらよいでつか・・・?
いままで0-MATERIALさんのに、スレからコピペ追加で使ってたんだが
どうも調子が悪いようなので変えたんだが・・・
よければ教えていただけるとチョーうれしい。
- 47 :(○口○*)さん :06/03/17 10:56
- ホムの移動速度をわざと遅くすることってできます?
一歩歩くごとに間をおくのが精一杯かな。でもこれだと尺取虫みたいだし・・・
むー。
- 48 :(○口○*)さん :06/03/17 11:11
- >>47
PC未完成で鈍足なケミなら可能かもしれない。
カートを引く→リログ→カートを外す
うちのケミはPC10だから試せないので検証頼む
- 49 :(○口○*)さん :06/03/17 11:35
- 次スレは
アルケミストのAIを語るスレ
でヨロ
- 50 :(○口○*)さん :06/03/17 11:35
- >>39
前スレ645のTarget_Chack()を攻撃時に適用しる。
って遅かったかなぁ。
- 51 :(○口○*)さん :06/03/17 11:40
- つうかSkillObjectは普通にクライアントに対してスキルを使用するように命令を出すだけで、
スキルディレイやなんかは無視できんよ。心配しなくて良い。
もう1つ、もっと危惧してる事はあるが…
リザホム5取った身としては赤ポPPより死なせてリザの方が安いし自動PPはお蔵入り(´・ω・)
- 52 :(○口○*)さん :06/03/17 11:55
- >>ケミのスキルまで使えてしまう件について
SkillObject関数がSkillLVとして渡された引数が
8009〜8013で無ければスキルを実行しないとかにすれば一発で修正できるよーな。
早ければさくっと修正きてくれないかなぁ。
- 53 :(○口○*)さん :06/03/17 11:56
- >>51
思いつきだけど、ホムが自分の死を予想してリザホムを自動化できたりして。
- 54 :(○口○*)さん :06/03/17 12:00
- >>53
GetTickとGetV(GetHP,id)の併用で、秒間ダメージは計測出来るから
「リザホムの詠唱時間以内に、死ぬ事が予測出来たら」使わせれば良いのかね。
回避率なんかも考えると、確実性が無いけど。
- 55 :(○口○*)さん :06/03/17 12:02
- なんつーか、このスレの住人の活躍次第でホムにゴーストが宿るほどのAIが生まれたらROは伝説になるな
(スマン冗談でも言ってみたかった。
「ご主人様は死んではいけない・・」(囲まれたときに勝手に位置入れ替え&PPのあとホムはモブを引き連れてPCから離れる、そして・・・)
XXXXXXXぅーーー(ホムの名前をどうぞ)
「またあとでね。」(瀕死のホムせりふ)(そりゃホムリザするけどさこんなことされたらどうよ)
- 56 :(○口○*)さん :06/03/17 12:03
- 死亡状態は判定できるんだっけか?
もしできるなら自動リザホムできるなw
ホム死亡後、周囲数マスにMobがいない時リザホム発動、とかw
- 57 :(○口○*)さん :06/03/17 12:05
- >>56
ああ、そういやそうだった…
MOTION_DEADが有ったっけな。
問題になるとすれば、「ホムが死亡状態でも、AIの活動は有効化」ってくらいか。
これは検証が必要な項目の一つだね。
死亡状態になってすぐ、死体は消えてしまうし。
死亡時グラフィックが出た時点で、AIコード実行は終了するのか
死体が消えるまで、時間の猶予があるのか。
- 58 :(○口○*)さん :06/03/17 12:07
- 5行目訂正。
×有効化
○有効か
- 59 :(○口○*)さん :06/03/17 12:09
- まあ一応死亡予測->リザホムも現状できてしまうんだけど
アルケミのスキル挙動までAIに書くのはあまりエレガントではないだろう。
あくまでホムAIはホムの挙動だけに完結するべきだと思うよ。
修正されたときに主人が無能化しかねないしな、某キッチンタイマーみたいに。
>>55みたいなのも作れなくは無いはず。
問題は「誰が実装するか」と「ホムしゃべらねえよ」の二点。
- 60 :(○口○*)さん :06/03/17 12:13
- というか、リザは詠唱もあるし自動にするより手動でやった方が良い。
なんでもかんでも自動にするべきじゃないって奴の典型だな。
スレ的には自動にするべきだがw
- 61 :(○口○*)さん :06/03/17 12:23
- 正直、○分間何もしなかったら安息とかは欲しい…
- 62 :(○口○*)さん :06/03/17 12:23
- 生成されてから10秒間は先行型も非先行型と同じ挙動を取らせてみた
-------------------------------------------
-- 攻撃モード選択 0:先行 1:非先行
MyEnemy_Type = 0
Generation_Time = GetTick() -- ホムが生成された時刻
-------------------------------------------
function GetMyEnemy (myid)
local result = 0
if (MyEnemy_Type == 1) then -- 非先行型だと判断できた場合
result = GetMyEnemyA (myid) -- 非先行型
elseif (MyEnemy_Type == 0) then -- 先行型だと判断できた場合
if(Generation_Time + 10000 < GetTick()) then -- 先行型でも最初の10秒は非先行型と同じ処理
result = GetMyEnemyB (myid) -- 先行型
else
result = GetMyEnemyA (myid)
end
end
return result
end
コールホムしてからいきなり殴りに行くことだけはない。
- 63 :(○口○*)さん :06/03/17 12:25
- >>55
http://enif.mmobbs.com/test/read.cgi/livero/1140798477/25
- 64 :(○口○*)さん :06/03/17 12:27
- >>61
放置しつつ親密度上げるときにそれだとちょっと困る
切り替えれば問題ないけど
- 65 :547 :06/03/17 12:32
- >>前スレ964さん
仕様上1秒間に何度もループする為、アクセスが増えるみたいです(たぶん)
940さんのように時間で制限するか、951さんのように
回数で制限すると良いと思います。
940さんのをパクってみました。
-- global variableに追加
Move_Scan = 500 --ケミ座標取得間隔(ミリ秒)
Move_Timer1 = 0
Move_Timer2 = 0
if (GetDistanceFromOwner(MyID) <= 3) then -- DESTINATION_ARRIVED_IN
if(GetV(V_MOTION,GetV(V_OWNER,MyID)) ~= MOTION_MOVE) then
MoveToOwner(MyID)
end
Move_Timer1 = 0
Move_Timer2 = 0
MyState = IDLE_ST
TraceAI ("FOLLOW_ST -> IDLW_ST")
return;
elseif (GetV(V_MOTION,MyID) == MOTION_STAND or GetV(V_MOTION,MyID) == MOTION_MOVE) then
Move_Timer1 = GetTick()
if(Move_Timer1 - Move_Timer2 > Move_Scan) then
local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID))
Move (MyID,x,y)
Move_Timer2 = GetTick()
return;
end
end
例によってまだテストしてません。ごめんなさい。
- 66 :(○口○*)さん :06/03/17 12:33
- 1分毎に本体と自分の座標、モーションを監視
→前回と全く同じならカウント++
→カウント一定以上で安息
とかにすればどうかね。
前スレにあった「座ってる間ホムがうろちょろ」と組み合わせてもよさげ。
- 67 :(○口○*)さん :06/03/17 12:56
- >>67
GetTick()しかしないならMoveTimer1個でよくね?
このへん
- Move_Timer1 = GetTick()
- if(Move_Timer1 - Move_Timer2 > Move_Scan) then
+ if(GetTick() - Move_Timer > Move_Scan) then
- 68 :(○口○*)さん :06/03/17 13:01
- カオティックベネディクションはコマンド送ってこないようだ。トリガーにしたかったんだがダメみたい。
カプリスはmobには行くけど、PCにはSP切れと同じ「・・・」アイコンが出てコマンドを送って来ていなかった。
これで友達登録とかできたら便利かと思ってたんだがなー
他のホムはどうだろう?
- 69 :(○口○*)さん :06/03/17 13:15
- アルケミが行動なかったら安息よりも
満腹度が10になったら強制安息って出来ないかな
あとゼロマテさんのAI見たいにコールした瞬間ケミの座標から1〜2歩離れるってどうやるんだろ
コールした瞬間飛び出してるようでけっこういいんだよねあれ
- 70 :(○口○*)さん :06/03/17 13:16
- すいませんケミの状態は位置しか取得できないでOKですか?
ケミの座りと立ちでホム動作変えれたらと思ってたんだけど・・・
- 71 :(○口○*)さん :06/03/17 13:20
- >>69
グローバルで適当にタイマー変数を作って、初期値を0にしとく
IDOL_STの中でその変数が0だったらMOVE(MyID,x,y)するように分岐。
MOVEの前には主人でもホムでもいいから現在座標を取得して
その座標に+1なり+2した値を放り込めばいい。
MOVEしたら変数に1でも加えておけばおk。
何かとタイマー用にグローバル変数使うときがあると思うから
そういうのを初期だけ流用すればいいと思う。
- 72 :(○口○*)さん :06/03/17 13:20
- >>68
羊とか無理って事になるな。単体指定して使うスキルが無い。
>>69
満腹度をどうやって取得するかが問題だ。
SPが満タンであれば周りをうろうろするために飛び出していくはずなんだが
SPが切れてる状態でコールすると止まってたりする?
- 73 :1/2 ◆yh4mdLYeP. :06/03/17 13:25
- 長文失礼します。
一回成功したので書き込んで見ます。
ALT+左クリックを押した後、2秒以内にもう一度ALT+左クリックをすると
一番近いエネミー以外にヒールLv3します。
-----------------------------
-- state
-----------------------------
HEAL_IDLE_TIME = 200
SKILL_TOUCH_OF_HEAL = 8001 --「ヒール」スキルID
ACTIV_HEAL_LEVEL = 3 --ヒールレベル
MyActivHealCount = 0 -- ヒール受付時間
-----------------------------
function AI(myid)
MyID = myid
local msg = GetMsg (myid) -- command
local rmsg = GetResMsg (myid) -- reserved command
--※此処から追加
if (type == LIF or type == LIF2 or type == LIF_H or type == LIF_H2) then
if (msg[1] == FOLLOW_ST) then
if ( MyActivHealCount > 0 ) then
OnSKILL_ACT_HEAL_ST () --手動ヒール
end
MyActivHealCount = HEAL_IDLE_TIME
end
if(MyActivHealCount > 0)
{
MyActivHealCount = MyActivHealCount - 1
}
TraceAI ("MyActivHealCount = ")
TraceAI (MyActivHealCount)
end
--※此処まで追加
- 74 :2/2 ◆yh4mdLYeP. :06/03/17 13:28
- --手動ヒール
function OnSKILL_ACT_HEAL_ST()
local result = false
local owner = GetV (V_OWNER,MyID)
local actors = GetActors ()
local heal_target = {}
local index = 1
local type
for i,v in ipairs(actors) do
if (v ~= owner and v ~= MyID) then
if (1 ~= IsMonster(v)) then
heal_target[index] = v
index = index+1
end
end
TraceAI ("roop_number = ")
TraceAI ( i )
end
local min_dis = 3
local dis
local target_counter
for i,v in ipairs(heal_target) do
dis = GetDistance2 (MyID,v)
if (dis < min_dis) then
result = true
min_dis = dis
target_counter = v
end
end
if ( result ) then
if ( target_counter ~= nll) then
TraceAI ("ACTIV_HEAL_USE")
SkillObject(MyID, ACTIV_HEAL_LEVEL, SKILL_TOUCH_OF_HEAL, target_counter) -- ヒール使用
end
else
TraceAI ("ACTIV_HEAL_FAIL")
end
end
現在改良中です
- 75 :(○口○*)さん :06/03/17 13:28
- 満腹度10以下で安息をやっちゃうと
満腹度10で安息
↓
コールホムンクルス!
↓
また呼んでも満腹度は10
↓
安息
↓
以下略
こうなるな。
- 76 :(○口○*)さん :06/03/17 13:31
- >>69 >>71
ちょっと書いてみた。
グローバル変数としてIdle_Flag = 0を宣言して
OnIDLE_ST ()内に以下のコードを追加
if(Idle_Flag == 0) then
OwnerX,OwnerY = GetV (V_POSITION,GetV(V_OWNER,MyID)) -- ケミの位置を格納
Idle_Flag = 1
Move (MyID,OwnerX + 2,OwnerY - 2)
end
SPが切れてる時にコールしても飛び出すようになった。
- 77 :(○口○*)さん :06/03/17 13:31
- >75
そこは自動安息の条件に「呼び出してからXX秒後である」を含めれば解決だな。
まあ満腹度は取得できないのでどうしてもダメだが…
- 78 :(○口○*)さん :06/03/17 13:31
- >>75
っ【また呼ぶ前に一度/hoai】
- 79 :(○口○*)さん :06/03/17 13:34
- >>76
そんな感じだね。
ホムとケミはどうせ呼び出した瞬間は同座標なんだから座標取得は
GetV (V_POSITION,MyID)
でもいいはず。
- 80 :73 ◆yh4mdLYeP. :06/03/17 13:34
- 今起動したらエラーが……IF文とか色々間違えていましたorz
修正してきますっ
- 81 :(○口○*)さん :06/03/17 13:43
- --MoveToOwner()すれば自動でセル選んでどいてくるかもしれない(未確認)
if (GetV(V_POSITION,MyID) == GetV(V_POSITION,GetV(V_OWNER,MyID))) then
MoveToOwner(MyID)
end
- 82 :(○口○*)さん :06/03/17 13:45
- GetMsg (myid)で取得できるコマンドをwikiに乗せようと思うんだけど
NONE_CMD = 0 --コマンド無し
MOVE_CMD = 1 --ALT+右クリック
STOP_CMD = 2 --?
ATTACK_OBJECT_CMD = 3 --ALT+敵右クリック*2
ATTACK_AREA_CMD = 4 --?
PATROL_CMD = 5 --?
HOLD_CMD = 6 --?
SKILL_OBJECT_CMD = 7 --Skill
SKILL_AREA_CMD = 8 --Skillが未実装
FOLLOW_CMD = 9 --ALT+T
こんな関係でいいかね
- 83 :(○口○*)さん :06/03/17 13:49
- >>75
コールホムのタイミングでグローバル変数が定義されるから
その時にすでに満腹度が10以下なら自動安息中止すれば良い。
満腹度は取得はできないけど与えることはできそう。
初回はiniファイルに手書きするとして、
餌をあげたとき、手動(ALT+右)でケミ自身の座標を指定したら、
餌を一回あげた合図で、内部的に満腹度+10する。
10分が経過したらケミの周りを旋回しておねだりとか。
作るのは大変だけど、可能ではあると思う。
長く使ってると時間ズレそうだけど、そこはまた手書きで(以下略
- 84 :(○口○*)さん :06/03/17 13:52
- ホムが動いてくれるのはケミの地点を0距離として14セルまでだね。
画面外に出るとログも何もはかなくなるからAIが動かない状態なのかな。
画面内に入ると変数リセットされて初期状態からやりなおしてるみたい。
要するに画面外に出たらカカシになるわけかな。
- 85 :(○口○*)さん :06/03/17 13:59
- 前スレの729さんのを使わせていただきたいのですが、
DLしてAIフォルダにいれてROを起動したところ
./AI/AIlua:14 could not load package `../AI/Const.lua'from path `?,?.lua'
attempt to call a nil value
とエラーがでてしまいます。
もし直し方などありましたら教えていただければ嬉しいです。
- 86 :(○口○*)さん :06/03/17 14:03
- っ AIの中に記述するのはRagexe.exeを基点とする相対パス
- 87 :(○口○*)さん :06/03/17 14:11
- ここで質問する事なのか悩みましたがお邪魔します
ID:GkN45Sfr氏の>>44,45を試してみて「おお、停止するよー」とか喜んでいたのですが
いざ狩場に行ってみるとホムが攻撃喰らっても反撃せず一方的にボコボコにされてしまいました。
おかしいと思い、リネームしておいたAI.Luaに戻してみた所、こちらものAIでも反撃しなくなっていました。
/hoaiは切り替えて使っていますし何故上手く動かなくなってしまったのかわかりません。
何か原因になりそうな箇所ありましたらご指摘お願いします。
注)ID:GkN45Sfr氏の話は流れを説明するために挙げました。両AIともに起きた現象ですので原因にはなり得ないと思われます。
- 88 :(○口○*)さん :06/03/17 14:15
- 反撃どころかalt+右クリックですら攻撃してくれない・・・なんでだろ・・・
- 89 :(○口○*)さん :06/03/17 14:16
- MOBDATA[1162] = {'ラフレシア',17,1333,300,0,0,3,2,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0}
ラフレシアが出るようになったそうで
詳しいステータスが分からないんで適当
- 90 :(○口○*)さん :06/03/17 14:17
- >>87
AIファイル入れ替えた後、リログ、MAP移動、安息→コールホム、ハエ蝶テレポした?
AIファイルは入れ替えただけではすぐ読まれなくて、↑に書いたような
MAPに新たにホムが出現する時読み直される
- 91 :(○口○*)さん :06/03/17 14:20
- >>90
その辺は完璧です。テレポ、リログ、コール、終いにはクライアント再起動までしました。
正常に動いていたAIすら動かなく・・・
- 92 :(○口○*)さん :06/03/17 14:24
- ユーザのAIじゃなくてデフォルトのほうはどうなってる?
- 93 :(○口○*)さん :06/03/17 14:26
- 攻撃は
OnIDLE_ST → OnCHASE_ST → OnATTACK_ST
の流れで行われている。
よって基本的に”攻撃してくれない”という問題の原因は
OnIDLE_ST が実行されないことにあると思われる。
>>44,45の改造だと目的座標に移動してもホムがずっとHOLD状態になってるので
サンドバッグ化してしまうのだと思われる。
とりあえず思いついた解決策は
1.改造を取っ払う
2.もっと改造して問題をなくす
2を誰かがやってくれることを期待 いやごめんうそやってみるけど期待はしないで。
- 94 :(○口○*)さん :06/03/17 14:29
- >>76
うーん、うまく飛び出してくれない…
246行目付近のOnIDLE_ST ()の所に記述だよね?
- 95 :(○口○*)さん :06/03/17 14:36
- >>91
ソースコードをUPしてくれれば、皆でどうにかする。
- 96 :(○口○*)さん :06/03/17 14:36
- >>94
(´・ω・`)「うまく」ってのはどういう状態かしら?
TraceAI ("OnIDLE_ST")とlocal cmd = List.popleft(ResCmdList)の間に>>76のIF文を突っ込みました
グローバル関数でIdle_Flagは定義してますかね?
あとMove (MyID,OwnerX + 2,OwnerY - 2)の+2、-2をいじれば飛び出す方向を変更できます。
- 97 :87 :06/03/17 14:36
- 再起動したのでID変わっていると思います
>>92
デフォルトのほうは何も弄っていませんが(リヒアップデート後そのまま)
何故かデフォルトAIまでサンドバックなので何が原因なのかさっぱりで…
- 98 :(○口○*)さん :06/03/17 14:37
- >>97
デフォAI落としてきて現状のとちゃんと比較してみないとそのままかどうかわかんないじゃん
- 99 :(○口○*)さん :06/03/17 14:41
- >>97
公式HP→リヒタルゼン特設ページ→ホムンクルスの項目、
ページの一番下にデフォルトAIが圧縮して置いてあるから、一度それを試してみるしか
AIフォルダ&USER_AIフォルダの中身一度どこか別にコピー退避させて、試してみてくれ。
AI.Luaだけじゃなくて3ファイル全部入れ替えね。
- 100 :(○口○*)さん :06/03/17 14:42
- >>93
OnHOLD_STは位置を固定してるだけで
敵が来れば反撃しますよっと
他の状態に遷移することはないけど、Alt+Tとかで解除できるし
そんな致命的な状態に陥るものじゃない
- 101 :(○口○*)さん :06/03/17 14:43
- そんな中、汎用オートスキル関数を書いてみた。
まずは使うスキルを好きなだけ定義。例えば↓
U_AUTOSKILL = {
{
name = "Rest", --スキル名称
id = 244, --スキルID
lv = 1, --スキルレベル
to = "return MyID", --対象を返す関数
interval = 120000, --使用インターバル
time = GetTick(), --タイマ初期化。安息だけは呼んですぐ使わないからGetTick()
type = "Obj", --スキルタイプ。地面指定=Areaだが未実装…
trigger = function() --使用トリガ関数。trueを返した時(かつインターバル経過後)実行
local x,y = GetV(V_POSITION,MyID)
if x2 ~= nil and y2 ~= nil and (x ~= x2 or y ~= y2) then
x2,y2 = x,y
return false
else
return true
end
end
},
{
name = "EmergencyAvoid",
id = 8002,
lv = 3,
to = "return MyID",
interval = 35000,
type = "Obj",
time = 0,
trigger = function() return true end --常時使用させたいので常に真を返す
},
}
- 102 :(○口○*)さん :06/03/17 14:44
- んでこっちが関数。
function AutoSkill_CMD () -- 汎用スキル自動使用関数
for k,v in ipairs(U_AUTOSKILL) do --定義された自動使用スキルを1つずつチェック
TraceAI (string.format("AutoSkill : check %q(%d)",v.name,v.id))
if GetTick() - v.time > v.interval and true == v.trigger() then
TraceAI ("check true")
U_AUTOSKILL[k].time = GetTick() --タイマ更新
to = assert(loadstring(v.to))() --to読み出し
if type(v.lv) == "table" then --lvが配列なら順次実行
for m,n in ipairs(v.lv) do
SkillObject (MyID,n,v.id,to)
TraceAI (string.format("SkillObject(%d,%d,%d,%d)",MyID,n,v.id,to))
end
else
SkillObject (MyID,v.lv,v.id,to)
TraceAI (string.format("SkillObject(%d,%d,%d,%d)",MyID,v.lv,v.id,to))
end
else
TraceAI ("check false")
end
end
end
そしてfunction AI(myid)の中で呼び出す。
if GetTick() - last > 1000 then -- 1秒間隔で自動スキルチェック
AutoSkill_CMD ()
last = GetTick()
end
最後に、global variableの辺りで
last = GetTick()
を定義しておけば完了。
新しく自動使用するスキルを増やすには多少知識が必要だけど、出来ない人は要望スレで。
- 103 :(○口○*)さん :06/03/17 14:45
- OnHold_STでは移動を一切しないので、敵との位置関係によっては
一方的にぼこられることはおきます。
毎回毎回となると、別の理由もありそうだけど。
- 104 :(○口○*)さん :06/03/17 14:48
- あ、type=="Area"の分岐を省略した方を載せちまった…
まあ未実装だし良いか。
- 105 :(○口○*)さん :06/03/17 14:50
- >>96
すいません、解決しました
カスタムAIの方いじってて切り替えてなかっただけでした
あー自分ポカすぎ(;´Д`)
- 106 :(○口○*)さん :06/03/17 14:59
- ホム種別をメンバに入れて関数内でチェックしてやるとより汎用的かも
- 107 :(○口○*)さん :06/03/17 15:02
- そしてお礼がまだだったことに気づいた
>>71>>76>>79>>96
本当に感謝
コールした時の他にリザホムでもケミの位置から飛び出してくれるので
低LvリザホムしたあとのPPがやりやすくなった
- 108 :(○口○*)さん :06/03/17 15:06
- >>99
MD5比較して一致してはいたのですが念のため公式から落としてこちらとも比較してみました
結果、全く同じファイルでした
デフォルトAIを改めて少し動かしてみたのですが…どうやら動くようです
今朝動かした時に比べると反応がどうもぎこちない気もしますがALT右クリック、反撃等動いてくれました。
先ほど書き込む前は何もしてくれなかったのですが。
で。
カスタムのほうにセットしておいたAIですが、
本スレのこちらの方の物を使わせてもらっていました。
ttp://gemma.mmobbs.com/test/read.cgi/ragnarok/1142433555/562
少なくとも今朝1時間ほど狩りをした時は何の問題もなくホムが動作していたのですが
先ほど狩りをしてみたところ微動だにせずボッコボコという有様で…
私が欲しい機能は今のところ
・ケミ移動中遅れずについて来てくれる様に
・全ホム非アクティブ
程度なのでアルケミwikiのライブラリから頂戴しても良いのですが。
原因はよくわかりませんが皆さんお騒がせして申し訳ありませんでした。
- 109 :(○口○*)さん :06/03/17 15:30
- 相対パスですか…
うーむ、それすらわからないので使わないほうがよさそうですね…。
一応ぐぐって色々調べてみます、すいません。
もしなにか他にアドバイスあったら教えてください。
- 110 :(○口○*)さん :06/03/17 15:37
- ちょっとまだ確証はないけど攻撃スタック対策案。
攻撃の標的をトレースしてみたらこんな感じでした。
d はホムと標的との距離。
OnCHASE_ST
IsOutOfSight=true : POSITION_ERR 41773=(128,154) 57387=(-1,-1) d=201
CHASE_ST -> IDLE_ST : ENEMY_OUTSIGHT_IN
OnIDLE_ST
IDLE_ST -> CHASE_ST : MYOWNER_ATTACKED_IN
OnCHASE_ST
IsOutOfSight=true : POSITION_ERR 41773=(128,154) 57387=(-1,-1) d=201
GetOwnerEnemyやGetMyENemyでは主人やホムを標的にしていれば敵と認識しているが、
倒した後の敵の標的がリセットされてないなどでそのままかけ離れた距離にいる敵のところへも移動しにいこうとして
追跡⇔待機を繰り返して何もできない状態なのではなかろうか。
もしそうなら敵の判断の時に IsOutOfSight を入れておけば対処できるかもしれない。
やってみるけどスタックなかなか起きないので他にも試してもらえるとありがたい。
- 111 :(○口○*)さん :06/03/17 15:39
- >>109
要は ../AI/〜〜.lua だとひとつ上の階層見に行っちゃうから
./AI/〜〜.lua だとか ./AI/USER_AI/〜〜.lua にしたら多分大丈夫。
多分。
エラーの中に、問題となる行数は書かれてるのでそこをチェックしてみるといいかも。
- 112 :(○口○*)さん :06/03/17 15:42
- >106
確かに…ホムを変える事を考えてなかったから気付かなかった。他にも色々修正してみた。
function AutoSkill_CMD () -- 汎用スキル自動使用関数
for k,v in ipairs(U_AUTOSKILL) do
TraceAI (string.format("AutoSkill : check %q(%d)",v.name,v.id))
TraceAI (string.format("Interval : %d",GetTick() - v.time))
if true == v.trigger() and GetTick() - v.time > v.interval then
TraceAI ("check true")
if GetV(V_MOTION,GetV(V_OWNER,MyID)) < 3 and (v.user == nil or v.user == math.mod(GetV(V_HOMUNTYPE,MyID)),4)) then --本体がスキル使用可能 かつ ホムの系統がuserとマッチした時
U_AUTOSKILL[k].time = GetTick()
to = assert(loadstring(v.to))()
if type(v.lv) == "table" then
for m,n in ipairs(v.lv) do
if v.type == "Area" then
SkillGround (MyID,n,v.id,to)
TraceAI (string.format("SkillGround(%d,%d,%d,%d)",MyID,n,v.id,to))
else
SkillObject (MyID,n,v.id,to)
TraceAI (string.format("SkillObject(%d,%d,%d,%d)",MyID,n,v.id,to))
end
end
else
if v.type == "Area" then
SkillGround (MyID,v.lv,v.id,to)
TraceAI (string.format("SkillGround(%d,%d,%d,%d)",MyID,v.lv,v.id,to))
else
SkillObject (MyID,v.lv,v.id,to)
TraceAI (string.format("SkillObject(%d,%d,%d,%d)",MyID,v.lv,v.id,to))
end
end
else
TraceAI ("Skill isn't in use.")
end
else
TraceAI ("check false")
end
end
end
- 113 :(○口○*)さん :06/03/17 15:43
- U_AUTOSKILL = {
{
name = "Rest",
id = 244,
lv = 1,
to = "return MyID",
interval = 120000,
time = GetTick(),
type = "Obj",
user = nil, --ケミスキルならnil
trigger = function()
local x,y = GetV(V_POSITION,MyID)
if x2 ~= nil and y2 ~= nil and (x ~= x2 or y ~= y2) then
x2,y2 = x,y
U_AUTOSKILL[k].time = GetTick() --座標が書き換わった時、タイマ更新
return false
else
return true
end
end
},
{
name = "EmergencyAvoid",
id = 8002,
lv = 3,
to = "return MyID",
interval = 35000,
type = "Obj",
time = 0,
user = LIF, --使用するホムの系統
trigger = function() return true end
},
}
…しかしMMOBBSはソースコードを貼り付けるのに向いてないと思った。
AI専用のBBSなりWikiなりSFなりが欲しい所。
- 114 :110 :06/03/17 15:47
- もう一つ。
移動不能状態は何秒も同じ状態でいることはありえないから
直前の座標とそれまでの時間を記録して比較することで長時間のスタックは解除できるんじゃないかな。
自分は移動処理に MyLastTIck MyLastX MyLastY みたいのを入れてやってみてる。
- 115 :前スレ729 :06/03/17 15:49
- >>85
デフォルトのAIに上書きしてる?
もしそうなら、AIファイルを開いて、最初のほうにある
「../AI/Const.lua」を「./AI/Const.lua」に、
「../AI/Util.lua」を「./AI/Util.lua」に、変えてみて。
今家に居ないから、とりあえずこれで。
帰ったら新しいの上げるわ。
- 116 :(○口○*)さん :06/03/17 15:51
- >>113
よければうちのWikiを使いますか?
個人サイトの付属Wikiとして用意してますが、ROのAIに関する内容を書いていくつもりだったのでスレ付属にしてもきにしなーい
→ ttp://wiki.ariela.jp/Lua/
明日ぐらいまで待ってもらえればSubversionを用意できますが・・・いらんかなw
- 117 :(○口○*)さん :06/03/17 16:15
- ケミ目指して頑張りつつ
仕事中にAIいじってるんだが
ケミになってないから確かめられないんだけど
>>82
で良いのか知りたい
- 118 :(○口○*)さん :06/03/17 16:17
- ちとネタ投下
local ownerTarget
ownerTarget = GetV(V_TARGET, GetV(V_OWNER, MyID)) -- ケミのタゲを取得
if 0 ~= ownerTarget then
if ownerTarget ~= GetV(V_OWNER,MyID) then -- タゲがケミ自身でなければ
local targetX, targetY
targetX, targetY = GetV (V_POSITION, ownerTarget)
Move (MyID, targetX, targetY-1) -- 対象の1セル下へ移動
return
end
end
これで、ケミがターゲットした相手を追いかけるようになる。
プレイヤーをターゲットする場合、Shiftクリックでカートを撃てばいい。
自分をターゲットし直せば、この部分は無視されるようになるはず。
- 119 :(○口○*)さん :06/03/17 16:24
- おもしろそうだけど、どのへんに入れるの?
- 120 :(○口○*)さん :06/03/17 16:27
- >>117
とりあえずおまいは仕事したほうがいいと思う
俺もだが
- 121 :(○口○*)さん :06/03/17 16:29
- >>119
俺はOnFOLLOW_CMD_ST()の頭に入れてみた。
OnIDLE_CMD_ST()でも良さそうだけど。
- 122 :(○口○*)さん :06/03/17 16:50
- ホムンクルスの穴、AIでケミを自動操作可能
プログラムに詳しい正体不明の人物が集う、にゅ缶の"AIスレ"。そこで驚くべき事実が判明した。
なんとホムンクルスのAIプログラムで、本体であるアルケミストのスキルを制御できるというのだ。
ホムのスキルと本体のケミのスキルが区別されていないために起こる現象らしい。
ものすごい速度でスキルを連打できるほか、自動でラウドボイスをかけ直したり、
HPが一定以下になったら自動でポーションピッチャーを使うといったプログラムも
可能なようだ。モンスターやPTメンバーを対象にしたスキルの使用もできるらしい。
たとえば画面内の敵に自動でメマーや宝剣ボルトを撃つといったBOT行為が実現する。
この"ホムンクルスのAIで操るアルケミスト"が完成すれば合法BOTの誕生と言える。
また、本来は不可能なはずのホムンクルスへのヒールも、AIで行動を指定すること
によって可能になるようだ。恐れていたとおりホムンクルスはBOT禁断の技術だった。
現時点ではまだ不完全な、この"ホムンクルスAIの穴"を利用したケミの自動化だが、
BOTerによって悪用される前になんとか塞いでもらいたい。
簡単に言えば、Lua使って本体のケミの操作が可能になる
ようはケミを合法でBOTとして動かせる
- 123 :(○口○*)さん :06/03/17 16:55
- 移動はできないけどな。
- 124 :(○口○*)さん :06/03/17 16:58
- テレクリがあるから歩くより効率よかったりして。ケミな時点でお察しだが。
- 125 :(○口○*)さん :06/03/17 16:59
- できることといやあ、宝剣もって固定砲台くらいか?
- 126 :(○口○*)さん :06/03/17 17:00
- 今やってる移動系のタイムアウト処理。
MyLastX,MyLastY,MyLastTIck に直前の座標と時間を記憶して、一定時間移動がなければタイムアウト。
移動不可エリアや崖の上とかを指定しても3秒で待機状態に戻る。
OnCHASE_STにも流用できる。
----------------------------------------
-- 移動コマンド
----------------------------------------
function OnMOVE_CMD (x,y)
TraceAI ("OnMOVE_CMD")
if ( x == MyDestX and y == MyDestY and MOTION_MOVE == GetV(V_MOTION,MyID)) then
return -- 目的地と現在地が同一の場合は、処理しない
end
local curX, curY = GetV (V_POSITION,MyID)
if (math.abs(x-curX)+math.abs(y-curY) > 15) then -- 目的地が一定距離以上なら (サーバーで遠距離は処理しないため)
List.pushleft (ResCmdList,{MOVE_CMD,x,y}) -- 元の目的地への移動を予約する
x = math.floor((x+curX)/2) -- 中間地点へ移動する
y = math.floor((y+curY)/2) --
end
Move (MyID,x,y) -- 移動
MyState = MOVE_CMD_ST -- 移動コマンド受付状態に移行
MyEnemy = 0 -- 標的をリセット
MySkill = 0 -- スキルをリセット
MyDestX,MyDestY = x,y -- 目的地をセット
MyLastX,MyLastY = curX,curY -- 現在地をセット
MyLastTick = GetTick() -- 現在時間をセット
end
- 127 :(○口○*)さん :06/03/17 17:00
- ものすごい速度でスキル連打も、ホムにヒールも(見た目だけで)出来ないしな。
まあBOTNEWSはいつもこんな感じだが。
>116
使わせてもらって良いのかな?
スレで上がったコードの保管と修正が主になると思うけど
- 128 :(○口○*)さん :06/03/17 17:01
- 続き移動状態処理。
----------------------------------------
-- 移動コマンドの処理中
----------------------------------------
function OnMOVE_CMD_ST ()
TraceAI ("OnMOVE_CMD_ST")
local tick = GetTick() -- 経過時間取得
local x, y = GetV (V_POSITION,MyID) -- 現在地取得
if (x == MyDestX and y == MyDestY) then
TraceAI ("OnMOVE_CMD_ST : DESTINATION_ARRIVED_IN") -- 目的地に到着
MyState = IDLE_ST
elseif (tick > MyLastTick+500) then
if (x ~= MyLastX or y ~= MyLastY) then -- 移動した
TraceAI ("OnMOVE_CMD_ST : MOVED")
MyLastX,MyLastY = x,y -- 直前の情報を更新
MyLastTick = tick
elseif (tick > MyLastTick+3000) then -- 長時間移動がなかった
TraceAI ("OnMOVE_CMD_ST : TIMEOUT")
MyDestX,MyDestY = 0,0
MyState = IDLE_ST -- 待機状態に移行
return
end
end
end
- 129 :(○口○*)さん :06/03/17 17:02
- >>124
テレポ窓が出るだけで飛べないけどな。
- 130 :(○口○*)さん :06/03/17 17:04
- >>13の
>function OnFOLLOW_CMD_ST () を
>function OnFOLLOW_CMD_ST ()
> return
>end
というのはfunction OnFOLLOW_CMD_ST ()のすぐ下に
return
end
と記述するということでいいのですか?エラーが出て困ってます
それともその下の中身ごと全て書き換えでしょうか?
一応エラーは出ずに動くことは動きますがALT+Tで戻ってきます。
どなたかご教授を
- 131 :(○口○*)さん :06/03/17 17:04
- ケミな時点でお察しだけど、そのお察しなケミを合法な手段で全自動狩りできるんだぞ。
普通に育てるのがダルいと感じる奴らが喜んで飛びつかないとも限らない。
テレクリか宝剣があれば実行可能なんだし(両方揃ってると効果向上)
- 132 :(○口○*)さん :06/03/17 17:06
- へー、全自動ねぇ。
へー。
へーぇ。
- 133 :(○口○*)さん :06/03/17 17:07
- >131
まあそう思うならやってみそ。
どう頑張っても半自動狩り程度が関の山だから。
- 134 :(○口○*)さん :06/03/17 17:09
- どうやってもホムAIじゃケミの移動は無理だしな
- 135 :(○口○*)さん :06/03/17 17:10
- >>127
ぶっちゃけ、BOTは効率や便利さがメインであるがホムはその対極をいっている。
使う道具は近しくても目的は全然違う。
連射パッドでシューティングクリアする人と、カルネージハートで遊ぶ人くらいやりたいことが違ってる。
- 136 :(○口○*)さん :06/03/17 17:10
- >>131
もう少し知識つけてからカキコしような?
- 137 :130 :06/03/17 17:12
- 自己解決しました。スレ汚しスマソ
>function OnMOVE_CMD_ST () の
> MyState = IDLE_ST
>を
> MyState = FOLLOW_CMD_ST
>に変更
を書き換え忘れてた
- 138 :(○口○*)さん :06/03/17 17:13
- >>121
む、うまく動かない。
例えば草とか殴れば一緒に殴ってくれるわけだよね?
- 139 :(○口○*)さん :06/03/17 17:13
- 気になったのだが
Move (MyID,x,y)?-- 移動
このコマンドにケミID送っても動かないってことでいいのかな?
- 140 :(○口○*)さん :06/03/17 17:19
- >>129
マクロでEnter連打すれば必要なときだけテレポするような気がする。
>>131
バグ利用だから合法じゃない。
効率悪いし、アイテムすら拾えないのにどう魅力を感じろと。
職たたきの正当化に使われて迷惑でしかないのが現状。
- 141 :(○口○*)さん :06/03/17 17:28
- 魅力を感じないチートならやっても問題は無いのですね
- 142 :(○口○*)さん :06/03/17 17:30
- かってにやれば?
その話題はAIスレとは関係ないから帰ってね
- 143 :(○口○*)さん :06/03/17 17:32
- >>139
話題が出て直ぐに試した。どうやってもケミは動かない。
- 144 :(○口○*)さん :06/03/17 17:33
- ここはアルケミストのAIスレではありません。
- 145 :(○口○*)さん :06/03/17 17:35
- 前スレ 596 へ。
前スレ 912 で公開されたデータのインターフェースを作ったんだが、
公開する際は、mobdata.lua を添付してもいいだろうか?
そのへん何かあれば書いておいてくれ。
- 146 :前スレ729 :06/03/17 17:38
- 自サイトにホムAI用のページを作ってみた。
ttp://www5b.biglobe.ne.jp/~snight/ro/ai.html
前スレ729の奴から少し機能も追加してるので、こちらをどうぞ。
- 147 :(○口○*)さん :06/03/17 17:51
- ,,,,;;,,,, ,,,
(ェ;,,@;;;;;ミ <ヒツジもアイシテ
uu''''uu
アミストルのディフィンス自動使用どなたかお願いします
- 148 :(○口○*)さん :06/03/17 17:54
- というかBOTNEWSの記事信じてる人なんていたのか
- 149 :(○口○*)さん :06/03/17 18:02
- >>148
ガンホー信者乙
どうしてそこまでして糞会社を擁護したいんだろ
- 150 :(○口○*)さん :06/03/17 18:04
- なんで>>148から>>149に繋がるのか分からん
- 151 :(○口○*)さん :06/03/17 18:04
- >>147
グローバル関数に
DelayCount = 0
Defence = 0
を定義
フリットムーブなんかを自動使用する関数の中に以下のコードを追加
if(type%nbsp;==%nbsp;AMISTR%nbsp;or%nbsp;type%nbsp;==%nbsp;AMISTR_H%nbsp;or%nbsp;type%nbsp;==%nbsp;AMISTR2%nbsp;or%nbsp;type%nbsp;==%nbsp;AMISTR_H2)%nbsp;then%nbsp;--%nbsp;ホムが羊の場合
%nbsp;%nbsp;%nbsp;%nbsp;local%nbsp;mysp%nbsp;=%nbsp;GetV%nbsp;(V_SP,myid)%nbsp;--%nbsp;自分のSPを格納
%nbsp;%nbsp;%nbsp;%nbsp;local%nbsp;tick%nbsp;=%nbsp;GetTick()%nbsp;--%nbsp;時間を取得
%nbsp;%nbsp;%nbsp;%nbsp;if(mysp%nbsp;>=%nbsp;30%nbsp;and%nbsp;tick%nbsp;>%nbsp;Defence)%nbsp;then
%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;Defence%nbsp;=%nbsp;tick%nbsp;+%nbsp;40000%nbsp;--%nbsp;スキルタイマーのセット
%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;DelayCount%nbsp;=%nbsp;tick%nbsp;+%nbsp;40000%nbsp;--%nbsp;持続時間中はずっとディレイタイム
%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;SkillObject(myid,%nbsp;1,%nbsp;8006,%nbsp;myid)
%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;%nbsp;return%nbsp;1
%nbsp;%nbsp;%nbsp;%nbsp;end
- 152 :(○口○*)さん :06/03/17 18:05
- うは…みすったorz ちょっと修正してくる
- 153 :(○口○*)さん :06/03/17 18:06
- 初歩ミス及び連投すみませんでした_| ̄|○|||
if(type == AMISTR or type == AMISTR_H or type == AMISTR2 or type == AMISTR_H2) then -- ホムが羊の場合
local mysp = GetV (V_SP,myid) -- 自分のSPを格納
local tick = GetTick() -- 時間を取得
if(mysp >= 30 and tick > Defence) then
Defence = tick + 40000 -- スキルタイマーのセット
DelayCount = tick + 40000 -- 持続時間中はずっとディレイタイム
SkillObject(myid, 1, 8006, myid)
return 1
end
- 154 :(○口○*)さん :06/03/17 18:08
- しばらくは変なのが増えそうだなあ
- 155 :(○口○*)さん :06/03/17 18:11
- すみません質問させて下さい
主人を攻撃する敵→自分を攻撃する敵→
主人が攻撃している敵または自分の10セル以内にいて、
なおかつ他PCが4セル以内におらず他PCと交戦状態になっていない敵
という優先順位でタゲらせようと初心者なりに頑張って
既存AIをしこしこ改造してるんですが
どうしても思い通りに動きません。
敵がすぐ近くにいてもタゲる事とタゲらない事があってどうにも不安定です。
これからソースの一部を貼り付けますので、
どうかどこに問題があるのか教えて下さい。
- 156 :(○口○*)さん :06/03/17 18:11
- >>70
位置以外にも色々取得できる。結論から言えば、主人が座ってるかどうかの判別は可能。
前スレ671に座り状態を用いた動作が出てる。
- 157 :(○口○*)さん :06/03/17 18:12
- 春だからな
- 158 :(○口○*)さん :06/03/17 18:15
- BOTニュースから気マシ阿多^^
BOT同然のホム使いは死ねよ
- 159 :155 :06/03/17 18:16
- GetMyEnemyB (myid)に色々加えています。
local others = {}
local indexo = 1
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
local type = GetV(V_HOMUNTYPE,v)
-- 対象がPCである場合他PCリストに追加
if (0 <= type or type <= 23 or 4021 <= type or type<= 4046) then
others[indexo] = v
indexo = indexo+1
end
end
end
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
local target = GetV (V_TARGET,v)
if (target == myid) then
local motion = GetV(V_MOTION,v)
if (motion == MOTION_ATTACK or motion == MOTION_ATTACK2) then
enemysA[indexA] = v
indexA = indexA+1
end
- 160 :155 :06/03/17 18:17
- elseif (1 == IsMonster(v))then
monster = v
local check = false
for i,v in ipairs(others) do
if (false == check) then
if (GetV (V_TARGET,MyOwner) == monster) and ((GetV(V_MOTION,MyOwner) == MOTION_ATTACK or GetV(V_MOTION,MyOwner) == MOTION_ATTACK2)) then
enemysB[indexB] = monster
indexB = indexB+1
check = true
elseif (GetV (V_TARGET,v) ~= monster) and (GetV(V_TARGET,monster) ~= v) and (GetDistance2 (monster, v) > 4) then
enemysB[indexB] = monster
indexB = indexB+1
check =true
end
end
end
end
end
end
- 161 :155 :06/03/17 18:19
- if (indexA >1) then
local min_dis = 100
local dis
for i,v in ipairs(enemysA) do
dis = GetDistance2 (myid,v)
if (dis < min_dis) then
result = v
min_dis = dis
end
end
else
local min_dis = 11
local dis
for i,v in ipairs(enemysB) do
dis = GetDistance2 (myid,v)
if (dis < min_dis) then
result = v
min_dis = dis
end
end
end
return result
end
連投申し訳ありません。あと読みづらいソースですみません…
自分で動作確認した限りではどうにかエラーは吐かないようには出来たのですが
動きが「普段は非先攻、たまに先攻」というとんだ気まぐれ屋になってしまっています。
- 162 :(○口○*)さん :06/03/17 18:29
- ×if (0 <= type or type <= 23 or 4021 <= type or type<= 4046) then
○if (0 <= type and type <= 23 or 4021 <= type and type<= 4046) then
では?
- 163 :(○口○*)さん :06/03/17 18:39
- ホムの攻撃って,基本的に「主人が攻撃されたら」その敵を攻撃ですよね。
ここを,「PTメンバが攻撃されたら」に変更するにはどうしたらいいでしょうか?
- 164 :155 :06/03/17 18:40
- >>162
あああ
確かに言われてみるとここは凄くおかしい…!!
ご指摘ありがとうございます!
早速修正して動作確認してきます。
- 165 :(○口○*)さん :06/03/17 18:40
- 元々ホムは公認BOTみたいな扱いだったし今更・・・
- 166 :(○口○*)さん :06/03/17 18:46
- >>163
「PTメンバー」を直接知る手段は、ホムにはない。
いくつかのAIで「友達登録」をして対処しようとしてるから、それを参考にするといいのでは。
- 167 :(○口○*)さん :06/03/17 18:47
- 前スレ見て、自動PPLV1は
SkillObject(MyID,1,231,MyID)
これでいけたんだが、PPLV2の番号を教えてくれないか?
SkillObject(MyID,1,232,MyID)
にしたらバイオプラント連打でサバキャンしたとです。
今後のためにもスキル番号とかまとめてあるとこあったら教えておくれ
- 168 :(○口○*)さん :06/03/17 18:49
- >167
SkillObjectの引数を良く見れ
- 169 :(○口○*)さん :06/03/17 18:49
- >>167
関数の仕様を調べると幸せになれるかも
- 170 :(○口○*)さん :06/03/17 18:58
- AIにハエパケ組込み、発動確認。
検知されてBANされなきゃハエ飛び宝剣砲台での活動可。
- 171 :(○口○*)さん :06/03/17 19:01
- ホムAIでケミのアイテム使用はできません
あしからず…
>>151-153
うーん、エラーが出ちゃう
- 172 :167 :06/03/17 19:01
- ありがとーばっちしいけました
リザホムしたあと即座にPPしてくれるのはなかなか良いです
聞いただけではなんですので貼り付けておきます
ホムのHPが40%きったら自動でPPLV2
function AI(myid)の適当なところに追記します。
if (GetV (V_HP,MyID)/GetV (V_MAXHP,MyID)*100<=40) then
SkillObject(MyID,2,231,MyID) -- PP Lv2
end
- 173 :(○口○*)さん :06/03/17 19:04
- >>171
一番最後にendをもう一個追加してくださいorz
- 174 :前スレ391 :06/03/17 19:05
- 羊さん用不完全版緊急時キャスリング自動使用関数です。
長くなったのでサイトに上げときます。
ttp://www.eonet.ne.jp/~sneakers/AI/AutoSkill.lua
不完全なのは、ケミから少し離れる処理が未実装な為です。
メモ帳で一からごりごり書いたのでバグがあるかも知れません。
上記を踏まえて興味ある方はダウンロードして使ってみて下さい。
- 175 :(○口○*)さん :06/03/17 19:15
- >>165
それでもあえてつかう君達…まあがんばってよw
- 176 :(○口○*)さん :06/03/17 19:16
- >>172
とりあえず、自動ケミスキルの問題点についてはおいといて。
これだと、ケミのアイテムに紅POTがない場合、
『スキル使用失敗』の連続で問題がおきないか?
SPは1しか使わないから大丈夫として。
- 177 :(○口○*)さん :06/03/17 19:18
- 単位時間当たりの自動スキル使用回数をカウントして
一定以上使用した場合は自動スキル使用を中止すればいいと思う
- 178 :(○口○*)さん :06/03/17 19:19
- スキル使ってもHPが回復しなかったら終了とかにすれば
- 179 :(○口○*)さん :06/03/17 19:22
- >>178
どんどんHPが減っていく環境を考えると
それは無理じゃないかね
- 180 :(○口○*)さん :06/03/17 19:22
- >>174
ちょうどケミから離れる処理を書いてる最中なので出来たら組み合わせて使ってみるよ。
- 181 :(○口○*)さん :06/03/17 19:22
- >>173
まだダメだぁ
スキル使ってくれない
- 182 :(○口○*)さん :06/03/17 19:24
- >166
ありがとうございました。
友達登録のを参考にしてみます。
(前回sage忘れてる。。。
- 183 :(○口○*)さん :06/03/17 19:25
- ケミスキル使用に関する話はしない方が良い気がす
- 184 :(○口○*)さん :06/03/17 19:33
- なにこのBOT配布スレ^^
- 185 :(○口○*)さん :06/03/17 19:38
- >>183
そうだな、すまんかった。
- 186 :(○口○*)さん :06/03/17 20:02
- GetMsg()
で、餌与えたメッセージが取得できればなー、って思うわん
そしたら餌最後に貰ったのを何時かわかるから空腹度の減少も想定できる
自動で餌はやれないけど、おねだりさせる事が出来るんよね
一番いいのは
GetV ( V_HUNGER , myid ) とかできればなぁ、と妄想
GetVの定数に12以上の数を食わせる実験はまだやってねぇけど、まぁやめとくか
- 187 :(○口○*)さん :06/03/17 20:26
- GetVの定数は0-255までは試したけどなにもなかったよ
- 188 :(○口○*)さん :06/03/17 20:37
- GetMsgをチェックしてみたけど、餌を与えた時らしきメッセージはなかった
っというか、ALT+T以外はキャラや位置の指定がないものは
メッセージは無いかもしれない
羊のスキルを使ったときはメッセージはなかったし
- 189 :(○口○*)さん :06/03/17 20:39
- 今度から誰かしたらばなり何なり借りてそこで立ててスレ監視すればいんじゃね?
アルケミストのAIについて語るようなの居ればその部分消せばいいわけだし
余りしつこい様ならアク禁にもできるとおもうが・・・
追記
じゃあお前やれって言われたらやってもやるが
居ない時間帯とかもあるからそういう時はお察し
- 190 :(○口○*)さん :06/03/17 20:47
- 初歩的な質問なのかもしれませんが・・・
function OnFOLLOW_ST ()ホムが遅れないように弄りたいのですが
./AI/USER_AI/AIlua:681 attempt toperform arithmetic on global `MoveTimeDeley(a nil value)
というエラーが、歩くたびに出ます
エラーはOK押したらそれで終わるのですが歩くたびにエラーが出て・・・
どこが悪いのかこれだけで分かりますでしょうか?
- 191 :(○口○*)さん :06/03/17 20:50
- 681行目でなんで中身がnilのMoveTimeDeleyなんて変数を入れてんだよ
ってことじゃね?
どんなの書いてるか分からんからそれ以上しらんが
- 192 :(○口○*)さん :06/03/17 20:50
- >>189
実際出来ないことを書いて騒ぎ立てる>>170みたいなのを、
みんなスルーすればそれで済む話だと思う
- 193 :(○口○*)さん :06/03/17 21:01
- プレイヤーの識別方法などをWikiに追加しといた
間違ってるかもしれないから、詳しい人チェックよろしく〜
あとGetVのV_TYPEって何のことかわかる人いる?
ランダムっぽいんだけど、いつまでたっても固有の数字返してくる人もいるし
なにかしら意味があると思うんだが
- 194 :(○口○*)さん :06/03/17 21:01
- ごめん、あげちまった・・・orz
- 195 :116 :06/03/17 21:05
- >>127
どこかにロジックがまとまってる方が皆参考にしやすいだろうと思ってるんで、どんどん使ってやってください。
もともと自分のロジック公開用に設置したものだし。
- 196 :(○口○*)さん :06/03/17 21:21
- 既出かもしれないけどバイオプラントのID調べたので貼っとく
-- [1589]マンドラゴラ(バイオプラント)
-- [1579]ヒドラ(バイオプラント)
-- [1575]フローラ(バイオプラント)
-- [1555]フェアリーフ(バイオプラント)
-- [1590]ジオグラファー(バイオプラント)
- 197 :(○口○*)さん :06/03/17 21:21
- >>193
--#define ( V_TYPE ) // 未実装?
TYPE_PC = 0 -- プレイヤーキャラクター
TYPE_NPC = 1 -- ノンプレイヤーキャラクター
TYPE_ITEM = 2 -- アイテム
TYPE_SKILL = 3 -- スキル
TYPE_UNKNOWN = 4 -- 不明
TYPE_MOB = 5 -- 敵NPC
TYPE_EVENT = 6 -- イベントNPC
TYPE_PET = 7 -- ペット
--End
俺のConst_Original.luaに突っ込んであるのをコピペ。
ソース元は、前々スレのログより。
(一部、定数名を書き換えてるが)
- 198 :(○口○*)さん :06/03/17 21:23
- http://jbbs.livedoor.jp/game/29222/
むしゃくしゃしてやった こうかいはしてない
だれもつかわなくてもなかない
- 199 :前スレ596 :06/03/17 21:24
- >>145
前スレ852と共同だけど使って貰う&使う為に作った訳だから
どんどん使ってもらって構わないと思うよ
むしろどんな物が出来たか速く見たい俺ガイル
- 200 :(○口○*)さん :06/03/17 21:29
- >>197
おかしいな、俺が数時間前に調べたときは5〜7桁の数字が返ってきたんだが
あれ?俺のROバグってる?
- 201 :(○口○*)さん :06/03/17 21:33
- それが現状仕様、GetVのV_TYPEはまだ未実装で
type = GetV(V_TYPE,id) -- これだとtypeにはidがそのまま入るみたい
- 202 :(○口○*)さん :06/03/17 21:38
- >>201&>>197
サンクス
だけどひとつだけ疑問が
200id分ほど調べてデータベース化してたんだけど
3つほどIDと違う数字が帰ってきているのが…
V_HOMUNTYPEの数字から、たぶんモンスターだと思うんだが
偶然かなー
- 203 :(○口○*)さん :06/03/17 21:38
- それってIDでないかい?
ホムでキャラクエとかに載ってるIDが・・・
- 204 :(○口○*)さん :06/03/17 21:40
- V_TYPEは前スレ二度くらいidがそのまま返ってくるってあったはず
- 205 :(○口○*)さん :06/03/17 21:41
- 書き忘れてたんで書こうかと思ったら、>>201が既に書いてくれていた。
まあ、そんな訳で未実装。
あくまで、「初期は、こう予定されていた」と云う参考程度にどうぞ。
同様の事をやろうと思ったら、
V_HOMUNTYPEで取得した値を、1000で割るとかで実装出来るし
正式実装されても、あまり有難味が無いね…。
- 206 :(○口○*)さん :06/03/17 21:43
- >>196
mobdata.luaのそのID部分を見るとX_が付いてるだけで
キャラ関係はそのままやね
- 207 :>>189 :06/03/17 21:54
- >>192
okわかったそうする
ただなんかこう放置されてるとなんかな・・・
まぁ流れ的に正常になってきたからまぁいいかな・・・
>>198
なむ・・・
- 208 :(○口○*)さん :06/03/17 22:03
- バニラにボルト打たせると、
打った後、敵に向かっていく仕様変えられませんでしょうか?
いまのままではせっかくの遠距離攻撃の特性が活かしきれません。
どうにかできないでしょうか
- 209 :(○口○*)さん :06/03/17 22:07
- >>191さん
参考にさせてもらっているのは146さんのサイトのAIなんです。
elseif(GetV(V_MOTION,MyID) == MOTION_MOVE)then
* if((MoveTime+MoveTimeDelay) > GetTick())then -- 多少時間を置けていたら
local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID)) --ケミの座標取得
local Hom_x,Hom_y = GetV(V_POSITION,MyID) -- ホムの座標取得
if(Hom_x < x)then -- ホムのほうが西にいれば
Move (MyID,x-1,y) -- ケミの1マス左に移動
else -- ホムのほうが東にいれば
Move (MyID,x+1,y) -- ケミの1マス左に移動
end
MoveTime = GetTick() --現在時刻格納
TraceAI ("FOLLOW_ST -> FOLLOW_ST") return
* else -- まだ時間が経っていなければ
* return -- 未処理
* end
end
191さんのを参考に*部分を削除する事によってうまくいったようなのですが
(エラーは吐かなくなった)これで大丈夫なのでしょうか?
- 210 :(○口○*)さん :06/03/17 22:08
- 190=209ですorz
- 211 :(○口○*)さん :06/03/17 22:09
- >>208
それを言うならどっちかというとこっち。
ホムンクルスAIについての雑談・要望スレ
http://enif.mmobbs.com/test/read.cgi/livero/1142513331/
それから、ケミスレにこんな書き込みがある
http://gemma.mmobbs.com/test/read.cgi/ragnarok/1142433555/769
- 212 :(○口○*)さん :06/03/17 22:10
- 普通に考えてif文削ったら問題が起こるような気がするのだが。
- 213 :(○口○*)さん :06/03/17 22:16
- >>208
function OnSKILL_OBJECT_CMD (level,skill,id)
TraceAI ("OnSKILL_OBJECT_CMD")
MySkillLevel = level←この行と
MySkill = skill←この行と
MyEnemy = id←この行の先頭に--を書き加えて(--MyEnemy = id)←こんな感じ
SkillObject (MyID,level,skill,id)--←この行を書き加えて
MyState = CHASE_ST←この行の先頭にも--を書き加える
end
試してないのでどうなるかは分かりません。
- 214 :(○口○*)さん :06/03/17 22:19
- >>209
MoveTimeかMoveTimeDelayが未定義で判定失敗してるんじゃないか?
ためしに*がついてるif文の直前に
if(MoveTime == nil or MoveTimeDelay == nil) then
TraceAI("未定義でした")
end
って追加して、ゲーム内で/traceaiコマンドでログとってみて
RagnarokOnlineフォルダのTraceAI.txtに未定義でしたって書いてあったら
MoveTimeかMoveTimeDelayの未定義が原因
- 215 :(○口○*)さん :06/03/17 22:19
- そういえば、基本以外の動作状態ってどこまで判別できる?
他のサイトまで見に行く暇まではないが。
MOTION_DEAD = 3
これはまだ見たことない。
MOTION_ATTACK2 = 9
こっちもみたことない。MOTION_ATTACK=2との違いは?
あと、6が座ってるときとバイオプラントで12という書き込みは見たが、
バイオプラントで12がうまくとれなかった。詠唱中だとすでに0?
以下自分で確認した分。定数は適当
MOTION_GETDAMAGE= 4 -- ダメージをくらった時のモーション
MOTION_SKILL=7 -- スキル攻撃中(インベ、カートレボリューション、ラウドボイス確認)
MOTION_SKILL2= 12 -- ホムにポーションピッチャー時確認
- 216 :(○口○*)さん :06/03/17 22:20
- >>211
ありがとうございます。
板違い申し訳ありません。
今度から気をつけます。
- 217 :(○口○*)さん :06/03/17 22:21
- ちょっと質問。
>>112の汎用オートスキル関数使ってみたんだけど
座標が書き換わったときにタイマ更新って
ケミが移動したらタイマーリセットで意味あってる?
張られたコードだと移動してもリセットされないんだが・・・
どなたかおねがいします。
- 218 :(○口○*)さん :06/03/17 22:30
- >>209
if((MoveTime+MoveTimeDelay) > GetTick())then
これが一番最初に使われるとき
MoveTime+MoveTimeDelayの中身がないから条件を比べることができずに
エラーを吐いた
だからグローバル変数にMoveTime=GetTickとグローバル定数MoveTimeDelay = 500を入れる必要がある
グローバル変数の中身は適当に書いたから好きな数字を入れるといい
- 219 :(○口○*)さん :06/03/17 22:38
- むう…
・ 改変されたスクリプトが次のいずれかに該当する場合、
当社はホムンクルスの利用中止を要請する場合があります。
当社から要請があった場合、ユーザー様は速やかに応じなければならないものとします。
また、当社は予告なく「AI」フォルダのデータを修正・削除することができるものとします。
→本規定に違反している、または不適切なものである場合
→GungHo-ID利用規約およびアトラクション利用規約または別途公式サイトに明示する
個別規定に違反していると当社が判断した場合
→ホムンクルスの利用中止または修正・削除せざるを得ないと当社が判断した場合
下手したらこれに引っかかるな・・・
実装直後にホム中止の危機、か・・・
- 220 :(○口○*)さん :06/03/17 22:43
- >>219
どこのソース?
記事を引用するときはURL張ってほしいお
- 221 :(○口○*)さん :06/03/17 22:44
- 公式で見た気が
- 222 :(○口○*)さん :06/03/17 22:44
- リヒルの紹介、ホム項目の1番下
ttp://www.ragnarokonline.jp/news/play/update060314/homunculus.html
- 223 :(○口○*)さん :06/03/17 22:45
- >>220
公式、リヒタルゼンアップデートの紹介のとこでホムンクルスのAIについて書いてある部分より
http://www.ragnarokonline.jp/news/play/update060314/homunculus.html
これの一番下な
- 224 :(○口○*)さん :06/03/17 22:49
- まだ無いと思うけど、既出だったらすまそ。
GetV (V_TARGET, モブID)
でモブが誰もタゲって居ない場合、戻り値は 0 だった
- 225 :(○口○*)さん :06/03/17 22:51
- ありがとう
ホムをやるためだけに復帰した俺としては
ホムが廃止されれば、RO垢を処分するしかないな(´・ω・`)
- 226 :(○口○*)さん :06/03/17 23:10
- >>雑談スレ68
local ownermotion = GetV(V_MOTION,owner) --主人のモーションを取得
if(ownermotion == MOTION_ATTACK or ownermotion == MOTION_ATTACK2) then --主人が攻撃中なら
result = GetV(V_TARGET,owner)--resultを主人の攻撃対象に
end
function GetOwnerEnemy (myid)ブロックの終わりのほうにあるreturn resultの前に↑をを書き足す
resultをMyEnemyに変えてOnATTACK_ST()内の最初に書けばホムが別の敵を攻撃中でも主人が殴ってる敵にタゲを変えるようになる
動作未確認
- 227 :(○口○*)さん :06/03/17 23:12
- >>13>>44>>45氏
ありがとうございます。
しかし、また一つ問題点が浮上しました。
デフォAIから>45までAI変更したあと、ALT+右クリックで待機させてるときに敵の攻撃を食らうと
462行目 attempt to compare function with numberとエラーがでます・゚・(ノД`)・゚・
- 228 :(○口○*)さん :06/03/17 23:21
- >>226
なるほど、ケミのモーションからとればよかったのか…
GetMyEnemyAの中にケミが草やキノコを殴ったら攻撃を仕掛けるよう仕込んでみたんだが
ケミが殴るのをやめてもホムが対象を殴り続けてたのです_| ̄|○
(´・ω・`)ありがとう、こっちを使わせてもらうよ。
- 229 :(○口○*)さん :06/03/17 23:38
- /traceai というコマンドがあるのを知り早速やってみた
2006ウ・3ソ・17タマ 23ステ 34コミ 50テハ OnIDLE_ST
何かと思ったら年月日時分秒がバグってんのな
- 230 :(○口○*)さん :06/03/17 23:38
- ぜろまての人が「switch文がないとはなんたるちあ!」と書いていたので、それっぽいコーディングを投下。
場所はAIの状態によって振り分ける部分。
これでだいぶ見やすくなるはず。
local switch = {
[IDLE_ST] = function() OnIDLE_ST() end,
[CHASE_ST] = function() OnCHASE_ST() end,
[ATTACK_ST] = function() OnATTACK_ST() end,
[FOLLOW_ST] = function() OnFOLLOW_ST() end,
[MOVE_CMD_ST] = function() OnMOVE_CMD_ST() end,
[STOP_CMD_ST] = function() OnSTOP_CMD_ST() end,
[ATTACK_OBJECT_CMD_ST] = function() OnATTACK_OBJECT_CMD_ST() end,
[ATTACK_AREA_CMD_ST] = function() OnATTACK_AREA_CMD_ST() end,
[PATROL_CMD_ST] = function() OnPATROL_CMD_ST() end,
[HOLD_CMD_ST] = function() OnHOLD_CMD_ST() end,
[SKILL_OBJECT_CMD_ST] = function() OnSKILL_OBJECT_CMD_ST() end,
[SKILL_AREA_CMD_ST] = function() OnSKILL_AREA_CMD_ST() end,
[FOLLOW_CMD_ST] = function() OnFOLLOW_CMD_ST() end,
}
switch[MyState]()
- 231 :13 :06/03/17 23:39
- あ、書き方悪かったかも
function OnFOLLOW_CMD_ST ()
を変更ってのはこの関数自体を全部変更ってことで
function OnFOLLOW_CMD_ST ()
TraceAI ("OnFOLLOW_CMD_ST")
〜〜略〜〜
end
end
まで
function OnFOLLOW_CMD_ST ()
return
end
に入れ替える、と
>>227
function OnHOLD_CMD_ST ()の
local d = GetDistance(MyEnemy,MyID)
を
local d = GetDistance2(MyEnemy,MyID)
に修正してない予感。試してないけど予感
- 232 :(○口○*)さん :06/03/17 23:55
- ホムが移動するときに、進路上に遠距離攻撃で位置固定のMob
(ヒドラ・マンドラ・フローラ・ジオ・将軍様)がいた場合
その射程内に入らないように避けて歩く、ってのができると思ってるんですが
ヒントとかいただけないですかね。なんだかよくわからない。
- 233 :(○口○*)さん :06/03/17 23:58
- GetV(V_HOMUNTYPE,ID)で遠距離攻撃モンスターか判定
その後、射程値を元にその射程外を動くようにMoveすればいいと思う
射程外を動くようにする方法は考えればいくらでも思いつきそうなので割愛
- 234 :(○口○*)さん :06/03/18 00:02
- >>231氏
function OnHOLD_CMD_ST ()の
local d = GetDistance(MyEnemy,MyID)
の部分。
local d = GetDistance2
に修正した後(MyEnemy,MyID)を削っちゃダメなんですね y=ー( ゚д゚)・∵. ターン
無事に問題解決しました。ありがとうございます。
- 235 :(○口○*)さん :06/03/18 00:03
- >>215
プレイヤーは即倒れるけど、敵は半透明になって消えるからその時なのかも?
いや適当だけど。
スキルや被ダメージみたいな少ないモーションは拾いにくいね。
>>226
これ、敵が倒れた後も V_TARGET の戻り値が残ったままになることがあるかも。
自分もGetMyOwner に主人を狙う敵だけじゃなく、主人が狙ってる敵も狙えって感じにしてたら
敵が死んだ後も同じ標的に対して MYOWNER_ATTACK_IN が起きてた。
mobやホムにも起きうるなら標的が消えた後も攻撃しようとしてスタックすることがあるのかもしれない。
IsOutOfSight も入れたら問題なく動くようにはなったけど。
あとペットのHOMUNTYPEはそのmobと同じみたいね。IsMonsterあたりで区別してんだろうか。
- 236 :(○口○*)さん :06/03/18 00:04
- やるのはいいけど、敵複数匹がいるときに
それぞれの位置間隔が悪いと
避けれなくなって止まるか、あらぬ方向にいきそうだな。
- 237 :(○口○*)さん :06/03/18 00:07
- ペットとかホムンクルスとか
種類ごとにある程度IDの範囲が決まってるっぽい
現にホムンクルスはプレイヤーに比べて一桁低いIDだし
ペットは……あまりデータが集まってないからなんともいえないけど
- 238 :(○口○*)さん :06/03/18 00:10
- 現在の仕様ならAI組まなくても大丈夫だな、
試しにヒドラ池にホム吶喊させてみれば分かる。
間違って主人も突っ込まないように注意
- 239 :(○口○*)さん :06/03/18 00:31
- >>232
>>238が言うように位置固定mobからはホムはタゲられないみたい
今さっきAlt+右で将軍のお膝元まで持っていったけど無反応だった
- 240 :(○口○*)さん :06/03/18 00:33
- やっつけだけど>>174用の羊移動関数作ったんで貼り付け。
必要なグローバル変数なんかは適宜宣言してください。
ちょっとおかしいとこあるかもしれないけど、>174のバグを取り除いた状態で動作確認済み。
----------------------------------------------------------------------
-- ケミから少し離れる
----------------------------------------------------------------------
function RemoveFromOwner()
-- ここにケミから少し離れる処理を書く
local x, y = GetV(V_POSITION, MyID)
if FlgRemove==false then
local radian = GetSafeDirection() --*1
local dx, dy = math.floor(REMOVEDISTANCE*math.cos(radian)), math.floor(REMOVEDISTANCE*math.sin(radian))
MyRemoveX, MyRemoveY = x+dx, y+dy
Move(MyID, MyRemoveX, MyRemoveY)
FlgRemove=true
end
Count = Count+1
if x==MyRemoveX and y==MyRemoveY or Count>15 then
FlgRemove = false
Count = 0
return true
end
return false
end
----------------------------------------------------------------------
*1 移動する方向を求める関数。
- 241 :239 :06/03/18 00:37
- 追記
一度位置固定mobにタゲ取られると画面外に出るまで
GetV(V_TARGET,id)が得られるので注意
非先行AIで一発殴られてから攻撃範囲外→コールホムすれば
位置固定mobに殴りに行くのですぐ分かる
- 242 :(○口○*)さん :06/03/18 00:38
- ----------------------------------------------------------------------
-- GetSafeDirection()
-- 最も安全な方向を取得する
-- 戻り値
-- 安全な方向をラジアン値で返す
-- 東を0とし、反時計回りをプラスとする
-- この関数では値の範囲は0〜2πとなる
----------------------------------------------------------------------
function GetSafeDirection()
local result = 0
local actors = GetActors()
local radian = 0
local atk, atk_x, atk_y = 0, 0, 0
for i, v in ipairs(actors) do --周りのID全てを処理
if IsActiveMonster(v) then --IDがアクティブモンスターならば *2
radian = GetRadian2(MyID, v) --ホムから見た角度を取得 *3
atk = GetMobData(M_V_ATKMAX, id) --MobのAtkを取得 *4
if atk~=nil then --Atkが取得できたら
atk_x = atk_x + atk * math.cos(radian) --AtkをX方向へ分解
atk_y = atk_y + atk * math.sin(radian) --AtkをY方向へ分解 それぞれ足していく
end
end
end
if atk_x==0 and atk_y==0 then --敵Atk分布が一様なら
result = GetRadian2(MyID, MyOwner) --ケミの方向を危険とする
if result==nil then --ケミと同一座標なら
result = 0 --東を危険とする
end
else --分布に偏りがあれば
result = math.atan2(atk_y, atk_x) --分布が濃い方向が危険
end
result = result + math.pi --反対方向を安全とする
return result
end
----------------------------------------------------------------------
- 243 :(○口○*)さん :06/03/18 00:44
- *2 IsActiveMonster(id) -> idがアクティブモンスターか調べる
*3 GetRadian2(id1, id2) -> id1から見たid2の角度を求める
*4 GetMobData(M_V_, id) -> idがMobなら対応するMobデータを取得
*注意点!!前スレ912のmobdata.lua必須です。
----------------------------------------------------------------------
- 244 :(○口○*)さん :06/03/18 01:27
- age
- 245 :(○口○*)さん :06/03/18 01:35
- shift+alt+右クリックでマウスジェスチャみたいなの実装した人居ないかな?
連続したMove_CMDがGetResmsgで帰ってくる筈だから、座標の位置関係をジェスチャとして
扱えそうな気がするんだけど
- 246 :(○口○*)さん :06/03/18 01:44
- 前スレの855にある一撃目をカリプスで攻撃、と言うAIを使いたいのですが
何やらいろいろ問題あった?らしく後から修正いっぱいあって
どこをどうしたらいいやらわからず困っていますorz
もしよろしければ直されたもの書いていただけないでしょうか(汗
申し訳無いです_| ̄|○
- 247 :(○口○*)さん :06/03/18 02:00
- >>246
855とは全く違うやり方だが初撃カプリス
まず、MyState = ATTACK_ST ←これが書いてある行を探して、その下に
SKILL_CAPRICE = 8013 --カプリスのIDを定義。どっか別の場所に書いてあるなら省いていい。
SKILL_USELEVEL = 5 --LV5で使用
if ((GetV(V_SP,MyID)/GetV(V_MAXSP,MyID))*100 >= 50)then --SPが50%以上の時
SkillObject (MyID,level,SKILL_CAPRICE,MyEnemy)--スキル使用
end
↑の五行を書き加えれば、初撃にカプリス使うようになる。
- 248 :(○口○*)さん :06/03/18 02:02
- 間違ってたらスマソ
まず下の関数本体をAI.luaの末尾にでも
-- ここから
-- 初撃必ずランダムボルト
function FirstAttackCaprice(level, usesp, spPer)
-- 既に使った
if CapriceFlag == 1 then return end
-- SP足りないので終了
if (GetV(V_SP, MyID) < usesp) then return end
-- 一定率以上SPないと使用しない
local sp = GetV(V_SP, MyID)
local msp = GetV(V_MAXSP, MyID)
if ((sp / msp) * 100) < spPer then return end
local type = GetV(V_HOMUNTYPE, MyID)
if (type == VANILMIRTH or type == VANILMIRTH2 or type == VANILMIRTH_H or type == VANILMIRTH_H2) then
local skillCaprice = 8013
SkillObject(MyID, level, skillCaprice, MyEnemy)
CapriceFlag = 1
end
end
-- ここまで
- 249 :前スレ391 :06/03/18 02:03
- >>240
お疲れ様です。よろしければ>>174のどこにバグがあったかを
上げてもらえないでしょうか?こちらでも修正して再UPしますので。
- 250 :(○口○*)さん :06/03/18 02:03
- 247訂正
SkillObject内のlevelはSKILL_USELEVELの間違いでした。腹を切って死ぬべきである。
- 251 :(○口○*)さん :06/03/18 02:06
- 次ぎにファイル先頭あたりの
-- global variableの囲みの最後あたりに
-- グローバル変数
CapriceFlag = 0 -- カプリス使用フラグ
これをコピぺ
最後にOnATTACK_ST ()の下の方の
if (MySkill == 0) then
Attack (MyID,MyEnemy)
else
を
if (MySkill == 0) then
FirstAttackCaprice()
Attack (MyID,MyEnemy)
else
ぐらいかな。
- 252 :前スレ391 :06/03/18 02:10
- if (MySkill == 0) then
FirstAttackCaprice()
Attack (MyID,MyEnemy)
else
ここは、
if (MySkill == 0) then
-- レベル3、消費SP26、SP残50%以上で使用
FirstAttackCaprice(3, 26, 50)
Attack (MyID,MyEnemy)
else
こうですね。
- 253 :(○口○*)さん :06/03/18 02:13
- OnATTACK_ST() で、戦闘中ランダムで攻撃スキルを使うという処理を
させてるんだけど、これだと実際のASPDと関係なく秒間に何回も試行
されるんで、時間あたりにすると予想以上に高確率になっちまうんだよな。
発動率を極小にするか、適当にディレイを入れるしかないのかねぇ。
実際の攻撃とリンクさせる方法があればいいんだけど、やっぱ無理?
- 254 :(○口○*)さん :06/03/18 02:15
- って>>251間違いまくりorz
------------------------------------------
-- global variable
------------------------------------------
の下あたりに
CapriceFlag = 0 --カプリス使用フラグ
CapriceLevel = 1 --カプリス使用レベル
CapriceUsesp = 22 --カプリス使用SP
SkillUseLimit = 60 --カプリス使用残SP%
を追加
OnATTACK_ST()の下の
if (MySkill == 0) then
Attack (MyID,MyEnemy)
else
を
if (MySkill == 0) then
FirstAttackCaprice(CapriceLevel,CapriceUsesp,SkillUseLimit)
Attack (MyID,MyEnemy)
else
追加
OnIDLE_ST()
の先頭あたりに
CapriceFlag = 0 --カプリス使用フラグリセット
を追加
これであってるかなorz
- 255 :(○口○*)さん :06/03/18 02:19
- 公式のAIフォルダを落として
ROのフォルダにつっこんだのですが、エラーがでてキャラがログインできません・・
何かしなければならない操作があったら教えてください。
- 256 :(○口○*)さん :06/03/18 02:23
- 玩具Dでよく困るんだけど、ホムがタゲらてた、または攻撃されてHP80%↑
の場合、安息を使うみたいなのって出来る?
あと、スキル使用で一番最初の攻撃時にスキルをspが○○%時に何%の確率で
使用みたいなのってできる?
- 257 :(○口○*)さん :06/03/18 02:29
- 初撃カプリス訂正版。よりシンプルに。
if ((GetV(V_SP,MyID)/GetV(V_MAXSP,MyID))*100 >= 50)then --条件式
MySkill = 8013 --スキルID
MySkillLevel = 5 --スキルLV
end
- 258 :(○口○*)さん :06/03/18 02:33
- >>256
安息はケミスキル。ケミにスキル使わすのはBOTと同意
- 259 :(○口○*)さん :06/03/18 03:04
- 標準のAIの動作をまとめた図を描いてみました。
せっかくなので、ご参考にどうぞ。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2963.gif
おかしいとこあったら、ご指摘くださいな( ´(ェ)`)
- 260 :(○口○*)さん :06/03/18 03:36
- -- id:対象モンスター
function CanAttack( id )
local actors = GetActors()
-- IDがタゲってる敵を取得
-- 何かをタゲっていてそれがホムでもマスターでもない
if( GetV( V_TARGET , id ) ~= 0 and
GetV( V_TARGET , id ) ~= ホムID and
GetV( V_TARGET , id ) ~= ケミID ) then return 1 end
for i , v in ipairs( actors ) do
if( IsMonster( v ) ~= 1 ) then
if( GetV( V_TARGET , v ) == id ) then return 1 end
else
end
end
local eTarget = GetV( V_TARGET , id )
if( eTarget == 0 ) then return 0 end
if( eTarget == ホムID or eTarget == ケミID ) then return 0 end
return 1
end
横殴りがウザイので、敵を殴っていいかの判断ルーチンを投げてみる
ついでにデバグよろw
- 261 :(○口○*)さん :06/03/18 03:37
- >>259
GJ、有り難くいただいた
TraceAI追うのに使えそうなだ
- 262 :(○口○*)さん :06/03/18 03:38
- >>230
なるほど、左辺を[]で括ると評価するのか。
でもこれでいいかな。
[IDLE_ST] = OnIDLE_ST,
もともと
function OnIDLE_ST() end
と
OnIDLE_ST = function() end
が等価で、変数にfunction型が代入されているだけだから
特別なことをしないなら、それをコピーするだけでいい。
ただしもちろん関数定義後ね。
- 263 :(○口○*)さん :06/03/18 03:39
- >>260
それだと完全にソロ専用になるな
- 264 :(○口○*)さん :06/03/18 03:42
- >>240
私もオートキャスリング使ってみたいのですが、AIについて詳しくないので
どうしたら使用できるか教えていただけないでしょうか?
- 265 :(○口○*)さん :06/03/18 04:11
- >>259
この図を期に気になってた点を質問してしまいますが
ターゲットを一回ALT+右クリックした状態はホムに何も影響を与えないって事ですか?
ダブルクリックして初めてメッセージを拾える、と……
- 266 :(○口○*)さん :06/03/18 04:14
- キャスリング見るたびに羊使いたくなる
が、対象指定スキルが無いのが困るんだよな
攻撃したくないMOBのID取得したり(MOBIDリスト使ってないので、これでジオ様殴らないようにしてる)できない
カススキルでいいから、羊に対象指定のスキル追加されないかなぁ
- 267 :(○口○*)さん :06/03/18 04:36
- >>265
/traceaiで見る限りでは、
ターゲットをALT+右クリでターゲッティングしても何もおきなくて、
ALT+右ダブクリ または、ターゲッティング後にさらにALT+右クリ
をした場合にATTACK_OBJECT_CMDイベントが発生するようです。
- 268 :(○口○*)さん :06/03/18 04:41
- 「ホムがMob殴ってタゲが来たら、
飼い主のから距離3マスの位置をぐるぐる回って逃げる」
とかやったら
ケミ側は射程2の敵を殴る事になるから
Mobのが1マス詰めるのにかかる時間分だけ
被ダメを減らせるようになるかな・・・
・・・とか思ったけど、
敵の移動速度とか、
Mobが殴ってきたホムをタゲって追尾ロックした位置、
ロックし直した位置によってホムの移動頻度日調節しないと
ケミに常に2マス殴りさせる距離を維持するのは無理なことに気付いた。
- 269 :(○口○*)さん :06/03/18 05:11
- ちょいと質問よいですか?
現在以下の様にフリットムーブを使っているのですが
FleetMoveDelay = 0
function OnAutoSkill_CMD_ST ()
Skilllevel = 1-- 使用するスキルレベル
SPEmpty = 30-- 使用後SPがこの%以下になる場合は使用しない
IN_SKILL_FLEETMOVE = 8010
FMSPGain = 20 + (Skilllevel * 10)--消費SP
FMSkillLimittime = 65000 - (Skilllevel * 5000)--持続時間
local casting = false
local type = GetV(V_HOMUNTYPE, MyID)
local HomunculusSP = GetV (V_SP,MyID)
local HomunculusMaxSP = GetV (V_MAXSP,MyID)
if (type == FILIR or type == FIRIR2 or type == FILIR_H or type == FILIR_H2) then
if HomunculusSP < FMSPGain then
return
end
if (FleetMoveDelay == 0) then
if (SPEmpty < ((HomunculusSP - FMSPGain) / HomunculusMaxSP)*100) then
FleetMoveDelay = GetTick() + FMSkillLimittime
casting = true
end
else
if (FleetMoveDelay <= GetTick()) then
if (SPEmpty < ((HomunculusSP - FMSPGain) / HomunculusMaxSP)*100) then
FleetMoveDelay = GetTick() + FMSkillLimittime
casting = true
end
end
end
if (casting == true) then
SkillObject(MyID, Skilllevel, IN_SKILL_FLEETMOVE, MyID)
end
end
end
- 270 :269 :06/03/18 05:12
- 続き
これに加えてオバードスピードも使用しようと
function OnAutoSkill2_CMD_ST ()
以下略
のように組んだ所、発動条件が重なる為片方しか発動してくれず、何とか時間差で使いたいけど
タイムタンプを取る方法や試してみたがうまくいかず。
他に良いアイデアが思いつかず困ってる。
なんとかならないだろうか。
- 271 :前スレ391 :06/03/18 05:37
- >>269
>>270の関数の内容が載ってないからなんとも言えないのですが、
ひょっとしてOnAutoSkill2_CMD_ST関数内でもFleetMoveDelay変数使って
ないですか?FlletMoveDelay変数はインターバル用変数でスキル毎に用意
して別に管理しないとだめです。
- 272 :(○口○*)さん :06/03/18 05:41
- >>269
条件が重なるってのが良くわからないのですが
OnIDLE_ST ()内で、こんな↓かんじで呼んだらいいのと違う?
/**********************************************************/
if (FleetMoveDelay < GetTick()) then
OnAutoSkill_CMD_ST ()
elseif (OverSpeedDelay < GetTick()) then
OnAutoSkill2_CMD_ST ()
end
/**********************************************************/
- 273 :(○口○*)さん :06/03/18 06:25
- >>269
やあ一昨日の俺。
おそらくモーションディレイ中に次のスキルを使用しようとして、
発動しないけど失敗判定ができなくて効果時間の設定だけしてる。だから動かない。
例をあげてみる
SKILL_INTERVAL = 1000
Skill_Delay = 0
こんな感じの変数をグローバルに作っておいて
OnAutoSkill_CMD_ST ()
OnAutoSkil2l_CMD_ST ()
それぞれの最初の方に
if (Skill_Delay > GetTick()) then -- モーションディレイ中は使用しない
return;
end
これを追加。
そして
SkillObject(MyID, Skilllevel, IN_SKILL_FLEETMOVE, MyID)の後に
Skill_Delay = GetTick() + SKILL_INTERVAL
これを追加する。
あとはOnATTACK_STの中でも同様に処理しておけばOK。
- 274 :269 :06/03/18 06:37
- >>271
変数のミスはないです。
270の関数は
-FleetMoveDelay
+OverSpeedDelay
-IN_SKILL_FLEETMOVE = 8010
IN_SKILL_FLEETMOVE = 8011
それだけです。
>>272
アドバイス感謝。
その方法で試してみたけど、やはり片方しか使ってくれませんでした。
条件が重なるというのは
発動条件がAI初期化後、同時に両方の関数を呼び出す。と言う事です。
スキルの発動が重なる為どちらか一方しか使ってくれません。
os.time()を利用して、フリートムーブ使用後にタイムスタンプを踏むようにし
オーバードスピードの発動条件にタイムスタンプ後x秒としてみても
やはり片方しか使ってくれませんでした。
- 275 :(○口○*)さん :06/03/18 06:45
- オーバードスピードが実はFlee増加せず、未実装と言う罠
- 276 :269 :06/03/18 06:55
- >>274
感謝
最後は
if GetTick() - AUTOSKILL_TIMER > 1000 then
OnAutoSkill_CMD_ST ()
U_AUTOSKILL_TIMER = GetTick()
end
なんてのを呼び出しに混ぜてたお陰で発動しなかったけど。
チェックを外したら普通に発動するようになったので、とりあえずは問題なしです。
ステ画面では一応Flee上昇はしてるけど…まさか数値だけ?
元々大して避けないから体感でも判断しにくいけど。
- 277 :(○口○*)さん :06/03/18 07:22
- >>雑談スレ86
先攻型AIでケミから12セルより離れてる敵は索敵対象としない処理
function GetMyEnemyB (myid)
の中の
if (1 == IsMonster(v)) then
という行を
if (1 == IsMonster(v) and GetDistance2(owner, v) <= 14-2) then
に変更するといけそうです。
草とかで簡単に試せます。
- 278 :(○口○*)さん :06/03/18 08:59
- >>259
わかりやすいね。
細かいことだけどFOLLOW_ST は敵を認識しないね。
- 279 :(○口○*)さん :06/03/18 09:32
- ttp://pc3merchant.net/ai/escort.html
少々力技だけど、友達登録なしで他のキャラを護衛するAIを作ってみた。
他のキャラを援護するというか、他のキャラをオーナーであるかのように騙す感じだが。
そんな仕組みな都合で、他のキャラにくっついてるときは、ケミは放置プレイ。
- 280 :(○口○*)さん :06/03/18 10:26
- 一撃目にカリプスできました!
ありがとうございました_|\○_
- 281 :(○口○*)さん :06/03/18 10:28
- >217
ゴメン、色々不備があったorz
修正するたびにここに貼り付けるのはウザいんで
アルケミテンプレの「スキル自動化」を参照して下さい。
- 282 :(○口○*)さん :06/03/18 10:44
- MOTION_PICKUP = 5 -- 拾う
- 283 :(○口○*)さん :06/03/18 10:47
- ミスって送信しちまった(´д`;)
MOTION系であと埋まってないのは8、10、11かな?
- 284 :(○口○*)さん :06/03/18 11:19
- dofile("AI/USER_AI/AI.lua")
でAIリロードできるからうまく組み込めばAI弄くってるときの安息コールホムのSP節約になるかもしれない
- 285 :155 :06/03/18 11:36
- >>159-161を貼り付けて質問させて頂いたものです。
申し訳ありませんが再度質問させて下さい。
他PCの取得を間違っていた部分(>>159の10行目)は修正出来たのですが
まだまともにタゲをとりません。一体どこが悪いんでしょうか…。
IDLE_STなども弄っていたのでGetMyEnemy以外がどこかいけないのかと思い、
試しに鳥のデフォAIのGetMyEnemyBだけを
>>159-161に差し替えたものを使ってみたところ
改造AIと同じく敵に攻撃しなくなりました。不具合があるのはやはり敵取得のようです。
その状態から色々検証してみましたが
・自分を攻撃している敵には反撃する(→>>159の敵リストAはちゃんと取得している)
・傍に敵がいても攻撃せず、主人の叩いている草も攻撃しない(→>>160の敵リストBは結果に反映されない)
・>>161の1〜11行目を削って実行しても(敵リストBだけを判定に使っても)
攻撃はしないまま(→敵リストBの内容そのものが取得出来ていない?)
このようになりました。なので>>160の
『ノンアクティブの敵の中から標的リストを作る』
という部分が何か悪いんだと思いますが
何回見返しても理由がさっぱり分かりません。
どうか間違いの分かる方、ご指摘をよろしくお願いします。
- 286 :(○口○*)さん :06/03/18 11:40
- >>283
モーション8は「詠唱中」っぽい。
ケミのエモ監視して、デモンストレーション使用で発生を確認。
- 287 :(○口○*)さん :06/03/18 11:52
- なあなあ、
io.open()とio.output():write()でファイルに出力できるけど、
これを外部プログラムで読みこんでほにゃららっていうのは・・・
いいのかなぁ?
していいのなら何か風なのができそうな予感するが。
- 288 :(○口○*)さん :06/03/18 11:58
- >>286
MOTION_CASTING = 8 -- 詠唱中
こんな感じか
- 289 :(○口○*)さん :06/03/18 11:59
- >>287
それは外部ツール使用で普通にアウトだろ
- 290 :(○口○*)さん :06/03/18 12:05
- >287
ついにホムに喋らせる事が出来るというわけか…
まあ>289だが。
io関数くらい潰しておけよと(´д`;
- 291 :(○口○*)さん :06/03/18 12:08
- >>283
スリムピッチャーでモーション28を確認…
なんで一気に28まで飛んでるんだろう?
アシデモでも28かな?
- 292 :(○口○*)さん :06/03/18 12:09
- でも別に研究用とかにTraceAIの代わりとして使うのはいいんだよな?
TraceAI使いづらくて苦手なんだ
- 293 :(○口○*)さん :06/03/18 12:13
- 会社のスパゲッティよりはマシだぜ!!
- 294 :(○口○*)さん :06/03/18 12:19
- まとめてみた
MOTION_STAND = 0
MOTION_MOVE = 1
MOTION_ATTACK = 2
MOTION_DEAD = 3
MOTION_DAMAGE = 4 -- ダメージをくらった時のモーション
MOTION_PICKUP = 5 -- 拾う
MOTION_SIT = 6
MOTION_SKILL = 7 -- スキル攻撃中(インベ、カートレボリューション、ラウドボイス)
MOTION_CASTING = 8 -- 詠唱
MOTION_ATTACK2 = 9
MOTION_PP = 12 -- ポーションピッチャー
MOTION_SLIMPP = 28 -- スリムポーションピッチャー
- 295 :(○口○*)さん :06/03/18 12:22
- >>291
クリエイターでの追加スキルだから、かな?
- 296 :(○口○*)さん :06/03/18 12:24
- モーションの7は1次職、12は2次職、28は転生2次職のスキルとか?
- 297 :(○口○*)さん :06/03/18 12:25
- >>287,289
参考までに・・・
・前スレ960で、TraceAI()の出力テキストをブラウザで見るモノが紹介されている。
・前スレ853で、エクスプローラ+ファイル名で簡易状態表示するAIが紹介されている。
どこまでを「規約違反の外部プログラム」と見るか、だよね。
例えば極論をいえば、/savechatした結果をテキストビューアで見たって
「外部プログラムは使用」してるけど、これを違反ってのはいくらなんでも無茶。
- 298 :(○口○*)さん :06/03/18 12:32
- なんか本当に欲しい機能が無くて、潰さなきゃいけない機能が残ってるんだよねぇ
ホム発言はセキュリティー上と世界観上(?)ダメかもしれないけど
ホムエモ制御は欲しかったよ、あと空腹度取得
- 299 :(○口○*)さん :06/03/18 12:39
- そうなんだよね・・・
「Yes」「No」だけでもいいから、ホムからの意思伝達専用の手段が欲しかった。
今でも、移動などで「逃げ回る」とかの表現はできるんだけど。
- 300 :259 :06/03/18 12:42
- >>278
確かに・・・
ALT+Tコマンドで、
点線で囲った状態遷移の集合を切り替えていることを
(索敵して攻撃する状態と、召還者を追いかけるだけの状態)
言いたかったんだけど、なんというか表現悪いですね。
ん〜どうしよ・・・まぁいいか(笑)
- 301 :前スレ391 :06/03/18 12:43
- >>174のバグ取りとともに>>240氏が作成された退避関数を組み込んだ、
羊さん用緊急時キャスリング自動使用関数を再UPしました。
私のホムはリーフなので、キャスリング使用部分を緊急回避に変えて
テストしたところ、問題なく動いたので大丈夫なはずです。
#条件をケミの敵1匹、HP残り100%で使用するにしてポポリン殴ったら
#退避してから緊急回避を使用した。
ファイルをデフォルトAI.luaと同じフォルダに置いて、AI.lua内に
2行追加するだけで動作するようになるはずです。
#詳しい場所はAutoSkill.lua内に記述。
興味ある方はダウンロードしてみてください。
ttp://www.eonet.ne.jp/~sneakers/AI/AutoSkill.lua
- 302 :(○口○*)さん :06/03/18 12:43
- >>279
Util.luaのGetOwnerPositionの箇所を
return GetV(V_POSITION,EscortTargetID)
に、書き換えてescort.luaをAI.luaにリネームしてUSER_AIには入れてみたんだけど
ALT+右クリでPCの隣に移動させてもついていってくれないんだ
他にやることってありますか?
- 303 :(○口○*)さん :06/03/18 12:48
- MOTION_ATTACKとMOTION_ATTACK2の違いは武器の違いじゃないでしょうか?
短剣や素手の時の「突き」っぽいモーションと、
片手剣や斧の時の「斬り」っぽいモーションみたいな。
入金してないので未確認ですが・・・
- 304 :(○口○*)さん :06/03/18 12:50
- 289>>
297>>
なら倒した敵のTypeをfileに書き出しして
後でgrepでも使って
killCountを数えるくらいなら…これも灰色っぽい(´・ω・`)
- 305 :(○口○*)さん :06/03/18 12:53
- 倒した数の割りにMOTION_DEADの確認数が少ない罠
倒した後もしつこくGetVで取得し続けてようやく取れるという微妙さ
あんまりMOTION_DEADの意味がない気がしてきた
- 306 :(○口○*)さん :06/03/18 12:56
- MOTION_DEADは一応チェックしておかないと、索敵時に結構ひっかかってるよ。
Get〜〜Enemy()のループ内でモーションチェックして、MOTION_DEADをはずしただけで、
結構軽快になった記憶がある。
- 307 :(○口○*)さん :06/03/18 13:00
- >>297
俺の記憶では、規約違反とみなすのはクライアントに直接干渉または
覗き見するプログラムだった気がするんだが・・・。
- 308 :(○口○*)さん :06/03/18 13:11
- 質問なんですが
等速移動だとパケ送りまくりで負荷がかかるようですが
0-materialのAIをそのまま使ったら等速移動時にパケ送りまくりですか?
送りまくり状態なら>>65の修正を追加でOKですか?
- 309 :(○口○*)さん :06/03/18 13:12
- >>305
主人がMOTION_DEADだったらホムも隣のセルに来て無抵抗状態となり、二人で安らかに眠るとか
- 310 :(○口○*)さん :06/03/18 13:13
- 私は>>65のはあまりオススメしないなぁ
もっと前にいいのがあったはず、どこだか忘れたが
- 311 :(○口○*)さん :06/03/18 13:14
- パトラッシュ
- 312 :(○口○*)さん :06/03/18 13:16
- モーションの12は投げる動作だと思ってたけどケミでしか見て無いからなぁ
槍投げと石投げ、取れる人居たらお願いしますorz
該当しそうな物だった
敵撲滅後の揺れるモーション、エサを食べるモーション、ペットパフォーマンス --> 立つ
罠設置 --> 拾う
武器の種類による攻撃 --> 全部同じ(プリの本杖鈍器素手)
未チェックの該当予想は
バード、ダンサーの演奏モーション、アサシンのカタールと2刀の2撃目
騎士のBB、Bdsの発動前の硬直モーション、この辺りかな
mobの固有モーションの可能性もあるけど
9は検知無し、拾う、投げる等は殆ど一瞬、死ぬに居たっては直後にAIが終了するので本当に↓の様な物で無いと難しい
function AI (myid)
fp = io.open("AI/USER_AI/motion.txt", "a")
if(fp == nil) then return end
Ty = GetV(V_MOTION,id)
fp:write( string.format("%s\n", Ty) )
fp:close()
end
ioの入出力テキストをどう見るかは各自主観が入るだろうからヘルプデスクに各自直接聞いてくれ
クライアントに直接干渉してはいないがそれを快く思わない人が居るのは確かだし
まぁスレの空気悪くしない様に、違反か?を問うスレじゃないからさ
- 313 :(○口○*)さん :06/03/18 13:19
- >>307
わたしの記憶もその通りです。
懸念しているのは、ROクライアント本体だけでは一般ユーザーにはわからないが、
ホムを使うとわかるというのは確かにある、という事実。
これを表に見せてしまうのは、リスクがありそうかな〜、というのがわたしの懸念事項。
まあ、クライアントで取れる情報だから違反じゃない、ともいえますが・・・
ルールに書いてないからやっていい、ってもんじゃないですし。
わたしの心配しすぎ、という話は否定しませんので、そのあたりはご理解ください。
- 314 :313 :06/03/18 13:22
- 指摘感謝。
本件、このあたりで撤退します。
お騒がせしました。
- 315 :(○口○*)さん :06/03/18 13:25
- 殺す時は一瞬しかでないけど>>306の言うように
周囲をサーチしてる時は結構引っかかってる
もしかしてMOTION_DEADって取得できるタイミング二つある?
- 316 :(○口○*)さん :06/03/18 13:28
- >>312
そうですね、ヘルプディスクに直接聞いてみることにします。
お騒がせしましたm(_ _)m
- 317 :(○口○*)さん :06/03/18 13:32
- >>315
モーションっていう言葉から考えて、MOTION_DEADって「死んで倒れていく」途中の絵なんじゃないかな。
だから倒したAttack()の直後では、まだ敵のモーションは通常orダメージのまま。
(うまくタイミングが合ったときだけ、倒れていく状態に見える)
で、こちらのホムAI制御が一度抜けて、次のAI()呼び出し時には、さすがにすでに「その敵が死んでいく」状態が見えているんじゃないかと。
- 318 :(○口○*)さん :06/03/18 13:39
- こちらのAIでは
GetVのMOTION取得で死亡判定
↓
GetVの座標取得で死亡判定
↓
どちらでもないなら攻撃
って感じで攻撃させているんだが、MOTIONで引っかかること自体が稀で
いつも座標値の取得で対応させてる感じ
だから>>317だとしたらちょっと辻褄が合わないと思う
- 319 :(○口○*)さん :06/03/18 13:42
- >>296
コールホムンクルスとコーディング系はモーション7でした。
1次、2次、転生2次とか関係ないんじゃないかな。
- 320 :(○口○*)さん :06/03/18 14:59
- >>285
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2964.zip
そちらの予定する機能と同じものを作ってみたので、参考になれば。
- 321 :(○口○*)さん :06/03/18 15:43
- >>312
後、固有モーションとしてはモンクスキルなんかが結構多い。
連打掌、猛竜拳使用直前、猛竜拳、発勁使用直前等
全部モーション異なるからね。
Odin鯖なら、検証に付き合えるよ。
- 322 :(○口○*)さん :06/03/18 15:56
- トレースしてて判明したんだけど、
修正をもっとも手軽に反映させる方法
ホムに画面はじへ移動命令→自分はその逆へ歩く→ホムが戻ってこない→合流
これでAIが読み直されて、トレース文の変更が確認できた
- 323 :(○口○*)さん :06/03/18 16:14
- >>321
モンク・・・白刃と残影も可能性あるかな
Odin鯖(´・ω・`)キャライナイ
>>322
[AIの(再)読み込みはホムが画面に現れる全ての時]
ってばにるみぃーが言ってた
- 324 :(○口○*)さん :06/03/18 16:18
- -- ホム4*4種(未実装)の条件分岐が面倒な場合の小ネタ
-- 剰余演算子'%'は非対応だった[lua5.1〜]
function GetHomunType (id)
return math.mod(GetV(V_HOMUNTYPE,id)-1,4) + 1
end
- 325 :(○口○*)さん :06/03/18 16:28
- コードが長くなってきたから2つのファイルに分けてコード書いたんだけど…
なぜか拡張側のコードでおかしなループになってるらしくホムが途中から動かなく…
かれこれ12時間近く格闘してるけど原因ワカンネ
誰かタスケテ
||||orz
HTML
ttp://www.uzukisyou.nobody.jp/AI2.html
zip
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2966.zip
〜バグの詳細〜
・オートスキルを仕様できるよう新たなコードを組んだものの、
謎のループになってしまったらしく
ホムが攻撃をしない and その場に固まるといった不具合仕様になっている
・TraceAI.txt見るとホム逃亡行動の文でループになってるっぽいと思い、
ホム逃亡のスクリプト抜いてみたら今度は他の処理でループになった…
ワケワカンネ
・コードが長くなったので2ファイルに分けてます、
AI_2.luaをAI.luaと同じフォルダにいれてください
・ホムが動き固まるだけで、エラー落ちはしないようです
ALT+Tでホムの動きをリセット可能
- 326 :(○口○*)さん :06/03/18 16:35
- 横殴り対策にプレイヤーの周囲の敵攻撃しないようにしていました。
んで、ホムも含めようと思ったんだけどプレイヤーからの値は職業が戻るわけだな。
そして一般職(追加は4000番代)の値は 0〜23 が使われていて、実際プレイヤーのIDいれるとこの値が来る。
そして、ホムの値は 1〜16。
値がかぶってます。
ホム自身は区別できるけど他人のホムがわかりません。
あと、IsMonster は名前がこれだから勘違いしてたんだけど
対象がモンスターかどうかじゃなくて攻撃できるか否かだね。
通常mobやバイオプラントも攻撃できるから 1 だし。
PvPいったらプレイヤーも 1 が返ってきた。
- 327 :(○口○*)さん :06/03/18 16:37
- まあ、プレイヤー側かどうかってことなら 0〜23 と4000番代いれればわかるからいいんだけどね。
他人のホム見つけて追いかけたりとか遊んでみたいよ。
- 328 :(○口○*)さん :06/03/18 16:43
- 以前に一撃目でカプリスを…の質問をした者なのですが
カプリスを敵の居る位置へ行く前に使いたいと思いいろいろ変えていたのですが
function OnCHASE_ST ()
の最初の方に>>247さんの5行を入れると近いものができました
しかしあまりにも遠距離の為迷惑になるかな?と思い
とりあえず敵の周囲3セルとかでカプリスを1回、
そのまま1セルまで近づいて通常攻撃、と言う流れにしてようと思ったのですが
if ((GetV(V_SP,MyID)/GetV(V_MAXSP,MyID))*100 >= 20)then
local x, y = GetV (V_POSITION,MyEnemy)
if (MyDestX ~= x or MyDestY ~= y) then -- DESTCHANGED_IN
MyDestX, MyDestY = GetV (V_POSITION,MyEnemy);
local ax,ay = GetV(V_POSITION,MyID)
if (MyDestX < ax) then
MyDestX = MyDestX+3
elseif (MyDestX > ax) then
MyDestX = MyDestX-3
end
if (MyDestY < ay) then
MyDestY = MyDestY+3
elseif (MyDestY > ay) then
MyDestY = MyDestY-3
end
Move (MyID,MyDestX,MyDestY)
TraceAI ("CHASE_ST -> CHASE_ST : DESTCHANGED_IN")
return
end
SKILL_CAPRICE = 8013
SKILL_USELEVEL = 5
SkillObject (MyID,SKILL_USELEVEL,SKILL_CAPRICE,MyEnemy)--スキル使用
end
を元のlocal x, y = GetV (V_POSITION,MyEnemy)の前に追加してみました
3セル前までは行くのですが、その後スキルを使ってくれずそのまま追いかけてしまいますorz
原因はなんなのでしょう?
- 329 :(○口○*)さん :06/03/18 16:49
- 最初のif文で
if (MyDestX ~= x or MyDestY ~= y) then-- DESTCHANGED_IN
敵の足元じゃないとスキル使わないようになってないか?
- 330 :(○口○*)さん :06/03/18 16:57
- >>325
MyStateがオートスキル関係(AUTOSKILL_STやLIF_ST)の状態になった後、
そのままなのでループ脱出できないのかと。
- 331 :155 :06/03/18 17:09
- >>320
おお、見事に自分のやろうとした事が再現されている…
条件分岐を大量に枝分かれさせるよりも
こちらの方がスマートですね。大いに参考になります。
手元に置いてちょくちょく参照させてもらいながら頑張ってみます。
もし挫折しちゃったらそのまま使わせて頂くかもですが…。
わざわざ作って頂いてありがとうございました!
- 332 :(○口○*)さん :06/03/18 17:12
- オートスペルにするならOnSKILL_OBJECTを呼び出せばいい。
初撃だけにしたいならOnIDLE_STの敵判定の直後に OnCHASE_STじゃなくて そっちを呼び出せばできる。
一定タイミングなら OnATTACK_ST内 で判定しないといかんが。
ところでボトルモンスター判定させたいのだけどマリンスフィアのIDってchar_tableに一個しかないからこれなのかな?
これだと通常mobと全く区別つかなくなってしまうのだけど。
- 333 :(○口○*)さん :06/03/18 17:22
- AIの副産物みたいなもんだけど、
割と便利な?ライブラリあげとく。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2967.zip
require "./AI/USER_AI/ailib.lua"
require "./AI/USER_AI/helper.lua"
を上のほうに置いて、
一番下のAI関数の二箇所に追記
else
List.clear (ResCmdList) -- 新しいコマンドが入力されたら、予約コマンドは削除する
ProcessCommand (msg) -- コマンド処理
end
+ DispatchEvents( EVENT_BEGIN_STATE )
-- 状態処理
if (MyState == IDLE_ST) then
〜省略〜
elseif (MyState == FOLLOW_CMD_ST) then
OnFOLLOW_CMD_ST ()
end
+ DispatchEvents( EVENT_END_STATE )
end
- 334 :(○口○*)さん :06/03/18 17:23
- で、どこでもいいので
function IsValidMyEnemy() -- MyEnemyがいるかどうかを返す
return MyEnemy > 0
end
function EventFunc()
TraceAI( "MyEnemy: "..tostring( MyEnemy ) )
end
SetEvent( EVENT_BEGIN_STATE, IsValidMyEnemy, EventFunc )
みたいなのを書くと、
毎回 DispatchEvents( EVENT_BEGIN_STATE ) のところで
IsValidMyEnemy が呼ばれて、結果が真なら EventFunc を呼ぶ
毎回必ず EventFunc を呼びたいなら
SetEvent( EVENT_BEGIN_STATE, true, EventFunc )
でおk。
他の言語で言うグローバル変数を使わないので、
他人のコードとうまく共存させたい時なんかに便利かも
- 335 :(○口○*)さん :06/03/18 17:24
- >>308
等速移動の実装有無でパケット量を計測してみた
結果は秒間あたりせいぜい数百bytes増える程度
単純にグラボの能力不足とか描画側の問題な希ガス
- 336 :(○口○*)さん :06/03/18 17:34
- ホムのDEFの意味なささを見てると羊のディフェンスは罠スキルだなぁ
Lv5で10しかあがらんし
せめて%上昇だったら…
- 337 :(○口○*)さん :06/03/18 17:35
- 誤爆した(;´Д`)
- 338 :333 :06/03/18 17:38
- スキルレベルをユーザー入力に使う方法。
OnSKILL_OBJECT_CMD 関数に
function OnSKILL_OBJECT_CMD (level,skill,id)
TraceAI ("OnSKILL_OBJECT_CMD")
+ if SkillCommandToKeyMsg( level, skill, id ) then
+ return
+ end
MySkillLevel = level
MySkill = skill
MyEnemy = id
MyState = SKILL_OBJECT_CMD_ST
end
を追記、
次にどこでもいいので
function KeyFunc( id )
TraceAI("Caprice Lv1 Called")
end
local CAPRICE_LEVEL = 1
SetKeyConfig( CAPRICE_LEVEL, SKILL_CAPRICE, KeyFunc )
みたいなコードを置く。
これで敵に向かってカプリスLv1を使うと KeyFunc が呼ばれます。
- 339 :333 :06/03/18 17:53
- あとは、
local EAVOID_DELAY = 36000
local EAVOID_LEVEL = 3
SetSkillInterval( LIF, 120, EAVOID_DELAY, EAVOID_LEVEL, SKILL_EMERGENCY_AVOID )
とかやると
ホムがリーフで、SPが120以上のときに、36秒ごとに緊急回避Lv3を使う、
とかの機能ぐらいかな。
- 340 :(○口○*)さん :06/03/18 17:56
- 既出かもしれないがIsMonsterみたいな物をあげてみる
------------------------------
--IDがNPCのものか?
------------------------------
function IsNPC(id)
local TypeID = GetV(V_HOMUNTYPE,id)
if((TypeID > 45 and TypeID < 126) or (TypeID > 699 and TypeID < 1000)) then
return 1
end
return nil
end
------------------------------
--IDがプレイヤーのものか?
------------------------------
function IsPlayer(id)
local TypeID = GetV(V_HOMUNTYPE,id)
if(((TypeID >= 0 and TypeID < 24) or (TypeID > 4000 and TypeID < 4046)) and id > 99999) then
return 1
end
return nil
end
------------------------------
--IDがホムンクルスのものか?
------------------------------
function IsHom(id)
local TypeID = GetV(V_HOMUNTYPE,id)
if((TypeID >= 0 and TypeID < 12) and id < 100000) then
return 1
end
return nil
end
- 341 :(○口○*)さん :06/03/18 18:14
- GMキャラのもわかればいいんだけどねえ。どっかに載ってないかな。
- 342 :(○口○*)さん :06/03/18 18:29
- 等速移動でMoveを大量に実行するのを直してみました。
タイマーのための変数も必要ありません。
function OnFOLLOW_ST ()
TraceAI ("OnFOLLOW_ST")
local x, y
if (GetDistanceFromOwner(MyID) <= 3) then -- 主人との距離が3以内
MyState = IDLE_ST -- IDLE_STに遷移
TraceAI ("FOLLOW_ST -> IDLW_ST")
return;
elseif (GetV(V_MOTION,MyID) == MOTION_STAND) then -- モーションが立ちなら
-- TraceAI ("MOTION_STAND") -- デバッグメッセージ出力
MyDestX, MyDestY = GetV (V_POSITION,GetV(V_OWNER,MyID)); -- 目的地(主人)算出
Move (MyID,MyDestX, MyDestY) -- 移動
TraceAI ("FOLLOW_ST -> FOLLOW_ST")
return;
elseif (GetV(V_MOTION,MyID) == MOTION_MOVE) then -- モーションが移動なら
x, y = GetV (V_POSITION,MyID) -- 現在の位置を取得
if (math.abs(x-MyDestX)+math.abs(y-MyDestY) < 3) then -- 目的地が一定距離以内なら
-- TraceAI ("MOTION_MOVE Move") -- デバッグメッセージ出力
MyDestX, MyDestY = GetV (V_POSITION,GetV(V_OWNER,MyID)); -- 目的地(主人の位置)算出
Move (MyID,MyDestX,MyDestY) -- 移動
TraceAI ("FOLLOW_ST -> FOLLOW_ST")
else -- 目的地から遠ければそのまま
TraceAI ("MOTION_MOVE NoMove")
TraceAI ("FOLLOW_ST -> FOLLOW_ST")
end
return;
end
end
http://homepage2.nifty.com/potion/hom/follow.lua.txt
通常のOnFOLLOW_ST ()と置き換えて使用してください
- 343 :(○口○*)さん :06/03/18 18:33
- おばぁちゃんの知恵袋
AI( myid )の呼ばれる間隔を計測したら家の環境だと約140msだった。ただし別の要因でクライアントが
重くなったりすると当然この値はのびる。
つまりこの間に複数の変化がおきると取りこぼしが発生する(死亡状態とかね)
>>341
いないものを処理してどうするヨ'`,、('∀`) '`,、
- 344 :308 :06/03/18 18:37
- >>335
あまり気にすることではないようですね
下手に弄っておかしくするよりは
そのまま使うことにします
ありがとうございました
- 345 :(○口○*)さん :06/03/18 18:39
- でもっておいらも小物関数を晒してみる
--------------------------------------------------------------------------------
-- idがリーフかどうかを返す
-- リーフならtrueを違うならfalseを返す
--------------------------------------------------------------------------------
function IsLif( id )
local type = GetV( V_HOMUNTYPE, id )
if( type == LIF or type == LIF_H or type == LIF2 or type == LIF_H2 ) then return true end
return false
end
--------------------------------------------------------------------------------
-- idがアミストルかどうかを返す
-- アミストルならtrueを違うならfalseを返す
--------------------------------------------------------------------------------
function IsAmistr( id )
local type = GetV( V_HOMUNTYPE, id )
if( type == AMISTR or type == AMISTR2 or type == AMISTR_H or type == AMISTR_H2 ) then return true end
return false
end
--------------------------------------------------------------------------------
-- idがフィーリルかどうかを返す
-- フィーリルならtrueを違うならfalseを返す
--------------------------------------------------------------------------------
function IsFiril( id )
local type = GetV( V_HOMUNTYPE, id )
if( type == FILIR or type == FILIR2 or type == FILIR_H or type == FILIR_H2 ) then return true end
return false
end
--------------------------------------------------------------------------------
-- idがバニルミルトかどうかを返す
-- バニルミルトならtrueを違うならfalseを返す
--------------------------------------------------------------------------------
function IsVanilmirth( id )
local type = GetV( V_HOMUNTYPE, id )
if( type == VANILMIRTH or type == VANILMIRTH2
or type == VANILMIRTH_H or type == VANILMIRTH_H2 ) then return true end
return false
end
- 346 :(○口○*)さん :06/03/18 18:40
- その2
--------------------------------------------------------------------------------
-- 囲まれ人数を返す
-- id はホムのid
-- 戻り値は囲まれているMob数
--------------------------------------------------------------------------------
function GetBoxNum( id )
local owner = GetV( V_OWNER, id )
local actors = GetActors () -- 周りのキャラクターidを全部取得
local index = 0
for i, v in ipairs( actors ) do
-- 敵をピックアップ
if( v ~= id and v ~= owner and IsMonster( v ) == 1 ) then
-- オーナーかホムをタゲっているものは敵
local target = GetV( V_TARGET, v )
if( target == id or target == owner ) then index = index + 1 end
end
end
return index
end
--------------------------------------------------------------------------------
-- id1から見たid2の方向(角度)を得る
-- 戻り値:0〜359(右方向=0度、上方向=90、左方向=180度、下方向=270)
--------------------------------------------------------------------------------
function GetDegree( id1, id2 )
local x1, y1 = GetV( V_POSITION, id1 )
local x2, y2 = GetV( V_POSITION, id2 )
local degrees = math.deg( math.atan2( y2 - y1, x2 - x1 ) )
if( degrees < 0) then degrees = 360 + degrees end
return degrees
end
- 347 :(○口○*)さん :06/03/18 18:46
- >277に似たような処理考えていたんだが
1つだけ気になることがあって
主人とホムがはぐれて見えない時には
主人座標情報とホム座標情報はどんなのが返ってくるのか?
実はケミすらまだいないのでこっちでは調べられくて・・・
- 348 :(○口○*)さん :06/03/18 19:04
- >>347
今、ホムを完全に画面外に出して/TraceAIしてみたらAIの処理自体されないみたい。
- 349 :(○口○*)さん :06/03/18 19:13
- 処理自体がないならエラー吐く心配はなくなるかな
それなら設定が楽になりそうだし
簡単な処理作って知り合いに試してもらおう
情報サンクス
- 350 :259 :06/03/18 19:15
- 以下のページに
ttp://www.kmzw.jp/nb/ai.html
・状態遷移図(今朝あぷろだに上げた奴)
・標準AIの各行に日本語の説明書きを加えたAIファイル
・更新中のオリジナルAIファイル
をUPしてみました。
オリジナルのAIで今のところ実装しているのは
-- ・ホムンクルスの種類ごとに索敵条件(先攻型/非先攻型)を設定可能
-- ・待機可能な召還者からの範囲(移動コマンド後戻ってこない範囲)指定可
-- ・攻撃範囲を召還者からの距離で指定可
-- ・待機時に旋回行動指定可
-- ・召還者を追尾している際に遅れないように最適化可
-- +ホムンクルスの初期状態(索敵するか/しないか)を設定可能
ってとこです。
ご自由にお使いください〜
一応、初心者の方にも判るようにしているつもりですが・・・どうかな?
この後は、みなさんの情報を参考にオートスキルとか
戦闘系のカスタマイズをしていこうとおもいます。
それでは、がんばりましょ〜
- 351 :(○口○*)さん :06/03/18 19:33
- ショートカットからのホムスキル即時使用のやりかた。
(ホムが今いる地点でスキルを発動するようになります)
OnSKILL_OBJECT_CMD (level,skill,id)の中の
MyEnemy = id
MyState = CHASE_ST
を
MyEnemy = id
SkillObject(MyID,MySkillLevel,MySkill,MyEnemy)
MySkill = 0
MyState = CHASE_ST
に書き換える。
これでホムスキルをショートカット登録>Mob指定すれば
PCでスキル使用するのと似たような挙動になります。
ただしばにるみーのカプリスでしか動作を確認してないので
鳥でムーンライトしたときにどういう挙動をするかわかりません、あしからず。
- 352 :前スレ853 :06/03/18 19:36
- 続々とAIやライブラリが公開されていますね・・・
独自に組んでいる身としては、感動したり、触発されたり。
やっぱり自分が書いたのよりスマートなのが出ると、ショックですね(笑)
というわけで?こちらも個人的に作成・使用しているAIを改訂公開。
独特なところは・・・ALT+T早押しでの学習モード。
学習モード中でのマウス操作で、以下のような設定ができるようになっています。
-友達登録。横殴り判定との組み合わせですね。
-敵種類ごとの、アクティブ/非アクティブ切り替え。
(例えばポリンは積極的に攻撃、クリーミーは殴らない、など)
-敵種類ごとの、オートスペル的攻撃スキル使用率設定
(例えばカプリスを草には使わず、エギラには高率で使うなど)
独自構築なので、なかなか他のAIとは共通化できないと思いますが・・・
なにかの参考になれば、という位置づけでご利用くださると、幸いです。
- 353 :前スレ853 :06/03/18 19:37
- そしてURL張り忘れ・・・
http://tomose.dynalias.net/RO/attach/hom/Glenelg_011.lzh
- 354 :(○口○*)さん :06/03/18 19:44
- すっごく気が引けるけど質問です
基本AIの289行目が
TraceAI ("FOLLOW_ST -> IDLW_ST")
になってますけどIDLWってIDLEの綴りミスですよね?
- 355 :(○口○*)さん :06/03/18 19:48
- >>351
確認してきた。
ムーンライト射程の設定が無いのか?画面端ギリのモンスターに攻撃可能。
- 356 :(○口○*)さん :06/03/18 19:53
- >354
そうだと思います。WとE、キーボードで並んでますし。
まあデバッグ用出力なので、動かないということはないので気が付かなかったのでしょう(笑)
- 357 :(○口○*)さん :06/03/18 19:56
- てことはムーンライト逃げ撃ちする鳥とか可能なのか。
- 358 :(○口○*)さん :06/03/18 19:58
- 下手するとモンスターのIDさえ拾っていればはるか画面外から攻撃可能かも・・・
- 359 :(○口○*)さん :06/03/18 20:00
- IDが拾える範囲はケミの視覚範囲内
だからメイン関数のAI(myid)も
ホムが視覚範囲外に行ったらmyidが来ないので動かなくなると
私は考えている
- 360 :(○口○*)さん :06/03/18 20:21
- そもそもAI関数自体が実行されてない気がする
>>355
こっちでも攻撃できた
これは卑怯だw
- 361 :(○口○*)さん :06/03/18 20:21
- てか、視野外攻撃はオットーでBOTの射程外狩りが問題になった時に修正されてなかったけ?
- 362 :(○口○*)さん :06/03/18 20:24
- これはホムから見える範囲にいる敵ならどこでもってことだろ
ホムから見えない敵は座標を取得できない
- 363 :325 :06/03/18 20:26
- >>330
returnでは処理を抜けないんですね
|||orz
MyStateなどで強制的に次の処理に移動するようにしてみます
>>332
>>338
そのオートスキルの方法も試してみます
皆様thx!バイトからいってきたら修正してみます
(`・ω・´)
ありがとうございました
- 364 :(○口○*)さん :06/03/18 20:31
- ×バイトからいってきたら修正してみます
○バイトいって帰ってきてから修正してみます
日本語変だよ自分(つдT)
Luaについて調べようとグーグル先生使ってたけど、情報案外少ないんですね…
Lua独特の関数とかさっぱりわからないけど自分なりにメモ帳でゴリゴリコード組み立てていきます
- 365 :259 :06/03/18 20:32
- >>351,355
うわ、ほんとだ。
スキルの攻撃範囲制限無いのか・・・
標準AIだと、SKILL_OBJECT_CMDイベントの後、
CHASE_ST状態に遷移して、敵の位置まで移動してから
ATTACK_ST状態に遷移して攻撃するのを、
SKILL_OBJECT_CMDイベントの後、
すぐにATTACK_ST状態に遷移したら、遠距離スキルになってしまうのか。
まさか、ATTACK_OBJECT_CMDイベントの後に
すぐにATTACK_ST状態に遷移したら、遠距離攻撃可能とか!
そんなわけないよね( ´(ェ)`)・・・ないよね!(゚д゚)
- 366 :(○口○*)さん :06/03/18 20:43
- >>365
>>351はATTACK_STには遷移してないぜー。
標準AIだと
スキル使え!(SKILL_OBJECT_CMD)
→接近(CHASE_ST)
→通常攻撃射程に入った(ATTACK_ST)
→スキル使う!(SkillObject)
なのを
スキル使え!(SKILL_OBJECT_CMD)
→スキル使う!(SkillObject)
→接近(CHASE_ST)
にしてるだけ。
にしても射程は設定するべきだよ重力…
- 367 :(○口○*)さん :06/03/18 20:46
- 通常攻撃も!って思ったら使えなかった…
射程未設定はスキルだけみたいだね
- 368 :259 :06/03/18 21:00
- >>366
あ〜はいそうですね。
イメージとしての動作を書いたので、実際のソースの話ではなかったのです。
紛らわしくてすいません。
>>367
私も、まさかとおもって、
ATTACK_OBJECT_CMDイベント直後に物理攻撃させたら、
その場で、鳥がぴくぴく死にかけみたいに震えて攻撃できませんでした(笑)
さすがに、物理攻撃には射程あるみたいです。
ただ、AIでスキルの射程が決まっているとすると
仕様なのか、不具合なのか判断が難しいですね。
今、公式HP見ても特に書かれていなそうだし・・・
- 369 :(○口○*)さん :06/03/18 21:02
- 周囲プレイヤーの有無によるアクティブノンアクティブの自動切換えスクリプト作った
以下OWNのBBSに乗せたときの奴をコピペ
もっと効率的に、便利に同じ以上の動作できるスクリプトすでに出来てたら、これ忘れておくれ(ω・`
--*****************プレイヤーID入手用ルーチン***********************
function GetPlayers (myid)
local result = 0
local PCowner = GetV (V_OWNER,myid)
local PCactors = GetActors ()
local PCPlayers = {}
local PCindex = 1
for PCi,PCv in ipairs(PCactors) do
if (PCv ~= PCowner and PCv ~= myid) then
if (IsMonster(PCv) == 0) then
PCPlayers[PCindex] = PCv
PCindex = PCindex+1
end
end
end
local min_PCdis = 50 --ここの数値を変えるとプレイヤーキャラに対する反応距離が変わる(はず)
local PCdis
for PCi,PCv in ipairs(PCPlayers) do
PCdis = GetDistance2 (myid,PCv)
if (PCdis < min_PCdis) then
result = PCv
min_PCdis = PCdis
end
end
return result
end
--*****************************************************************************
↑をAI.luaの適当な位置にコピペ
- 370 :(○口○*)さん :06/03/18 21:02
- 続き
次に
--************************アクティブ・ノンアクティブ自動切換え**********************
local Players = GetPlayers (MyID)
TraceAI (string.format("Players:%d",Players))
if (Players ~= 0) then
result = GetMyEnemyA (myid)
else
result = GetMyEnemyB (myid)
end
--*******************************************
↑を「function GetMyEnemy (myid)」のところの「result = GetMyEnemyB (myid)」と
「end」の間にコピペ。(その際result = GetMyEnemyA (myid)の行頭に「--」を入れてスクリプトを殺す)
よくわかんなかったら「function GetMyEnemy (myid)」の下の「if (type == LIF or type」からreturn resultのすぐ上の「end」までの
各行頭に「--」をいれてスクリプト殺して、return resultの上の行にコピペ。
注意事項は、あくまで自動切換えで、任意での切り替えは無理。だからダンジョンとか行くと
周りに誰もいない場合突撃しまくって死ぬ可能性が高い。
デフォルトノンアクティブのAIを保存しておいて、ダンジョンに行くときはそっち等に
切り替えるなどの作業が必要。
あくまで他人に迷惑をかけないためのスクリプトなのでその辺よろしく。
(命令文の受付部分を弄くれば任意で切り替えられるかも)
ちなみに、デフォルトAIのモンスター索敵部分を少しいじって作った。
- 371 :(○口○*)さん :06/03/18 21:12
- まだ完成してないけど公開してみる。
無駄にSubversionを使ってみたw
http://project.ariela.jp/repository/HomunculusAI/trunk/Library/
- 372 :(○口○*)さん :06/03/18 21:24
- IsInAttackSightの
if (MySkill == 0) then
a = GetV (V_ATTACKRANGE,id1)
else
a = GetV (V_SKILLATTACKRANGE,id1,MySkill)
end
を
if (MySkill == 0) then
a = GetV (V_ATTACKRANGE,id1)
else
a = 100
end
に変えちゃえば手動使用では遠距離スキルに早代わりするね
思ったんだけど、ID取得ってクローキングしている人のIDを取得できる?
取得できそうならGvでバイオプラントの代わりに使えると思ってるんだが
- 373 :MvMwAXGR :06/03/18 21:47
- >思ったんだけど、ID取得ってクローキングしている人のIDを取得できる?
>取得できそうならGvでバイオプラントの代わりに使えると思ってるんだが
うちは試してないなら分からんけど、たぶん取得できると思う
クローキングとかは多分視覚的に見えなくなってるだけだとおもうので。
- 374 :(○口○*)さん :06/03/18 22:18
- >>373
クローキングしてるかどうかの判断はどこでやるんだ?
- 375 :(○口○*)さん :06/03/18 22:21
- >>374
完全妄想だけどモーションで取得できたりしてな
- 376 :(○口○*)さん :06/03/18 22:42
- >375
昨日やってみたけどクローキング中は取れなかった
ただし、クロキン連打してたらクロキンのディレイ中だかモーション中かなんか知らんがMOTION 8 になった
- 377 :(○口○*)さん :06/03/18 22:45
- おまえら、あんまりそういう方向に可能性を広げようとするなよ
ホム廃止の可能性があることを忘れないでくれ
- 378 :(○口○*)さん :06/03/18 22:47
- アインマップでポリンポポリン、ドロップス、盗蟲をアクティブで、
ポルセリオ、メタリンをノンアクティブにする設定はどのようにするのでしょう?
今のところこのようなものを作りましたが、エラー落ちシマス
local target = GetV(V_HOMUNTYPE,TargetID) -- MOBのIDを取得
if(target == 1002 or target == 1031or target == 1131 or target == 1051) then ) then -- もし、ターゲットがポリンかポポリンかドロップスか盗蟲だったら
result = v --攻撃する
end
- 379 :(○口○*)さん :06/03/18 22:53
- なぜthenが二個あるのか聞きたい
もし打ち間違えじゃないのなら、エラーの原因はそれだ
- 380 :(○口○*)さん :06/03/18 22:53
- それBOTみたいなもんだよ
- 381 :(○口○*)さん :06/03/18 22:54
- そこの一文だけ抜かれてもなんで ") then" 2個あるのとしか言いようが
- 382 :(○口○*)さん :06/03/18 22:56
- >>377
いやまあ、現時点(何も弄らないデフォルトの設定)でも
・タゲった対象がクロークした場合、攻撃できないながらも追跡はする
仕様なんよ。ぶっちゃけ、デフォルト透視AIを癌が配布してると言ってもいい。
そこから取得される情報を洗い出すのは、極めて自然な流れだよ。
可否の判断を下すのは癌であって、我々ホムユーザーでも、外野でもない。
また癌が否と判断した場合、事前に通告を出すだろうから、それに従えばいい。
BOTBOT言われて気になるのは判るが、ホムのAIとBOTはまったくの別物だ。
BOT呼ばわりする人間が無知なだけで、こちらが気にする必要は微塵も無い。
- 383 :(○口○*)さん :06/03/18 23:01
- とおっしゃっております
- 384 :(○口○*)さん :06/03/18 23:05
- >>382
釣れますか?
- 385 :378 :06/03/18 23:18
- すまん。プログラムは学校で少しかじったくらいなので・・・
変わりに作ってくれる人いないだろうか。
組み込み先はノンアクティブ設定のところだ。
- 386 :(○口○*)さん :06/03/18 23:27
- >>385
とりあえず、助言を実行してみたらどうだろう
- 387 :(○口○*)さん :06/03/18 23:31
- >>385
そしてTargetIDはMyEnemyにしておくといい。
- 388 :(○口○*)さん :06/03/18 23:34
- >378
簡単に見た範囲では
result = v --攻撃する
resultとvについて全くわからない
簡単にいじるならこんな感じ?
local target = GetV(V_HOMUNTYPE,MyEnemy) -- MOBのIDを取得
local result = False
if(target == 1002 or target == 1031or target == 1131 or target == 1051) then --略
result = true --true攻撃する
end
resultを使用した処理をこの後に追加すれば使えそう
- 389 :(○口○*)さん :06/03/18 23:34
- AIの内容サパーリなんですが、AIフォルダの中にある
AI、Const、Utilの3つのファイルは何が違うんですか?何のために3つにわけてあるの?
- 390 :(○口○*)さん :06/03/18 23:37
- >>389
何の為のテンプレだ
ttp://www.sgv417.jp/~winter/alchemy/manual.html
公式AIを読み解くならここの解説に一旦目を通すんだ、それでほぼ把握できるはず
- 391 :(○口○*)さん :06/03/18 23:39
- >>389
その3つは、それぞれ別のことが書いてある。
3つあわせて、1つのプログラム。
3つに分けてあるのは、プログラムを書くときのセオリー。
1つのソースファイルに全部を書くと、ファイル全体が大きくなって見づらいので、分けてある。
- 392 :(○口○*)さん :06/03/18 23:40
- >>385
作ったぞ。ただし動作未確認。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2972.zip
- 393 :(○口○*)さん :06/03/18 23:44
- >389
ぶっちゃけると内容をファイル1つにまとめて作っても使えないことはないんだけど
自分のPCのデータが増えたらフォルダで整理するでしょ
自分のPCにあるデータをフォルダで整理しないで
全部がデスクトップに並べてある状態なんてやらないでしょ?という感じの事
ファイル3つに分かれている理由は
プログラムの整理整頓だと思っていい
- 394 :(○口○*)さん :06/03/18 23:46
- >>389
ROやめた方がいいかと思います
- 395 :378 :06/03/18 23:49
- >>392 ありがとう。
動作確認完了しました。
- 396 :(○口○*)さん :06/03/19 00:01
- >>394
その言い方はあんまりといえばあんまりだ
まあ>>389の質問もどうかとは思うが
- 397 :(○口○*)さん :06/03/19 00:06
- AIがそれなりに形になったので晒してみます。
自分用なのでバニルにしか対応してませんが。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2973.zip
パラメータ設定次第で前衛になったり、後ろに陣取って後衛に徹したり、
最初だけスキル使ったり、スキル使いまくったりします。
- 398 :(○口○*)さん :06/03/19 00:54
- Move関数でいける場所といけない場所の判定処理って誰かやってる人いる?
索敵中に行けない場所の敵を殴りに行こうとしてホムがスタックするのを
どうにかして直したいんだがいい方法が思いつかないorz
- 399 :(○口○*)さん :06/03/19 00:58
- >>284追記
_LOADED = {}
dofile("AI/USER_AI/AI.lua")
としないとうまくリロードされなかった。
requireが2重ロードを防ぐために_LOADEDテーブルを使っているらしい。
- 400 :(○口○*)さん :06/03/19 00:58
- プログラム全くわからない者ですが、他の方のAIを参考にさせて貰って、
自分に必要な機能だけを搭載するAIを作るトコまでこぎつけました。
ですが、困ったことに、どうもMAP内にいるMobをホムが上手く捕捉してくれないようなのです。
どういう状況かというと、1匹目は普通に捕捉してくれるのですが、それを倒してもまだMAP内にMobがいるのに、
2匹目のMobに向かって行ってくれないという状況が起きるのです。
主人が少し動いてMobに近づくなりすると、捕捉してくれるようなんですが……。
こちらにAI晒したらどなたか助言していただけますでしょうか?
- 401 :(○口○*)さん :06/03/19 01:02
- まずコードを見ないことには助言できるかどうかの判断すらできんぜよ。
それでもあえて助言するならば、/traceaiで自分のAIがどういう動作してるかチェックするといい。
- 402 :(○口○*)さん :06/03/19 01:06
- >>369-370
のやつと
>>388
のを組み合わせて、周囲に他のプレイヤーがいないときだけ特定モンスターに対してのみ
アクティブになるスクリプトにしてみた
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2974.zip
>>369-370を追加したスクリプトの-- 先攻型 GetMyEnemy部分に
数行の変更を加えただけだけど、だいぶ実用的になったと思う。
動作としては、一定範囲の周囲に人がいないときに一部ルートモンスターを自動排除
ちなみに対人判定は>>370のまま入れたので、デフォルトでは鳥ともう一つのホムしか自動アクティブにはならないはず
先攻ルーチンの最短距離と>>369の対人反応距離をいじればフレキシブルに反応距離を調節できるはず。
- 403 :(○口○*)さん :06/03/19 01:07
- >>301
前スレ391さんへ
無事動きました。
これで楽しく羊と狩りができそうです!
キャスリングでもっと綺麗にタゲが移ればもっといいんですが、
これはスキルの仕様だから仕方ないですねZzz
- 404 :(○口○*)さん :06/03/19 01:08
- 確かにそれもそうですよねorz
↓コチラにうp晒してみました。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2975.zip
/traceaiやってなかったので、それもやってみます。
- 405 :(○口○*)さん :06/03/19 01:09
- 地面に落ちている、ドロップアイテムのIDって取れます?
ODで狩りしてて、PPできなくて邪魔なので、
そのセルにアイテムあったら移動するって設定にしたいのだが。
- 406 :400 :06/03/19 01:10
- >>401さん
すみません、404=400です。
連投申し訳ないです。
- 407 :(○口○*)さん :06/03/19 01:11
- >>398
とりあえずやってみた。
以下の関数をどっか適当に記述。
----------------------ここから---------------
function HomSTOPCHK ()
local x, y = GetV (V_POSITION,MyID) -- ホムの現在座標を取得
if (x == x2 and y == y2) then -- 停止している
if(StopTime ==0) then -- 停止し始めた時間が取得されてないなら
StopTime = GetTick() -- 停止し始めた時間を取得
end
if((StopTime+StopLimit) < GetTick()) then -- 停止時間が長いようであれば
TraceAI ("停止時間が長いので移動をキャンセルしました")
MyState = IDLE_ST -- ホム状態を待機状態にする
end
else
StopTime = 0
end
x2, y2 = GetV (V_POSITION,MyID) -- ホムの現在座標を停止判定用に取得
end
----------------------ここまで---------------
次にglobal variableに
StopLimit = 3000 -- ホムが停止してる場合に、追従状態に以降するまでの時間 (単位はミリ秒)
StopTime = 0 -- ホムが停止し始めた時間の格納用
x2 = 0 -- ホムの停止判定用
y2 = 0 -- ホムの停止判定用
以上4つを追加。
StopLimit = 3000は適当に数値弄ってもよし。
推奨は1000-3000。
みっつめ。
function OnCHASE_ST ()の一番最後に
HomSTOPCHK ()
を記述。
実際には「行けない場所の判定」はしてないんだが長時間のスタックは防げる、はず。
- 408 :(○口○*)さん :06/03/19 01:14
- >>398
一応うちはこんな感じでなんとか動いてる
でも、なんか不安定なような……
「1セルも動けなかった」判定が怪しい感じ
ttp://lliorzill.hp.infoseek.co.jp/ai.html#ignorecell
- 409 :1M801HtA :06/03/19 01:16
- ちょっと今自分で動作テストしたけど、初期値100とかなってるのって、100セルってことだったのね…
100を1桁台に書き換えないとかなり遠くのMOBまで反応して画面外の他人とタゲかぶるかもしれない
- 410 :(○口○*)さん :06/03/19 01:19
- >407
軽く眺めてみて気になったこと
1、endが1つ多い気がする
2、多少工夫をしないと
戦闘が3秒超えた場合に戦闘を停止してしまわないかな?
3、SP回復のために停止させておいてケミが動くって設定にも問題はない?
- 411 :(○口○*)さん :06/03/19 01:25
- >>369-370のGetPlayers関数だが、チェックがIsMonsterだけじゃ不十分な希ガス。
>>326によればIsMonsterは攻撃可能かどうかだけを調べるみたいだし、だとすると>369のコードだと「GetActorsで取得できて、殴れないオブジェクト」はPCとみなされてしまう。
つまりNPCやWP、ギルドフラッグなんかもPCとみなしてしまうんじゃなかろうか。
きちんとV_HOMUNTYPEでの判断を入れたほうがいいと思う。
- 412 :(○口○*)さん :06/03/19 01:32
- >>245
遅レスだけど、たぶん同じようなものを実装してます
ソースはあげてないけど前スレで一度報告ずみ
- 413 :(○口○*)さん :06/03/19 01:32
- >>409
画面外も何も、主人から見える範囲の情報しか取得できないみたいだから
実際に画面外までは取得出来ないから問題ないはず
- 414 :407 :06/03/19 01:36
- >>410
1.最後のendはHomSTOPCHK関数の終了のendなので過不足は無いはず。
2.「CHASE_ST時に移動が出来ていないようなら待機状態に戻す」
という関数なので戦闘時には動作しないはず。
3.2の回答と多少被るけど、デフォAIに>>407を増やしただけならたぶん問題ない。
他の方の書いたAIとの競合でならSP回復を阻害することがあるかもしれない。
まあ場当たり的な関数なのでIDLEに戻ったあと移動不可能なセルを挟んだ相手にタゲられたら
またスタックする可能性があるんだ。どうしよう。
- 415 :409 :06/03/19 01:38
- >>413
画面端の方だと画面外の遠距離職がタゲってる可能性があるので…
当方、昔ハンターやってたのでその辺が気になって気になって(笑
とりあえずいまは8セルくらいに調整しました。
ルートモンスターはほかっといても足もとに集まってくるのでだいじょうぶだろう…。
- 416 :(○口○*)さん :06/03/19 01:45
- >407
それだと単純にMoveで移動させたときのスタック対策には使えるんだけど
索敵した時に、IDや座標から殴りにいけるかいけないかの判定に使えないん
で今回は使えないかも・・・すまん。
>408
IgnoreCell のリストを作るってのは面白いですな。
それ系でちょっくらいぢって見ます。
THX
- 417 :408 :06/03/19 01:54
- >>416
ごめんなさい説明の最初の
Enemy追加の条件に and IsNotIgnoreCell(v) == true を追加
OnChese_ST () の「-- ENEMY_OUTSIGHT_IN」の条件に or IsNotIgnoreCell(v) == false を追加
の部分さっきまでandとorが逆だった、この状態が正しいです
しかしホムが迷ってる時間が長い。
もっと効率良くリストを作成・リセットできればいいんだけどねぇ
- 418 :(○口○*)さん :06/03/19 02:19
- >>404
GetEnemyB内のメタリンかどうか判断するタイミングがおかしい。
404のAIだと、最寄のMobを抽出してからそれがメタリンかどうか調べているので、最寄のMobがメタリン以外だと画面内にメタリンがいてもresultは0になってしまう。
enemysにMobのIDを保存する時に、メタリン以外なら保存しないという風にすれば正しく動作すると思う。
- 419 :400 :06/03/19 02:21
- すみません、ちょっとうたた寝をしてましたorz
>>407さん
ありがとうございます。
早速試してみますね。
ところで、/traceaiをしてみたんですが、全く意味がわかりませんでしたorz
- 420 :378 :06/03/19 02:37
- アクティブノンアクティブの奴で、
mobdate.luをいじって
MOBDATA[1001] = {'スコーピオン',0}
MOBDATA[1002] = {'ポリン',1}
MOBDATA[1004] = {'ホーネット',2}
0=攻撃しない
1=通常のみで攻撃
2=スキルを一定確率で使用し攻撃
っていうルーチンできないかな。
GetMyEnemyC、GetMyEnemyDとかもできるのは確認した。
後は行動を分ける数字を取得するところだけなんだが。
- 421 :400 :06/03/19 02:46
- いま、試してみました。
どうやら418さんの言うような状況のようです。
407さんのを導入しても、他のMobが近くにいる時には反応しませんでしたorz
ただ、407さんのはこのままスタック防止として組み込ませていただこうかと思います。
ありがとうございました。
418さんの言うとおりに書換えようかと思ったんですが、
言語の知識が全くないもので、どこをどういじっていいやら全くわからないので、
とりあえず、現行のまま使用してみることにします。
お二方ありがとうございました〜。
- 422 :378 :06/03/19 03:13
- 今のところ2パターンで悩んでる
function GetMyEnemy (myid)
local result = 0
local mobact = MOBDATA[id][M_V_ACT] --行動を取得
if (mobactid == 0) then
result = GetMyEnemyA (myid) --0ならば攻撃しない
elseif (mobactid
== 1)then
result =GetMyEnemyB (myid) --1ならば攻撃する
end
return result
end
- 423 :378 :06/03/19 03:15
- なんかおかしく貼り付けられた・・・
- 424 :(○口○*)さん :06/03/19 03:18
- >>421
動作未確認だけど改善方法。
GetMyEnemyB 内の
if (GetV(V_HOMUNTYPE, result) ~= 1613) then
result = 0
end
を削除。
そのあとこれまた GetMyEnemyB 内の
if (dis < min_dis) then
result = v
min_dis = dis
end
を
if (dis < min_dis) then
if (GetV(V_HOMUNTYPE, v) == 1613) then
result = v
min_dis = dis
end
end
に書き換える。
これで多分いけるが動作確認はしてないのでバックアップはとっておいてな。
378の悩んでるのも似たようなやり方でいけるはず。
- 425 :(○口○*)さん :06/03/19 03:24
- >>420
その場合ルーチンの用途と、mobdate.luaを不特定多数の人間が使うモジュールとして考えると、
AI.luaの方でモンスターの種類ID取得したらそのままスクリプトで処理したほうがいいはず。
一応定数を追加して攻撃パターン用の数値を初期値1などで追加、必要に応じて0や2などに使用者が書き換える
という方法もあるけど、mobdate.luaはモンスターのステータスなどのデータライブラリのようなので、
手を加えるのは余り好ましくないはず。(間違って変なところを変えると、帰ってくる値が謝ったものになることもあるので)
AI.lua内でif文を使って、モンスターIDごとに攻撃パターンを分岐したほうがたぶん確実だと思う。
- 426 :400 :06/03/19 03:30
- >>424さん
ありがとうございます!
無事作動しました〜。
- 427 :13 :06/03/19 03:41
- >>13 の改良版
ケミが移動すると停止を解除。ALT+Tで戻すのが面倒な人向け
-- global variable
に
MyOwnerX = 0 -- OwnerのX座標
MyOwnerY = 0 -- OwnerのX座標
を追加
function OnMOVE_CMD_ST ()
の
MyState = IDLE_ST
を
MyOwnerX, MyOwnerY = GetV (V_POSITION,GetV(V_OWNER,MyID))
MyState = FOLLOW_CMD_ST
に変更
function OnFOLLOW_CMD_ST ()
TraceAI ("OnFOLLOW_CMD_ST")
〜〜略〜〜
end
end
を
function OnFOLLOW_CMD_ST ()
local ownerX, ownerY
ownerX, ownerY = GetV (V_POSITION,GetV(V_OWNER,MyID))
if (ownerX ~= MyOwnerX or ownerY ~= MyOwnerY) then
MyOwnerX = ownerX
MyOwnerY = ownerY
MyState = IDLE_ST
end
return
end
に変更
やってることはMyOwnerX,Yにケミの座標を保存しておいて、
停止中に座標が変わったらホムの状態を待機状態に変更してるぐらい
- 428 :378 :06/03/19 03:58
- function GetMyEnemyB (myid)
local result = 0
local owner = GetV (V_OWNER,myid)
local actors = GetActors ()
local enemys = {}
local index = 1
local type
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
if (1 == IsMonster(v)) then
enemys[index] = v
index = index+1
end
end
end
local min_dis = 100
local dis
for i,v in ipairs(enemys) do
dis = GetDistance2 (myid,v)
if (dis < min_dis) then
local mobact = MOBDATE[id][M_V_ACT] -- モンスター名称取得
if (mobact == 1) then
result = v
min_dis = dis
end
end
end
return result
end
- 429 :378 :06/03/19 03:58
- って作ったんだが。エラー落ちしま。
mobdata.luaは
M_V_ACT にして
1 攻撃しない
2 攻撃する
と変更。
起動はいけるんだが、mobが画面内に入るとエラー
落ちする
- 430 :378 :06/03/19 04:05
- ちなみにmobdateの中身はこんな感じ。
--------------------------------------------------
-- constants # 定数 #
--------------------------------------------------
M_V_NAME = 1 -- モンスター名称
M_V_ACT = 2 -- # 行動 #
--------------------------------------------------
-- # 行動 #
--------------------------------------------------
M_ACT_NONE = 1 -- 攻撃しない
M_ACT_ATTACK = 2 -- 通常攻撃
--------------------------------------------------
MOBDATA = {}
MOBDATA[1001] = {'スコーピオン',1}
MOBDATA[1002] = {'ポリン',1}
MOBDATA[1004] = {'ホーネット',1}
- 431 :(○口○*)さん :06/03/19 04:06
- >>427
ケミの移動モーション拾ってきた方が早くないか。
それで問題なく動作してるんだけど。
local ownerMotion = GetV(V_MOTION, GetV(V_OWNER, MyID))
if ( MOTION_MOVE == ownerMotion ) then -- 追加した条件
if ( distance > 3 or distance == -1) then -- MYOWNER_OUTSIGNT_IN
MyState = FOLLOW_ST
TraceAI ("IDLE_ST -> FOLLOW_ST")
return;
end
end
デフォルトの状態に「ケミが移動していたら」
という条件を付け加えただけだけど。
ただし、ちょっとしか動かないときは着いてこないこともある。
- 432 :(○口○*)さん :06/03/19 04:13
- >>428っつーか378氏
とりあえず[id]に数値はいってなくてエラー起きてるんだと思うんだ。
あとmobdata.luaは有志の作ってるのと名前が一緒だから
アドバイスする側に多少の混乱を招く。あと正直その使い方じゃもったいない気も。
とりあえず有志のmobdata.luaを使用する前提で話すけど、
ポルセリオとメタリンだけLv高いから(26と28)
if (dis < min_dis) then
local mobact = MOBDATE[id][M_V_ACT] -- モンスター名称取得
if (mobact == 1) then
result = v
min_dis = dis
end
end
を
if (dis < min_dis) then
if(25<MOBDATA[GetV(V_HOMUNTYPE,v)][M_V_LV])then
result = v
min_dis = dis
end
end
にすりゃいけそうな気がする。試してないけど。
- 433 :(○口○*)さん :06/03/19 04:15
- あ、不等号逆だ。
×if(25<MOBDATA[GetV(V_HOMUNTYPE,v)][M_V_LV])then
○if(25>MOBDATA[GetV(V_HOMUNTYPE,v)][M_V_LV])then
こっち。
- 434 :(○口○*)さん :06/03/19 04:30
- カスタムAI使用中だと速度増加がマップ移動で消えることがある…
元のマップに戻ってくると速度アイコンがまた付いたりして
再現条件がまだ判ってないんだけどLIFの緊急避難と関係あるのかな
- 435 :(○口○*)さん :06/03/19 04:36
- ソース見ててふと思ったんだけど、攻撃スキルを使いたいときって、
MySkillに使いたいスキルのID入れて
MySkillLevel = 5とでも入れておけば、
デフォルトのままでもスキル使うんじゃないか?
OnATTACK_ST()の中にスキル使う記述があるし。
- 436 :378 :06/03/19 04:40
- すまんな。あと有志の方もここで謝っとく。
個人的に、mobdateの種類IDと名前を使って
一種ずつ攻撃、非攻撃などの設定を作れば、便利だと思ったんだ。
>>430の設定で
if (1 == MOBDATA[GetV(V_HOMUNTYPE,v)][M_V_ACT]) then
等の設定も試したがだめだったので、ここに質問させてもらった。
今日は一度頭を冷やすことにする。
FFkNnQbkさんやいろいろとありがとな。
- 437 :(○口○*)さん :06/03/19 05:01
- >>435
MySkill = 0 の記述がスキル使用後に入ってるよ。
消したら消したで、今度はSP無いときに攻撃しなくなる。
- 438 :(○口○*)さん :06/03/19 05:18
- 作ったはいいけどエラーが出ますわかりませんっ><
そんな人はまずTraceAIを使って考えた方がいいと思うんだ
- 439 :(○口○*)さん :06/03/19 05:23
- ケミ、クリエスレ412、413を見て
これでいいと思うのだけど
動作確認はしていないので注意
試した人は結果報告お願いします
function OnATTACK_ST ()
TraceAI ("OnATTACK_ST")
if (true == IsOutOfSight(MyID,MyEnemy)) then -- ENEMY_OUTSIGHT_IN
MyState = IDLE_ST
MyEnemy = 0 --これ追加
TraceAI ("ATTACK_ST -> IDLE_ST")
return
end
if (MOTION_DEAD == GetV(V_MOTION,MyEnemy)) then -- ENEMY_DEAD_IN
MyState = IDLE_ST
MyEnemy = 0 --これ追加
TraceAI ("ATTACK_ST -> IDLE_ST")
return
end
- 440 :前スレ391 :06/03/19 05:29
- >>428
local mobact = MOBDATE[id][M_V_ACT] -- モンスター名称取得
この行だけど、
local mobact = MOBDATA[id][M_V_ACT] -- モンスター名称取得
じゃないの?(MOBDATA)
- 441 :(○口○*)さん :06/03/19 06:18
- >>435
一撃目だけスキル使うならそれでいける。>>257とかそれ使ってるし。
- 442 :(○口○*)さん :06/03/19 07:28
- --初撃のみスキル使用しあとは通常攻撃(残SPが30lを越える場合のみ)
function OnATTACK_ST ()
TraceAI ("OnATTACK_ST")
if (true == IsOutOfSight(MyID,MyEnemy)) then -- ENEMY_OUTSIGHT_IN
MyState = IDLE_ST
TraceAI ("ATTACK_ST -> IDLE_ST")
return
end
if (MOTION_DEAD == GetV(V_MOTION,MyEnemy)) then -- ENEMY_DEAD_IN
MyState = IDLE_ST
TraceAI ("ATTACK_ST -> IDLE_ST")
return
end
if (false == IsInAttackSight(MyID,MyEnemy)) then -- ENEMY_OUTATTACKSIGHT_IN
MyState = CHASE_ST
MyDestX, MyDestY = GetV (V_POSITION,MyEnemy);
Move (MyID,MyDestX,MyDestY)
TraceAI ("ATTACK_ST -> CHASE_ST : ENEMY_OUTATTACKSIGHT_IN")
return
end
--SPが余ってる(30l超)場合は攻撃スキル使用(初撃のみスキル使用)
if (GetV(V_SP, MyID) / GetV(V_MAXSP, MyID) > 0.30 and AttackEnemy ~= MyEnemy ) then
if (MySkill == 0) then
MySkill = MOONLIGHT
MySkillLevel = 5
end
end
AttackEnemy = MyEnemy
if (MySkill == 0) then
Attack (MyID,MyEnemy)
else
SkillObject (MyID,MySkillLevel,MySkill,MyEnemy)
MySkill = 0
MySkillLevel = 0
end
TraceAI ("ATTACK_ST -> ATTACK_ST : ENERGY_RECHARGED_IN")
return
end
- 443 :前スレ853 :06/03/19 07:45
- >>420
遅レス&汎用ではない情報ですが。
当方が作成・公開しているAIで、「敵ごとの対応をファイル入出力で対応」している
処理を作っています。
ttp://tomose.dynalias.net/RO/attach/hom/Glenelg_011.lzh
上記内、enemy.lua。
設定ファイルは個人ごとに差があると思うので、独自作成。
当方のはRO画面上で切り替えを行うようにしているので、設定ファイルの内容は
人間には理解しづらい形式ですけど・・・vs_enemy.ini ってファイルの中で
敵種類ID = スキル使用率の標準に対する比率 , アクティブ攻撃するか否か
・・・っていう情報の羅列を作るようにしています。
参考情報まで。
- 444 :(○口○*)さん :06/03/19 08:07
- ゼロマテさんの等速追従ってもしかしてものすごい勢いでルータにアクセスしてる?!
点きっぱなしでなんかコワイ
- 445 :(○口○*)さん :06/03/19 08:16
- >>443
showstateライブラリの作成理由みてだが
Tails Version 2.40などのtail -f系の使用はどうか?
(前スレでJS&ブラウザベースのもあったが)
もちろん専用のログファイルを通して。
これはこれで面白いアイデアだとおもうけどね。
- 446 :443 :06/03/19 08:19
- >>445
情報サンクス。ちょっと調べてみるわ。
まあ、別アプリを極力インストールしたくなかったんで、苦肉の策ではあるんだが(笑)
- 447 :(○口○*)さん :06/03/19 08:27
- >>398
遅いけど>>126に書いたやつじゃだめかな。
特にこれで問題ないのだけど。
- 448 :(○口○*)さん :06/03/19 08:32
- ああ、でもどうせなら126は Move のラッパーとして Move2 でも作って
その中で移動したか否かの判定して true false 返したほうが使い勝手はよいかもしれんなあ。
デフォのは nil しか返さないし。
関係ないけど意外とここの住人多くてなんか嬉しい。
- 449 :(○口○*)さん :06/03/19 09:05
- ファイルの作成&出力ってやっちゃっていいのかなあ。
現状出来ちゃうのが「想定外です!」とか言われると凄く困りそうなんだが
韓国でもやってるしいいのかなあ。うーん。
<chirashi>
まだプログラミングの勉強はじめて一年弱しか経ってないゆえに
皆さんのやり方がすげー参考になるですよ。
遊びながら学べるっていいね!
</chirashi>
- 450 :(○口○*)さん :06/03/19 09:24
- ファイル作成はアリだと思うよ
iniファイル作成して設定保存したり、そのiniで詳細設定やってホムに反映させたり
誰でも好きにカスタマイズできるようなホムスクリプト作るなら必須になると思う
- 451 :(○口○*)さん :06/03/19 09:28
- >>450はなんか違うハナシなような…
- 452 :(○口○*)さん :06/03/19 09:40
- ゲーム内で得たプレイヤー情報やMOB情報を、プレイ中にAIスクリプトのなかから
吐き出していいのか、ってこったな、TRACEみたいに。
- 453 :(○口○*)さん :06/03/19 09:58
- プレイヤーの固有IDを抜いてデータベースを……って前あったよね
あそこまでの情報は抜けないはず
装備やレベル等の情報は取得できない
キャラ固有IDが分かるので、同垢別キャラの判別は出来る
画面内に居るMobの種類は判る
画面内にアイテムが落ちてるのは判るがアイテムの種類は判別できない
実験してないから適当かもしれないけど
こんな感じの仕様なんじゃない?今って
外部に書き出せても問題にならないんじゃないかな?
間違った情報書いてなんとかNEWSに拾われても困るんで間違ってたら訂正して・・・
- 454 :(○口○*)さん :06/03/19 10:08
- 要は、人間がROクライアント画面から取れるどおりの情報を、ホムが取れればいいんだけどね。
キャラの名前が取れず、代わりにIDがとれているのが、微妙なところ。
敵の名前やスキル名(ID)なんかもそうだね。仕方なくはあるんだけど。
それ以外は、ホムが知ることができない情報はあっても、ホムでしか取れない情報はないと思う。
これだけだとアレなので、ちょっと質問なんですが・・・
現状、GetV( V_HP 〜)類で取れるのは、自ホム&自ケミのデータだけだよね。
これ、PT組んでたら、そのPTメンバーのものって取得できますかね?
さすがに1人では調査しようがないので、誰か試みたことがある人がいれば、情報お願いします。
- 455 :(○口○*)さん :06/03/19 10:32
- なんかどんどん怪しい方向に進んでないか
- 456 :(○口○*)さん :06/03/19 11:12
- function GnGHO_ST ()
TraceAI ("GnGHO_ST")
if (true == SonTaizo(MyID,MyEnemy)) then -- ENEMY_GUNGHO_IN
MyState = GAMBATTE_MAS
MyEnemy = GUNGHO
TraceAI ("GRAVITY_ST -> GUNGHO_ST")
return
end
if (GUNGHO_DEAD == GetV(V_MOTION,MyEnemy)) then -- GUNGHO_DEAD_IN
MyState = SOUTEI_GAI
MyEnemy = GRAVITY
TraceAI ("GUNGHO_ST -> TOUSAN_ST")
return
end
こう書き換えたらエラーがでるんだがなぜだろう
- 457 :(○口○*)さん :06/03/19 11:27
- >>456
AIについて雑談するスレに行ったらどうだろう?
- 458 :(○口○*)さん :06/03/19 11:37
- >>457
有名なミスだな
× GUNGHO
○ GANGHO
- 459 :(○口○*)さん :06/03/19 11:44
- おk、なんか誰も答えてくれないので自分で考えてしてみた。
画面内にアイテムが落ちてるの判ったら、
攻撃中にそのアイテムから2マスとか移動はなんとかできたが、
露店とかのPCも避けるの反応しそうで怖い。
- 460 :前スレ823&325 :06/03/19 11:56
- 昨日、Ver.2を公開しました
ttp://www.uzukisyou.nobody.jp/AI.html
Ver.2は、前回のVerより
----------------------------------------
・Mobから逃げ回る処理に移る際、攻撃行動をキャンセルできなかった仕様を修正、
攻撃行動をキャンセルして逃げるようになりました
・ホムの逃亡行動中にスキルを使えるようにしました
・プログラムを少し整理
・等速移動時にパケ送りまくりの仕様を調整
・リーフはデフォルトで非先行
・移動の時遅れ気味なホムがまっすぐついてくるように調整
・追加分global variableで簡単な設定変更を出来るように
----------------------------------------
といった修正がされています
- 461 :前スレ823&325 :06/03/19 11:57
- あと現在原因不明のバグで開発が滞っているVer.3
ttp://www.uzukisyou.nobody.jp/AI2.html
>>330氏の助言をもとに修正してみるも不具合直らず
現在分かっていることは
・どうやら"MyState = "での処理移動が働いていない様子
・"MyState = AUTOSKILL_ST"の一文を抜いたら各ソースは正常に動く
AUTOSKILL_ST ()内部をくまなく見るも原因分からず
・オートスキルを仕様できるよう新たなコードを組んだものの、
謎のループになってしまっているらしく
ホムが攻撃をしない and その場に固まるといった不具合仕様に
----------------------------------------
2006ウ・3ソ・19タマ 11ステ 5コミ 20テハ OnATTACK_ST
2006ウ・3ソ・19タマ 11ステ 5コミ 20テハ ATTACK_ST -> AUTOSKILL_ST
2006ウ・3ソ・19タマ 11ステ 5コミ 20テハ OnRUNAWAY_ST -- ここでなぜか急に"OnRUNAWAY_ST"へ飛んでいる
2006ウ・3ソ・19タマ 11ステ 5コミ 20テハ RUNAWAY -> CHASE_ST -- この後ホムの動きが止まる、以降反応なし、処理が止まっている
2006ウ・3ソ・19タマ 11ステ 5コミ 30テハ OnFOLLOW_CMD -- ALT + Tで"OnFOLLOW_CMD"にする
----------------------------------------
ソースが汚いかもですが良かったら何かの参考にしてください
(つдT)
- 462 :(○口○*)さん :06/03/19 12:10
- >>459 は >>405 かい?
前スレ見てきたけど、V_TYPE未実装っぽいな、アイテム判別できないのか……
GetV(V_HOMUNTYPE,ID)使う方法もあるかもしれない、前スレのログに有用な情報がある
まぁ、これも想定外動作だし修正されたりしれな
>>510
>→GungHo-ID利用規約およびアトラクション利用規約または別途公式サイトに明示する
個別規定に違反していると当社が判断した場合
ここの事を言いたいんだろうな、でも判断するのは癌崩さんがいう「当社」らしいぞ
スレで薀蓄垂れる前に通報に行っておいで、判断するのは君の仕事じゃぁ無い
まさか「俺の判断で明らかに違反だから今すぐやめろ」なんて馬鹿な事は言わないでくれよな?
- 463 :(○口○*)さん :06/03/19 12:10
- うっへ、後半別スレへのレスが混じった、スルーヨロ(´・ω・`)
- 464 :(○口○*)さん :06/03/19 12:26
- >461
AUTOSKILL_STをどこで定義してあるのかが見当たらないのだけど
RUNAWAY_ST、FILIR_ST、VANILMIRTH_ST、AMISTR_STのあたり
定義してあるのはどこ?
- 465 :(○口○*)さん :06/03/19 12:27
- >>439
遅レスだけど、私はめんどいので OnIDLE_ST( )の一番最初に
MyEnemy , MyDestX , MyDestY = 0 , 0 , 0
を加えてる
デフォルトのままだと
予約コマンドがあるときにIDLEになってもここがリセットされないっぽい
>>461
うーん
AUTOSKILL_ST と RUNAWAY_ST の値がどっちもnilになってるとか?
もしそうなら両方に、他の〜〜_STと被らない適当な数値いれれば解決するんだけど
どうでしょう
- 466 :400 :06/03/19 12:42
- 昨晩は、ありがとうございました。
一夜明けて、また新しい機能を実装しようとしたんですが、エラーが起きてしまいましたorz
HPが50%以下になったら攻撃しないという風にしたかったので、
0-materialさんのコードを拝借して、
global variableの次にHomunculusSafetyHP = 50を記入し、
function GetOwnerEnemy (myid)の所の最後 return result の直前に、
-- ホムンクルスの残りHPが一定%以下の場合は攻撃させない(=ターゲット放棄≒敵を取得しない)
local HomunculusHP = GetV (V_HP,myid)
local HomunculusMaxHP = GetV (V_MAXHP,myid)
if ((HomunculusHP/HomunculusMaxHP)*100 < HomunculusSafetyHP) then
result = 0
end
コレを追加した所エラーになってしまいました。
どこか他にもいじる所があるのでしょうか?
どなたか助言お願いします。
AIは404でうpってます。
- 467 :(○口○*)さん :06/03/19 12:47
- >>461
OnRUNAWAY_ST ()関数の最後の方にあるMyState = OnIDLE_STは
MyState = IDLE_STの間違いじゃないか?
- 468 :(○口○*)さん :06/03/19 13:00
- ちょっと質問なんだけど、
「座標(x,y)のセルが移動可能かどうか」っていう情報って取得できないかな。
(正確には、移動可能、移動不可+視線が通る、移動不可+視線が通らないの3種)
直接取得できるんだったら、PCに負荷がかかりそうだけど壁向こうの
モンスターに攻撃しようとして起こるスタック対策とかに使えるかと思うんだけど。
直接取得ができない場合は、マップ情報を別ファイルで用意したりするしか
ないだろうけど、そうなると「現在いるマップがどのマップか」っていう問題も
起こるんだよね…。
- 469 :(○口○*)さん :06/03/19 13:00
- >>466
if文でその条件使ったら、最後のデフォルトのreturnはelseで囲わないとダメくね?
- 470 :前スレ823 :06/03/19 13:01
- >>464
AI.Luaのほうの"function AI(myid)"の下のほうに
elseif (MyState == RUNAWAY_ST) then
OnRUNAWAY_ST ()
elseif (MyState == AUTOSKILL_ST) then
OnAUTOSKILL_ST ()
elseif (MyState == FILIR_ST) then
OnFILIR_ST ()
elseif (MyState == VANILMIRTH_ST) then
OnVANILMIRTH_ST ()
elseif (MyState == LIF_ST) then
OnLIF_ST ()
elseif (MyState == AMISTR_ST) then
OnAMISTR_ST ()
と追加してます
これではダメなのでしょうか
>>465
VBかじった程度のプログラミング知識しかなくて半分勘の粗削りでプログラミングしてるので
よく分からないです
|||orz
>>467
マジダ
ここ修正したらホムが止まるというのは直りました
ありがとうございます!
- 471 :(○口○*)さん :06/03/19 13:13
- エラーが出てどうしたらいいんだって人は
とりあえず、エラー内容書こうぜ、どこが変なのか探すのが面倒だ
- 472 :(○口○*)さん :06/03/19 13:19
- >466
エラーメッセージで表示されている文を書いてくれるといいなぁ
>470
またトレースしてこうなってないか?
----------------------------------------
OnATTACK_ST
ATTACK_ST -> AUTOSKILL_ST
OnRUNAWAY_ST -- ここでなぜか急に"OnRUNAWAY_ST"へ飛んでいる
RUNAWAY -> IDLE_ST
----------------------------------------
定義っていうのは
-----------------------------
-- state
-----------------------------
〜省略〜
AUTOSKILL_ST = 21
RUNAWAY_ST = 22
FILIR_ST = 23
VANILMIRTH_ST =24
AMISTR_ST =25
-----------------------------
って感じに追加してみて
- 473 :sage :06/03/19 13:25
- ホムAIでとりあえずSkillObject()について公式に問い合わせてみたが、
ホムに関する質問は、他のゲーム仕様に対する質問と同じように:
・(あなただけに)具体的事例に対して答える事はできません
という(お決まりの、まあ当然と言ったら当然の)解答だった。
それと、
・<AIのカスタマイズに関する注意事項>を読んで、自己判断せよ
ttp://www.ragnarokonline.jp/news/play/update060314/homunculus.html
とのことだった。
そこには、「何か問題があったら中止連絡するよ」と書かれているので、
自分で規約に違反してないと判断すればその機能を使ってよいということだ(もちろん自己責任で
- 474 :(○口○*)さん :06/03/19 13:26
- AI.luaに追加するよりConst.luaの
------------------------
-- command
------------------------
の下に追加するほうが見やすいかもな
- 475 :前スレ823 :06/03/19 13:33
- >>472
直りました
定義のしかたが不完全だったのですね
|||orz
ありがとうございます
今、新たに「スキルしか使わない」というバグを確認したので
フラグ関係を洗って原因追求していきます
ありがとうございました!
- 476 :(○口○*)さん :06/03/19 13:54
- デフォAIに使用によるホムの行動をスムーズにするように
基礎固めから改造しているんだが
どうしても直し方が分からない部分があったのよ
ROに昔からある座標ズレ(重力座標)が原因だと思うのだが
OnATTACK_ST ()関数内でIsInAttackSight(MyID,MyEnemy)関数が
trueでも無いのにtureを吐くようなんだ
実際はホムの攻撃距離は決まっているから
攻撃ができない上にCHASE_STでは無くATTACK_STのままで
ループしてしまう
これの解決方法が分からないんだ
すでにIsInAttackSight()関数が使えないから他の方法を取ることになるが
そのAttack()関数は返り値が無いから、攻撃使用可否では判断不可
だからといって、敵のダメージモーションで判断すると
ホムの攻撃ミスでもその条件に入ってしまう
誰か助けて
- 477 :(○口○*)さん :06/03/19 13:54
- 先攻的なリーフを連れて赤ウィロMAPに突入したところ、
クマーに殴りかかって泣きながらPP連打してた俺がきましたよ。
デフォの先攻型だとタゲってないmob全て攻撃はじめるから、
タゲにしたいmobだけセットできたらいいなと思い、
"右ダブルクリックでタゲ指定攻撃したmobを以降タゲmob種類と判断して攻撃"
のようなコードを書いてみた。
テキトーに追加したのでテレポアウト後や、ホム画面外移動すると
タゲリスト忘れます…
あと、横殴り防止とか入れたほうがいいと思う。
次レス追加および修正コード
- 478 :477 :06/03/19 13:56
- *追加コード(global variableの各宣言の下に)
-- mob登録用
TargetEnemy = {}
TargetEnemyCount = 0
*修正コード
function OnATTACK_OBJECT_CMD (id)
TraceAI ("OnATTACK_OBJECT_CMD")
-- ここから追加
local EnemyFlg = false
local EnemyID = GetV(7,id)
local i
for i in TargetEnemy do
TraceAI (string.format("タゲNo:%d,ID:%d",i,TargetEnemy[i]))
if (TargetEnemy[i] == EnemyID ) then
TraceAI ("登録済み")
EnemyFlg = true
break
end
end
if EnemyFlg == false then
TargetEnemyCount = TargetEnemyCount + 1
TargetEnemy[TargetEnemyCount] = EnemyID
TraceAI (string.format("タゲ登録No:%d,ID:%d",TargetEnemyCount,TargetEnemy[TargetEnemyCount]))
end
-- ここまで追加
MySkill = 0
MyEnemy = id
MyState = ATTACK_OBJECT_CMD_ST
end
- 479 :477 :06/03/19 13:58
- *修正コード("ここから修正〜ここまで修正"は元のコードをコメント化)
function GetMyEnemyB (myid)
local result = 0
local owner = GetV (V_OWNER,myid)
local actors = GetActors ()
local enemys = {}
local index = 1
local type
-- ここから修正
-- for i,v in ipairs(actors) do
-- if (v ~= owner and v ~= myid) then
-- if (1 == IsMonster(v)) then
-- enemys[index] = v
-- index = index+1
-- end
-- end
-- end
- 480 :477 :06/03/19 14:00
- for i,v in ipairs(actors) do
local j
local EnemyID = GetV(7,v)
if (v ~= owner and v ~= myid) then
if (1 == IsMonster(v)) then
local target = GetV( V_TARGET, v)
-- タゲってないmobで、登録されてるものは敵リスト追加
if target == 0 then
for j in TargetEnemy do
if (TargetEnemy[j] == EnemyID ) then
TraceAI (string.format("タゲNo:%d,ID:%d",j,TargetEnemy[j]))
enemys[index] = v
index = index+1
break
end
end
else
enemys[index] = v
index = index+1
end
end
end
end
-- ここまで修正
- 481 :477 :06/03/19 14:02
- 以上、長くなってスマソ
- 482 :>>369-370 :06/03/19 14:03
- >>411
THX!
実は懸念の事項だったけど、思いもよらずまともに動いてたんでついすっかり忘れてた(笑
ちょっと直してみる
- 483 :前スレ640 :06/03/19 14:11
- 前スレ640で適当に作ったリーフの緊急回避自動発動コード(OnAUTOEA_CMD_ST)
まだ使ってる人いるかな・・・
改めてコード読んだら無駄だらけな上根本的におかしな所があったので
需要はないかもしれませんが訂正版を貼っておきます
該当する部分に上書きしてください
前スレでもAI関数内で状態判定すべきという指摘はありましたが
互換性を考えて今回も自作関数内に判定を組み込みました
- 484 :前スレ640 :06/03/19 14:12
- -- リーフに自動で緊急回避を使用させる関数定義ここから --
EmergencyAvoidDelay = 0 -- 緊急回避間隔管理用
EACasting = false -- 緊急回避発動フラグ
SkillUseLimit = 100 -- 発動条件SP残量(パーセント)
IN_SKILL_EMERGENCYAVOID = 8002 -- スキルID
function OnAUTOEA_CMD_ST () -- 緊急回避Lv3を自動で使用
local type = GetV(V_HOMUNTYPE, MyID)
local flag_sp = GetV(V_SP, MyID)
-- リーフの緊急回避
if ((type == LIF or type == LIF2 or type == LIF_H or type == LIF_H2) and (MyState == CHASE_ST or MyState == FOLLOW_ST)) then
if (EmergencyAvoidDelay <= GetTick()) then
if (flag_sp * 100 >= GetV(V_MAXSP, MyID) * SkillUseLimit) then -- SP残量が指定%以上の時
EACasting = true -- 発動フラグをONに
end
end
if (EACasting == true) then
SkillObject(MyID, 3, IN_SKILL_EMERGENCYAVOID, MyID) -- 緊急回避レベル3使用
if (GetV(V_SP, MyID) < flag_sp) then -- SP消費時
EACasting = false -- フラグリセット
EmergencyAvoidDelay = GetTick() + 35000 -- 次にかけ直すまでの時間
end
end
end
end
-- リーフに自動で緊急回避を使用させる関数定義ここまで --
- 485 :前スレ640 :06/03/19 14:18
- タブをスペースに置き換えるのが大変な方へテキスト版
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2977.zip
- 486 :(○口○*)さん :06/03/19 14:33
- >>476
デフォAIだと、多分位置ずれなしでもスタックするように感じる。
(実際に、メタリン相手に微妙な距離で攻撃せずに止まることが何度もある)
原因としては、GetDistanceで「X」と返ってくるホムとモンスターの位置関係のとき
攻撃可能距離X(GetV (V_ATTACKRANGE,id1)での返り値X)だと攻撃できないマスが
あるんだと思う。
(縦2横1(攻撃可能距離2)or縦3横1(攻撃可能距離3)あたりが怪しいと思う)
根本的な解決策としては、
・ホムの通常攻撃が可能なマスを調べる(素手と同じ?素手より長い?)
・IsInAttackSightでtrueを返すマス全てが、攻撃可能になるように設定する
(IsInAttackSightでfalseが返るが、ホムが攻撃可能なマスが含まれてもいい)
対症療法的な解決策としては、
・IsInAttackSight内の上から14行目の
「if a >= d then」を「if a-1 >= d then」に。
ただ、やっぱり座標ズレには対応できてない。
座標ズレに関しては、こっちもいろいろ考えているんだけど
うまい解決法が見つからない状態。
「通常攻撃時に必ず隣接マスまで移動してから攻撃する」で
ある程度防げそうな気もするんだけど…。
- 487 :(○口○*)さん :06/03/19 14:43
- function GetMyEnemyC (myid)
local result = 0
local owner = GetV (V_OWNER,myid)
local actors = GetActors ()
local enemys = {}
local index = 1
local target
local type
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
type = GetV(V_HOMUNTYPE,v)
target = GetV (V_TARGET,v)
if (target == myid) then
enemys[index] = v
index = index+1
elseif ((mob1) or (mob2) or (mob3) or (mob4)) then
if (GetV(V_TARGET,v) == 0) then
enemys[index] = v
index = index + 1
end
end
end
end
という関数をつくり
----------------------------
-- 対象mob設定
----------------------------
mob1 = 1002
mob2 = 1031
mob3 = 1051
mob4 = 1131
-----------------------------
を上のほうに作ったのですがエラー落ちシマス。
助言お願いします
- 488 :(○口○*)さん :06/03/19 14:45
- いきなりなんですが・・・
韓国AIを使っているのですが、
どうしても主人のHPが設定以下になってもヒールをしてくれません(つД`)
必要かどうかわかりませんがoption_aiのせておきます・・・。
どなたか教えてください・・・(´;ω;`)
option_ai内容
Ragnarok AI iN 設定ファイル (2005/09/19 18:28:40)
IN_AutoCastling_HP = 35
IN_AutoFleetMove = 1
IN_AutoDefence = 1
IN_AutoMonlight_SP = 30
IN_VANILMIRTH = 0
IN_AutoEmergencyAvoid_Owner_HP = 10
IN_AMISTR = 1
IN_MyAutoFleeHP = 35
IN_ChaoticVenediction = 1
IN_FILIR = 1
IN_AutoEmergencyAvoid = 1
IN_AutoCastling_Owner = 1
IN_AutoOveredSpeed_SP = 20
IN_AutoEmergencyAvoid_SP = 15
IN_AutoCaprice = 1
IN_AutoDefence_SP = 30
IN_AutoCastling_Owner_HP = 35
IN_LIF = 0
IN_ChaoticVenediction_Owner_HP = 10
IN_AutoCastling = 1
IN_AutoEmergencyAvoid_HP = 10
IN_AutoOveredSpeed = 0
IN_AutoFleetMove_SP = 20
IN_AutoMonlight = 1
IN_AutoEmergencyAvoidHP = 1
IN_AutoCaprice_SP = 20
IN_ChaoticVenediction_HP = 40
IN_AutoHea = 0
IN_AutoHeal_Owner = 0
IN_AutoHeal_Owner_HP = 30
IN_AutoHeal_HP = 30
です・・・
- 489 :(○口○*)さん :06/03/19 15:05
- >>487
elseif ((mob1) or (mob2) or (mob3) or (mob4)) then ←これを
elseif ((v==mob1) or (v==mob2) or (v==mob3) or (v==mob4)) then ←こう。
- 490 :(○口○*)さん :06/03/19 15:16
- >>487
もう一つ。
最寄のMobを抽出してresultを返す処理(デフォルトAIのlocal min_dis = 100からreturn resultまでの部分)を入れておかないと、そのままじゃ何の動作もしない。
ここに書き込む時に省略しただけかもしれないけど、念のために。
- 491 :(○口○*)さん :06/03/19 15:24
- IN_LIF = 0
IN_AutoHea = 0
IN_AutoHeal_Owner = 0
AI見てないから、知らんけど
上記の項目は0でいいの?
- 492 :前スレ912 :06/03/19 15:34
- >>436
アレンジするのは全然構わない、気にするな
が、mobdata.luaとMOBDATAの名称はバッティングしないように
変えることはお勧めしておく、自分用のになるんだから
mymobdata.luaとかMYMOBACTとかが、皆にも分かりやすくてオススメ
>>482
idがプレイヤーかどうかの判別なら>>340にあるが少し間違っているので勝手に修正
function IsPlayer(id)
local TypeID = GetV(V_HOMUNTYPE,id)
if ((0 <= TypeID and TypeID <= 23) or (4001 <= TypeID and TypeID <= 4044) or TypeID == 4046) then
return 1
end
return nil
end
4046がSuper Baby、4045は未定義
本当は昨日、書き込もうと思ったら丁度>>340があって、やめといたけど一応うpしとく
ホムンクルス用モンスターデータライブラリ
playerjobdata.lua
配布場所(後日変更の可能性有)
ttp://briefcase.yahoo.co.jp/kulus_project
ttp://proxy.f3.ymdb.yahoofs.jp/bc/44183003_d9ee/bc/playerjobdata.lua?bc91PHEBpzBNNXpN
IsPlayer (id) -- idはプレイヤーキャラか? yes -> 1 no -> 0
GetPlayerJobName (id) -- プレイヤー職業を取得
GetPlayerClass (id) -- プレイヤー職業のジャンルを取得
- 493 :前スレ912 :06/03/19 15:38
- >>492
思ったら --> 思ったけど
モンスターデータライブラリ --> ライブラリ
で脳内よろorz
>>486
指定された座標の最も近い隣接マスに移動する
function GetContactPoint (x1, y1)
local MyX , MyY = GetV (V_POSITION, MyID)
local x2 = x1
local y2 = y1
if (x1 < MyX) then
x2 = x2 + 1
elseif (x1 > MyX) then
x2 = x2 - 1
end
if (y1 < MyY) then
y2 = y2 + 1
elseif (x1 > MyX) then
y2 = y2 - 1
end
return x2, y2
end
MoveToOwnerの代わりにMoveでこれ使ってる
>>491
Luaは0を偽とは判定しないからそれでOK
- 494 :476 :06/03/19 15:44
- >>486
やはり重力座標対応は無理っぽいか…
ホムの攻撃範囲を検証してIsInAttackSight関数の修正だけがでもやてみるよ
- 495 :486 :06/03/19 15:56
- >>494
すまん、いま丁度終わった。
リーフの攻撃可能距離は2(GetV (V_ATTACKRANGE,id1)での返り値)
攻撃可能なマスは、自分を中心に5*5のマス内全て。
…あれ?想定自体が間違ってたっぽい。
ちょっと他の原因を考えてみる。
- 496 :488 :06/03/19 15:57
- function GetMyEnemyC (myid)
local result = 0
local owner = GetV (V_OWNER,myid)
local actors = GetActors ()
local enemys = {}
local index = 1
local target
local type
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
type = GetV(V_HOMUNTYPE,v)
target = GetV (V_TARGET,v)
if (target == myid) then
enemys[index] = v
index = index+1
elseif ((v == mob1) or (v == mob2) or (v == mob3) or (v == mob4)) then
if (GetV(V_TARGET,v) == 0) then
enemys[index] = v
index = index + 1
end
end
end
end
local min_dis = 100
local dis
for i,v in ipairs(enemys) do
dis = GetDistance2 (myid,v)
if (dis < min_dis) then
result = v
min_dis = dis
end
end
return result
end
これでもエラーでますね
- 497 :(○口○*)さん :06/03/19 16:00
- GetActorsで取得できるIDに自キャラも含まれてるみたいね
索敵時ホムよりも近いPCがいたら除外とかやったらうまくいかなくて
調べてみたら自キャラまで判定してやがった
既出だったらスマソ
- 498 :(○口○*)さん :06/03/19 16:08
- >>496
すまん俺も間違えてた
elseif ((v == mob1) or (v == mob2) or (v == mob3) or (v == mob4)) then←これも間違いで、
elseif ((type == mob1) or (type == mob2) or (type == mob3) or (type == mob4)) then←正しくはこう
- 499 :>>369-370 >>402 :06/03/19 16:33
- GetV関係の助言などを反映させて「他プレイヤー認識型自動アクティブ切替AI」仕上げた。
助言くれた方THX。
ttp://www.mmobbs.com/uploader/files/69.zip
動作は
「ホムンクルスから(初期値)12セル以内に他プレイヤーがいない場合、
ホム周囲(初期値)6セルの特定モンスター(初期設定は弱小ルートモンスター)を
自動排除」
詳しい動作や目的、導入方法はAI.luaの冒頭に書いておいた。
正しく導入すれば他のスクリプトと干渉することも無いはず
(他のモンスター自動選別型スクリプトとは干渉する可能性あり。完全自作AIは不明)
後PvPでの動作は未確認(おそらくノンアクティブになる)
- 500 :(○口○*)さん :06/03/19 16:34
- >>488
IN_LIF = 0
IN_AutoHeal = 1
IN_AutoHeal_Owner = 0
IN_LIF: 0
アクティブ(横殴りする): 1
非アクティブ(横殴りしない): 0
IN_AutoHea = 0
IN_AutoHeal のタイプミスですか?
IN_AutoHeal_Owner_HP: 0
主人のHPが設定HP(%)以下の時→HPが0%以下の時にヒールという設定
以後詳細は以下に追記されています。
ttp://www.sgv417.jp/~winter/alchemy/korea.html
- 501 :488 :06/03/19 17:07
- 461さんの設定で
function GetMyEnemyB (myid)
local result = 0
local owner = GetV (V_OWNER,myid)
local actors = GetActors ()
local enemys = {}
local index = 1
local type
local MyHP = GetV (V_HP,MyID)
local MyMaxHP = GetV (V_MAXHP,MyID)
local HPper = (MyHP / MyMaxHP) * 100
if (AwayHP >= HPper) then -- AwayHP以下だとアクティブに敵認識(逃亡用の敵認識)
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid ) then
if (1 == IsMonster(v) and IsNotNoManner( myid, v )) then -- vがモンスターでタゲが無い、または自分か主人をタゲってる場合
if (3 >= GetDistance2 (myid, v)) then -- 自分との距離が3の敵を認識(逃亡用)
enemys[index] = v -- 敵リストにvのidを追加
index = index+1
end
end
end
end
else -- AwayHPより高い場合、ホムはアクティブ
if (AwayHP < HPper) then ← ここを追加
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then -- vの値が主人のidでもホム自身のidでもない場合
if (1 == IsMonster(v) and IsNotNoManner( myid, v ) ) then -- vがモンスターでタゲが無い、または自分か主人をタゲってる場合
if (AttackArea >= GetDistance2 (GetV(V_OWNER,MyID), v)) then -- 主人との距離がAttackArea以下の場合
enemys[index] = v -- 敵リストにvのidを追加
index = index+1
end
end
end
end
- 502 :488 :06/03/19 17:07
- end
local min_dis = 100
local dis
for i,v in ipairs(enemys) do
dis = GetDistance2 (myid,v) -- 自分をタゲってる敵(v)との距離をdisに代入
if (dis < min_dis) then -- 距離が100未満だったら
result = v -- resultへvを代入
min_dis = dis
end
end
return result
end
HP40%を切った時逃げ惑う設定にして、HPが40%を超えた時再度アクティブ化する
設定に書き換えてみたいのだけどこのようにしたらエラー落ちシマス
- 503 :(○口○*)さん :06/03/19 17:10
- 上げ進行は別にどうでもいいんだが、スペース入れないからすごく見難いぞ
- 504 :(○口○*)さん :06/03/19 17:43
- >>495
ttp://wing.zero.ad.jp/~zau54498/HP/technique.html#AllRange
- 505 :(○口○*)さん :06/03/19 17:49
- >>504の言いたいことがまったく分からん
自分で羊の攻撃範囲を調べたけど、ホム中心5*5で間違いない
やはり、重力座標が原因だろうと思われる
解決方法は分からん
- 506 :(○口○*)さん :06/03/19 17:52
- Wikiに書いてあるGetV(V_MOTION,id)の返り値なんだが、
どれがどの値を返すかは調べてないが、
自分にスキル使用、
他のPCにスキル使用、
Mobにスキル使用、
地面にスキル(デモンストレーション等)使用、
対象の無いスキル(ラウドボイス等)使用、
スキル戻り、
詠唱、
ってなってるんじゃないだろうか。
何となく固有のスキル使用の値が返ってくるのはおかしい気がする。
- 507 :前スレ823 :06/03/19 18:00
- >>501
else -- AwayHPより高い場合、ホムはアクティブ
if (AwayHP < HPper) then ← ここを追加
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then -- vの値が主人のidでもホム自身のidでもない場合
if (1 == IsMonster(v) and IsNotNoManner( myid, v ) ) then -- vがモンスターでタゲが無い、または自分か主人をタゲってる場合
if (AttackArea >= GetDistance2 (GetV(V_OWNER,MyID), v)) then -- 主人との距離がAttackArea以下の場合
enemys[index] = v -- 敵リストにvのidを追加
index = index+1
end
end
end
end
end
□
単純にendが足りないだけだと思います
endを□の位置に追加すれば直るはずです
でも「if (AwayHP < HPper) then ← ここを追加」を追加しなくても
ifの「else」で同じ内容の分岐になるので
追加したif文は意味が無いと思います…
- 508 :(○口○*)さん :06/03/19 18:01
- >>506
それだとPPとスリムPPで違う数字が返ってきたのが説明できないのでは?
- 509 :(○口○*)さん :06/03/19 18:03
- ライブロってスペース認識されないのね
||||orz
- 510 :(○口○*)さん :06/03/19 18:07
- >>488
スリム赤持ってるか?
- 511 :(○口○*)さん :06/03/19 18:10
- --------------------------
MOTION_STAND = 0 -- 立っているモーション(動作)
MOTION_MOVE = 1 -- 移動中のモーション
MOTION_ATTACK = 2 -- 攻撃中のモーション
MOTION_DEAD = 3 -- 死んで倒れるモーション
MOTION_DAMAGE = 4 -- ダメージを受けた時のモーション
MOTION_PICKUP = 5 -- 拾うモーション
MOTION_SIT = 6 -- 座るモーション
MOTION_SKILL = 7 -- スキル攻撃中モーション(インベ、カートレボリューション、ラウドボイス確認)
MOTION_CASTING = 8 -- 詠唱モーション
MOTION_ATTACK2 = 9 -- 攻撃モーション
MOTION_PP = 12 -- ポーションピッチャーのモーション
MOTION_SLIMPP = 28 -- スリムポーションピッチャーのモーション
--------------------------
- 512 :1/2 :06/03/19 18:13
- 流れを無視して過去ログにあるか不明なものができたじぇ。
内容は『ケミのタゲ先を攻撃先に認識させる』というものだ。
・・・まぁ単に function GetOwnerEnemy (myid) 中の文を応用しただけだが。
補足文はThe Winter's Taleのとこの注釈入れてあるようなもんだ、深く気にしないでくれ。
-------------------------------------------
-- ケミが攻撃しようとしている敵のidをターゲットとして取得する(距離順に優先)
-- <戻り値>敵のキャラクターid
-------------------------------------------
function GetOwnerAtackEnemy (myid)
local result = 0 -- 敵のキャラクターid
local owner = GetV (V_OWNER,myid) -- ケミ自身のキャラクターid
local actors = GetActors () -- 周りのキャラクターidを全部取得
local enemys = {} -- 敵のリスト
local index = 1 -- インデックス番号(初期値1)
local target -- ターゲットのキャラクターid
-- (1,actors[1])、(2,actors[2])、…のペアを繰り返す
-- 周りのキャラクターidをひとつひとつチェックして、そのキャラクターに
-- ケミが攻撃しようとしていたら、ケミのタゲをホムのターゲットとして取得
for i,v in ipairs(actors) do
if (v == owner) then -- ケミならば
local motion = GetV(V_MOTION,v) -- そのキャラクターのモーションを取得
-- モーションが攻撃モーションだったら
if (motion == MOTION_ATTACK or motion == MOTION_ATTACK2) then
target = GetV (V_TARGET,v) -- そのキャラクター(ケミ)のタゲを取得
enemys[index] = target -- 敵のリストに追加
index = index+1 -- インデックスを1増やす
end
end
end
- 513 :2/2 :06/03/19 18:13
- local min_dis = 100 -- 最小距離(初期値は100)
local dis -- 距離
-- (1,enemys[1])、(2,enemys[2])、…のペアを繰り返す
-- 敵リストの中で、ホムから一番近い敵をホムの攻撃対象とする
for i,v in ipairs(enemys) do
dis = GetDistance2 (myid,v) -- ホムと敵との距離を取得
if (dis < min_dis) then -- 最小距離より近ければ
result = v -- その敵をターゲットとする
min_dis = dis -- その敵との距離を最小距離とする
end
end
return result -- ターゲットを返す
end
タブの部分は全角スペースになってるので導入時はタブに変換がいいかと。
文を入れる先は優先順位的に function GetOwnerEnemy (myid) のあとがいいと思われる。
一応動作確認済みだけど、他のコードは等速のしか入れてないから競合とかはどうなるか不明。
- 514 :前スレ391 :06/03/19 18:16
- □ホムに1発だけ殴らせる機能
ホム操作の[ALT]+[右クリック2回]に割り当て
※攻撃の成否判定が取れないのでもしMISSなら再度[ALT]+[右クリック2回]
-- グローバル定数
USEWALLMODE = 1 -- (1:壁モード 0:通常モード)
-- グローバル変数
ReadyWallMode = 0
FinishedAttackFlag = 0
OnIDLE_ST()関数内に以下の2行を追加
ReadyWallMode =0
FinishedAttackFlag = 0
OnATTACK_OBJECT_CMD関数内に以下の行を追加
if USEWALLMODE == 1 then
ReadyWallMode = 1
FinishedAttackFlag = 0
end
OnATTACK_ST()関数内の以下の部分を変更
if (MySkill == 0) then
Attack(MyID, MyEnemy) --←この部分を(1行)
else
↓
if (MySkill == 0) then
if FinishedAttackFlag == 0 then Attack(MyID, MyEnemy) end -- ←このように
if ReadyWallMode == 1 then FinishedAttackFlag = 1 end -- ←変更する(2行)
else
以上。
これで1回だけ攻撃するようになります(ポポリンでテスト済み)。
#ホムのレベルが高いと低レベルモンスターなんて1撃だろうから壁の意味
#ない気がする…。
- 515 :512・513 :06/03/19 18:23
- まちがった>>513の
function GetOwnerEnemy (myid) のあとがいいと思われる。
っての、
function GetOwnerEnemy (myid) の 『前』 がいいと思われる。
に変更よろ
- 516 :(○口○*)さん :06/03/19 18:27
- >>511
このモーション定義ってケミ・ホム・Mob全部共通?
- 517 :512・513・515 :06/03/19 18:27
- 連投ばっかりですいません。
更に失敗が・・・orz
local object = GetOwnerEnemy (MyID) -- ケミを攻撃している敵のキャラクターidを取得
if (object ~= 0) then -- ケミを攻撃している敵がいるならば
MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする
MyEnemy = object -- objectの敵をターゲットにする
TraceAI ("IDLE_ST -> CHASE_ST : MYOWNER_ATTACKED_IN")
return -- 戻る
end
これを function OnIDLE_ST () 内の
localobject = GetOwnerEnemy (MyID) の前に入れてください;;
今回も文前タブは全角スペースです・・・
- 518 :(○口○*)さん :06/03/19 18:44
- >>508
PPは、自分、他のPC、ホムに使用可能ですよね?
だから、それぞれで返ってくる値が違うんじゃないかなって思ったんですが。
- 519 :(○口○*)さん :06/03/19 19:08
- 510
ちゃんと持ってます。
そしていまだに自動ではヒールをしてくれません…
- 520 :(○口○*)さん :06/03/19 19:12
- >>519
>>500読んだ?
- 521 :(○口○*)さん :06/03/19 19:15
- >>511
ちょっと補足。
MOTION_SKILL = 7 -- スキル攻撃中モーション(インベ、カートレボリューション、ラウドボイス確認)
を報告したんだが、攻撃には限らないみたい。応急手当とかも同じモーション。
まぁ、スキル使用という表現は合ってると思う。
ファイヤーボルトとか詠唱すると、
MOTION_CASTING = 8 詠唱開始。手を前に出して静止している時(詠唱バーのびる)
MOTION_SKILL = 7 詠唱バーが100%になって、手をふっている時
MOTION_STAND = 0 モーション終わり
と順番に変化した。
しかし、いまだに9はみたことないなぁ。リーフでやってるが、たまに違う攻撃モーション
する時もあるが、そのときもMOTION_ATTACK(=2)だった。
取得しそこねてただけならすまん。
- 522 :(○口○*)さん :06/03/19 19:15
- http://www.mmobbs.com/uploader/files/72.zip
のAI使っているのですが、HPが40%以下の時逃げ惑うのですが、
HPが40%以上に戻った時、再度読み込みなおさないと逃げ惑うのをやめません。
読み込みなおさずに逃げ惑うのをやめて攻撃に戻せるAIにできないでしょうか?
- 523 :(○口○*)さん :06/03/19 19:22
- >>476
位置ずれを再現できないので確認してないが
位置ずれ中は
Attack()
のあと
GetV(V_MOTION,MyID) が攻撃モーションじゃなかったり
GetV(V_TARGET,MyID) が0だったりするかも知れない
ホムはクライアントの情報しか得られないっぽいからサーバー上の正しい位置は
わからないけど、
CHASE_STになる直前の
GetV(V_POSITION,MyEnemy)と GetV(V_POSITION,GetV(V_TARGET,MyEnemy))
の中間点あたりに移動させて攻撃させてみればいいんじゃないかな
- 524 :504 :06/03/19 19:44
- >>505
すまん要点書かなかった上に勘違いだったorz
攻撃可能範囲に居るのにIsInAttackSightがfalseを返すことだと思ったんだけど逆だったのねorz
しかも、試してたら対象から縦横[+2,+1]マスでも移動するから、実攻撃範囲はmobと同じだけど
IsInAttackSightがプレイヤーの範囲で返す思ったんだがAI.luaのカスタムミスだったorz
ミスは直したけど位置ズレが起きない・・・
- 525 :(○口○*)さん :06/03/19 19:59
- >>518
こちらではホムに使っても自分に使っても
AI操作で使ってもモーションは12でした
>>516
ホムでスキルと攻撃の時に
モーション0ばかりで一度も別モーション取得できなかったから
ホムは違うかもしれない
- 526 :(○口○*)さん :06/03/19 20:16
- >>523
なるほど、V_MOTIONですか・・・試してみます
- 527 :(○口○*)さん :06/03/19 21:44
- >>506
そう思う。
マイキャラしかトレースしてないから判明はしてないけど
街や狩場で他人のモーション全部拾ってれば別職でも使用スキルなどで共通する部分があると思う。
とりあえず28番は他に見ないものだし 12番以降のモーションを他職で拾えればいいとは思う。
うちのPC貧弱だから常時トレースとか無理だけど。
- 528 :(○口○*)さん :06/03/19 21:47
- 流れぶった切りの初心者丸出しな質問失礼します。
「スキルID」ってどうやって取得するんですか?どなたか教えて下さい。
- 529 :(○口○*)さん :06/03/19 21:48
- >>528
勇気と情熱があれば君にもできるさ
- 530 :(○口○*)さん :06/03/19 21:49
- >>528
とりあえずこのスレと前スレを読んでみよう。
- 531 :(○口○*)さん :06/03/19 22:00
- 質問なのですが、
バニルを使用しているときに
「主人のHPが○%以下で、ホムのSPが○以上の時カオティックベネティクション自動発動」
っていうのは可能ですか?
ゼロマテさんのリーフの部分いじくればできるのかなって考えたのですが、
よくわからなかったのでわかる方いたら教えてもらえませんか?
- 532 :(○口○*)さん :06/03/19 22:12
- >>531
っ[過去ログ]
っ[ホムンクルスAIについての雑談・要望スレ ]
http://enif.mmobbs.com/test/read.cgi/livero/1142513331/l50
- 533 :(○口○*)さん :06/03/19 22:12
- 前スレ249にホムのスキルIDはあったんですが、ケミのスキルIDってどこに・・・
どなたかマジでお願いしますorz
- 534 :(○口○*)さん :06/03/19 22:16
- >>533
分からなければ触るな
ホムだけを動かすことに集中するんだ
- 535 :(○口○*)さん :06/03/19 22:18
- >>533
ケミのスキルIDなんて何に使うつもり?
AIでケミのスキル制御はお勧めしないから諦めれ
- 536 :(○口○*)さん :06/03/19 22:19
- >>532
過去ログ漁ってきます。
過去ログ| λ=3
- 537 :535 :06/03/19 22:26
- ケミのスキルIDで自動ラウドがやってみたくてorz
過去ログ漁るより教えてもらった方が早いかと思った未熟者です(´・ω・`)
やり方だけでも(´・ω:;.:...
- 538 :504 :06/03/19 22:30
- >>537
前スレを「ラウド」で検索しろ、これ以上は他の皆に迷惑じゃまいか
- 539 :(○口○*)さん :06/03/19 22:39
- >>537
ホムのAIでケミ制御するな
- 540 :535 :06/03/19 22:39
- >>538
申し訳ない。そして汚しスマソ@ありがとー!!
- 541 :(○口○*)さん :06/03/19 22:46
- まっとうな使い方をするとなれば例えば
ラウドに反応してボルト使用とかな。「薙ぎ払えッ!!」
…素直にSCから普通にやるべきだよな。
- 542 :(○口○*)さん :06/03/19 22:51
- カオティックベネディクションを使う関数を入れてみたんだが…
function Cast_Venediction(MyID)を攻撃のルーチンの中に入れることを前提にして
function Cast_Venediction(myid)
local my_sp = GetV (V_SP,myid)
local my_maxsp = GetV (V_MAXSP,my
id)
local mysp_sp_persent = (my_sp / my_maxsp) * 100.0
local my_owner = GetV(V_OWNER,myid)
local my_owner_hp = GetV(V_HP,my_owner)
local my_owner_maxhp = GetV(V_MAXHP,my_owner)
local my_owner_hp_persent = (my_owner_hp / my_owner_maxhp) * 100.0
if(type == VANILMIRTH or type == VANILMIRTH_H or type == VANILMIRTH2 or type == VANILMIRTH_H2) then
if(mysp_sp_persent >= 70 and my_owner_hp_persent <= 30) then
SkillObject(myid, 5, 8014, GetV(V_TARGET,myid))
return 1
end
end
return 0
end
こんな感じの関数にしたらどうだろう、って思ったんですが…
SPが余ってたら容赦なくケミを叩く奴攻撃する設定と被って
まったく発動してくれなかったとか…
ケミがピンチ時になったら魔法を使わないようにするとか
オートカプリスの設定の方をいじって
常時40以上のSPを保持するように設定すればいけると思います。
ただ、動作実験としてPvで軽く殴って貰ったら一発でHP4k飛んで死にかけて
自分のホムが攻撃してきた人を全力で魔法攻撃する様に胸が熱くなりました。
- 543 :(○口○*)さん :06/03/19 22:52
- >>542
× function Cast_Venediction(MyID)
○ Cast_Venediction(MyID)
_| ̄|○すみませんでした。
- 544 :(○口○*)さん :06/03/19 22:52
- Gvでホムを連れてみたら、ナローバンドのせいかパケ死しました;;
ホムの追尾移動関連のパケットで自キャラのターンが全て終了してしまう模様
しまいには他キャラの移動を尻目に全く動けなくなってあぼーん
ホムを追尾させなければさほど重くならないようなので
Gvでは支援させる時だけ呼んで即安息するか、
追尾を使わない専用のAIを組んだ方が良さそうです
とりあえず緊急回避5常用でのペコ+IA級の移動速度は(゚д゚)ウマーでした
>>528
ぐぐれ
- 545 :(○口○*)さん :06/03/19 22:53
- >>541
あー、ケミ限定ならモーションから使ってるスキルはある程度絞れるな。
トリガに使えないことはないが常時監視してないといかんし
モーション抜けたりして空撃ちになることも考えられるかな。
- 546 :(○口○*)さん :06/03/19 23:01
- ラウドをモーションで拾うの結構ムズくない?
インベナムにスキルモーションで反応させてるんだけどよく抜ける
一瞬で終了する系のモーションはトリガーとしては不安定
他の方法でスキル使用拾えないっけ
- 547 :(○口○*)さん :06/03/19 23:04
- 主人限定ならSP量を常時監視していればある程度はいけるかも
1ならPPで8ならラウドでって感じに
まぁ、不安点でよく抜けることは変わらないけど
モーションよりはましな気がする
- 548 :(○口○*)さん :06/03/19 23:06
- 飼い主のスキルならGetMsg(id)で監視できるんかな、できるといいな
SKILL_OBJECT_CMDが来たらそれをトリガーにすればいいんだろうけど
GetMsg(id)あんまり弄ってないんで仕様がわかんねぇ
- 549 :(○口○*)さん :06/03/19 23:08
- >>548
ケミスキルは取得できなかった…orz
フィーリルスキルのフリットムーブも取得できなかった
もしかしたら、対象指定なしのスキルはホムのスキルでも取得できないのかも
- 550 :(○口○*)さん :06/03/19 23:17
- >>542 の続き
if分の前に
local type = GetV (V_HOMUNTYPE,myid)
が抜けてるからホムのタイプを識別出来ないので、使えなかった模様。
更に改良してきちんと動作するようにしてみたものの、実用性は皆無のようです。
あと、攻撃の所に入れるんじゃなくて待機状態の時に使わせればまだいいかも…
失礼しました_| ̄|○
- 551 :(○口○*)さん :06/03/19 23:17
- >>548
GetMsgでケミの行動読めたらAIの幅広がるんじゃね!?
って思って前にやったけど、全部nilが返された
たびたびID変わってるけど>>476です
重力座標が原因と思われるATTACK_STのループバグを潰す方法が
まったく思いつかない
本当にタスケテ
- 552 :(○口○*)さん :06/03/19 23:21
- あっれ……対象非指定は拾えないのか、マジかぃ(´・ω・`)
普段使わないレベルのホムスキルを命令トリガーにするって手法は前スレあたりに出てたね
そか、ケミスキルはトリガーにならんか……
- 553 :(○口○*)さん :06/03/19 23:27
- >>548,549
できない。それができてしまうとAI関数を空にするとケミがスキル使えないことになってしまう。
ホムですらカオベネみたいな対象指定しないのは拾えない。
今のところ拾えたのはカプリスとムーンライトくらいかな。
他のホム試せないのでわからないのでリーフとアミストル試してもらえるとありがたい。
- 554 :(○口○*)さん :06/03/19 23:30
- >551
座標ずれが原因なら
CHASE_ST⇒ATTACK_STの時に
ホム座標を再取得して
MyDestX、MyDestYと比較すればいけないかな?
あるいは
CHASE_ST⇒ATTACK_ST
の遷移の条件をもう少し見直してみるとか
- 555 :前スレ391 :06/03/19 23:33
- >>553
リーフも対象無指定スキル(癒しの手、緊急回避)はGetMsg()で取れないぽい
です(TraceAI()では拾えなかった)。
てかリーフ対象無指定スキルとパッシブしかないな。
- 556 :(○口○*)さん :06/03/19 23:36
- >>554
座標取得で分かる座標がクライアントから見た座標で
クライアント上でずれてると取得しても、ずれた座標が返ってくるのが問題
>>551
Move命令連発すれば無限ループは避けれるけど重くなるしな…
MyDest系の座標に向けて、常にMoveし続けるとかどう?
- 557 :(○口○*)さん :06/03/19 23:46
- 既出かもしれないけど
直接移動で、水平or垂直方向に見えない位置まで指定できてしまうのを封じるロジック
function OnMOVE_CMD (x,y)
TraceAI ("OnMOVE_CMD")
if ( x == MyDestX and y == MyDestY and MOTION_MOVE == GetV(V_MOTION,MyID)) then
return -- 目的地と現在地が同一の場合は、処理しない
end
local curX, curY = GetV (V_POSITION,MyID)
if (math.abs(x-curX)+math.abs(y-curY) > 15) then -- 目的地が一定距離以上なら (サーバーで遠距離は処理しないため)
List.pushleft (ResCmdList,{MOVE_CMD,x,y}) -- 元の目的地への移動を予約する
x = math.floor((x+curX)/2) -- 中間地点へ移動する
y = math.floor((y+curY)/2) --
end
---ここから--------------
OwnerX, OwnerY = GetOwnerPosition (MyID) -- 主人の座標を取得
if (math.abs(x-OwnerX) > 14 or math.abs(y-OwnerY) > 14) then -- 主人から見えない位置には移動しない
return
end
---ここまで--------------
Move (MyID,x,y)
- 558 :(○口○*)さん :06/03/19 23:48
- ホムスキル窓でディフェンス使うとケミとホムにエフェクトが出るのに
SkillObject()だとホムにしかエフェクトが出ない。
ケミのVIT/HPも増えてるんで効果は同一なんだけど、仕様なのかbugなのか。
- 559 :(○口○*)さん :06/03/19 23:53
- 簡単なことで申し訳ないが、
mob1 = 1002
という振り方で mob1に1002と1063に代入させる方法はないだろうか。
つまり&の記号のことなだが、わからない
- 560 :(○口○*)さん :06/03/19 23:55
- ちょっと考えてみたんだけど、試してみたらダメだったシリーズ。
参考情報として投下しておきます。
○やろうとしていたこと。
ALT+右クリックで、MOVE_CMDが通知されるよな。
→じゃあ、ALT+右クリックを2回連続同じ座標でやったら、ダブルクリック的な
判定ができるんじゃないかな?
○結果
座標変更せずに何度ALT+右クリックをしても、MOVE_CMDはきませんでした。
よって、この分岐は失敗。
#そんな余計なフィルタリングしなくたっていいじゃん (^^;;
- 561 :(○口○*)さん :06/03/20 00:23
- >>560
ちょっと試してみたところ、
・同一座標のAlt+右クリック2回
・ホムがいる座標でのAlt+右クリック
どちらもMOVE_CMDが来てるっぽい。
試したのは、
・指定座標の1マス右に移動という設定>ホムの真下を指定すると1マス右に
・指定座標からAlt+右クリックした回数分右の座標に移動という設定
>同じマスを指定し続けるとどんどん右に移動
Alt+右ダブルクリックだとMOVE_CMDは一回しか送られないかもしれない。
- 562 :(○口○*)さん :06/03/20 00:37
- >561
対確認実験、さんくす。
やっぱりダメだよね(^^;;
いや、前からときどき要望のでている「移動後、その場所にとどまる」っていう動作と
現状の動作を両立できる手段として
・ALT+右クリック⇒従来どおりの移動(そのマスまで移動して、戻ってくる)
・ALT+右ダブルクリック⇒移動後、そのマスで停止
・・・とかやろうと思ったんだけどさ (^^;;
難しいねぇ。
- 563 :(○口○*)さん :06/03/20 00:44
- >>559
無理だべ
- 564 :(○口○*)さん :06/03/20 00:54
- >>559
逆の発想をしないとダメ
条件分岐に使いたいなら、その分岐のところでandをかければいいだけの話。
- 565 :400=466 :06/03/20 00:55
- 急に出かける用ができてしまったので、レスできずにすみませんorz
帰ってきてから、もう一度試してみたところ、エラーは出なかったのですが、
追加した条件が全く適用されてないようなのです。
追加したい条件とは、ホムのHPが一定値を下回ったら、攻撃しないような設定です。
↓に現状で使ってるAIうpってみました。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2980.zip
どなたか助言お願いします。
- 566 :(○口○*)さん :06/03/20 01:03
- >>565
GetOwnerEnemyでしかHPチェック処理をしてないようだが、GetMyEnemyの方でもチェックしないと攻撃しちゃうぞ。
- 567 :(○口○*)さん :06/03/20 01:06
- ttp://www.mmobbs.com/uploader/files/72.zip
のAIでホムのHP40%以下逃げ惑うはできたのですが、
40%以上になったら攻撃を再開するというAIはできないでしょうか?
- 568 :(○口○*)さん :06/03/20 01:11
- >>567
OnRUNAWAY_ST ()の中でHPが40%以上になったらMyStateをRUNAWAY_ST以外にするようにしたらいいんじゃね。
- 569 :(○口○*)さん :06/03/20 01:25
- >>568 すまん書いてくれないか?
- 570 :前スレ391 :06/03/20 01:29
- 指定スキル(可変レベル)コンボ実行関数(ムーンライト、カプリス量対応なはず)
使い方。
OnSKILLOBJECT_CMDT()関数内の最後にでも以下の行追加。
if skill == 8009 and level == 3 then ComboCounter = 1 -- ムーンライトレベル3ならば
AI()関数内の状態処理の直前に以下の行追加。
-- 例)ムーンライトをComboListで指定した順番、レベルでMaxCombo回実行
ComboCounter = UseComboSkill(8009, ComboList, MaxCombo, ComboCounter, 0)
以下コード。
-- グローバル定数
SKILLTOSKILLINTERVAL = 2000 -- スキルインターバル
-- グローバル変数
ComboCounter = 0 -- カウンタ
ComboList = {1, 2, 3} -- 使用するスキルレベルとその順番
MaxCombo = 3 -- 最大コンボ回数
ComboDelay = 0 -- ディレイ管理用
-- 消費SP
SKILLUSESP = {}
SKILLUSESP[8009] = {4, 8, 12, 16, 20} -- ムーンライト
SKILLUSESP[8013] = {22, 24, 26, 28, 30} -- カプリス
function UseComboSkill(skillId, list, maxCombo, index, spRemainPer)
-- 終了条件(コンボ完了、SP不足)
if index == 0 then return 0 end -- コンボ開始じゃない
if index > maxCombo then return 0 end -- コンボ終了
-- SP残%割るのでここで終了
if math.floor(GetV(V_SP, MyID) / GetV(V_MAXSP, MyID) * 100) < spRemainPer then return 0 end
-- SP足りないのでここで終了
if GetV(V_SP, MyID) < SKILLUSESP[skillId][list[index]] then return 0 end
-- ディレイ待機中
if (ComboDelay ~= 0) and (ComboDelay > GetTick()) then return index end
-- 攻撃中?
if MyState ~= ATTACK_ST then return index end
-- スキル実行
SkillObject(MyID, list[index], skillId, MyEnemy)
ComboDelay = GetTick() + SKILLTOSKILLINTERVAL -- ディレイセット
index = index + 1 -- コンボカウンタ加算
return index
end
- 571 :前スレ391 :06/03/20 01:38
- >>570
よく見たらコンボ実行中に敵が死んだときにどうするか判定するルーチン
が抜けてますね…。どうしようか(ぇ
- 572 :(○口○*)さん :06/03/20 01:46
- if (MOTION_DEAD == GetV(V_MOTION,MyEnemy)) then -- ENEMY_DEAD_IN
MyState = IDLE_ST
TraceAI ("ATTACK_ST -> IDLE_ST")
return
end
のとこにフラグ突っ込んで
そのフラグがONならコンボ強制終了してフラグOFFにする処理かなぁ
- 573 :(○口○*)さん :06/03/20 01:48
- ここだけのいい話:
実はAttackの直後にSkillObjectでムーンライトを使うと
通常攻撃とスキルを同時に使用できます。
これも不正な使い方なんですかねー?
- 574 :前スレ391 :06/03/20 01:50
- >>572
そこに「ComboCounter = 0」を追加すればOKですね。
- 575 :(○口○*)さん :06/03/20 01:53
- >>573
ある意味ではモーションキャンセルの極みだな
まぁ各人の自主性に任せておいていいんじゃないか
- 576 :400=466 :06/03/20 01:53
- >>566さん
あ、そういえばそうですねorz
参考にしていた0-MATERIALさんのAIでは、
ケミの殴ったものしか自発的にホムが攻撃しに行かないから、
GetMyEnemyの方には何も記述がなかったんですね。
ありがとうございました!
それでは早速試してきます〜。
- 577 :(○口○*)さん :06/03/20 01:57
- それぞれの処理の間かコンボ処理の下にDEAD関数?か対象のID確認を
噛ませて見るのはどうでしょう。
もし攻撃中に対象が死亡の戻り値を返した場合は処理中止。と。
もしくは、mobidをロスとした場合中止。
でしょうか…
当方プログラムを書けないので、お門違いの事でしたら申し訳ないです。
- 578 :(○口○*)さん :06/03/20 02:04
- >>568
function OnRUNAWAY_ST ()
TraceAI ("OnRUNAWAY_ST")
local distance = GetDistanceFromOwner(MyID)
if ( distance > AwayRange or distance == -1) then -- Mobから逃げるより主人を追う方を優先
MyState = FOLLOW_ST
TraceAI ("RUNAWAY -< FOLLOW_ST") ここか?
return;
end
- 579 :(○口○*)さん :06/03/20 02:30
- >>573
一番確実なのは、不正行為か? と少しでも思ったらそれはやらないこと。
- 580 :(○口○*)さん :06/03/20 02:33
- >>579
それは違う
問題点は早々に広めて、仕様か要対策が癌に問うのが正しい
この程度は問題点としても取り上げられなさそうなんだけどな
- 581 :567 :06/03/20 02:41
- 自己解決しました。
function OnRUNAWAY_ST ()
TraceAI ("OnRUNAWAY_ST")
local distance = GetDistanceFromOwner(MyID)
if ( distance > AwayRange or distance == -1) then -- Mobから逃げるより主人を追う方を優先
MyState = FOLLOW_ST
TraceAI ("RUNAWAY -> FOLLOW_ST")
return;
end
を部分を以下のとおりに書き換え
function OnRUNAWAY_ST ()
TraceAI ("OnRUNAWAY_ST")
local distance = GetDistanceFromOwner(MyID)
local MyHP = GetV (V_HP,MyID)
local MyMaxHP = GetV (V_MAXHP,MyID)
local HPper = (MyHP / MyMaxHP) * 100
if (AwayHP < HPper) then
MyState = ATTACK_ST
TraceAI (" ATTACK_ST -> RUNAWAY")
return;
else
if ( distance > AwayRange or distance == -1) then -- Mobから逃げるより主人を追う方を優先
MyState = FOLLOW_ST
TraceAI (" RUNAWAY -> FOLLOW_ST")
return;
end
end
HP40%以下になると逃げる→HP40%以上になると攻撃モードに変更します
チェックお願いします
- 582 :(○口○*)さん :06/03/20 03:11
- >>580
癌の対策力に問うてもなぁ…
- 583 :前スレ823 :06/03/20 03:22
- >>522
そのプログラムを作ったものです
確認したところ、逃亡処理を調整中だったころの
古いバックアップのものをアップしてしまっていたようです
すいませんでした
||||orz
ホムペの連絡先に似た報告が来てたので気づき、修正したものをアップしなおしました
コピペ大変だと思うので修正版を置いておきます
http://www.mmobbs.com/uploader/files/74.zip
- 584 :前スレ823 :06/03/20 03:26
- って、これだと522氏のカスタマイズが全部リセットされてしまう…
http://www.mmobbs.com/uploader/files/75.zip
これで直ってるハズ…
- 585 :(○口○*)さん :06/03/20 03:34
- テンプレにあったホムの定期スキル使用だけど、こんな感じのあっさりコードじゃ不味い?
今のところ不具合は感じてないけど、実はパケ送りまくって重くなるとかあるのかも…
-- ホム定期スキル使用
function EverySkill()
do
SKILL_TIME = 30 -- スキル使用間隔(1=2秒?)
local HOM_Motion = GetV(V_MOTION,MyID)
if HOM_Motion > 0 then -- ホム自身が何かしてたら使わない
return;
end
if os.difftime( os.time(), EveryTime ) > SKILL_TIME then
SkillObject(MyID,3,8002,MyID) -- 緊急回避使用
EveryTime = os.time()
end
end
end
- 586 :567 :06/03/20 03:34
- なんとか使いやすくしたので
ttp://www.mmobbs.com/uploader/files/76.zip
機能
・攻撃時オートでスキルを使用。使用%変更可能(sp量での使用頻度も変更可能)
(フィーリル、バニルのみ)
・主人と等速移動(遅れにくく)
(主人にIAがかかり、召喚されるとホムにもIAと同じ効果が得られます(移動速度のみ))
・主人が殴ると自動で攻撃対象に
(他人にタゲが行ってても可能)
・HPが減ると、非攻撃モードに、回復すると攻撃モードになる(逃げる範囲など変更可能)
・横殴り防止機能(ただし射程外攻撃しているPCには無反応)
・主人より一定の範囲内のmobしか殴らない
・選択mob型を導入しました
・選択mob型の選択mobを変更しやすくしました。(GetMyEnemyCが選択mob型です
(選択する種類は増減可能)
・リーフとアスミトルはノンアクティブ設定です。
- 587 :(○口○*)さん :06/03/20 04:13
- >>573
現在、通常Mobの詠唱が無いスキル使用なんかも通常攻撃のASPDってかモーションを無視して
発動してくる。詠唱無いスキルは通常攻撃とほぼ同時に使われたりする。
ホムの仕様はMobに順ずる部分が多いから、そういう特性がホムにもあるんだと思う。
現状出回ってるAIでオートスキルは攻撃ルーチンの中の1回で行われているから、
見かけ上ASPDに従ってるように見えるだけでしかないのかも。
わがままかもしれないが、Mobのスキルの扱いがこのままである以上
ホムのスキルもこういう扱いでいいのかもしれない。
っていうかホムスキルは射程すら設定されてないようだから本当いい加減すぎるな。
- 588 :259 :06/03/20 04:14
- >>560-562
ダブルクリックではないですが、
ホムンクルスのいるセルをALT+右クリックすることで、
索敵条件の先攻/非先攻を切り替えると言ったことができます。
以下のページのv0.23のAI.lua 139〜158行目をご覧ください。
ttp://www.kmzw.jp/nb/ai.html
- 589 :前スレ391 :06/03/20 04:25
- よくよく見直してみると>>570のコードそのままじゃ、
最初のコンボスキル発動→手動スキル発動→2番目のコンボスキル発動になりますね…。
>>570の修正点だけ書いておきます。
↓この行を、
if skill == 8009 and level == 3 then ComboCounter = 1 -- ムーンライトレベル3ならば
↓のように修正。
if skill == 8009 and level == 3 then
-- コンボ発動中に再度トリガが起動された場合にカウンタが1に戻るのを防ぐ
if ComboCounter == 0 then ComboCounter = 1 end
end
↓この行を、
ComboCounter = UseComboSkill(8009, ComboList, MaxCombo, ComboCounter, 0)
AI()関数内の状態処理の「直前ではなく、」直後に追加する。
後、追加でOnATTACK_ST()関数内の、
SkillObject(MyID, MySkillLevel, MySkill, MyEnemy)
MySkill = 0
の直後に以下の行を追加する。
-- コンボ開始している場合、手動スキルと最初のコンボスキルのディレイを設定しておく。
if ComboCounter == 1 then ComboDelay = GetTick() + SKILLTOSKILLINTERVAL end
最後にUseComboSkill()関数内で抜けているコンボ途中で敵がいなくなった場合の処理として、
関数内の最初の行にでも、以下の行を追加する。
--コンボ発動中に戦闘状態が終了している
if (index > 0) and (MyState ~= ATTACK_ST) and (MyState ~= CHASE_ST) then return 0 end
これで大丈夫なはずはずはず…。
- 590 :(○口○*)さん :06/03/20 04:41
- >>雑談スレ132
0マテのAIの
グローバル変数の所に、
HealDelay = 0 -- 時間格納用
HealCancellationTime = 10000 -- スキル中止時間
Delay = 5 -- 失敗回数
redslim = 1 -- 赤スリム所持状態判断用
を追加して、
elseif (MySkill == 8001 and HomunculusHeal == 1) then
if (HomunculusDeadlineHP > (HomunculusHP / HomunculusMaxHP)*100 or OwnerDeadlineHP > (OwnerHP / OwnerMaxHP)*100) then
SkillObject (MyID,MySkillLevel,MySkill,MyID)
ActionFlag = 1
TraceAI ("ATTACK_ST -> ATTACK_ST : AUTO_HEAL")
end
end
の部分を、(次レスに続く)
- 591 :590 :06/03/20 04:41
- elseif (MySkill == 8001 and HomunculusHeal == 1) then
TraceAI("確認用")
if(redslim ~= 0)then
if (HomunculusDeadlineHP > (HomunculusHP / HomunculusMaxHP)*100 or OwnerDeadlineHP > (OwnerHP / OwnerMaxHP)*100) then
SkillObject (MyID,MySkillLevel,MySkill,MyID)
if(HomunculusSP >= GetV(V_SP,MyID))then -- 治癒の手助け失敗用
redslim = redslim +1 -- 失敗回数++
if(redslim > Delay)then -- Delay回使用失敗したら(ディレイなど考慮)
redslim = 0 -- 赤スリムなしと判断
HealDelay = GetTick() + HealCancellationTime -- ヒール禁止時間指定
end
else
redslim = 1 -- 成功していたら初期化
end
end
ActionFlag = 1
TraceAI ("ATTACK_ST -> ATTACK_ST : AUTO_HEAL")
end
if(GetTick() > HealDelay and redslim > Delay)then -- 時間が経っていたら、ヒールの使用禁止解除する
redslim = 1
HealDelay = 0
end
end
に変更、でいけるはず……。
これだったら、5回失敗したら10秒間使用中止の設定。
眠い頭で書いたのでミスしてたらゴメン。
- 592 :352 :06/03/20 07:56
- 何度かこちらで独自AIを紹介させていただいている者です。
おそらく現状誰も普通には使っていない
「ALT+SHIFT+右クリック」を通常UI的に取り入れてみました:
RO画面上で「友達登録」や「敵ごとのアクティブ/非アクティブ条件」、
「敵ごとのオートスペル的使用率」を変更できます。
ttp://tomose.dynalias.net/RO/attach/hom/Glenelg_020.lzh
独自構築なので、なかなか他のAIとは共通化できないと思いますが・・・
-AI() 内の GetResMsg()〜 rmsgからの分岐条件変更
-ProcesCommand() 内、分岐条件追加
-OnIDLE_ST()内、微修整
・・・の上記3点の修整で対応できるので、他のAIでも流用できると思います。
なにかの参考に、という位置づけでご利用くださると、幸いです。
- 593 :352 :06/03/20 08:09
- 舌足らずだった oTL
×・・・の上記3点の修整で対応できるので、
○・・・の上記3点の修整で「ALT+SHIFT+右クリック」対応はできるので、
- 594 :(○口○*)さん :06/03/20 08:45
- >>592
コメントがやたら多いんでJavaランタイムのソースを思い出した。(褒め言葉)
- 595 :(○口○*)さん :06/03/20 08:49
- >>592
ドキュメントを書かないソフト屋の癖みたいなもんです(^^;;
コメント書かないと、時間たってから読み直したときに、なんでそーなってるのか忘れるのさ(笑)
- 596 :(○口○*)さん :06/03/20 09:42
- foobar += 1; // foobarをインクリメントする。
とか書いてある過去の自分をしばきにいきたいぜ…… orz
- 597 :(○口○*)さん :06/03/20 11:13
- すまん、ちょっと脱線するけど教えてほしい。
Luaでビット演算はできないでFAなのだけど
>>559が他の言語でうまくいく理由がわからない。
フラグなら|で合成して&でマスクすれば結合・分離できるけど、
数値でそれは使える?
たとえば3(0011b)と4(0100b)のビット積は0になってしまう。
ビット和だとしても7(0111b)になるから、1〜7ならなんでも引っかかって
しまうはず。
それとも根本的になにか勘違いしてるのかな。
- 598 :(○口○*)さん :06/03/20 11:20
- >>592
友達リストは自分の中で最優先事項なので(なぜ)
前回に引き続き今回も参考にさせてもらってる。
コメント多くていろいろ参考になるわ、ありがとう。
- 599 :(○口○*)さん :06/03/20 11:35
- >>597
変数の値が少ない(32くらいまで)なら、
「数値Xが含まれるかどうか」を「X桁目にフラグが立っているか」で
判断すればいいかと。
3と4のみが含まれるなら「00001100」(二進)のような感じで。
- 600 :(○口○*)さん :06/03/20 11:52
- >>599
thx、でもそれは限定した状況でのロジックとしては使えるけど
>>559の
>mob1に1002と1063に代入
なんてことはできないよね。
- 601 :(○口○*)さん :06/03/20 12:28
- >>600
>559は別にビット演算のことを言ってるわけではないと思う。
>559のやりたいことはつまり、
mob1 = { 1002, 1063 }
...
if ( List.search(mob1, GetV(V_HOMUNTYPE, id)) ~= nil )
こんな感じかと。もちろんList.searchは自作するとして。
- 602 :(○口○*)さん :06/03/20 12:33
- あ、宣言がこれじゃ駄目か。
mob1 = { 1002, 1063 }
mob1.first = 0
mob1.last = 1
かな?あるいは
mob1 = List.new()
List.popright(mob1, 1002)
List.popright(mob1, 1063)
- 603 :(○口○*)さん :06/03/20 12:38
- 連レスすまん。さらに違う。
mob1 = {}
mob1[0]=1002
mob1[1]=1063
...
でいいかな?段々自信がなくなってくるぞー。
あと、下のがpoprightじゃなくてpushrightだ。
- 604 :(○口○*)さん :06/03/20 12:51
- >>601
そうか、&がビット演算とは限らないか。あのVBじゃ文字列結合演算子みたいだし。
すっきりした。ありがとう。
でもlistはただのテーブルじゃない(listobj.firstとlistobj.lastが必要)
だから、代入含めてList関数群で操作しないと整合性とれないよ。
- 605 :(○口○*)さん :06/03/20 12:52
- 簡単なものだけど ALT+T で追従か待機かわからないことがあるので自分用に書いたの出してみる。
ALT+Tで上に行くと追従、下に行くと待機。
----------------------------------------
-- 追従コマンド
----------------------------------------
function OnFOLLOW_CMD ()
-- 待機命令は、待機状態と休息状態を互いに転換させる
if (MyState ~= FOLLOW_CMD_ST) then -- 追従状態
local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID))
Move(MyID,x,y + 1) -- 主人の上に移動
-- MoveToOwner (MyID)
MyState = FOLLOW_CMD_ST
MyDestX, MyDestY = GetV (V_POSITION,GetV(V_OWNER,MyID))
MyEnemy = 0
MySkill = 0
TraceAI ("OnFOLLOW_CMD")
else
local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID)) -- 追従解除
Move(MyID,x,y - 1) -- 主人の下に移動
MyState = IDLE_ST
MyEnemy = 0
MySkill = 0
TraceAI ("FOLLOW_CMD_ST --> IDLE_ST")
end
end
- 606 :(○口○*)さん :06/03/20 12:59
- Lua詳しくないのでわかったら教えて欲しい。
table[100000] のようなでかい値を指定してもメモリや処理が無駄に増えたりはしないのかな?
テーブルの扱いが配列なのかハッシュなのかよくわからない感じなので
フラグとして基本的に大きな数字のキャラIDをキーにしてテーブルに入るなんてのをする時にちょっと心配。
- 607 :(○口○*)さん :06/03/20 13:06
- ふと思ったんだけど、ROの射程距離計算ってどっちが正しい?
例:射程4
□□□□□□□□□□□ □□□□□□□□□□□
□□□□□■□□□□□ □□□■■■■■□□□
□□□□■■■□□□□ □□■■■■■■■□□
□□□■■■■■□□□ □■■■■■■■■■□
□□■■■■■■■□□ □■■■■■■■■■□
□■■■■☆■■■■□ □■■■■☆■■■■□
□□■■■■■■■□□ □■■■■■■■■■□
□□□■■■■■□□□ □■■■■■■■■■□
□□□□■■■□□□□ □□■■■■■■■□□
□□□□□■□□□□□ □□□■■■■■□□□
□□□□□□□□□□□ □□□□□□□□□□□
右図なら問題ないんだけど、左図だった場合 IsInAttackSight() に問題出るような?
- 608 :(○口○*)さん :06/03/20 13:15
- あと念のため。ipair(list)は期待した動作にならないから
バグの温床になる。
>>606
Luaのコード読んだわけじゃないけど、実装からして
table[10000] = 10000
hash["key"] = 10000
struct.name = 10000
はデータ量的に(ほぼ)等価。
要するに連想配列のkeyに数値使ってるだけ。
ただやっぱりipairsには注意。
>>607
PCの射程は右図の形状。
「桂馬の位置」までそれで合ってるかはうろ覚えだけど。
- 609 :(○口○*)さん :06/03/20 13:16
- >>607
プレイヤーの射程?
プレイヤーのほうは知らないけど、モンスターは完全な四角形だったはず
- 610 :(○口○*)さん :06/03/20 13:25
- >608
> ipair(list)は期待した動作にならないから
出来れば、どういう動作を期待してどういう動作になるのか具体的に書いてほすぃ
- 611 :(○口○*)さん :06/03/20 13:26
- >>607
問題はないのね。
基礎ライブラリ疑ってもしょうがないやね。
>>609
と思ったけど、モンスター四角形なのか!
射程外まで逃げるの処理作ろうとして、ちょっと気になってたんですよ。
PCとモンスターで射程違うのね・・・もしかして魔法、スキル射程も違ったりする?
- 612 :(○口○*)さん :06/03/20 13:32
- そしてUtil.luaを見直してみた。
function List.clear (list)
for i,v in ipairs(list) do
list[i] = nil
end
これが重力クォリティか…。
List自体はProgramming in Luaに載ってて、
List.clearとList.sizeは重力作のはず。
>>610
ipairs()の動作(1から始めて値がnilになるまで)と
List.popleftやpushleftが添え字そのものは操作していないことに注意。
first<1ならipairs()はfirst<=i<=0を無視するし
first>1ならipairs()はなにも返さない。
- 613 :(○口○*)さん :06/03/20 13:38
- >>607
GetDistance だとこうなるね。
PCもNPCも同じに扱ってるけど違うのかな射程。
7 6 5 5 5 5 5 5 5 6 7
6 5 5 4 4 4 4 4 5 5 6
5 5 4 3 3 3 3 3 4 5 5
5 4 3 2 2 2 2 2 3 4 5
5 4 3 2 1 1 1 2 3 4 5
5 4 3 2 1 0 1 2 3 4 5
5 4 3 2 1 1 1 2 3 4 5
5 4 3 2 2 2 2 2 3 4 5
5 5 4 3 3 3 3 3 4 5 5
6 5 5 4 4 4 4 4 5 5 6
7 6 5 5 5 5 5 5 5 6 7
>>608
多分そうだとは思うけどひっかかる。まあ、いいか。
しかし仮に数値もそのままキーにしてるとしたら table[8] と table["\t"] が同じとかはないよなー
と、試してみたらやっぱり違った。Cの'\t'じゃないんだからあたりまえか。
- 614 :(○口○*)さん :06/03/20 13:39
- 単純な実例。
list = List.new()
List.pushright(list, 1)
for i,v in ipairs(list) do print(i,v) end --> 「1 1」を期待するも反応なし
print(list[0]) --> 1
for k,v in pairs(list) do print(k,v) end
--[[
0 1
first 0
last 0
--]]
- 615 :(○口○*)さん :06/03/20 13:40
- >>601-603
こういう関数を作れば
function List.new2(...)
local list = List.new()
for i, v in arg do
List.pushright(list, v)
end
return list
end
こう書けて幸せになれるかも
mob1 = List.new2(1002, 1063)
それともこういうのを作って
Array = {}
function Array.search(array, val)
for i, v in array
if (v == val) then
return i
end
end
return nil
end
こうしてもいいかも
mob1 = { 1002, 1063 }
if (Array.search(mob1, GetV(V_HOMUNTYPE, id)))
- 616 :(○口○*)さん :06/03/20 13:41
- >612
あ、なるほどね。
List関数は使ってなかったから気付かなかった。
解決するにはpopleft/pushleftを書き換えるか、ipairsを置き換えるしかないか…
- 617 :(○口○*)さん :06/03/20 13:42
- >>615
forのところ思いっきり間違えてた_| ̄|○
function List.new2(...)
local list = List.new()
for i, v in ipairs(arg) do
List.pushright(list, v)
end
return list
end
と
function Array.search(array, val)
for i, v in ipairs(array) do
if (v == val) then
return i
end
end
return nil
end
- 618 :(○口○*)さん :06/03/20 13:43
- >>613
type(8) == "number"
type("\t") == "string"
だから同一ではないよ。
- 619 :(○口○*)さん :06/03/20 13:59
- Array 系の関数は欲しいな。
push pop だけじゃなくてperl のsplice みたいに配列の間に追加ってのも。
これとは別だけど関数に可変長の引数渡せないのだろうか。
関数定義側でテーブルみたいに受け取れるとありがたいんだけど
- 620 :(○口○*)さん :06/03/20 14:03
- >>619
>>617のList.new2にある...がズバリそれ。
関数定義の引数に...と書いておけば関数内でテーブルargから取り出せる。
- 621 :(○口○*)さん :06/03/20 14:09
- お、そうなんだ。>>617,620 サンクス。
これで多次元配列に代入しても直前の次元ががnilでも扱う関数作れる。
- 622 :(○口○*)さん :06/03/20 14:53
- local mobset = ActiveSet[id][Setting]
上記のようなスクリプトで、[id]によって送られてきたMOBやプレイヤーのIDに対して
下のようなアーカイブから数値返そうとしています。
Setting = 1
ActiveSet = {}
ActiveSet[1002] = {1,''}
ActiveSet[1031] = {1,''}
ActiveSet[1051] = {1,''}
ActiveSet[1053] = {1,''}
ActiveSet[1070] = {1,''}
ActiveSet[1113] = {1,''}
この状態で、1003など、定義されていないIDが送られてきたときにエラーが出るのですが、
未定義のIDなどが送られてきた場合のエラーを回避するにはどうすればいいでしょうか?
- 623 :(○口○*)さん :06/03/20 14:55
- かなり際どいけど、Ctrl+1みたいなショートカットキーで
Luaの任意の関数を呼べるようにしてみた。
ttp://www5e.biglobe.ne.jp/~akemino/upload/mmobbs/files/2984.zip
実行ファイルのほうでショートカットキーを処理して、
それをIO経由でLuaに渡すっていう原理なので、
aiinput.exeを常駐させてる必要があるのがネック
とりあえず
Ctrl+1 でラウドボイス
Ctrl+2 で安息
Ctrl+3 でassert(nil)を呼ぶようにしてみた。
具体的なコードはaiinput.luaを参照。
(実際にイベントハンドラを登録してるのはevents.luaの末尾)
ちなみに同封してるAIは
ttp://blog.livedoor.jp/aidev/で配ってるやつのテスト版です。
- 624 :(○口○*)さん :06/03/20 14:57
- 癌に質問してきた
■質問内容■
現在ホムンクルスのAIを改変することでホムンクルを使役するアルケミストに、そのアルケミストが取得しているスキル(クリップ等で使用可能になるスキルを含む)を使用させることが出来てしまいます。
これによって商人スキル「ラウドボイス」を一定周期で発動させたり、アルケミストスキル「ポーションピッチャー」を任意のタイミングで自分自身、又は使役するホムンクルスに対して使用することが可能になります。
上記のホムンクルスのAIを改変することで商人・アルケミストのスキルを自動使用させることが可能になる現象は仕様なのでしょうか?それともバグなのでしょうか?これを質問とさせて頂きます。
- 625 :(○口○*)さん :06/03/20 14:58
- んでこれが解答。
■返答内容■
ご投稿いただきまして誠に申し訳ございませんが、ゲーム内の仕様に関しましては、
公正なルールを保つ為、返答を差し上げる事は控えさせていただいております。
大変申し訳ございませんが、何卒ご了承ください。
- 626 :(○口○*)さん :06/03/20 14:59
- >>622
既に定義してある数値のリストを別に作っておいて、
local mobset = ActiveSet[id][Setting] に通す前に
送られてきたidがリスト内に存在するもののどれかと合致するかどうかの
チェックを挟むしかないんじゃない?
- 627 :(○口○*)さん :06/03/20 15:05
- >>623
際どいって言うか完全に外部ツール使ってるじゃねぇかw
- 628 :(○口○*)さん :06/03/20 15:07
- >>622
if( ActiveSet[id] ~= nil ) then
--処理
end
で、通らないかな
- 629 :(○口○*)さん :06/03/20 15:14
- >>627
外部ツールってクライアントやパケットに
直接干渉するプログラムのことじゃないの?
exeが生成したファイルをAIから読んだだけで外部ツールなら、
韓国AIに入ってる設定変更用のexeも外部ツールってことになると思うけど
- 630 :(○口○*)さん :06/03/20 15:20
- 動的なプロセス間通信でしょ
filestreamで
- 631 :(○口○*)さん :06/03/20 15:21
- >>623
拝見しました。
要は、
・ROの外部プログラムで、キー監視&特定キー操作で「特定フォーマット構造の書かれたテキストファイル作成」
・RO内ホムAIプログラムで適時ファイル監視して、そこに何か書き込まれていたら読み出して実行。
・・・ってことね。
規約上どうこうってのは話すと荒れるだけなので「がんほー次第なので、あえて語らず」ということで。
- 632 :(○口○*)さん :06/03/20 15:42
- >>629
>■ 運営チームにて定義する「不正ツール」
>・プレイヤーの代わりにキャラクターを自動的に操作することができるもの
>・マクロの機能(特定の操作手順を自動的に行う)を利用することができるもの
>・キーボードやマウスなどに一定の動作を実行させることができるもの
>・通常のクライアントでは表示されないデータを表示させることができるもの
>・運営チームが指定する以外の方法で画像や動画などを撮影することができるもの
>■運営チームにて定義する「不正ツール」には当てはまらないもの
>・「ラグナロクオンライン」のゲームサーバーに干渉することがなく、「ラグナロクオンライン」を
> プレイするために直接必要のないものツール単体で動作することができるもの
主に3番目に該当する可能性あり
韓国AIの設定用exeと違って常駐させる点もかなり危険
- 633 :(○口○*)さん :06/03/20 15:53
-
この話題はやるだけ無駄とわかっているのでココマデ
- 634 :(○口○*)さん :06/03/20 16:11
- よしじゃぁコの字型の壁の向こうにいる敵に
回り込んで攻撃する方法を考えようぜ
ぅう ちくしょう似たようなスレ立てやがって・・・
- 635 :(○口○*)さん :06/03/20 16:31
- 移動できてない
->最終移動目標として移動目標X.Y座標を記録
->移動目標Y座標をランダムで変更
->それでも移動できてない
->移動目標X座標をランダムで変更
->それでも移動できてない
->移動目標Y座標をランダムで(ry
->移動できた
->その地点から最終移動目標へ移動してみる
->移動できない
->移動目標Y座標をランダムで(ry
->移動できた
->攻撃
こんなん考えたがまず上手くいかないだろうな。根本的に考え方変える必要がある。
個人的にはFOLLOWさせてケミと一緒に壁向こうに回り込んだほうが早いんじゃないだろうかと思う。
- 636 :(○口○*)さん :06/03/20 16:40
- >>634
迷路脱出系プログラムだね・・・
問題は、壁がどこにあるか、というのがホムにはわからないというところ。
まずは「進入不能マスをホムがどうやって知るか」を考えないとならない。
人間が調べてiniファイル作るって手もあるけど、ROの広いマップすべてをそんなことはできないので、
自動的に検出したいねぇ・・・
- 637 :(○口○*)さん :06/03/20 16:44
- 自動検出走査AIをつくればいいじゃなーい
ごめん、言いだしっぺはスキル無い人だから許してorz
- 638 :(○口○*)さん :06/03/20 16:49
- Move()の移動先に移動不可能な時は全く移動しない。
これを使って…
->前回との座標差分を取得。
->前回と同じならカウンタをインクリメント
->カウンタ一定以上で、移動先を「移動できないセル」に認定
->現在座標と目標座標のセットを「移動不能」として外部ファイルに書き出し
->前回と違うならカウンタ初期化
->現在座標と目標座標のセットを「移動可能」として外部ファイルに書き出し
->現在の座標を変数に保存
こんなプロセスをMove()の周辺で毎回行えば、うろうろしていればいずれ
移動できない場所を覚えるんじゃなかろうか。
- 639 :(○口○*)さん :06/03/20 16:56
- >>638
たぶんそんな感じでやっていくしかないでしょうね。
ちなみに、iniファイルを使うにしてももう1つ課題があって、
ホムは「自分がいるマップがどこなのか」も知らない。
なので、もし638氏の方法でマップができたとしても、それを保存・再利用するには
何かうまい方法を考えないとならない。
課題はいろいろと多そうです。
- 640 :(○口○*)さん :06/03/20 17:09
- >639
そうなんだよな…
AIをロードするたびに新しいファイルに書き込む事にする(テレポ使えなくなるが)とか、
出現するMobからMAPを類推するルーチンと組み合わせる(同じMobの出るMAPはどうするのか)とか、
狩場に着くたびに手動でファイルを選択&バックアップする(面倒だしスマートじゃない)とか…
どれもイマイチ現実的じゃないなorz
壁を取得するのは諦めてその場限りの回避ルーチンを組んでいくか、
いっそその場その場でご主人様がフォローしてやるか…?
- 641 :(○口○*)さん :06/03/20 17:13
- マップリスト作ることはできるけど場所特定できないし、さらにでかいデータを「頻繁に読み込むのはネックだな。
AIつっても全自動じゃなくて半自動くらいに思ってるんで
一定時間動きがなければ状態を解除ってくらいにしといたほうが組むのも楽ではある。
複雑にするとクライアントにどんどん負荷がかかってくる。
- 642 :(○口○*)さん :06/03/20 17:26
- よく理解してないのに言うのもなんだが
OnFOLLOW_CMDで待機と休息の2択じゃなくて、
何種類か用意してAlt+T押すごとに変わってくとかできないの?
- 643 :(○口○*)さん :06/03/20 17:30
- 出来なくもないけど、ホムからケミに伝える方法がないから
今どの状態が判別つき辛くなって大変だった
- 644 :(○口○*)さん :06/03/20 17:31
- >642
出来る。
さらに言えば状態を入れ替えるだけじゃなく、トリガーとしていろんな用途に使える。
- 645 :(○口○*)さん :06/03/20 17:32
- >>642
できます。
ただ、あまり複雑なものは、やりかたを考えないとなりません。
というのは、現状のAI仕様では「ホムからの情報発信」は非常にプアなので、
今どういう状態にホムがなっているのかを、ユーザーが判断しづらいのです。
例えば現状の標準AIでも、ALT+Tで「通常」「待機(非戦闘)」の2つの状態をトグル動作できます。
が、そのどちらになっているのかは、ぱっと見では判らないと思います。
(多分近くに敵が来て、戦闘するかどうかではじめてわかる)
このスレの605氏みたいな「ホムの通常待機位置で表現」や、
592氏のAIのような方法を併用していけば、かなり有用な方法にはなると思います。
- 646 :(○口○*)さん :06/03/20 17:36
- for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
type = GetV(V_HOMUNTYPE,v)
target = GetV (V_TARGET,v)
if (target == myid) then
enemys[index] = v
index = index+1
elseif (ここだと思う) then
if (GetV(V_TARGET,v) == 0) then
enemys[index] = v
index = index + 1
end
end
end
このAIに外部よりmobact.luaで編集したデータで攻撃、非攻撃設定ができないだろうか。
mobact.luaからの関数の引き出し方がわかりません。教えてもらえないでしょうか?
mobact.luaの中身はこんな感じ
--------------------------------------------------
-- constants # 定数 #
--------------------------------------------------
M_V_NAME = 1 -- モンスター名称
M_V_ACT = 2 -- # 攻撃 #
--------------------------------------------------
M_ACT_NONE = 1 -- 攻撃しない
M_ACT_UNDEAD = 2 -- 攻撃する
--------------------------------------------------
MOBACT = {}
MOBACT[1001] = {'スコーピオン',1}
MOBACT[1002] = {'ポリン',2}
MOBACT[1004] = {'ホーネット',2}
- 647 :(○口○*)さん :06/03/20 17:37
- 今どの状態かが分かりづらいなら。
トリガ使って「今どのモード?」って聞けないかな。
その命令が出たら、モードにあわせて動作を変えるとか
モードAならケミの右に移動して旋回
モードBならケミの左に移動して旋回
モードCならケミの下に移動して旋回
ALT+Tで状態変更時に見せる動作と同じものにするとか…
戦闘中そんなことさせてるヒマ無いっすねorz
- 648 :(○口○*)さん :06/03/20 17:40
- そう言われてみるとそうだな・・
Alt+Tで簡単に動き方いろいろ変えれたらと思ったけど、難しそうだ
- 649 :(○口○*)さん :06/03/20 17:47
- 最後の悪あがきで
Alt+Tのダブルクリックとか押し方で判断はできないかな
一定時間内にクリック何回あったらこの状態にするとか
- 650 :(○口○*)さん :06/03/20 17:50
- >>649
実は592なんですが(笑)
592で紹介している拙作AIでは、
・元AI同様に、ALT+Tで「通常状態」と「待機状態」に切替。
・上記の待機状態から、ALT+Tを素早く2回で「学習状態」に切替。
・独特な方法で、「待機状態」「学習状態」を画面表示して、見た目で状態がわかる。
・・・というような実装がなされています。
独自AIなので汎用的ではないですが、実現は可能だよ、ということで。
- 651 :622 :06/03/20 17:54
- >>626
>>628
お二方助言ありがとうございます
どうも、未定義の数値送られてくるとエラーは回避できないようなので、
めんどくさいの我慢してテーブルを使ってデータを整理しようと思いますorz
- 652 :(○口○*)さん :06/03/20 18:00
- >>560あたりで話題になってた右ダブルクリックの処理をを自分なりに書いてみました
function OnMOVE_CMD (x,y)
+ if ((DoubleRightClick_PositionX == x) and (DoubleRightClick_PositionY == y) and (DoubleRightClick_Time + DoubleRightClick_TimeRemit > GetTick())) then -- ダブルクリックされているならば
-----------------------------------↓
-- ダブルクリックの処理をここに追加
-----------------------------------↑
+ DoubleRightClick_Time = 0
+ DoubleRightClick_PositionX = 0
+ DoubleRightClick_PositionY = 0
+ return
+ end
+ DoubleRightClick_Time = GetTick()
+ DoubleRightClick_PositionX = x
+ DoubleRightClick_PositionY = y
TraceAI ("OnMOVE_CMD")
if ( x == MyDestX and y == MyDestY and MOTION_MOVE == GetV(V_MOTION,MyID)) then
return -- 目的地と現在地が同一の場合は、処理しない
というのを追加してみたんですが、どうもうまく行きません。
ダブルクリックの間隔を短くすると認識されていないみたいなのですが・・・
遅めにダブルクリックすると一応認識されました。
速めにダブルクリックしても認識させたいのですが・・・助言お願いしますorz
- 653 :652 :06/03/20 18:01
- あれ・・・スペース入れたのに消えてる・・・
見づらくてすみませんorz
- 654 :(○口○*)さん :06/03/20 18:03
- >653
1文字目から始まる半角スペースは全部キャンセルされるよん。
タブにするよろし。
- 655 :(○口○*)さん :06/03/20 18:38
- 短すぎる連続クリックはそもそもROクライアントが拾ってくれない(クリックと見なさない)可能性が。
どうでも良いけど、Remit→Limitだよな、たぶん
- 656 :(○口○*)さん :06/03/20 18:42
- >>654
それがタブもキャンセルされるんだなあ、困ったことに。
「 」でスペースを入れるか、全角スペースを使うかのどちらかしかなさそう。
- 657 :(○口○*)さん :06/03/20 18:46
- ホム静止
function OnMOVE_CMD(x,y) --{
--# 関数呼ばれた時間を取得して比較
if( (GetTick() - MoveTimeSet) > 2000) then --{
MoveTimeSet = GetTick()
MoveTimeX = x
MoveTimeY = y
MoveTimeFlag = 0
--}
else --{
if(x == MoveTimeX and y == MoveTimeY) then --{
MoveTimeFlag = 1
end
--}
end
--} (略
ダブルクリック(同じ座標を2秒以内にもう一回クリック)でフラグを立てて
あとの処理がそのフラグで分岐・・という風にしてます。
- 658 :(○口○*)さん :06/03/20 18:50
- >>652
GetTick取ってみると、だいたい280ms〜400msくらいの間隔でOnMOVE_CMDは認識してるようです。
よってそれ以下の間隔は無理ぽ
- 659 :(○口○*)さん :06/03/20 19:04
- ホムの攻撃ってさ
念3以上のMobにも当たるのね。
- 660 :(○口○*)さん :06/03/20 19:12
- >>659
ホムは、属性関係ないぽ
- 661 :(○口○*)さん :06/03/20 19:12
- >>658
認識の間隔は各PCのスペックやAIの中身、ラグでも大きく変わるでしょ
空っぽのAIでGetTickのみ取ると結構速いよ
- 662 :(○口○*)さん :06/03/20 19:19
- 重力座標による攻撃できてないのにATTACK_STがループする現象を直す試みを
いくつか考えやってみた、そして、ここの人たちにも聞いてみた
1.重力座標が原因なので位置取得系は全部没
2.敵のモーションで判断させる
→他の人が殴ってたら誤認
→ホムの攻撃がミスだったら誤認
3.ホムの攻撃モーションで判断させる → 通常時でも攻撃モーションが取れない
4.ホムを定期的に動かす
→定期的に別セルに動かれたら殲滅速度に多大な影響
→ホムの現在座標を取得し、定期的にそこへ動くようにする
→やってみたが意味が無かった
他に手はないものかねぇ・・・('A`)
- 663 :(○口○*)さん :06/03/20 19:31
- オート緊急回避やCHASE_STタイムアウトなど
ありがたくソースを使わせてもらってるミジンコケミ
mobdata.luaを何かに使えないかととりあえずAI.luaファイルの一番上のところに参照ファイルを追加したんだけど、
なにがいけないのかファイルがロードできないと起動時エラーが出る始末。
もしかしてどこかで使うでもないのに参照したりするとダメなんだろうか?
ちなみにmobdata.luaファイルは有志のやつです。
- 664 :(○口○*)さん :06/03/20 19:35
- >>663
だからさ、「エラーがでて困ってるんです。どうにかできませんですか」
エラーの内容その他(この場合AI,luaとmobdata.luaの位置関係及びrequireをどう書いたか)
を書かなきゃ推測のみで答えなきゃならんわけだから
答える側は単純に困るよ
- 665 :(○口○*)さん :06/03/20 19:36
- 重力座標の原因が
「敵の攻撃によるヒットストップ」
ってことだから、
Move中にHPが減った場合に再度Move命令するようにするとかどうよ?
あと、自分のターゲットが変わるとき(死亡した or 画面外に消えた)に
たとえ攻撃範囲内にいると判定できてもMove命令するのも良いかも
- 666 :663 :06/03/20 20:12
- 申し訳ない、その通り
mobdata.luaはAI.luaと同フォルダ内、参照記述は
require "./AI/Const.lua"
require "./AI/Util.lua"
require "./AI/mobdata.lua"
-----------------------------
-- state
(以下略)
ほかにmobdata.luaにアクセスするような記述はまったく追加してない。
mobdata.luaのファイル内容も一切変更無し。
エラーメッセージは
./AI/USER_AI/AI.lua:4 could not load package './AI/mobdata.lua' from path '?,?.lua'
と、こんなんでいいんだろうか
- 667 :(○口○*)さん :06/03/20 20:15
- >>666
USER_AIフォルダに置いてない?
- 668 :(○口○*)さん :06/03/20 20:17
- エラー文がパスミスのそれだな。多分>>667。
- 669 :(○口○*)さん :06/03/20 20:17
- USER_AIフォルダに置いてるなら
require "./AI/USER_AI/〜.lua"
に直すだけ
ところでミジンコって単語使うのはどうかと思うわ
- 670 :(○口○*)さん :06/03/20 20:18
- エラーメッセージである程度原因特定できるから整理して雑談スレのテンプレにでもしてもらおうか。
とりあえず nil 値のエラーとファイルパスあたりはそのまんまだし。
- 671 :(○口○*)さん :06/03/20 20:19
- >>665
たしかに、そうすればホムの重力座標は取れそうですね。やってみます
ただ、モンスターの重力座標はやはり無理ですね
人だって、重力座標の敵は予測してやらなければいけないんだし
AIでは根本的に無理かもしれませんね
>>666
おそらく、USER_AIにmobdata.luaを入れてるんだと予想する
USER_AIフォルダの中身のファイルを取り入れる場合
少し特殊で./AI/USER_AI/[ファイル名]でないといけない
- 672 :(○口○*)さん :06/03/20 20:36
- FoundIDで一緒に取得できるTypeで対象が何かを判別するんでしょうが,
「その数値のいくつが何に対応しているのか」がわかるサイトはないでしょうか?
知りたいのは,他プレイヤーのType番号なんですけど。。。
- 673 :663 :06/03/20 20:40
- >>664,667,668,669,671
うわー、ほんとだ・・・こんな単純ミスだったとは。
そもそもUSER_AIフォルダを指定してなかったのか、スレ汚しスマン・・・orz
みんな親切にありがとう、もうちょっと他の人のファイルもよく見てから質問するよ。
>>669
ごめん、BOTNEWSに毒されすぎた気をつける。
- 674 :(○口○*)さん :06/03/20 20:43
- BOTNEWSは最近ネタがなくて管理人の悪い部分が出まくり
自分の中で一気に冷めた感じ
- 675 :(○口○*)さん :06/03/20 20:45
- >>663
だったら最初から書くなよ。
毒されようがなんだか知らんが、自分の発言には違いないだろ。
自分の発言を他に責任転嫁するな。
- 676 :(○口○*)さん :06/03/20 21:02
- 原因特定できて失言も理解したんだからそれ以上言うことないだろうに。
主旨が違うよ。
つ[雑談スレ]
- 677 :(○口○*)さん :06/03/20 21:14
- 対人反応型アクティブ・ノンアクティブ自動切替スクリプトとして>>369-370とか
>>402や>>499でアップした拙作スクリプトを
新規命令文追加モジュールにしてみた。
スクリプトを丸ごと移植しないでも他の命令文同様に扱えるので、
全く別の自作スクリプトでもだいぶ扱いやすくなったと思うけどどうだろうか?
ttp://www.mmobbs.com/uploader/files/81.zip
・使用方法はAIフォルダに解凍したフォルダの中身のモジュールをぶち込んでスクリプト先頭にrequire "./AI/AutoActive.lua"
を入れる。
・デフォルトAIのGetMyEnemy系の一行を追加命令文に置き換えるだけで
周囲に人がいないときに特定モンスターを自動排除。
・上記の目的のための統合型命令文のほかに、それを構成する命令文も単一の命令として使用可能。
(範囲内のユーザーID(個別および職業)の取得、指定したモンスターの索敵)
・対象のモンスターや他プレイヤーの反応距離等を設定用luaファイルで追加指定・変更可能。
- 678 :(○口○*)さん :06/03/20 21:15
- Listの代替モジュール
ttp://www.mmobbs.com/uploader/files/80.zip
使えるメソッド
Push/Pop
Enqueue/Dequeue
Size/Clear/Pickup
(公式AIのUtilに入ってる奴とは同居できないので注意)
例:
list = List.New()
list:Push("a")
a = list:Pop()
といった使い方が出来ます。
よかったらどうぞー。
- 679 :(○口○*)さん :06/03/20 21:16
- >>646の問題解決してもらえないでしょうか?
- 680 :(○口○*)さん :06/03/20 21:34
- >>前236
亀レスですが、ホムの情報をテーブルにまとめたものを投下してみます。
まあ、コレだけじゃ役に立たないでしょうけどorz
ttp://www.mmobbs.com/uploader/files/82.zip
- 681 :677 :06/03/20 21:40
- 補足追記
初期状態はルートモンスター自動排除用に最適化させてあるけど、
モンスターリストの編集で好きなモンスターを先制攻撃することも可能
>>679
M_ACT_NONE = 1 -- 攻撃しない
M_ACT_UNDEAD = 2 -- 攻撃する
これは必要ないんじゃない?
M_V_ACT = 2 -- # 攻撃 #
これだけで2番目の項目がresultに編入されて返ってくるから、
メインスクリプトの方で返ってきた値が1か2か判断してもいいと思うけど…
- 682 :677 :06/03/20 21:44
- って、肝心なこと書き忘れた
そのスクリプトの場合
MOBACT[モンスターのID][引き出したいデータの項目]
ぽりんの名前を引き出したい場合
MOBACT[1002][M_V_NAME]
でいいはず
- 683 :680 :06/03/20 21:45
- 書きかけの方あげてもうた。コッチで
ttp://www.mmobbs.com/uploader/files/83.zip
- 684 :(○口○*)さん :06/03/20 21:56
- >>672
只単に一覧表が見たいだけなら>R○Addr.ini 解説所
AI内部でFoundIDの対象がノービスならば「Novice」が取得できる物がいいなら
ホムンクルス用ライブラリ
playerjobdata.lua
配布場所(後日変更の可能性有)
ttp://briefcase.yahoo.co.jp/kulus_project
ttp://proxy.f3.ymdb.yahoofs.jp/bc/44183003_d9ee/bc/playerjobdata.lua?bc91PHEBpzBNNXpN
IsPlayer (id) -- idはプレイヤーキャラか? yes -> 1 no -> 0
GetPlayerJobName (id) -- プレイヤー職業を取得
GetPlayerClass (id) -- プレイヤー職業のジャンルを取得
- 685 :(○口○*)さん :06/03/20 22:05
- mobdata.luaを利用して、
MoveMob = MOBDATA[GetV (V_HOMUNTYPE,id)][M_V_MOVE]
のように敵が静止型どうかの情報を取得しているのですが、
一覧にまだ含まれていない敵の場合どのように対処すればよろしいでしょうか?
ご教授願います。
エラーメッセージは、attempt to index field '?'(a nil value)です。
if( MOBDATA[GetV (V_HOMUNTYPE,id)][M_V_MOVE] ~= nil ) then
MoveMob = MOBDATA[GetV (V_HOMUNTYPE,id)][M_V_MOVE]
end
という方法も試みましたが、同一のエラー(if分の行で)が
起きます。
- 686 :(○口○*)さん :06/03/20 22:08
- >>679,685
こんな感じでどうだろ
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
type = GetV(V_HOMUNTYPE,v)
target = GetV (V_TARGET,v)
if (target == myid) then
enemys[index] = v
index = index+1
elseif (MOBACT[type] ~= nil and MOBACT[type][M_V_ACT] == 2) then
if (GetV(V_TARGET,v) == 0) then
enemys[index] = v
index = index + 1
end
end
end
end
省いたんだろけど end一個足りないよね。
あと MOBACT[type][M_V_ACT] == M_ACT_UNDEAD
が本来の書き方なんだろうけどアクティブ状態の定数が UNDEAD って変じゃない?。
- 687 :677 :06/03/20 22:11
- >>685
>>622で、目的が違いますが自分も同じような事をしてエラーが出ています。
未定義の数値を送られるとエラーが出てしまいます。
未定義の数値を処理することはどうも不可能らしく、
回避方法は定義してやるしかないようです。
- 688 :(○口○*)さん :06/03/20 22:23
- 微妙に違うけど、
自分もmobdataの扱いに四苦八苦してた所だけど
686さんの見ながら修正したら、やっと思い通りに動いた(ノω・`)
マジ感謝!!
- 689 :(*○口○)さん :06/03/20 22:26
- >>685
nilの判定は
if (MOBDATA[GetV (V_HOMUNTYPE,id)] == nil) then
で行うとエラーが出ないと思います
>>622の場合も
local mobset = 0
if (ActiveSet[id] ~= nil) then
mobset = ActiveSet[id][Setting]
end
とやればいいかと
- 690 :(○口○*)さん :06/03/20 22:48
- >>672
ありがとうございました。
普通にRO内部のメモリアドレス(という表現でいいのかな?)で返していたわけですね。
ライブラリのほうも参考にさせていただきます。
- 691 :(○口○*)さん :06/03/20 22:54
- >>689
if(MOBDATA[GetV(V_HOMUNTYPE,id)][M_V_MOVE]==nil) then
も試みたのですが、同様のエラーが起きてしまいました。 orz
- 692 :691 :06/03/20 22:56
- あ、すいません、idだけでnilかどうかをチェックするんですね(汗)
間違えました。
if (MOBDATA[GetV (V_HOMUNTYPE,id)] == nil) then
で動作しました。 本当に有難うございました。
- 693 :(○口○*)さん :06/03/20 22:56
- >>686 書く時に、mobdata.luaを少しコピペしたから書き換え忘れた。
書き込んでから気が付いた;
- 694 :(○口○*)さん :06/03/20 23:09
- 主人の過去位置を2歩毎ずつくらい記録して置くようにして
主人の2歩前の位置 = 過去位置(1)
4歩前の位置 = 過去位置(2)
6歩前の位置 = 過去位置(3)
として移動するたびに一つずつずらして随時記憶するようにしておいて
ホムが主人から離れていてかつ数秒前と位置が変化していない時に
主人の2歩前の位置に移動する
まだ移動しないなら4歩前の位置に移動
まだ移動しないなら6歩前の位置に移動
過去位置に移動が成功したら次は元に戻ってしまわないように
主人の次の位置に移動→その次の位置に移動
とすれば障害回避できるんじゃないかな
- 695 :677 :06/03/20 23:15
- >>689
なるほど
>>628氏のいってた
if( ActiveSet[id] ~= nil ) then
ってのはアーカイブのほうに書くんじゃなくて、
呼び出し側の処理前に書くんでしたかorz
勘違いしてた(ω・`;
- 696 :(○口○*)さん :06/03/20 23:55
- ふと思ったんだけど、移動不可セルを2次元配列に随時記録していく方法だと
バースリーのホールドウェブとかで移動不可状態になったときに誤認識する可能性があるかも?
- 697 :(○口○*)さん :06/03/21 00:01
- >>678
ちょっと動かしてみたけど、table関数が無いって言われない?
もしかしてROのLuaって4.x系?
・・・でもioやos使えるって事は5.x系だよねぇ。
俺のやり方が悪いだけかな・・・
- 698 :(○口○*)さん :06/03/21 00:02
- >>686
ありがとうございます。実験結果も良好でした。
今mobact.luaを作ってますので完成後配布します
- 699 :(○口○*)さん :06/03/21 00:04
- 突っ込まれそうなのでコード
require "./AI/USER_AI/List.lua"
CmdRes = List.New()
function AI(myid)
end
この時点でListのコンストラクタ(もどき)のtable.setnでtable関数が無いっぽいエラーが出てる。
- 700 :(○口○*)さん :06/03/21 00:15
- ホムってハイドとかクロークとかしてても追いかけるんだがこれ仕様?
- 701 :(○口○*)さん :06/03/21 00:23
- ROのLuaは標準tableライブラリが入ってないっぽい。
グローバル変数tableがnilになってた。
で、標準にほぼ互換(sortだけ未実装)なtableライブラリを作ってみたんだけどほしい人いるかな?
- 702 :(○口○*)さん :06/03/21 01:01
- GetMyEnemy関数で横殴り防止のためにモンスターのモーションをチェックして
戦闘中かどうかを判断するAIが多いですが、タイミングによってすり抜けたり
しませんか?
トレースしてみると、MOTION_ATTACKだけでなくMOTION_STANDも見られるので、
この時に戦闘中のモンスターではないと判断してしまっているようですが。
この辺は対処されているのでしょうか。
戦闘中でないモンスターにGetV(V_TARGET)すると何が返ってくるのかな。
- 703 :(○口○*)さん :06/03/21 01:09
- >159=164=166
どっか他所でどーぞ
こうなんつーかなぁ…俺の中に渦巻く貴方への感情を上手く表現できん
憐れみとも蔑みとも違うし怒りや憎しみとも違うし、う〜ん…
- 704 :(○口○*)さん :06/03/21 01:10
- >703
ケミ、クリエスレでど〜ぞw
- 705 :(○口○*)さん :06/03/21 01:11
- よ よ よ
あぁケミスレと間違えて誤爆ったぁ…
慣れない批判はするもんじゃあないな…
ごめんよみんな
- 706 :(○口○*)さん :06/03/21 01:12
- >>705
吹いたwww
ただのテキストデータいじるツールがなんで規約に引っかかるって判断になるのかは疑問だが。
ツールって言葉に過剰反応しちゃう子なんでしょ
- 707 :(○口○*)さん :06/03/21 01:22
- 1.IDをあらかじめ取得しておいてGetMyEnemy?の戻り値をそのIDにする。
2.対象のID垢のキャラがクローク状態で接近する(or こちらから接近する)
3.ホムがクロークしているキャラの付近をうろうろする(当たらないぽいけどムーンライトの使用可)
- 708 :(○口○*)さん :06/03/21 01:24
- >707
最初のID取得が少し怪しいからやめておこうな
- 709 :(○口○*)さん :06/03/21 01:25
- mobact.luaができたので配布します。
一緒にAIの中に入れるスクリプトも付属していますので、ご自由にどうぞ
ttp://www.mmobbs.com/uploader/files/84.zip
- 710 :(○口○*)さん :06/03/21 01:26
- >707
GetMyEnemy?関数の戻り値が何かご存知?
- 711 :(○口○*)さん :06/03/21 01:28
- >710
ホムとGv関連呼んでたら
人をタゲれないって報告が目立ったからさ
無理なのかと思ってた
人をタゲって取得できた?
- 712 :(○口○*)さん :06/03/21 01:34
- http://www.mmobbs.com/uploader/files/85.zip
>>677のAIを追加変更したAIです。
- 713 :(○口○*)さん :06/03/21 01:34
- >711
たぶんタゲれる
先攻型のGetMyEnemyB関数は「if(1==IsMonster(v))then」でチェックしてるけど
たぶん非先攻型で詠唱のあるスキルをオーナーに使われるとホムが追尾していかないか?
- 714 :(○口○*)さん :06/03/21 01:37
- >713
どちらかと言うと
「取得できた」のかどうかが重要なんだけど
試してみた?
こっちは試してない以上
そちらを否定するわけにもいかないので
- 715 :(○口○*)さん :06/03/21 01:39
- >714
取得できた、試してみた
Pvでクローク中のアサクロにムーンライト使用したの確認した
- 716 :678 :06/03/21 01:40
- >>697
ROでは動作確認してなかったんですよね・・・table使えないとは盲点でした。
table無しで実装し直した奴を
ttp://www.mmobbs.com/uploader/files/86.zip
に上げておきましたので、よろしければどうぞー。
- 717 :(○口○*)さん :06/03/21 02:03
- >714
失礼、うちのGetMyEnemy?関数は少しいじってあった
for i,v in ipairs(actors) do
if (v ~= owner and v ~= myid) then
target = GetV (V_TARGET,v)
if (target == myid or target == owner) then --←この行
enemys[index] = v
index = index+1
end
end
end
これでオーナーに詠唱のあるスキル使われると追尾するようになる
非アクティブモンスでホム養殖用に書き換えてた
- 718 :677 :06/03/21 02:52
- さっきアップした命令文追加モジュールに致命的不具合があったので修正。
ttp://www.mmobbs.com/uploader/files/87.zip
MESAttackmode命令使用時にホム自身が殴られても無反応で
サンドバック状態だったのをちゃんと反撃するように修正。
ゲフェンDで毒キノコにホム殺されそうになるまで気付かなかったorz
他の新規命令文はだいじょうぶ…のはず
- 719 :(○口○*)さん :06/03/21 05:06
- 韓国サクライ アップデートで
> PVP 可能なマップで同じパーティまたは同じギルドのホムンクルスを攻撃したり、ホムンクルスに攻撃を受ける現象が修正。
だそうだが、これのAIは入手できないだろうか?
PT、G情報を入手できる方法または今回追加された組み込み関数、返り値が入ったと考えられるが…
- 720 :(○口○*)さん :06/03/21 05:30
- >>701
ライブラリー関係はぜひ公開してほしい。
- 721 :(○口○*)さん :06/03/21 05:53
- ttp://www.mmobbs.com/uploader/files/91.zip
ケミ、クリエスレの285の自動スキル発動率100%ってのと
このスレで見た攻撃スキルの射程制限がないこと
2つを組み合わせて考えた怪しい機能
オプションモード搭載!!・・・グラディウスのオプションを想像しましょう
敵への接近移動を行いません(通常攻撃は敵が接近してきた時のみです)
攻撃スキルをその場で使用します
主人からある程度離れたら接近を行います
もしかしたらジオなどの固定Mobに便利かも?
Alt+Tのアクティブ設定変更と一緒にお試しあれ
(この機能はAI再読み込み不要、むしろ再読み込みで初期状態)
ただし、動作未確認なのでそこだけ注意
- 722 :(○口○*)さん :06/03/21 06:05
- 忘れてた・・・
オプションモードに関してはON/OFF機能になってます
オプションモードは初期状態ではOFFになってます
オプションモードのON/OFFに関してはゲーム内では行えません
今回はゲーム内処理は見送りました
設定する場所はわかりやすいと思うので
AI.Luaファイルの中を見て
設定変更をしてお楽しみください
- 723 :(○口○*)さん :06/03/21 06:33
- >>702
遅レスですが。
確かに敵のモーションを見て動くと、反応が鈍い(うまく検知できていない)ことがよくあります。
顕著なのは攻撃速度の遅い敵。
たとえばOD1でオークゾンビを相手にしていると、(ROの画面上は)どう見てもたげられているのにホムの反撃開始が遅いとか、
同様にオークゾンビを倒したはずなのにその前で立ちすくんでいる(まだ倒していないと思っている)節があります。
他の敵(同マップの各種こうもり)ではそういう反応をしないので、敵のモーション速度や敵自体のGetV(V_TARGET)の値設定の
遅さがあるようです。
- 724 :前スレ391 :06/03/21 10:10
- 戦闘中にターゲットが第3者と重複していないかチェックする関数
OnCHASE_ST()関数とOnATTACK_ST()関数内の適切な場所に、
if IsOverlapTarget(MyEnemy) == true then
MyState = IDLE_ST
MyEnemy = 0
return
end
とでも書けばターゲットがかぶった瞬間に攻撃動作をやめます。
が、弊害として今度はPTプレイ中に一切攻撃に参加しなくなります(苦笑)。
#そこらへんのチェックは他の人にまかせた(ぉ
----------------------------------
-- ターゲットが重複しているか?
----------------------------------
function IsOverlapTarget(nowtarget)
-- 現在のターゲットがケミでもホムでもない第3者をターゲットにした
local target = GetV(V_TARGET, nowtarget)
if (target ~= 0) and (target ~= MyOwner) and (target ~= MyID) then return true end
local actors = GetActors()
for i,v in ipairs(actors) do
if IsMonster(v) == 0 then
if (v ~= MyOwner) and (v ~= MyID) then
target = GetV(V_TARGET, v)
-- ターゲットが第3者とかぶっている?
if target == nowtarget then
if (GetV(V_MOTION, v) == MOTION_ATTACK) or (GetV(V_MOTION, v) == MOTION_ATTACK2) then
return true
end
end
end
end
end
return false
end
- 725 :前スレ391 :06/03/21 10:14
- >>724の補足。
IsOverlapTarget()関数内の変数、「MyOwner」にはケミのIDがセット
されていること。
#検証内容。
#バイオプラントで植物を召喚後、ホムに攻撃命令。
#攻撃確認後、他のプレイヤーに植物を攻撃してもらい、攻撃動作を
#中断することを確認。
- 726 :(○口○*)さん :06/03/21 10:25
- http://www.mmobbs.com/uploader/files/92.zip
- 727 :(○口○*)さん :06/03/21 10:26
- また途中で送信しちまった。。。
↑tableライブラリです。
- 728 :前スレ391 :06/03/21 10:57
- 失礼、>>724の関数自己解決。
以下のようにすればケミ自身が殴ってる場合にかぎり、重複していないと判断されます。
function IsOverlapTarget(nowtarget)
local result = false
-- 現在のターゲットがケミでもホムでもない第3者をターゲットにした
local target = GetV(V_TARGET, nowtarget)
if (target ~= 0) and (target ~= MyOwner) and (target ~= MyID) then result = true end
-- ターゲットを第3者が殴っているかどうか?
local actors = GetActors()
for i,v in ipairs(actors) do
if IsMonster(v) == 0 then
if (v ~= MyOwner) and (v ~= MyID) then
target = GetV(V_TARGET, v)
-- ターゲットが第3者とかぶっている?
if target == nowtarget then
if (GetV(V_MOTION, v) == MOTION_ATTACK) or (GetV(V_MOTION, v) == MOTION_ATTACK2) then
result = true
end
end
end
end
end
-- ケミ自身がターゲットを殴っている場合はかぶってないものとする
if result == true then
if GetV(V_MOTION, MyOwner) == MOTION_ATTACK or GetV(V_MOTION, MyOwner) == MOTION_ATTACK2 then
if GetV(V_TARGET, MyOwner) == nowtarget then result = false end
end
end
return result
end
- 729 :前スレ391 :06/03/21 10:57
- …スペース変換するの忘れてた…。orz
- 730 :(○口○*)さん :06/03/21 12:13
- もしかしてホムのfleeって取れない?
mobの必要fleeから計算しえ?%回避達成なら攻撃
とかしたかったんだけど・・
- 731 :(○口○*)さん :06/03/21 12:19
- 初心者で勉強中なのですが、自分で関数(?)を作る時は「*_ST」の形にしないといけないルールがあるのですか?
- 732 :(○口○*)さん :06/03/21 12:20
- >>730
FLEEどころか、ホムは自分自身の性能をHP/SP以外はまったく取得できません。
・HITがわからないので、当たるかどうかも判断できません。
・持っているスキルのレベルがわからないので、レベルごとの使い分けも自律判断は難しいです。
(こちらは消費SPなどから強引に判断することは可能ですが)
その他もろもろも同様。
- 733 :(○口○*)さん :06/03/21 12:23
- >>731
関数名の付け方には、そんなルールはありません。
単にデフォルトAIが「状態遷移法」を取っているので、
「追跡しているときに実施する関数だから、CHACE-STATEを省略して、CHASE_STにしよう。」
・・・という命名を作法としているだけです。
(プログラムを見たときに理解しやすくするため)。
まあ逆に言えば、デフォルトAIの関数名は「きちんとした理由があって」あの名前になっているので、
そこを理解して、自分の関数名も決めるといいと思います。
- 734 :(○口○*)さん :06/03/21 12:24
- 基本非アクティブで、特定の敵にのみ攻撃ってできますかね?
- 735 :(○口○*)さん :06/03/21 12:27
- >>732
情報サンクス つД`)
ステータスウインドウでは表示されてるから取れるもんだとばかり・・・
取れないならConst組んでおくか・・・
Lv上がるごとに編集(´-ω-`)
- 736 :(○口○*)さん :06/03/21 12:30
- >>734
過去レス参照。
ちなみに307〜402あたりで、構想〜実装AI公開までがなされている。
他にも何箇所かで記載あり。
- 737 :(○口○*)さん :06/03/21 12:42
- >>736
見つかりました、ありがとう。
敵ごとにアクティブ非アクティブの設定に加えて
敵ごとにオートスキルの使用率を設定できるようでまさに私が求めていたAIです。
- 738 :(○口○*)さん :06/03/21 13:13
- Trace()ってなんだろ?
- 739 :677 :06/03/21 13:29
- >>737
(他にもいくつかあるので違う人のスクリプトかもしれないけど)もしそれが
>>402や>>369-370系だったらごめん。
作った人間なんだけど、AIに致命的欠陥があるので>>718の奴使って欲しいorz
- 740 :677 :06/03/21 13:32
- あ、>>712のAIか。
ならだいじょうぶか
- 741 :(○口○*)さん :06/03/21 13:41
- あげてくれるのすごくうれしいけど
CRCやMD5もつけてくれるともっとうれしいっす
- 742 :(○口○*)さん :06/03/21 14:03
- >>733
ありがとう御座います
話は変わりますが例えばメマーナイトLv10で攻撃したMOBにはムーンライトで攻撃するというのを書きたい場合に
メマーのスキルを取得もしくはメマーの消費SPを取得もしくは消費したゼニーを取得して書くと思いますが
ホムが取得出来るのはケミのスキル、MHP/HP、MSP/SP、座標xy、ケミホムMOBの状態などそれらの状態で取得できるリストはどこかに有るのでしょうか?
教えて君ですみません人(・x・)
- 743 :(○口○*)さん :06/03/21 14:31
- >>732
と言うことはホムレベルも取得出来ないのか・・・
夢が夢が縮まりんぐ
- 744 :(○口○*)さん :06/03/21 14:52
- >>742
ゼニー消費もメマー使用の取得も無理だと思う。
消費SPなら何とかなるかもしれない。
ムーンライト5を手動で使ったときに、メマー→ムーンライトとさせるなら簡単。
ただ、これってケミをホムAIで制御になっちゃうからグレーだけど。
- 745 :(○口○*)さん :06/03/21 14:55
- レベルなんてそうそう頻繁にあがるものじゃないし、下がることはありえないから
内部にグローバル変数とかで定義しといて、気付いたときに書き換えればいいじゃない
まぁfleeも同じことだけど。
- 746 :(○口○*)さん :06/03/21 14:59
- >>742
公式ページをまずみようね(笑)
ttp://www.ragnarokonline.jp/news/play/update060314/homunculus.html
ここの一番下に、スクリプトの仕様があります。
質問の答えも、とりあえずは上記仕様から読み取れます。
もちろん、仕様書には書かれていない現実の値などもありますが、
それはアルケミテンプレサイトなどにもまとめられています。
老婆心ながら補足すると、742で列挙された項目のうち、
MHP/HP,MSP/SP,XY座標,状態(立ち/攻撃など)が、ホム・ケミについて取得できます。
が、Zennyはわかりません。ケミがなんのスキルをつかっているかもわかりません。
(ケミが何かスキルを使っている、ということは、タイミングが合えばわかります)
- 747 :(○口○*)さん :06/03/21 16:26
- 追跡状態、攻撃状態のときに IsOutOfSight を無視して
画面外でも動かしてみたんだけど、スタックしてしまうもより。
これは仕様?そして既出?
- 748 :(○口○*)さん :06/03/21 16:32
- 既出かどうかは知らないが、仕様。
本体の可視範囲(±13セル)からホムが出ると、そもそも function AI が動かない。
- 749 :(○口○*)さん :06/03/21 16:35
- >>748
激しくありがとう。
うーむ、離れ離れに狩るのは無理なのね・・・。
ちなみに自分はウルド人なんだけど、昨日実験した限りでは
IsMonsterを飛ばせばPKMAPでプレイヤーへの攻撃を確認。
NPKMAPでは近づくのみ。後、PKMAPでもPK対象でないと近づくだけみたい。
更にプレイヤーはどうやってもホムに攻撃できんかった。
本鯖の人はPvPやらGvGで試してみるとよいかも。
- 750 :前スレ391 :06/03/21 16:42
- 要望スレ207氏の要望を実装する為の拡張ファイルです。
長くなったのでサイト(というか、ファイル置き場)にUP。
ttp://www.eonet.ne.jp/~sneakers/AI/Addon.lua
できるだけ、本体のAI.luaをいじらずに実装できるようにしました。
本体の変更箇所はファイル内の先頭に書いてあります。
動作未確認です。
- 751 :(○口○*)さん :06/03/21 16:43
- >>749
スキル攻撃はあたるのでさくっとやられてしまいました。
ただ、ホムもレベルがあれば
そこそこ攻撃力、ASPDがあるのでそのうち一緒にPvできる…かも?
んで、Pvエリアでのホム→ホムを実験した人はいるのかね?
ホム同士で戦えるのなら
○○モンバトル専用AIとか出てきそうだな(デジでもポケでもお好きな方をどうぞ)
- 752 :(○口○*)さん :06/03/21 16:59
- >>751
スキルあたるんですか・・・。試してなかったです。
対人戦で使うには公開情報が少ないかもしれないですね〜。
PTMとかGMとかの情報とれないぽいですし。
V_HOMUNTYPEではどうやらJOBごとのIDが取れてました。
ノビなら1、剣士なら2とかみたいに(←は例です。)
1対多で戦うしかないのかな・・・orz
あ、あと主人が召還した花は主人のホムを攻撃してしまいます。
(上記のPKMAPでのお話。)
この際、花もAIにして欲しいものですね。
- 753 :(○口○*)さん :06/03/21 17:20
- 質問です。
工体研究所の所のAIを使っていて、鳥に自動でスキルを撃たせているんですが、
・月光5を1で撃つようにさせる
・月光を撃つ確率を調整する
にはどこをどういじればいいのでしょうか。
- 754 :(○口○*)さん :06/03/21 17:20
- 敵を倒した後にスタックする原因の1つは敵との距離判定が入ってないせいろうか。
ログとってみるとたまに画面内にいるわけのない長距離のmobの座標も取得できてしまうのだけど
これはMOTION_DEADが拾えずに別の場所で即沸きしたmob(画面内で消滅中)を生存中と認識して追いかけようとしてるんじゃないだろうか。
ログでは OnIDLE_ST → OnCHASE_ST → OUT_OF_SIGHT → IDLE_ST を繰り返してた。
GetMyEnemy や GetOwnerEnemy にも IsOutOfSIght いれれば解決できると思うんだがどうだろう?
この場合は完全に消滅してしまえばまた動き出すから大きな問題ではないのだけど。
- 755 :(*○口○)さん :06/03/21 18:20
- OnATTACK_ST関数内でMOTION_DEADを取り逃がしたのなら、敵のモーションが取得出来ないかもチェックする
local EnMo = GetV(V_MOTION,MyEnemy)
if (EnMo == -1 or EnMo == MOTION_DEAD) then
if (false == IsInAttackSight(MyID,MyEnemy) and EnMo ~= -1) then
GetDistance2は画面外idに対して-1を返すが、
GetOwnerEnemy、GetMyEnemy関数の距離判定では-1が一番近いと判定する(関数同士の相性問題)
AI関数内部でGetDistance2の返り値-1を期待する部分があるので改変できない
またUtil.luaはユーザー同士、内部が同じであるという前提があるので改変できない
よってGetOwnerEnemy、GetMyEnemy関数の距離判定で-1を除外する必要がある
具体的には
if (dis < min_dis and dis ~= -1) then
※例外※ 自己責任で対処してください
AI関数内部でGetDistance2の返り値-1を期待する部分はOnHOLD_CMD_ST関数だけなので
返り値を99などにしてGetOwnerEnemy、GetMyEnemy関数を変更しない方法もある
- 756 :754 :06/03/21 18:25
- ごめん勘違いっぽい。拾えるのはやっぱり画面内みたい。
NPCから一歩ずつ遠ざかって試してみたら表示されなくなった段階でGetVで-1しか返ってこなくなった。
どうも即沸きした敵が画面の角ギリギリに出たせいで動けなくなってたみたい。
- 757 :(○口○*)さん :06/03/21 18:27
- >>754
IsOutOfSIghtでチェックしなくてもどっか適当なところでMyEnemy = 0すればいいんじゃない?
- 758 :(○口○*)さん :06/03/21 18:30
- >>753
MySkillLevel = MAXLV_MOONLIGHT
という行がAILib.luaにあるので、それを
MySkillLevel = 1
にすればいいと思う。
確率は計算してる部分(↑の変更箇所の少し上)を弄る必要があるけど、
SELF_SKILL_PERCENTAGE を調整するほうが早いんじゃないかな
- 759 :(○口○*)さん :06/03/21 18:31
- 質問なのですが、
色々いじっていて3次元配列を使いたいなぁとおもったんです。
で、↓のようにして、
ARREY[1][1][1]の値(111)とか拾えるのかなと
試みたんですが、どうもうまくいきません。
ARREY = {}
ARREY[1] = {}
ARREY[1][1] = {111,112}
ARREY[1][2] = {121,122}
ARREY[2] = {}
ARREY[2][1] = {211,212}
ARREY[2][2] = {221,222}
誰か、へるみぷ〜
- 760 :(*○口○)さん :06/03/21 18:37
- 755に追記
GetOwnerEnemy、GetMyEnemy関数のGetActors () で集めたidが
GetDistance2されるまで画面内に居るとは限らないって事です
forループ回している一瞬で敵が画面外に出たりケミが移動したり等
OnHOLD_CMD_ST関数の461行目GetDistanceがGetDistance2の間違いです(引数2つだし
どの道、OnHOLD_CMD_ST自体呼ばれることがないからどうでもいいんだろうけど^^;
- 761 :前スレ391 :06/03/21 18:44
- なんか重力の書いたコードを総出でデバッグ、リファクタリングしてる
感じだなぁ^^;
- 762 :(*○口○)さん :06/03/21 18:53
- >>759
>へるみぷ〜
というか、それをそのままコピペして問題なく動いたよ
3次元配列を別のファイルに書いて、require "./AI/USER_AI/〜.lua"を忘れたとか
スペルミスしてるとかじゃないかな?文字列は''で囲むとかね
- 763 :(○口○*)さん :06/03/21 18:59
- >>759
ARREYをARRAYに直せば動くと思うよ
- 764 :(○口○*)さん :06/03/21 19:10
- >>762
あれ?おかしいなぁ・・・
Const.luaに書いていて、インクルードのパスもあっているんです。
なんでだろう?
>>763
・・・! ヽ(`(ェ)´)ノ
やりたいのはスキルの
消費SPとか、ディレイとか、持続時間とか、詠唱時間とかをとりたいんです。
以下のように、Const.luaに書いて、
- 765 :(○口○*)さん :06/03/21 19:11
- -------------------------------------------------
-- スキルの消費SP,ディレイ,持続時間データ
-- 使用方法
-- local SkillSP = SKILLDATA[スキルID][スキルLv][SKILL_SP]
-- local SkillDelay = SKILLDATA[スキルID][スキルLv][SKILL_DELAY]
-- local SkillSustain = SKILLDATA[スキルID][スキルLv][SKILL_SUSTAIN]
-------------------------------------------------
-------------------------------------------------
SKILL_SP = 1
SKILL_DELAY = 2
SKILL_SUSTAIN = 3
SKILLDATA = {}
SKILLDATA[8001] = {} -- ■癒しの手■ディレイ不明
SKILLDATA[8001][1] = {13,0,0}
SKILLDATA[8001][2] = {16,0,0}
SKILLDATA[8001][3] = {19,0,0}
SKILLDATA[8001][4] = {22,0,0}
SKILLDATA[8001][5] = {25,0,0}
SKILLDATA[8002] = {} -- ■緊急回避
SKILLDATA[8002][1] = {20,3500,40}
SKILLDATA[8002][2] = {25,3500,35}
SKILLDATA[8002][3] = {30,3500,30}
SKILLDATA[8002][4] = {35,3500,25}
SKILLDATA[8002][5] = {40,3500,20}
SKILLDATA[8005] = {} -- ■キャスリング
SKILLDATA[8005][1] = {10,0,0}
SKILLDATA[8005][2] = {10,0,0}
SKILLDATA[8005][3] = {10,0,0}
SKILLDATA[8005][4] = {10,0,0}
SKILLDATA[8005][5] = {10,0,0}
SKILLDATA[8006] = {} -- ■ディフェンス
SKILLDATA[8006][1] = {20,4000,4000}
SKILLDATA[8006][2] = {25,3500,3500}
SKILLDATA[8006][3] = {30,3000,3000}
SKILLDATA[8006][4] = {35,2500,2500}
SKILLDATA[8006][5] = {40,2000,2000}
- 766 :(○口○*)さん :06/03/21 19:12
- 自分のやってるスタック処理も晒してみる。
OnCHASE_STの最後に以下を追加
if GetV( V_MOTION, MyID ) ~= MOTION_MOVE then
MyDestX, MyDestY = 0, 0
TraceAI("CHASE_ST -> CHASE_ST : Detect Stuck (Reset)")
return
end
これで結構弾いてくれてる
- 767 :(○口○*)さん :06/03/21 19:12
- SKILLDATA[8009] = {} -- ■ムーンライト■ディレイ不正確
SKILLDATA[8009][1] = {4,1000,0}
SKILLDATA[8009][2] = {8,1000,0}
SKILLDATA[8009][3] = {12,1000,0}
SKILLDATA[8009][4] = {16,1000,0}
SKILLDATA[8009][5] = {20,1000,0}
SKILLDATA[8010] = {} -- ■フリットムーブ
SKILLDATA[8010][1] = {30,0,60}
SKILLDATA[8010][2] = {40,0,55}
SKILLDATA[8010][3] = {50,0,50}
SKILLDATA[8010][4] = {60,0,45}
SKILLDATA[8010][5] = {70,0,40}
SKILLDATA[8011] = {} -- ■オーバードスピード
SKILLDATA[8011][1] = {30,0,60}
SKILLDATA[8011][2] = {40,0,55}
SKILLDATA[8011][3] = {50,0,50}
SKILLDATA[8011][4] = {60,0,45}
SKILLDATA[8011][5] = {70,0,40}
SKILLDATA[8013] = {} -- ■カプリス■ディレイ不正確
SKILLDATA[8013][1] = {22,1000,0}
SKILLDATA[8013][2] = {24,1000,0}
SKILLDATA[8013][3] = {26,1000,0}
SKILLDATA[8013][4] = {28,1000,0}
SKILLDATA[8013][5] = {30,1000,0}
SKILLDATA[8014] = {} -- ■カオティックベネットディクション■ディレイ不明
SKILLDATA[8014][1] = {40,0,0}
SKILLDATA[8014][2] = {40,0,0}
SKILLDATA[8014][3] = {40,0,0}
SKILLDATA[8014][4] = {40,0,0}
SKILLDATA[8014][5] = {40,0,0}
-------------------------------------------------
AI.lua内で
AutoSkillWaitTime = GetTick() + SKILLDATA[MySkill][MySkillLevel][SKILL_DELAY]
と呼ぼうとするとうまくいかないのです・・・
もうちょっと格闘してみます。
- 768 :(○口○*)さん :06/03/21 19:14
- それ2次元行列に3次元入れてない?
- 769 :(*○口○)さん :06/03/21 19:26
- OK原因は簡単だった
Luaの配列、Array[n]はn=0,1,2,3...
ではなくn=1,2,3,4...である点に注意
- 770 :(*○口○)さん :06/03/21 19:29
- と思ったら違ったorz 早漏れすぎだorz
AutoSkillWaitTimeをディレイ時間ピッタシにすると失敗するとか過去ログで見た気がする
- 771 :(○口○*)さん :06/03/21 20:01
- 流れぶった切ってゴメンナサイ。
AI.lua の GetOwnerEnemy 関数内の
local motion = GetV(V_MOTION,i)
なのだが、これ何故最後 i なんだろう。
i って actors の配列のキーだよね。
要素(つまりID)は v に格納されてると思ってたのだが・・・
解釈間違ってる・・・?
- 772 :(○口○*)さん :06/03/21 20:07
- なんで、重力はtable削除してるんだ
当社ご自慢のListライブラリをお使いください!ってことですか
その割には、あのお粗末な実装はなんなんですか
誰かtableの実装書いた人いない?
- 773 :759 :06/03/21 20:28
- >>768-771
お騒がせしました。自己解決しました。
理由は、SKILLDATAがSKILLDETAだったなんて、
763の人に顔向けできない!(*ノノ)
>>765,767 のスキル配列はどうやら使えるようです。
ありがとうございました。
ついでに、スキルの情報はテンプレから持ってきてるんですが、
癒しの手、ムーンライト、カプリス、カオティックベネットディクション
のディレイわかるひといませんかね?
ホムが違うので調べられません・・・
- 774 :(○口○*)さん :06/03/21 20:32
- >>771
vで正解。
>>772
>当社ご自慢のListライブラリをお使いください!
http://www.lua.org/pil/11.4.html
しかも真に「当社ご自慢」の部分は虫入り。
>誰かtableの実装書いた人いない?
スレ嫁。
>>773
ディレイ未実装じゃなかったっけ。
- 775 :759 :06/03/21 20:40
- >>773
あれ?ディレイ無いんですか?
ムーンライトは体感で0.5〜1のディレイあるってテンプレに書いてあるので
対象を指定するスキルはディレイあるのかなと勝手に思っていたんですが・・・
じゃ、0でいいか・・・
- 776 :759 :06/03/21 20:41
- - >>773
+ >>774
orz
- 777 :(○口○*)さん :06/03/21 20:44
- スキルディレイじゃなくてモーションディレイってことはない?
- 778 :(○口○*)さん :06/03/21 20:44
- >>774
リンク先の読んだが、高速化のために双方向キューを採用してたのね。
それにしたってtable削除することはないだろうに…ボトルネックになるのも
ほんとにハードな使い方した時だけだし。
>>716のやつだけど、名前がUtil.luaのListと同じなのと(まぁこれは変えればいいだけだけど)
言語の標準じゃないコレクションはあんまり使いたくないんで、
tableの実装が欲しいなと言ってみたり
- 779 :(○口○*)さん :06/03/21 20:51
- >使用後ディレイがあるのでAPSD通りの連打は不可。
すまんかったorz
>>778
そんなわがままいうなら自分で書け(゚∀゚)
あとtableをluaレベルで再現するのは、
・setnでの「内部状態」を変更できない(nフィールドを必ず追加する)
・いちいちループを回すことになるから速度面でネック。特にsort
組み込みでtableがあると便利だけど、なきゃないでわざわざ使おうとも
思わないし、必要になったときに書けばいいやというのが本音。
いやloadlibとdebug消したのはともかくtableまで消すなよっていうのは
激しく同意。
- 780 :(○口○*)さん :06/03/21 21:10
- >>779
うん書いた。
sortとconcatはいらんかったので割愛(あとで書き足すかも)
ttp://blog.livedoor.jp/aidev/archives/50181009.html
> setnでの「内部状態」を変更できない(nフィールドを必ず追加する)
これなんだけど、優先度がvar.n>>>内部状態>>>最初にnilの現れるインデックス値(getn)
なんだし、setn/getnで直接nフィールド使っちゃって問題ないと思うのは私だけ?
> 必要になったときに書けばいいやというのが本音。
同感です。必要になったので書きました。
- 781 :(○口○*)さん :06/03/21 21:16
- >>780
偉い。見直した。
>直接nフィールド使っちゃって問題ない
あくまでもnがあれば優先するってだけで、ふつうはnを持っていない。
pairsで引っかかってしまうとかの非互換性が生まれるという問題がある。
だから完全な互換がとれないって話。
- 782 :(○口○*)さん :06/03/21 21:45
- なるほど。そう言われてみれば互換性無くなるな
ってことで、内部状態も再現してみたw
あとはtable.insert( tbl, -1, v )とかやった場合の仕様だけど、
これは実装依存てことでいいのかな?
- 783 :(○口○+) :06/03/21 22:41
- >>774
ありがとう。さっそく v に書き換える。
どこかに
「スキル使用前と使用後のSPを比べて、スキルが発動したかをチェックする」
って関数があったと思うんだケド、真似てみようとしたところ
SkillObject() の次の文を実行する時点では、まだSP減ってないみたい。
0.5秒弱後に減ってた。
とりあえず「使用直後から0.5秒経った時点でSPが減ってたら発動」って風に
書いてみたケド、スマートじゃないな・・・
- 784 :前スレ823 :06/03/21 23:03
- ようやくVer3の試作版が自分で納得のいく仕上がりになったので
AI貼ってるページを置いていきます
動作確認はバニルとフィーリルでしか行えなかったので
オートスキルのあたりがかなり不安
ttp://www.uzukisyou.nobody.jp/AIlist.html
Ver2からの追加機能は
・先行状態の時、バイオプラントを殴りにいかないように
・先行状態の時、反撃しないMob(プパ、卵、草、キノコ)を殴りにいかないように
・逃げ回る時の処理を少しだけ軽く
・バニルミストがオートでボルトを撃つように
・フィーリルがオートでムーンライトを、自動でフリートムーブをかけなおすように
・リーフが自動でヒールと緊急回避をかけなおすように
・アミストルが主人のHPが指定した値より低くなると自動でMobから離れてキャスリングをするように
です
リーフとアミストルのオートスキル関係の動作確認と調整が完了次第
"試作"の字をはずす予定
- 785 :前スレ823 :06/03/21 23:14
- 雑なプログラムですが何かの参考になれば幸いです
(ノ∀`)
- 786 :(○口○*)さん :06/03/21 23:29
- >767
スキルの消費SPと有効時間をとるだけなら
function GetSkillData( skill , level )
local sp = 0
local delay = 0
if( level > 0 ) then
local SkillData = {}
local tmpLevel = level - 1
-- SkillData
SkillData[SKILL_TOUCH_OF_HEAL] = { 13 , 3 , 3000 , 0 }
SkillData[SKILL_EMERGENCY_AVOID] = { 20 , 5 , 3000 , 0 }
SkillData[SKILL_CASTLING] = { 10 , 0 , 3000 , 0 }
SkillData[SKILL_DEFFENCE] = { 20 , 5 , 40000 , -5000 }
SkillData[SKILL_MOONLIGHT] = { 0 , 4 , 3000 , 0 }
SkillData[SKILL_FLEET_MOVE] = { 30 , 10 , 60000 , -5000 }
SkillData[SKILL_OVERED_SPEED] = { 30 , 10 , 60000 , -5000 }
SkillData[SKILL_CAPRICE] = { 22 , 2 , 3000 , 0 }
SkillData[SKILL_CHAOTIC_VENEDICTION]= { 40 , 0 , 3000 , 0 }
if( SkillData[skill] ~= nil ) then
sp = SkillData[skill][1] + ( tmpLevel * SkillData[skill][2] )
delay = SkillData[skill][3] + ( tmpLevel * SkillData[skill][4] )
end
end
return sp , delay
end
だけでいいと思われ
有効時間のないスキルに関して適当に値を入れないとエラーチェックできないから
これでは3000が入ってる
- 787 :786 :06/03/21 23:32
- あ・・・
SKILL_TOUCH_OF_HEAL とかは独自定数(変数)なんで自分で書いてね
- 788 :759 :06/03/22 00:30
- >>786
[Lv1の消費SP]+([使用Lv]-1)*[単位Lv当りのSP増加量]
っていう感じで求めるってことですよね。
テンプレで、フリートムーブのLv5ディレイが跳んでるのを見て
やめちゃったんですよね。
現状、ディレイ無ければこれでよさそうですね。
ありがとうございます。
- 789 :786 :06/03/22 00:45
- >788
ムーンライトの基本SPが0になってるんで、使うなら直しておいて
すまん
- 790 :(○口○*)さん :06/03/22 00:56
- 鳥が攻撃を受けて反撃を開始する時にフリートムーブを使うようにしてたのですが、
なぜか敵を倒した直後にフリートムーブ発動。
調べてみると、その瞬間の敵のモーションがMOTION_DEADでした。
GetMyEnemyで、たった今ホムが倒した敵のIDを拾っていたため、その敵の攻撃対象が
ホムのままだった。よって反撃しようとしてフリートムーブ発動というオチ。
気づかなかったけど、死んだ敵を攻撃しようとするムダな行動が入っていたんですね。
MOTION_DEADのモンスターは選ばないようにしました。
- 791 :(○口○*)さん :06/03/22 01:29
- >>782
いちおう本家の処理は、指定された添え字より大きい添え字を
インクリメントする感じ。
a = {1, 2}; table.setn(a, 2)
table.insert(a, -1, 3) --> {[-1]=3, [2]=1, [3]=2}
table.insert(a, -1, 4) --> {[-1]=4, [0]=3, [3]=1, [4]=2}
table.insert(a, 1, 5) --> {[-1]=4, [0]=3, [1]=5, [4]=1, [5]=2}
もっとも配列の定義上、i<=0はエラー出していいんじゃない?
と思ったけど、i<=0をforeachで無視する特性を活かした
予約可能なスタックを作ることができるか。
[0]に積んで[1]を抜くとか。…素直にスタック二個使うべきか。
とりあえず「例外起こすかnilを返す」か「本家に従う」のが
ライブラリとしては親切。
あとList.clearのバグは決して「重大」ではない。
参照が解消できないからGCできないというだけ。
(listの扱いさえ間違えなければ)不用意にアクセスされることはない。
clear時点でGC対象にならないっていうだけでpushleftの際に
どんどん参照されなくなるから、メモリリークが拡大することもない。
ROクラのlua環境の生存時間はかなり短いから、GCされないことが問題に
なることもまずない。
あんなバグは恥ずかしいなとは思ったけどね。
それとこのスレが先なのに「ここだけの話」っていうのもなんだかなぁ。
話振ったの自分だし。
- 792 :(○口○*)さん :06/03/22 01:42
- 某NEWSのような誇張表現にいらだって噛みついた。
いまでは反省している。
- 793 :(○口○*)さん :06/03/22 01:43
- 予想はしてたけど、AI.lua ベタ書きの人が多いのね。
Javaみたくクラスっぽく管理した方が見通しが良くなるし、拡張もしやすいよ。
- 794 :(○口○*)さん :06/03/22 02:03
- local distance = GetDistanceFromOwner(MyID) -- ホムンクルスと召還者の距離を得る
local ownerX, ownerY = GetV(V_POSITION, GetV(V_OWNER,MyID)) -- 召還者の位置を得る
local x, y = GetV (V_POSITION,MyEnemy) -- 敵の座標を取得して
if(GetV(V_HP,MyID)<GetV(V_MAXHP,MyID)/2) then -- HPが50%以下
if(ownerY >y and ownerX > x) then--敵の座標が左上
Move (MyID,ownerX+5,ownerY-5)
elseif(ownerY >y and ownerX < x) then--敵の座標が右上
Move (MyID,ownerX-5,ownerY-5)
elseif(ownerY <y and ownerX > x) then--敵の座標が左下
Move (MyID,ownerX+5,ownerY+5)
elseif(ownerY <y and ownerX < x) then--敵の座標が右下
Move (MyID,ownerX-5,ownerY+5)
end
else --HPが50%以上なら、召還者追尾へ
if ( distance > DistanceNotReturn or distance == -1 or MyOwnerX ~= ownerX or MyOwnerY ~= ownerY) then
MyState = FOLLOW_ST-- ホムンクルスを召還者追従状態にして
MyOwnerX = ownerX-- 召還者の位置を更新する x
MyOwnerY = ownerY-- 召還者の位置を更新する y
TraceAI ("IDLE_ST -> FOLLOW_ST")
return; -- 抜ける
end
end
赤芋大地で狩りしながらAI組んでたら、こんな感じのができてしまった。
ホムのHPが50%以下→ケミと敵の位置によって、別の方角に移動して待機な感じです。
HPが減ったらケミの周囲を回るよりも、個人的にはだいぶPPしやすくなったかも。
ホムとケミの位置が、同じ列のときの処理がよく分からないorz。>動いてくれない
- 795 :(○口○*)さん :06/03/22 02:26
- >>791-792
すまん俺自身がList.clearのバグのせいで時間割かれたことがあるんで
つい誇張表現してしまったわ
重大な、てのはバグの起こる頻度が高いんでそう書いたんだけど、
いわゆる fatal error やセキュリティホールほどのものじゃないわな
どうでもいいけど、「ここだけの話」に初公開っていうニュアンスはないと思う
- 796 :(○口○*)さん :06/03/22 02:36
- >>793
マンドイ
- 797 :(○口○+) :06/03/22 02:45
- >>794
elseif ownerY > y and ownerX == x
elseif ownerY < y and ownerX == x
elseif ownerY == y and ownerX > x
elseif ownerY == y and ownerX < x
のようにそれぞれ設定するか、
あるいは等号付き不等号(>=,<=)を使ってほかの方向と
同じ処理をさせるようにすると上手くいくはず。多分。
- 798 :(○口○*)さん :06/03/22 02:47
- >>793
Luaみたいなプロトタイプベースだと、
クラスベースのOOPのようなコーディングはやりづらいよ。
そもそも、OOP自体が大規模なプロジェクト向けの方法論なんで、
スクリプトのような小さいプログラムには適用しにくい。
自分は無名関数とクロージャが使えることを利用して関数型プログラミングっぽく書いてる
- 799 :(○口○*)さん :06/03/22 03:08
- おk、なんとか解決できたかも。
あと、よく見直したら方角違ってた。
↓な感じになったが、もう眠くて試す気力ないので動作は未確認。
ちなみにこれを作ってみようと思ったのは、ケミの周りを逃げても
赤芋が大きすぎるため、PPができないことorz
おかげで死にすぎだが、これ作ってからPP成功率アップ→死ななくなったze
個人的には満足なので、おやすみー。
if(x<ownerX and y>ownerY) then--敵の座標が左上→右下に移動
Move (MyID,ownerX+5,ownerY-5)
elseif(x>ownerX and y>ownerY) then--敵の座標が右上→左下に移動
Move (MyID,ownerX-5,ownerY-5)
elseif(x<ownerX and y<ownerY) then--敵の座標が左下→右上に移動
Move (MyID,ownerX+5,ownerY+5)
elseif(x>ownerX and y<ownerY) then--敵の座標が右下→左上に移動
Move (MyID,ownerX-5,ownerY+5)
elseif(x==ownerX and y>ownerY) then--敵の座標が上→下に移動
Move (MyID,ownerX,ownerY-5)
elseif(x==ownerX and y<ownerY) then--敵の座標が下→上に移動
Move (MyID,ownerX,ownerY+5)
elseif(x<ownerX and y==ownerY) then--敵の座標が左→右に移動
Move (MyID,ownerX-5,ownerY)
elseif(x<ownerX and y==ownerY) then--敵の座標が右→左に移動
Move (MyID,x>ownerX and y==ownerY)
end
- 800 :(○口○*)さん :06/03/22 03:13
- クラスベース化はまぁ、こういう方法をとればオブジェクトの生成と継承は統一できる。
function clone( A ) -- http://lua-users.org/lists/lua-l/2003-05/msg00077.html
local T = type(A)
if T == "string" then return string.sub(A,1)
elseif T == "number" or T == "boolean" or T == "function" then --does function need to be handled differently?
local B = A --do I have to do this or will (return A) return a copy
return B
elseif T=="table" then
local Build={} local function cloneItem(i,v) Build[i] = clone(v)
end
table.foreach( A, cloneItem) return Build
else return nil end
end
function extends( obj, base ) -- 継承
return setmetatable( obj, { __index = base } )
end
function super( obj ) -- スーパークラスの参照
return getmetatable( obj ) and getmetatable( obj ).__index
end
function new( class ) -- 新しいオブジェクトの作成
return setmetatable( clone( class ), { __index = super( class ) } )
end
-- クラス定義
AClass = {}
AClass.a = function() print("AClass.a called") end
BClass = {}
extends( BClass, AClass ) -- ここで BClass は AClass を継承
BClass.a = function() print("BClass.a called") end
-- 以上
local obj = new( BClass ) -- インスタンス化
obj.a() -- AClass.a called
super(obj).a() -- BClass.a called
- 801 :(○口○*)さん :06/03/22 03:27
- if(x<ownerX and y>ownerY) then--敵の座標が左上
Move (MyID,ownerX+5,ownerY-5)
elseif(x>ownerX and y>ownerY) then--敵の座標が右上
Move (MyID,ownerX-5,ownerY-5)
elseif(x<ownerX and y<ownerY) then--敵の座標が左下
Move (MyID,ownerX+5,ownerY+5)
elseif(x>ownerX and y<ownerY) then--敵の座標が右下
Move (MyID,ownerX-5,ownerY+5)
elseif(x==ownerX and y>ownerY) then--敵の座標が上
Move (MyID,ownerX,ownerY-5)
elseif(x==ownerX and y<ownerY) then--敵の座標が下
Move (MyID,ownerX,ownerY+5)
elseif(x<ownerX and y==ownerY) then--敵の座標が左
Move (MyID,ownerX+5,ownerY)
elseif(x<ownerX and y==ownerY) then--敵の座標が右
Move (MyID,ownerX-5,ownerY)
end
ほんと眠いとろくに書けないなorz
さきほど、気になって赤芋を相手に試しに狩りしてみた結果、
すごいことがwww
赤芋1匹だけなら、ケミは歩かなくてもほぼ捕まらずに
ケミの周りを移動→待機可能、PPすることができた。
複数匹のときはどうなるかまだ分からんので、メンテ後に
検証しようと思う。
- 802 :(○口○*)さん :06/03/22 04:12
- なんか物理シミュレーションっぽくなりそうだ
- 803 :(○口○*)さん :06/03/22 04:17
- すみません、INIファイル使って敵毎にアク/ノンアク設定を行わせようとしているのですが、マニュアル読んでも理解できなかったので質問させてください。
ファイルから文字列読み込んで、string.gfind (s, pat)で代入しようと思っているのですが、
読み込ませる文字列のパターンが、
1128 = 1 , 1 , "ホルン"
といった感じの場合、string.gfind (s, pat)のpatはどういう書式になるのでしょうか。
ご助力お願いしますorz
- 804 :(○口○*)さん :06/03/22 08:32
- 間違えて雑談スレに書き込んでしまったのだけど
GetActorsで取得するIDでたまに-1が帰ってくるのがある。
ID=-1 TARGET=0 X=110 Y=66 TYPE=-1 HOMUNTYPE=Baby Alchemist(4041) MOTION=MOVE(1) ATTACKRANGE=2
座標やホムンタイプは出てくるようなので瞬間的なエフェクト用だろうか。
ID判定に主人とホムだけじゃなく v > 0 って判定も入れたほうがいいかもしれない。
- 805 :(○口○*)さん :06/03/22 09:10
- >803
常時読み書きする必要があるか ini ファイル型式にこだわる必要がないんだったら
mobdata.lua 使えば?
require "./AI/mobdata.lua"
function istActive (MobID)
-- 返り値:データナシ=nil,アクティブ=1,ノンアク=0
local result=nil
if (MOBDATA[MobID] and MOBDATA[MobID][M_V_ACTIVE]) then
result = MOBDATA[MobID][M_V_ACTIVE]
end
return result
end
で済むんだが…
- 806 :(○口○*)さん :06/03/22 09:17
- >805
あ、くっついちまった
functionistActive (MobID)
は
function istActive (MobID)
ね
- 807 :803 :06/03/22 10:04
- >>805
RO上でMOBの設定を行いたいのですよー。
右クリ>右クリでアクティブ/ノンアクティブの設定切り替えする、みたいな。
っと、ここまで書いて気付いた・・・
>>803の「敵毎にアク/ノンアク設定を〜」っていうのはホム側のアク/ノンアクでして、
敵毎に攻撃するしないをRO上で行いたいのです。
言葉足らずで申し訳無い・・・orz
- 808 :(○口○*)さん :06/03/22 10:36
- >>795
バグに振り回されるような状況あったっけ。
見落としていたらすまん。
>ここ"だけ"の話
限定公開という感じが気になった。
でも「スルーしとけ」っていう程度。申し訳ない。
>>793,798,800
とりあえずpackage程度でいいんじゃないかな。
My = {}
My.id = 0
My.state = IDLE_ST
Duck Type(必要なインターフェイスが同じなら、同じものと見なす)で
扱えるのと、ライブラリもコードの形で公開されるのが基本だから
継承できることはさほど重要ではないし。
あと__indexを上書きする方法は多重継承やMix-inのような拡張(追加)が
できないから、extendじゃなくてinheritのほうがいいな、とか
どうでもいいことを思った。
- 809 :(○口○*)さん :06/03/22 10:38
- >>801
たぶんこれでいいはず。
local dx = ownerX - x
local dy = ownerY - y
dx = dx == 0 and 0 or dx / math.abs(dx) * 5 -- 0でなければ符号抜いて5倍
dy = dy == 0 and 0 or dy / math.abs(dy) * 5
Move(MyID, ownerX + dx, ownerY + dy)
ただ囲まれたときはうろちょろしそう。
>>803
INIにこだわらないのがマジオススメ。
http://www.lua.org/pil/12.html
要するにLuaスクリプトとして書いた方が早いという話。
RO上でINIなんて書き換えれないでしょ…?
と思ったけどLiveROだからツールOKか。
次はもうMMOBBSに引っ越すのはどうか。
とにかく書き出しをINIじゃなくしたほうが早い。
散らかすのは簡単だけど片づけるのは面倒なのと似ている。
- 810 :(○口○*)さん :06/03/22 10:54
- ここだからまだマシだと思う。
MMOに移動したら普段LIVEROなんて見ない愉快犯の荒らしが増えるだけかと。
INI等が嫌なら組み込まないのは勝手だけど自粛を強要するのは野暮だ。
結局容認派はこっちに立て直すだけになるだろう。
俺自治厨乙
- 811 :(○口○*)さん :06/03/22 10:55
- 無駄に難しく書いただけな気がしてきた。
function comp(a, b)
if a < b then return -1
elseif a == b then return 0
else return 1 end
end
Move(MyID, ownerX + 5 * comp(ownerX, x), ownerY + 5 * comp(ownerY, dy))
comp()は汎用関数になると思うけど、名前があんまりよくないかも。
- 812 :(○口○*)さん :06/03/22 10:57
- 同じくこのままに一票。にゅ缶ならLIVEROに行くべきだと思うが
今のところここで頑張ってる人が何人もいるし移動する必要性は感じない。
- 813 :(○口○*)さん :06/03/22 11:48
- 過去ログを別で用意しなきゃならんことくらいで、他に移動するメリットもないな。
- 814 :(○口○*)さん :06/03/22 12:08
- >>110
確かに、MMOBBSは荒らし多いな。
旧Lydia板とか、表向きは閉鎖されてるけど実は運営されてたり
するからそことかもいいが、それだと鯖限定になるなぁ。
(直だと入れないけど、違う場所からのリンクだと入れたりする。)
>>811
おk、メンテ30分前になんか起きれたので試してみたが、
ケミの周囲に複数敵がいると、うろちょろしてたまに
動かないときがあったorz>ケミ自身が動いて調整はできるが
とりあえず、これからAI組み直してみるノシ
- 815 :(○口○*)さん :06/03/22 13:06
- え〜っと・・・
移動関係の処理を少し変えてみようと思って
移動関係の状態の遷移を追ってみたのだけど
MOVE_CMD_STって穴があるように見えたのだが・・・
Alt+右クリック処理でOnMOVE_CMD ()を起動して
MOVE_CMD_STに入るわけだが
OnMOVE_CMD ()内の移動でミスがあって目標座標に到達できなかった時の
OnMOVE_ST ()のはずだけど
OnMOVE_CMD ()の時点で移動に失敗してたら
何かの指示があるまで
OnMOVE_ST ()だけ永久にループしないか?
OnMOVE_CMD ()でMyState = MOVE_CMD_STやってる意味ないよな?
- 816 :(○口○*)さん :06/03/22 13:07
- 韓国AIのhttp://www.inguild.com/だけど
AIのファイルってどこにあるかわかる人いる?
最新版とか見てみたいんだけどAIファイルらしきものが見つからない・・・
- 817 :(○口○*)さん :06/03/22 13:10
- >>803
拙作AIで似たようなことを実現している。
#戦闘中に殴っている/戦闘終了後最後に殴った敵に対して、
#ケミの左上空間をALT+SHIFT+右クリックで「アクティブ対象」。
#ケミの左下空間を同操作で、「ノンアクティブ対象」。
独自AIだから他のAIへの汎用操作となると厳しいが、参考にはなると思う。
ttp://tomose.dynalias.net/RO/attach/hom/Glenelg_021.lzh
上記内、enemy.luaでファイル入出力をやっている。
- 818 :(○口○*)さん :06/03/22 13:33
- 敵の位置ずれとかで、真横に居ても攻撃できないときに処理を変えたいんですが、
「ホムが対象を攻撃が出来ているか?」のチェックって出来ますかね?
- 819 :(○口○*)さん :06/03/22 13:41
- 待機中ホムを主人の周りをグルグルと回って動くようにするのはどうすればいいんだ・・・orz
- 820 :(○口○*)さん :06/03/22 13:42
- マルチかよ
あっちでレス付いてるの無視か
- 821 :牛乳 ◆1fBR9J/x5I :06/03/22 13:45
- >>818
できますよ。
if(GetV(V_MOTON, MyID) ~= MOTION_ATTACK) then
この条件の時、攻撃できていない。
- 822 :(○口○*)さん :06/03/22 13:45
- >>819
誰かの作ったAIを読むorコピペ
円運動にも色々あるからな
場合によっちゃ三角関数で座標求めないとダメかもしれんね、要求する動き次第だけど
- 823 :(○口○*)さん :06/03/22 13:48
- >>821
モーション判定はタイミング次第で拾い損ねるから怖いよね
実験してみて拾い損ねが無ければいいけど、もしあるようなら
「数回連続で攻撃モーションが確認できなければ」って条件分岐にしないとダメかも
- 824 :(○口○*)さん :06/03/22 13:59
- たぶんSkillObjectってスキルを実行する関数ではなく
クライアント内部に行動スタックを積むだけの関数なんだよな。
だからSkillObjectを発行しても、実際に処理する内部関数が
ディレイ中だったり座ってたりしてスキルを使えないと判断したら
その行動は捨てられる。
それならSkillObjectの直前と直後でSP比べても無駄な事も納得できる。
じゃあどうすれば良いのかってのは思いつかんが…
上の方にあった、500ms後にSPを比較するっていう手もあると思うが、
500msあると自然回復が間に挟まる可能性も高くなるし、何よりスマートじゃない気がして…
- 825 :(○口○*)さん :06/03/22 13:59
- >>810,812,814
LiveROにしか適当なスレがない現状で>>812の主張はおかしいと思うけど
荒れるようなら仕方ないか。
あとツールがイヤなんじゃなくて、ツール使うのを当たり前のように
話をされるのがやりにくい。回答の仕方が変わるから。
それならいっそ、ツール禁止なMMOBBSのほうが楽じゃないかと
思っただけ。
- 826 :(○口○*)さん :06/03/22 14:00
- MMOBBSじゃなくてRO板だった。
- 827 :(○口○*)さん :06/03/22 14:01
- >>821,823
なるほど、モーションで判別するんですね。
ただ、モーションは拾い損ねが結構ありそうで怖いな・・・。
死亡判定はモーションだけだとよく取り逃すので、
V_POSITION 見て x==-1 なら居ない等の処理加えちゃってますしね。
- 828 :(○口○*)さん :06/03/22 14:14
- >>825
全部に貴方が回答しなきゃいけないわけでもないから
やりにくいのはスルーすればいいんじゃない?
- 829 :(○口○*)さん :06/03/22 14:49
- >>828
「当たり前」というのは「当然だから言わない」という意味。
つまり、せっかくあれこれ考えてレスして、後出しでツール使うからと
いわれるのが困るってこと。それが始めからわかれば、それに適した回答が
できるしスルーだってできる。
ともかくツール使用は環境依存に他ならないから、ちゃんと書こう。
- 830 :(○口○*)さん :06/03/22 14:58
- オチツケ。いつのまにか論点変わってるようだけど言いたい事はわかったから。
- 831 :(○口○*)さん :06/03/22 14:58
- 自動PPってできてるのか?
- 832 :(○口○*)さん :06/03/22 15:34
- >>831
手前でやってみれ。できるから。
- 833 :(○口○*)さん :06/03/22 16:10
- 無意識のうちにPPしちゃってるくらい体に叩き込めば自動で出来るよ
- 834 :(○口○*)さん :06/03/22 16:29
- 出来ません。
出来てもするな。
- 835 :牛乳 ◆1fBR9J/x5I :06/03/22 16:32
- 寝落ち防止関数も
本来プレイヤーが行うRO終了処理をAIに行わせているんだよな。
これは良いの??
- 836 :(○口○*)さん :06/03/22 16:32
- >>835
どちらかというとダメだろうと思う。
- 837 :(○口○*)さん :06/03/22 16:35
- AIの行動制御から掛け離れてるから
アウトで良いかも。
眠たきゃ寝る。
寝落ちして逃げるとこまで面倒見なくて良いかと。
- 838 :(○口○*)さん :06/03/22 16:36
- 提供されている以上、今の所は良いんじゃないの?
今後どうなるかは知らんが
- 839 :803 :06/03/22 16:42
- >>817
ありがとうございます、しかし実は自分がやっているのは前に>>817さんのUPなされたプログラムを参考にさせて頂いているのでして・・・
分からない点は、vs_enemy.iniの最後に文字列を追加した場合、LoadEnemy()内の
for k, v1,v2 in string.gfind(buf, "([_%w]+) = ([_%w]+) , ([_%w]+)") do
はどういう表記になるのか、なのです。
for k, v1,v2 v3 in string.gfind(buf, "([_%w]+) = ([_%w]+) , ([_%w]+) , ([_%w]+)") do
としても無理みたいですし・・・付け加える文字列は、後で数字だけのINIファイルを見ても自分が分かるようにコメント付けるみたいな感じなので、実際は使わなくてもいいんですが・・・
アドバイスお願いします。
>>829
えと、自分のせいで荒れてしまって申し訳ないです。
自分は全然ツールとかは使ってないですし、これからも使うつもりはありません。
ただ、ホムAIを制御する上でMobに対する個別な設定をLuaに書いていたら多すぎて大変だなぁと・・・
それなら韓国AIにも使われてるしINTファイルで設定を保存・読み込めば→前スレ823さんが自分の望むことを実装している→なら前スレ823さんが作ったのからプログラムを拝借して・・・
とこういう経緯です。
したがって、ツールを使う気は自分には無いです。
ホント、分かりにくい文章で申し訳ないです・・・orz
- 840 :(○口○*)さん :06/03/22 16:47
- >>815
その通り。
そのために、OnMOVE_CMD()に
ホムのモーションを調べるチェックを入れてた人がいたはず。
たぶんこのスレのどこか。
- 841 :(○口○*)さん :06/03/22 17:00
- MobのHPやMAX最大HP求めるのって出なくなりました?
EnemyHP = GetV (V_HP,MyEnemy)
EnemyMaxHP = GetV (V_MAXHP,MyEnemy)
昨日の段階で出来ていたと思っていたものが出来なくなったので…
昨日上記の記述含むAIを動かして意図どおり動いていたので詳細にテストしなかったのですが
今日同じAIを詳細にテストしていたらMobのHPが-1で返ってきたので…
何かの拍子で意図するような動きをしていただけなのかな?
- 842 :(○口○*)さん :06/03/22 17:02
- 汎用のデバッグ出力ツールなんだけどどうやらTraceAIの出力もしてくれたので紹介
DebugView:
http://www.sysinternals.com/ntw2k/freeware/debugview.shtml
リアルタイムで出力してくれるので便利なのだが唯一の欠点は
他のアプリのデバッグ出力もしてしまう点。
(Option→Win32PIDsでPID出力してFilterでつぶせばOK)
- 843 :(○口○*)さん :06/03/22 17:07
- >>835
AIとか外部ツールに頼らず、リアルの財布にも優しい方法を提案
■XPの寝落ち防止
画面のプロパティ
↓
スクリーンセーバーのタブを開く
↓
モニタ電源の電源ボタンをクリック
↓
システム休止状態を「なし」から「15分後」に変更
たぶん、OSが停止してサバキャンされると思う。
- 844 :(○口○*)さん :06/03/22 17:33
- 灰色なAIを語れるスレと普通のAIを語るスレに分けようぜ
- 845 :(○口○*)さん :06/03/22 17:38
- どっちかっつーと
普通のプレイヤーとRO厨を分けたいな
ウザイウザイ言ってるような奴は後者でお願い
- 846 :(○口○*)さん :06/03/22 18:14
- >>839
早合点とか最悪だ。お詫びに解説。
>for k, v1,v2 in string.gfind(buf, "([_%w]+) = ([_%w]+) , ([_%w]+)") do
_ アンダースコアそのもの
%w 英数字一文字
[_%w] 英数字かアンダースコア
[_%w]+ それが一文字以上
([_%w]+) その塊を返値にする
>1128 = 1 , 1 , "ホルン"
>for k, v1,v2 v3 in string.gfind(buf, "([_%w]+) = ([_%w]+) , ([_%w]+) , ([_%w]+)") do
これは「ホルン」の両端にある「"」が一致する部分がどこにもないから
全体がパターンマッチしない。だからこうすればいいはず。
さらにポイントなのは
「Luaは8bit文字を扱えるけど日本語そのものには対応していない」
日本語は「英数字」に含まれず、"."(なにか一文字)を使う必要がある
あと書き足したv3の前にカンマがないので、それを足したら完成。
for k, v1,v2,v3 in string.gfind(buf, "([_%w]+) = ([_%w]+) , ([_%w]+) , \"(.+)\"") do
- 847 :(○口○*)さん :06/03/22 18:24
- >>815
意味はあると思う。
OnMOVE_CMD_STは目標座標に到達できなかった時のためのものではなく、移動中は移動を最優先する(移動中は敵サーチを行わない)ためのものなんじゃなかろうか。
- 848 :(○口○*)さん :06/03/22 18:56
- つまり
移動には時間がかかるからその間のためのSTってことか
そこでMobから食らうと移動処理が止まって
動がいつまでたっても直さない座標ずれか・・・
ここのループに座標取得もりこめば
動作としてはイマイチだが座標ずれの時の座標情報取得できるかも?・・
- 849 :(○口○+) :06/03/22 19:36
- >>824
上のほうにあった500ms云々の者ですが。
試行回数は少ないから断定できないけれど、SkillObjectから発動成功までは
500ms以下なのですよ。多分サーバの状態によって上下するんだろうけれど。
だから、もしスキル発動時にホムの V_MOTION が MOTION_SKILL を有するなら
if GetV( V_MOTION,MyID ) == MOTION_SKILL and GetTick > preTime+500 then
みたいなことが出来ないか・・・とか思ってみたら
案の定 MOTION_SKILL 有さなかったどころか、 MOTION_STAND のままデスヨ。。。
返り値の実装を期待するのも無駄っぽいしなぁ。
GetV ( V_MOTION,MyID ) ってもしかして
MOTION_STAND と MOTION_MOVE と MOTION_DAMAGE しか返さない?
MOTION_DEAD は試してないけど、攻撃させようがスキル使わせようがMOTION_STANDのまま・・・
- 850 :803 :06/03/22 20:07
- >>846
ありがとうございます、詳しく解説いただいてしっかり理解できました。
アドバイス通りにプログラムを書き換えたところ、MOB毎にちゃんとアク/ノンアクを使い分けてました。
後はこれに横殴り設定を加えていけば完成かな。
引き続きプログラム頑張っていきたいと思います、ありがとうございました。
- 851 :(○口○*)さん :06/03/22 20:59
- >>849
ホムは通常攻撃でもスキル攻撃でも、確かに殆どMOTION_STANDばかり返してきますねぇ……
やっぱりMobやプレイヤーに比べて、かなり限定された実装に今はなってる予感。
他に何か判定基準に使えそうなのあればいいんだけど、
いまいちスマートな方法が思いつかないまま。
- 852 :(○口○*)さん :06/03/22 21:02
- これってステータスウィンドウ出しっぱなしに出来ないのかな
- 853 :(○口○*)さん :06/03/22 21:48
- >>852
それは無理じゃ?
- 854 :(○口○*)さん :06/03/22 21:53
- local motion = GetV(V_MOTION,MyID)
if motion == MOTION_STAND then
TraceAI("なっ!?立ったままの姿勢!腕だけであんな攻撃を!")
end
ホムの名前はツェペリ
- 855 :(○口○*)さん :06/03/22 21:58
- ハエとかマップ移動するごとに、ホム消滅>再生成をしているっぽいね。
ホム消滅の段階でホムのスレ窓は消えてしまう。
仕様だからあきらめるしかなさげ。
- 856 :(○口○*)さん :06/03/22 22:17
- テレポしないからMAP移動ごとにショトカで出せばいいんだが、
でかすぎるのがナ。一番みたい満腹度は窓の下のほうだから
はみ出させて使うこともできん。
透明スキンでもクリックのジャマになることには変わりないしなぁ
- 857 :(○口○*)さん :06/03/22 22:57
- 結構手の込んだのを作ってるとプロの十字路とか酷い重さになるので
追従しかしない軽いのを作って回避することにしてみた。
require "./AI/Const.lua"
require "./AI/Util.lua"
----------------------------------------
-- 追従するだけ。軽い。
----------------------------------------
InitFlag = true
MyID,MyOwner = 0,0 -- ホムと主人のID
MyDestX,MyDestY = 0,0 -- ホムの目的地
MyLastTick = 0
function AI(myid)
if (InitFlag == true) then -- 初期設定
InitFlag = false
MyID = myid
MyOwner = GetV(V_OWNER,MyID)
end
local tick = GetTick()
if (tick > MyLastTick + 250) then -- 250ms間隔で追従状態を確認する
MyLastTick = tick
local myX,myY = GetV(V_POSITION,MyID) -- ホムの座標
local ownerX,ownerY = GetV(V_POSITION,MyOwner) -- 主人の座標
if (GetDistance(ownerX,ownerY,myX,myY) > 3) then -- ホムと主人が4セル以上離れたら
if (GetV(V_MOTION,MyID) == MOTION_MOVE) then -- 移動中なら
if (GetDistance(ownerX,ownerY,MyDestX,MyDestY) > 3) then -- 移動先と主人が4セル以上離れていたら
MyDestX,MyDestY = ownerX,ownerY
Move(MyID,MyDestX,MyDestY) -- 移動
end
else
MyDestX,MyDestY = ownerX,ownerY
Move(MyID,MyDestX,MyDestY) -- 移動
end
end
end
end
- 858 :(○口○*)さん :06/03/22 23:06
- >>815
>>126,128 でタイムアウト処理入れたけどあまり興味はひかれなかったようだ。
モーションチェックのがいいのかな。
- 859 :牛乳 ◆1fBR9J/x5I :06/03/22 23:16
- >>857
よくローカル変数を使用してるのを見かけますが、
ガベージコレクタの発生頻度によっては大差ないと思いますけど
GetDistance(ownerX,ownerY,MyX,MyY)
↓
GetDistance2(GetV(V_OWNER,MyID), myid)
にすればローカス変数4つ使用しないで済みますよね。
質問1:ガベージコレクタ発生頻度はどの程度か
質問2:GetDistance()とGetDistance2()のパフォーマンス差はどれくらいか
- 860 :(○口○*)さん :06/03/22 23:31
- ownerX,YはどっちにしろMyDestX,Yに入れるんで省くと二度手間になるかと。
まあmyX,Y使うのもGetDistance2使うのも好みですかね。
そういえば移動していない時はMoveToOwner使った方がきれいに動いてくれるのだっけな。
- 861 :(○口○*)さん :06/03/22 23:34
- >>857
どうせ使いっこない./AI/AI.luaと差し替えて
/hoaiで切り替えると便利そうだね
でもそもそもプロ歩くとき重いなら安息させとけばいいような…
- 862 :(○口○*)さん :06/03/22 23:42
- おっしゃる通りだけど安息させると親密度上げられないのだよね・・・
- 863 :(○口○*)さん :06/03/23 00:19
- デフォルトのAIを、クラスっぽく書き直してみたよ。(まだ不完全)
http://www.mmobbs.com/uploader/files/98.zip
機能的には、等速移動と寝落ち防止以外つけてまへん。
- 864 :(○口○*)さん :06/03/23 01:06
- 現在使ってるAI投下。
結構見やすくなってると思う。
ttp://www.mmobbs.com/uploader/files/97.zip
- 865 :(○口○*)さん :06/03/23 01:07
- >>859
デフォルトAIからして、local変数へのGetVが多いのは気になる。
>ガベージコレクタ発生頻度はどの程度か
監視してみるとか。
TraceAI(string.format("gcinfo(): Used %dKB, Limit %dKB", gcinfo()))
メモリに余裕あるなら、collectgarbage(limit)で上限増やして
gc頻度を落としてしまうのもいいかも。
ただあんまり大きくすると、いざGCが起きたときに極端に重くなって
しまう可能性があるから、ほどほどに。
- 866 :(○口○*)さん :06/03/23 01:09
- >>863
けっこう読みやすくなってるね。
MyState などのグローバル変数と
OnXXX のようなイベントハンドラもまとめてオブジェクト化できないかな
AI関数のifの振り分け処理もまだ見ぐるしいし、IDLE_STとOnIDLE_STなんかの関係は
テーブルで定義して振り分けたほうがよさげ
- 867 :(○口○*)さん :06/03/23 01:21
- >863
Character.Luaの中で
function Character.setName(value)
function Character.setX(value)
これであってるの?
「.」と「:」間違いじゃない?
- 868 :(*○口○)さん :06/03/23 01:27
- >>857,862
いっそのことコレ位した方が思い切りがあっていいかもw
--------------------
-- 擬似ペット化AI --
--------------------
MS = 0
function AI (x)
if (MS == 0) then
if ( GetD(x) > 3) then MS = 1 end
elseif (MS == 1) then
if (GetD(x) <= 2) then MS = 0
elseif (GetV (3, x) == 0) then MoveToOwner (x) end
end
end
function GetD (y)
local a, b = GetV (1,GetV(0,0))
local c, d = GetV (1,y)
if (a == -1 or c == -1) then return 99 end
return math.floor(math.sqrt((a-c)^2+(b-d)^2))
end
デフォルトの切り張りだからまだ減らせるだろうけど、これ以上はどうでもいいや(ぇ
- 869 :(○口○*)さん :06/03/23 01:34
- あ、すまない、500ms後に比較っていうアイデア自体はナイスだと思うんだ。
ただちょっと、こう、直接の因果できっちり組み上がってないルーチンを書くのが
個人的にダメなんで…誤解を招く表現で申し訳ない(´д`;
MOTION_SKILLはホムのASPDが高い事と相俟って本当に一瞬しか取れないもより。
通常攻撃でもそうだがASPDディレイの間(攻撃と攻撃の間)はMOTION_STANDになってる。これはケミ本体でも同じ。
やれる事はたくさんあるのにやらせる方法が少ない…orz
- 870 :(○口○*)さん :06/03/23 01:40
- >864
attack.Luaの中でGetMyEnemy()で
ホムの種類の判定は不要じゃないかな?
あと
local type = GetV (V_HOMUNTYPE,myid)
がずいぶんと使われてるけど
AI起動中にホムの種類が変わることはないはず(進化はまだ不明)だから
グローバルで1度取得しちゃえば十分じゃないかな
- 871 :(○口○*)さん :06/03/23 01:49
- スレ住民の皆様、夜遅くにこんばんは。
もしよろしければ、二つほど質問よろしいでしょうか?
1.バイオプラントで呼び出されたMOBのIDは取得可能か
バイオプラントで召還されたモンスターのIDを何人かのケミに協力して
もらってTraceAIにて拾ってみたのですが値が全く違いました。
このバイオプラントのIDに法則性が見いだせなかったのですが、
IDを決定する計算式等などありますでしょうか?
例)ケミのIDとバイオプラントの固定IDを組み合わせた計算
2.障害物のオブジェクトを判別できるか
何か用意された関数を使って障害物を判断できるでしょうか?
Moveで移動した先が障害物の場合、移動できなかったりしますよね。
今はMove後一歩も動いていなかったら別の座標を指定と回避して
いるのですが、もっとスマートなやり方があるものでしょうか?
GetActors()の戻り値もチェックしてみましたが、無理っぽいです…
ピンポイントで障害物とわかればいいのですが。
もしよろしければ上記2つについてご教授お願い致します
- 872 :(○口○*)さん :06/03/23 01:51
- >>867
おお、見事に記述ミスだ。指摘thx
突貫工事でやったから、他にも記述ミスがありそうで怖いな。
修正した奴を上げ直したよ。
http://www.mmobbs.com/uploader/files/99.zip
- 873 :(○口○*)さん :06/03/23 02:04
- >>871
>>196
MOB種類じゃなくて個体IDでみてたんじゃないか?
まぁ196が正しいかどうか自分では調べてないが、
TargetID = GetMyEnemy (MyID)
target = GetV(V_HOMUNTYPE,TargetID)
このうちの、targetじゃなくてTargetIDの方を見てたとか
- 874 :(○口○*)さん :06/03/23 02:18
- とりあえず省きまくればここまではいけるかな。
なんだこりゃAIか本当に。
require "./AI/Const.lua"
require "./AI/Util.lua"
function AI(myid)
if(GetDistanceFromOwner(myid) > 3) then
MoveToOwner(MyID)
end
end
>>868
いくら簡略化されても変数の意味が不明な上に割り当てられた定数を無視するのはよろしくないと思う。
>>871
>1
同じmobでも個体IDが違うってことは鯖側の処理ではないということになるな。
式などはわからないしわかる必要もないと思う。
>>873の言うような種類を知りたいってことなら V_HOMUNTYPE で取得しないといけない。
これはどのプレイヤーから見ても同じはず。
>2
できない。
ゆえに先攻型では壁越しに敵に対しても向かって行こうとするが動けなくなる。
- 875 :(○口○*)さん :06/03/23 02:19
- あ、クセでMyID使ってしまってた。myid だな。
- 876 :(*○口○)さん :06/03/23 02:47
- >>874
趣旨ズレとるがな 簡略化じゃなくて動作の軽さな
と言うか動作が軽くなればそれでいいから、そんなこたぁどうだっていいのさ
- 877 :(○口○*)さん :06/03/23 02:48
- 「プロで重い」だから、GetActors()にまつわる処理をなくすだけで
目的は果たされるはず。
>>868は7行プログラミングみたいなものじゃない?
>>871
プラントに関する実験レポートplz。
興味があるけど、なにを比較したのかがちょっと曖昧。
- 878 :(○口○*)さん :06/03/23 03:10
- ちょっと質問したいのですが、
「IDでモンスターなら1が返ってくる」
「IDでモンスター以外なら0が返ってくる」
のことで、落ちてるアイテムと人との区別って可能でしょうか?
落ちているアイテムが邪魔で、よくPPできない事がorz
- 879 :(○口○*)さん :06/03/23 04:20
- >>873
お恥ずかしながら、おっしゃるとおりケアレスミスでした。
GetV(V_HOMUNTYPE,TargetID)で拾った値を使わず
(この場合で言うと)TargetIDをチェックしていました。
>>874
丁寧な説明ありがとうございます。
2については無理でしたか。やはり移動できなかった場合
に、別の座標を指定するしかないですかね。
私は先攻型をあまり使わないので、壁の向こうを〜という
ことは知りませんでしたがスキルを使用させた時動かなく
なったことがあり、それも壁等の関係かもしれませんね。
また調べてみながら色々やってみたいと思います。
>>877
>>873様にレスしている通り個体IDで見ていました。
お詫びにこれ置いていきますね。
っ[1142] -- マリンスフィア(スフィアーマイン)
最後に、レスをくださった方ありがとうございました。
- 880 :(○口○*)さん :06/03/23 08:05
- IDに色々あって混乱するよね、これ
GetActors(table) で取れるのはそのMap内オブジェクトに振られるオブジェクト毎の固有ID(の一覧が格納されたtable)
そのtable内の固有IDに対してGetV(V_HOMUNTYPE,TargetID)すると、対象の種別を表す種別IDが返ってくる
って事なのかな
GetV(V_TYPE,TargetID)は未実装でTargetIDがそのまま返ってくる:>>201,204
混乱するんでメモっておこう
- 881 :(○口○*)さん :06/03/23 08:56
- ホムが一度死亡か安息状態になった後、
コールホムかリザホムをするといままで殴ってた敵を殴りにいかない
理由は、ホムが消えてまた出てくる時にホムのIDが変化して、
今まで殴ってた敵は古いホムのIDをV_TARGETにしたままなので、
ここで敵が他人を殴ってると思い込んで横殴り判定で弾かれるみたい
- 882 :(○口○*)さん :06/03/23 09:40
- >>878
実験してみた。以下実験ソース。
function AI( myid )
local actors = GetActors()
local tick = GetTick()
for i,v in ipairs(actors) do
TraceAI( string.format( "[%d] ID=%d / Type=%d", tick, v, GetV( V_HOMUNTYPE, v ) ) )
end
end
この状態でアイテム落としても表示される項目が増えなかったのでアイテム判定は無理かもしれない
- 883 :(○口○*)さん :06/03/23 09:43
- メタリンマップの盗蟲やポリンに対してのみアクティブになるように
>>718氏の追加モジュールを導入しようと思ったのですが
ぜろ・まてりあるのAIで
--基本的使い方は、デフォルトのAI.luaの「function GetMyEnemy (MyID)」部分にある
--「GetMyEnemyA (MyID)」もしくは「GetMyEnemyB (MyID)」を「MESAttackmode (MyID)」に
--置き換えるだけです。
に変更してみたところエラーが出ました。
これはぜろ・まてりあるさんのAIとの互換性が無いという事なのでしょうか。
- 884 :Tia鯖のおっさん :06/03/23 10:16
- AI作ってみたんだどね、
MMOBBSのアップローダーに投稿でいいのかしらん?
- 885 :(○口○*)さん :06/03/23 10:24
- >>883
エラーがでましたじゃわからないのでどんなエラーが出たのかも書いたほうがいい。
- 886 :Tia鯖のおっさん :06/03/23 11:04
- うははw
↑『け』が抜けてた。
UPしてきましたよ
http://www.mmobbs.com/uploader/files/100.zip
いや〜、ワシ、プログラムいじるのとか十数年ぶりで
すんごい楽しかったわ〜
- 887 :(○口○*)さん :06/03/23 11:16
- >>326
すんごい遅レスだが、実測したGetActors()でのPCのIDは65536以上、PC以外はそれ未満なので
これでホムかPCかが判別できると思う。
- 888 :(○口○*)さん :06/03/23 11:17
- ふと思った、このレベルのAIなら追加改修より
一から作ったほうが早く思い通りに動くのではないかと
できたら上げようかとも思ってるんだけど
そういうAIってここでは需要あるのかね?
車輪の再開発好きなのはPGの性だw
- 889 :(○口○*)さん :06/03/23 11:20
- 0-MATERIAさんとこのをちょっと改造
ホムがタゲられたら緊急回避
ホムといっしょに戦うときにラクになります
なんでホムばっかタゲってくるんだろ
function OnIDLE_ST ()
中略
object = GetMyEnemy (MyID)
if (object ~= 0) then -- ATTACKED_IN
MyState = CHASE_ST-----------ここ削除
MyState = ESCAPE_ST----------ここ追加
- 890 :(○口○*)さん :06/03/23 11:37
- >>721さん
死にそうになったら残りSP**%になるまでスキル発動率100%になるようにとかできないでしょーか?
- 891 :(○口○*)さん :06/03/23 11:56
- >>887
それじゃあこういうのもできるかな。type判定自体なくしてもいいかもしれんね。
NPCのIDでかつtypeがホムならホムと断定できるかもしれないね。
未公開情報だからいつ実装内容変わっても文句言えないが。
-- プレイヤーキャラ・もしくはホムンクルスかどうかの判定
function IsPlayer(id)
if (id == nil or id <= 0 or id < 65536) then -- IDが未定義かNPC
return false
end
local type = GetV(V_HOMUNTYPE,id)
if (0 <= type and type <= 23) then -- 転生前・スパノビ・ホムンクルス(0〜23)
return true
end
if (4001 <= type and type <= 4046) then -- 転生職・ベビー(4001〜4046)
return true
end
return false
end
>>808
そう思って時々作ってる部品をここに上げて反応見てたりする。
- 892 :(○口○*)さん :06/03/23 12:02
- x808 >>888
そういえばジルとアリス以外のペット持ってるんでHOMUNTYPE調べたがやっぱり全部通常mobと同じだった。
ただしIsMonsterが0。
- 893 :(○口○*)さん :06/03/23 13:15
- >>889
>なんでホムばっかタゲってくるんだろ
>>887から適当に想像してみたけど
敵ってIDが若い順にタゲ決めてるんじゃないか?
敵AIタイプによっては距離とか詠唱反応とかもあるだろうけど
それらを全部抜きにした場合の順番=ID昇順
なーんて
- 894 :(○口○*)さん :06/03/23 14:17
- >>893
興味深い推測だな。経験則だが臨時PTなどでもmobが一人をよくタゲって来ることがある。
マップ内ID(出現時に振られると思われる)をもとにタゲ優先度を決めてるとすれば
このこともうまく説明が付く。
- 895 :(○口○*)さん :06/03/23 14:20
- そういえば大昔にログイン時間が長いほど敵のタゲがくるって時代があったね
固有IDの数値と考えると微妙だけどキャラリスト順と考えるとしっくりくる
その部分は修正されたらしいんだけどもしかしたら何か名残が残ってるかもね
- 896 :(○口○*)さん :06/03/23 14:45
- --[[
から
]]
までコメントとして扱われるんだけど、
秀丸の強調表示設定をどうしたらいいか、
教えていただけないでしょうか?
- 897 :(○口○*)さん :06/03/23 15:49
- CとかPerlならモードで設定できるなだけどLuaのがないからできないんじゃないかな。
- 898 :牛乳 ◆1fBR9J/x5I :06/03/23 15:59
- 正確には
--[[ ←ここから
--]] ←ここまでだ。
秀丸はコメント強調は指定できないのでsakkura使え^^
- 899 :(○口○*)さん :06/03/23 15:59
- 0mateAIにスキル使用と寝落ち対策を追加した灰色verとか
- 900 :(○口○*)さん :06/03/23 16:03
- >>898
--[[
から
]]
までで合ってるだろ?
- 901 :(*○口○)さん :06/03/23 16:14
- >>894
プレイヤーの固有IDの数値は常に固定、ホムはmap出現時に割り振りの変動
プレイヤーの固有IDは推測だけど、プレイアカウント作った順番だと思う
それと固有IDの数値自体はプロ中のIDをGetActors()したけど120000台が一番低かったかな、上は223万台
単精度と倍精度でID分けされてるとすればホムとプレイヤーでV_HOMUNTYPE被るのも納得は行く
>>895
恐らく昔はプレーヤーもmap出現時にIDを振られていたからかもしれない(現ホム仕様
先にログインすると若い番号、後からログインするとそれ以降の、と・・・
まぁ固有IDがタゲられる理由ならAIで出来る対処法は逃げるくらいしか無いだろうね
- 902 :(○口○*)さん :06/03/23 16:19
- >>882
やっぱりできないのか、残念だorz
ID取得できないってことは、
>>891の
IDが未定義のときの判定でできるかも?
AI見る限り、攻撃モーションの敵のIDのみ取得してるっぽいから、
それを全部にしてみるとできるかなと思った。
そのIDの場所と同じセルなら少し動くな感じにしたいなと。
- 903 :(○口○*)さん :06/03/23 17:17
- 放置露店しながら勝手にエサをやってくれるなんてできますか?
- 904 :(○口○*)さん :06/03/23 17:28
- >>896-898,900
できるよ〜。
1. Luaファイルを秀丸で開く。
2.「その他」→「ファイルタイプ別設定」→「設定のリスト」から、
C言語あたりをコピーして「LUA言語ファイル」の定義を自分で作って閉じ、
その作った定義ファイルを選択する。
3. 同じ窓の左側、設定の詳細で、「表示とカラー」の下「複数行コメント」で、
ユーザー定義でうまいことやる。
俺は今は秀丸でLua編集してないけど、そんなに難しい話じゃないよ。
自分好みの色に染めるべし(ぇ
- 905 :(○口○*)さん :06/03/23 17:51
- >>903
できません
- 906 :(○口○*)さん :06/03/23 17:54
- うーん表示とカラーの下層にはモードと強調表示しかないな。その中にもそれっぽいのが見当たらない。
複数行コメントってのも複数行コメント編集できそうな部分も見当たらないな。ver5.13だけどだめなのかな。
- 907 :(○口○*)さん :06/03/23 18:14
- >>906
Σ('-'つ)つ
すまんかった、俺のはこの間試験的に入れた6.00βだった・・・
古いやつはどうなってたか、覚えてないわ。
申し訳ない。
- 908 :(○口○*)さん :06/03/23 18:21
- 秀丸ver5.15においては、正規表現使っても複数行に渡っての強調は出来ないようです。
それ以外についてはテンプレに強調定義ファイルがあるから使ってみておくれ・・・
- 909 :896 :06/03/23 18:47
- βって何か不安でしたが、6.00β8入れてみて
>>904
さんの方法でできました。
ありがとう。
- 910 :(○口○*)さん :06/03/23 18:52
- GetMsg()にコマンド送るショートカット分かる人居ませんか?
Alt+地面を右クリック
→ MOVE_CMD(1)
Alt+敵を右ダブルクリック
→ ATTACK_OBJECT_CMD(3)
Alt+T
→ FOLLOW_CMD(9)
未だに、これしか分からず・・・。
もうちょっと分かれば、ケミの行動切り替えとか楽になりそうなのに。
- 911 :(○口○*)さん :06/03/23 19:02
- >>910
ショートカットは、それしかないです。
なので、皆が操作方法に苦しんでいます。
それ以外の方法で、ROクライアント上操作でAIにユーザー操作を知らせる方法は、多分以下のものしかないです。
・ホムの「対象を取るスキル」(バニルのカプリス、フィーリルのムーンライト)使用
→ SKILL_OBJECT_CMD
また、GetResMsg()経由での操作があるので「SHIFT+ALT+右クリック」系列も使えないことはありません。
(標準AIではGetMsg()と同じ分岐ですが、別入力系統なので、別コマンドとして解釈させることが可能)
- 912 :(○口○+) :06/03/23 19:56
- いじってて思ったのですが・・・ホムの攻撃範囲って独特?
□□□□□
□□□□● ■ : 攻撃対象
□□■□□ ● : ホムもケミ(PC)も攻撃できる位置
□□□□□ ★ : ホムだけ攻撃できる位置
□□□□★ (ケミで攻撃しようとすると近づく)
※ ●も★も、■とのGetDistanceの返り値は同値(2)。
試行回数は少ないけれど、こんな結果になったのです。
あ、スレ違いかも・・・?
- 913 :(○口○*)さん :06/03/23 20:06
- >>912
本スレ607、609あたりで話題になっている件ですね。
・ケミはプレイヤーキャラなので、円に近い形の射程→桂馬位置は届くけど2マス斜めはNG
・ホムはモンスター扱いの射程で、完全な□射程→斜め2マスも射程内。
・・・という、はからずもそういう検証になった、というところでしょうか。
情報ありがとうございます (^^
- 914 :(○口○*)さん :06/03/23 20:08
- ちょっと質問です。
まだAIをあまり弄ってなく、いまからLUA覚えていこうかな・・というとこなんですが
LUAのリファレンスを読んでたらC言語を使うことができると書いていたのですが
できそうですか?
できれば、MDBとかの情報を色々登録できたりして夢が広ります。(・∀・)
LUAでできそうなファイルIOだと遅そうなので・・
エディタの話がでてるけど
SciTEって名前のエディタを今日発見したんだけど、LUAのビルダいれると
コンパイルもできるのでちょっとした文法ミスがすぐ解りよさそうでした。
- 915 :(○口○*)さん :06/03/23 20:23
- >>914
loadlib がつぶされてるので使用できません。
- 916 :(○口○*)さん :06/03/23 20:28
- 今.NET使ってるんだけどこれでLuaできないかな?
- 917 :(○口○*)さん :06/03/23 20:38
- >890
>死にそうになったら残りSP**%になるまでスキル発動率100%になる
SPが**%「より少なくなる」までという処理なら簡単なのですが
SPを**%「以上確保できるように」という設定にするには
しばらく時間がかかります
自動スキルの関係で
後者の処理に関連した機能は必須かと思っているとこなので
そのうちであればどちらの処理でも可能になると思います
- 918 :牛乳 ◆1fBR9J/x5I :06/03/23 20:44
- .NETは質の悪いテキストエディタですよ。
まだメモ帳のが良いな。
- 919 :(○口○*)さん :06/03/23 20:45
- >>915
返事ありがとう。
FileのI/Oだけでデータいっぱい持つと重くなりそうだorz
よく殺されるてきは殴りにいかないとか
7回以上たたく必要がある敵はムーンライトでたおすとかを
学習するようなAIを作ろうかとはりきってたんだけどねぇ・・
- 920 :(○口○*)さん :06/03/23 20:58
- >>919
以前ココだかで出ていたmobdata.luaとかを使って
・対象のHP/自分のHP>6の時スキルを使う。
とかじゃダメか?
当方ではプログラムを組めないが…
- 921 :(○口○*)さん :06/03/23 21:28
- >>929
そんなものを作ってくれた人がいたのですね。
でも「学習」していくってのをコンセプトにつくりたかったよ(´・ω・`)
愛着わきそうだしね。
- 922 :(○口○*)さん :06/03/23 21:43
- 質問です。
mobdata.luaにはリヒタル追加モンスターのデータが無いようなのですが、
リヒタル追加モンスターのIDはどうなっているのでしょうか?
- 923 :(○口○*)さん :06/03/23 21:57
- リヒタル追加モンスターにもちゃんとIDはあるから心配するな
- 924 :(○口○*)さん :06/03/23 22:17
- >>917
>SPを**%「以上確保できるように」という設定にするには
残りSP >= 確保したいSP+スキルの消費SP
この場合に使用じゃダメなの?
- 925 :(○口○*)さん :06/03/23 22:26
- このAI仕様だと、自己学習で戦闘させるには得られる情報が少なすぎると思う
HP減少と敵の種類を監視させて、防御行動の自己学習くらいならできるかもしれない
アクティブのいる場所で一番被ダメの少ない回避パターンを自己選択させたりとか、
その結果から、次回からそのMAP(要MAP判別)では最適な回避をとらせたりとか・・・
まあ、画餅だがな
自己学習に対して、人間が結果分析とそのフィードバックを受け持つって手もある(つまりは手動設定)
ホムの不得手な部分を主人が補完するってのもいいと思うぞ
- 926 :(○口○*)さん :06/03/23 22:38
- >>922
はい。さすがにダンジョンまでホム連れて行く余裕はないけど。
[1680]="ヒルウィンド(空)",
[1629]="ヒルウィンド(陸)",
[1627]="ウィルス",
前に出たリストになかったから自分で追加したけどこれはあるのかな。
[1128]="ホルン",
[1162]="# ラフレシア",
あと、マリンスフィアの種類1つしかなかったし召喚のもmobと同じHOMUNTYPEみたいだ。
どっちにしろ先攻すべきじゃないmobだから構わないだろうけどまぎらわしい。
- 927 :(○口○*)さん :06/03/23 22:48
- >>926
dクス。
mobdataで敵のレベル判別して先行/非先行してたらリヒフィールド行ったとたんにエラー吐きまくったので。
ところでモンスターのIDって調べ方ありますか?
- 928 :(○口○+) :06/03/23 22:54
- >>913
本スレ・・・見てないから知らなかったです。
こちらこそ情報ありがとですよー。
最高命中率もMOBと同じでしたっけね、そう言えば。
質問ばかりで申し訳ないけれど・・・
指定範囲内の指定タイプのオブジェクトのリストを返す、と言う関数を作ってるのですが
1) 一度全リストを作成して、指定されたリスト(複数可)を返す関数を一つ書く
2) 指定されたリストだけを作成して返す関数を複数書く
の二つでは、ホムンクルスAIの性質上、2の方が良いのでしょうか。
最初の読み込みが重くなる分、動作は軽くなると踏んでるのですが・・・
- 929 :(○口○*)さん :06/03/23 23:31
- >>927
mmoアプロダの、mobdataってどうだろ?
- 930 :前スレ912 mobdata.luaの人 :06/03/23 23:37
- 今、外出先からなので途中までの物は手元にありませんが、
リヒタルゼンモンスターデータは更新作業用のインターフェイスファイルと
合わせてちょこちょこ編集しているのでもう少ししたらUPできると思います。
未定義モンスターIDでエラーが出る場合はMOBDATA[id][M_V_***]を参照する前に
if (MOBDATA[id] ~= nil) then 等、事前に未定義かどうかのチェックを行ってください。
自分はID調査用にAlt+TをトリガとしてGetActors()で画面内一括取得する関数を作って対応しています。
ex) string.format("[ x , y ]\t%s\t%s\t%s",x座標,y座標,生ID,GetV(V_HOMUNTYPE,id),固有名称)
固有名称にはIsMonsterとIsPlayerでmobdata.luaとplayerjobdata.luaから名称を入れ、
その他、未定義にはHOMUNTYPEをそのままですね。
- 931 :(○口○*)さん :06/03/23 23:38
- >>927
mobdataに、データ引っ張ってくるキーとして渡してるのはモンスターのIDだろ?
だったらAIの中で自分がタゲってるやつのIDを取得して渡してるはずだろ?
ならそのIDをTRACEで吐き出してやればいい。
mobdataからそのIDで引っ張った結果がエラーだったらIDをTRACEに吐き出す、みたいに
してれば、未登録のMOBのIDだけを吐き出すこともできるな
- 932 :(○口○*)さん :06/03/23 23:46
- ちょうどいいとこにmobdataの人がいらっしゃった。
簡単に未登録IDのみを吐き出していくなら
if (MOBDATA[id] == nil) then
TraceAI (string.format("Unknown MobID: %d",id) )
〜未登録MOB用の暫定処理(未登録だったら攻撃しないとか)〜
else
MOBDATA[id]による処理
end
ってやっとけばいいやな
- 933 :(○口○*)さん :06/03/24 01:37
- mobdata.lua で未定義ID入れるとエラー吐くんでこういうのをあればどうかと思った。
眠いんでなんかおかしいかもしれないけど
MOBDATA[mobid] とかが nil の時に比較演算してエラー吐くことはなくなると思った。
function GetMobData(mobid,attr)
if (MOBDATA == nil or MOBDATA[mobid] == nil or MOBDATA[mobid][attr] == nil) then
return nil
end
return MOBDATA[mobid][attr]
end
name = GetMobData(1001,M_V_NAME)
if (name ~= nil) then
TraceAI(name)
end
- 934 :(○口○*)さん :06/03/24 01:43
- >if (MOBDATA[id] ~= nil) then
if MOBDATA[id] then
>if (MOBDATA[id] == nil) then
if not MOBDATA[id] then
すっきり。
- 935 :(○口○*)さん :06/03/24 02:27
- 分かりやすさとスマートさ、どっちを取るかだろうけどな
- 936 :(○口○*)さん :06/03/24 02:31
- 中身を見られるソースはわかりやすさを取るべきじゃないだろうか。
主観だけどな。
- 937 :(○口○*)さん :06/03/24 03:02
- すっきりさせたほうがわかりやすいと思ふ
むしろそっちに慣れるのオヌヌメ
世の中、スッキリソースのが好まれるっぽくて、そういうソースのが多い
- 938 :(*○口○)さん :06/03/24 05:27
- 個人的な体感論だけど、スッキリソースが好まれる世の中って
プログラマの世の中であってAI弄ってるユーザーの世の中の事じゃないよね
現実的に見て>>934が理解できてそっちの方(notとか)がいいと思える人が
AI弄ってるユーザーに何割いるだろう(1,2割程度だと思うけど・・・
ホムの為にLuaで初めてプログラム触れる人も多いだろうし
どっちがどうのと言うより使って使いやすい方を使えばいいと思う。
ただ、分からないなりに頑張っている人が見る事を考えるならば
見せるソースの書き方って大事じゃない?って感じかな
まぁ、誰(上,初級者)に見せるソースかってのは個人の趣向だろうけどね
- 939 :(○口○*)さん :06/03/24 07:36
- >>917
ありがとうございます。前者でも全然構わないのですがw
ようは、逃げ回るくらいならスキル連発して倒した方が安全なときもあるので
(遠距離MOBにタゲられてるとき等)
逃げ回るか、全力モードで倒すか選べたりするといいかもしれませんね。
- 940 :(○口○*)さん :06/03/24 08:02
- >>934−938
何をもって「すっきり」と見るかは、多少主観もあるので、そこは人によりけりだと思う。
ちなみに俺だったら、
if (MOBDATA[id] ~= nil) then ・・・は許容する。
だけど、
if ( IsEnemyKnown( id ) ~= nil )then ・・・は嫌。これは
if IsEnemyKnown( id ) then ・・・にすると思う。
- 941 :(○口○*)さん :06/03/24 09:24
- 確かに、プログラミングしたソースファイルを会社とかに持ち込むときに、
綺麗に見やすくしたほうが成功しやすいってよく聞くな。
個人の能力も、それで判断されるらしい。
- 942 :(○口○*)さん :06/03/24 11:10
- io関数の使い方教えてください。
韓国AIの友達登録のあたり見るんですけど
自分が思うような保存方法が分からないです。
DATA[1] = {1, 2, 3}
DATA[2] = {4, 5, 6}
この、DATAをファイルに書き出す方法と
書き出したファイルから読み込んで、
再度DATAに格納したいです。
「Lua」「io.open」で検索してヒット数が5件(内 1件がリファレンス)って・・・
リファレンスの用語専門的すぎて、まず言葉の意味がわからないorz
- 943 :(○口○*)さん :06/03/24 11:33
- >>938
if MOBDATA[id] then -- 値がnilでなければ
とでもコメントつけておけば、動作の理解はともかく
「お約束」としてわかるはず。
==を使うのが好きだからとそっちで書くのはかまわない。
でも見る人のためというのは、その見る人(と読む努力)を
バカにしかねないし、過保護でいわゆる「温室育ち」だと思うけどね。
抗菌の砂場で遊ばせると免疫がつかないっていう話を思い出した。
あと回りくどい表現はバグの温床。
だから複雑にならない範囲ですっきり書くのは大事。
>>942
local path = "./path/filename.lua"
local fh = io.open(path, "w")
for i,v in ipairs(DATA) do
fh:write(string.format("DATA[%d] = {%d, %d, %d}\n", i, unpack(v))
end
fh:close()
読み込みはdofile(path)するだけ、のはず。間違ってたらごめん。
- 944 :(○口○*)さん :06/03/24 11:55
- 個人的には nil 自体が周りくどい表現に思えるけどな。
戻り値に nil を返されるのがまだ慣れないところ。
どうでもいいけど、ターゲットの定義が
「1度以上攻撃・スキルを使用した対象(沸いた直後は0)」
のせいで、他のPC攻撃に向かってるのか判別し辛くてしょうがない。
あと、ヒールやブレス等の支援でもターゲット取るおかげで、
PvやGvだと対象定義に苦労しそうだ。
- 945 :(○口○*)さん :06/03/24 12:15
- そういえば、クルーザーとかからの、
遠距離攻撃を受けると止まって動かなくなるのは、
なんでだろう?orz
- 946 :(○口○*)さん :06/03/24 13:06
- >>944
ターゲットはほんと使いにくいよねぇ
見つけた瞬間に攻撃スキル使ってから追いかけるようにしてみたら
「自分の画面内で」+1度以上攻撃・スキルを使用した対象だから
交戦中の人が画面外に居た場合こっちの移動で中に入ると
いきなりスキル発動してから殴りに行ってしまう。
今はケミからの距離で策敵範囲を画面内の80%まで絞ってるから
大体先にターゲット設定されるけど面d
まだ距離を開けて引っ張ってるのは取得できないし
だめもとで修正依頼だしてみるかね?
クライアントのMobAI処理や通信パケまで変わりそうだから望みは無いけど
- 947 :(○口○*)さん :06/03/24 13:20
- >> 945,946
でも、考えようによってはそれも「人間が取れるのと同じ」情報。
人間だって「アクティブ敵がこっちに向かって近づいてきている→たぶんこっちのタゲ」って判断してるんだから、
同じことをするAIを作れば、できないことはない。
視界内の全ての敵を継続的に監視して「同じ敵がこちらに近づいてきている」という判断をいれればいい。
もちろん、他に攻撃している人がいないことを確認するなどの手間はいると思うけど。
まあ、標準AIでは索敵はその場しのぎ(ある瞬間・瞬間)でしか見ていないので、
どっちにしても独自で練らないとダメだけどね。
- 948 :(○口○*)さん :06/03/24 14:04
- 人間で敵に手を出さないケースを考えると、
・ 既に敵が target == 他人 の場合
・ 既に他人が target == その敵 の場合
・ 距離が一定以上の場合
・ 敵の移動方向が他人に向いている場合
・ 他人の移動方向が敵に向いている場合
・ 敵が自分から離れる方向を一定時間保持している場合
・ 敵が自分の実力では倒せない場合
・ 敵が特定のスキルを使っている場合(ホムでは無理)
……とかかな
- 949 :(○口○*)さん :06/03/24 14:51
- ようやく触り始めたんだけど、↓のエミュレータっていくつかバグあるぽ?
ttp://www.sgv417.jp/~winter/alchemy/emulator.html
GetTick()が何度呼ばれても同じ値しか返さないとか、
ホムの位置がズレてるとか。
最新版出てる?
出てなければ自分で書き換えて時間経過を付加したソースでもうpるんだが・・・
- 950 :(○口○*)さん :06/03/24 15:03
- すみません、質問させて下さい。
>>794さんのAIを使いたいのですが挙動がおかしくて困っています。
ホムが交戦中にHP50%以下になっても移動せずに戦闘後HP50%以下の時に離れた所をうろうろする状態になってしまいます。
-- グローバル変数(追加
ownerX = 0
ownerY = 0
DistanceNotReturn = 0
- 951 :続き :06/03/24 15:03
- function OnIDLE_ST () 内の最後に
local distance = GetDistanceFromOwner(MyID) -- ホムンクルスと召還者の距離を得る
local ownerX, ownerY = GetV(V_POSITION, GetV(V_OWNER,MyID)) -- 召還者の位置を得る
local x, y = GetV (V_POSITION,MyEnemy) -- 敵の座標を取得して
if(GetV(V_HP,MyID)<GetV(V_MAXHP,MyID)/2) then -- HPが50%以下
if(x<ownerX and y>ownerY) then--敵の座標が左上
Move (MyID,ownerX+5,ownerY-5)
elseif(x>ownerX and y>ownerY) then--敵の座標が右上
Move (MyID,ownerX-5,ownerY-5)
elseif(x<ownerX and y<ownerY) then--敵の座標が左下
Move (MyID,ownerX+5,ownerY+5)
elseif(x>ownerX and y<ownerY) then--敵の座標が右下
Move (MyID,ownerX-5,ownerY+5)
elseif(x==ownerX and y>ownerY) then--敵の座標が上
Move (MyID,ownerX,ownerY-5)
elseif(x==ownerX and y<ownerY) then--敵の座標が下
Move (MyID,ownerX,ownerY+5)
elseif(x<ownerX and y==ownerY) then--敵の座標が左
Move (MyID,ownerX+5,ownerY)
elseif(x<ownerX and y==ownerY) then--敵の座標が右
Move (MyID,ownerX-5,ownerY)
end
else --HPが50%以上なら、召還者追尾へ
if ( distance > DistanceNotReturn or distance == -1 or MyOwnerX ~= ownerX or MyOwnerY ~= ownerY) then
MyState = FOLLOW_ST -- ホムンクルスを召還者追従状態にして
MyOwnerX = ownerX -- 召還者の位置を更新する x
MyOwnerY = ownerY -- 召還者の位置を更新する y
TraceAI ("IDLE_ST -> FOLLOW_ST")
return;
end
end
以上のようにしているのですが何かおかしい所があったら教えて下さい。
- 952 :(○口○*)さん :06/03/24 15:22
- >>951
それを作った本人が突っ込んでみる。
if(GetV(V_HP,MyID)<GetV(V_MAXHP,MyID)/2) then -- HPが50%以下
else
end
を、敵が攻撃しそうなプログラムのとこ全てに追加で。>OnATTACK_ST ()など
自分用に作っただけなので、それだけだと動きませんorz
あとの微妙な調整は、ご自由に。
このプログラム、意外とODや赤芋でPP活躍できたりしてますw。
- 953 :(○口○*)さん :06/03/24 15:22
- >>950
それ自体はいいんだけど、それはあくまでIDLE_ST(非戦闘状態)での動作。
戦闘中(ATTACK_ST)や戦闘のための追跡中(CHASE_ST)でも「HPが50%以下なら〜」
っていう処理を入れないと、戦闘中に離脱はしてくれないです。
if(GetV(V_HP,MyID)<GetV(V_MAXHP,MyID)/2) then
Mystate=IDLE_ST
end
・・・って感じのを、OnATTACK_ST() の頭のほうに入れておけばいいんじゃないかと。
- 954 :(○口○*)さん :06/03/24 15:23
- >>950
単にOnIDLE_ST内の最後に書いてるせいじゃないのか?
戦闘中、ホムやケミにタゲがあるんだから、途中の処理で返ってるでしょ。
- 955 :(○口○*)さん :06/03/24 15:23
- >950
戦闘中の挙動ならfunction OnATTACK_ST()内への記述じゃないか?
OnIDLE_ST内にそれを書いておくと、
待機状態かつHPが50%以下の時に、主人の後ろに隠れる形になると思う
で、肝心の敵の所在が不明なおかげで変にうろうろしてるんじゃないかな?
- 956 :(○口○*)さん :06/03/24 15:24
- >>951
OnIDLE_ST ()のとこも、
HP50%以下と以上で分けた方がいいかも。
- 957 :(○口○*)さん :06/03/24 15:25
- >>950
DistanceNotReturnのとこなんだが、これはデフォAIだと3って値のはず。
なんで値0にしたんかな?
0だとHP50%のときはケミの座標==ホムの座標にならない限りFOLLOW_STになっちゃうから、そこら辺が原因な希ガス
違ったらスマソ
- 958 :(○口○*)さん :06/03/24 15:40
- -- バニル迫害処理
function TrampolineVanilmirth()
if (GetV(V_HOMUNTYPE,MyID) == LIF) then
local actors = GetActors()
for i,id in ipairs(actors) do
if (GetV(V_HOMUNTYPE,id) == VANILMIRTH) then
if (id > 0 and id < 65536) then
Move(MyID,GetV(V_POSITION,id))
end
end
end
end
end
思いつきで書いた。
エラーチェックすらしていない。
だが、反省はしていない。
- 959 :(○口○*)さん :06/03/24 15:44
- LIFに弄ばれるなんて幸せじゃないか
- 960 :(○口○*)さん :06/03/24 15:47
- バニル見つけたら、バニルの上に勝手に移動とかもできそうだwww
- 961 :(○口○*)さん :06/03/24 15:48
- そして八匹重なると…
- 962 :(○口○*)さん :06/03/24 15:51
- びっくりしてでっかくなるわけだ
- 963 :958 :06/03/24 15:52
- 気付いたらループ抜けてないから、
バニル複数いたら、どっちに乗ろうか右往左往しそうだな。
バニルの間をキョロキョロしてるリーフ見かけたら、
生暖かい目で見てあげてね!
- 964 :(○口○*)さん :06/03/24 15:56
- >>958
蝶乙
溜まり場内の、自分が調整担当してる羊に鳥を追いかけさせるよう仕込んでみる
- 965 :(○口○*)さん :06/03/24 16:02
- >>964
さらに鳥は羊から逃げるようにすれば完璧じゃね?w
- 966 :(○口○*)さん :06/03/24 16:14
- >>965
鳥は調整任されてないのよ。
逃げるにしても逃走パターンをうまく作らないと詰みそうだし・・・
・・・捕まったら負けとかで鬼ごっこできるかもw
戦闘関連ばっさり切り捨てて、お遊び重視のAIでも作ってみるかな?
- 967 :(○口○*)さん :06/03/24 16:16
- >バニルとか迫害
それ、対ホムじゃなくて、対人でできないかなぁ?
人とは重なれないので特定の人を見つけるとその人の周りを回るリーフとかさ
たまり場にリーフもちケミに向かって「お嬢さんをください」見たいなこといってるのいるんでね。
キャラ特定は職IDと垢IDをキャラクエからとか・・・(まずいのかな?
- 968 :(○口○*)さん :06/03/24 16:21
- >>966
他人のホムに追跡仕込むのかよw
追跡、逃亡スクリプトが、嫌に発達したAIになりそうだな。
>>967
特定プレイヤー見るだけなら、ID固定だからすぐよ。
どうせ作るなら、Alt+右ダブルクリックしたプレイヤー(指定できたっけ?)の周辺回るぐらいの方が。
- 969 :(○口○*)さん :06/03/24 16:35
- IDって固定なの?
それだと別人に強制的にスキル使用させるとか出来ちゃわない?
>>968
現状だとAlt+右クリックでプレイヤー指定が出来ないんじゃないかな
それが出来れば解決しそうなんだが、それができると↑見たいな事も可能になる気が
- 970 :(○口○*)さん :06/03/24 16:43
- >>969
別人にスキルを使用させられないのは確認済み。
あと工体研究所のAIでALT右クリックで登録とかの機能があるからいろいろ可能なはず。
(登録するとそのキャラの周りをまわるっていうのがあるからそれを応用すればいいかと)
- 971 :(○口○*)さん :06/03/24 16:47
- >>969
ALT+右クリックではプレイヤーは選べませんが、「プレイヤーの立っている地面」は選べます。
それを元に、その周囲にいるActorをスキャンして・・・という判断が可能です。
- 972 :(○口○*)さん :06/03/24 16:50
- >>969
ALT+右クリックの位置に立っているプレイヤーを指定という考えで
移動コマンド実行時の処理として実装すれば
出来ないことも無いんじゃない?
- 973 :(○口○*)さん :06/03/24 16:51
- かぶった・・・
- 974 :(○口○*)さん :06/03/24 17:14
- mobdata.lua側の工夫。未知のIDに対してdefaultの値を返す。
MOBDATA = {}
MOBDATA.default = {"",0, (省略)}
setmetatable(MOBDATA, {__index = function(t,v) return MOBDATA.default end})
MOBDATA[1001] = (以下省略)
AI.lua側で「未知のmobはポリンと見なす」とするには
require"mobdata.lua"
MOBDATA.default = MOBDATA[1002] --ポリン
ちゃんとエラーチェックするぞ、という人は
require"mobdata.lua"
MOBDATA.default = nil
- 975 :(○口○*)さん :06/03/24 17:22
- TraceAIしておこ。
setmetatable(MOBDATA, {
__index = function(t,v)
TraceAI(string.format("MOBDATA: unknown id(%d)", v)
return MOBDATA.default
end
})
- 976 :(○口○*)さん :06/03/24 17:23
- 質問させて下さい。
ホムンクルスの攻撃回数をカウントするには
どうしたらよいのでしょうか?
試された方いらっしゃいましたら、
どうかご教授を・・・
- 977 :(○口○*)さん :06/03/24 17:29
- グローバルでカウンタを用意して
全部のAttack (MyID,MyEnemy)の後ろに
カウンタの数字を+1する処理を入れればいいんじゃ?
スキル攻撃の回数をカウントするのはもうちょっと処理が要るけどね
- 978 :(○口○*)さん :06/03/24 17:38
- >>976
ATTACK_STでモーションが返ってきたときにカウントする処理しかないかな。
モーション取り逃す可能性もあるから、正確にってのは辛いかもしれない。
>>977
それじゃ攻撃命令を出した回数になる。
ASPDの関係で、命令が破棄されることもあるからね。
- 979 :(○口○*)さん :06/03/24 17:38
- >>977
説明が足りなかったようですみません。
単にAttack (MyID,MyEnemy)の前後で
カウンタをインクリメントするだけですと、
実際の攻撃回数ではなくて、Attack関数を呼んだ回数になってしまうのです。
モーションを取得したりして試したりしているのですが、
うまくいきません(ノ(ェ)`)
- 980 :976 :06/03/24 17:46
- >>978
やっぱりモーションとるしか方法無いですか・・・
直前でモーションとってカウントを取ってみてるんですが
そもそもAttackが実際に処理される(もしくは処理されない)
ホムのモーションって、どれなんでしょう?
・・・試してきます((((っ ・(ェ)・)っ
- 981 :(○口○*)さん :06/03/24 17:51
- アタックモーションはかなりの勢いで取り逃すぜ。
せめて「Hit or Miss」ぐらい分かればなぁ・・・。
私もアタック処理してるかの判別が出来なくて困ってるところ。
- 982 :(○口○*)さん :06/03/24 17:51
- そろそろ次スレだなー
テンプレリンクの追加とか修正とかある?
- 983 :(○口○*)さん :06/03/24 17:55
- 要望スレ323について
※注、AI設定しだいではこれだけでは役割を果たせないことがあります
もっとスマートにできるよ、とかここ間違ってるよ、って意見があったら書いてくださいな
-- global variable
ActiveFlag = 0 --アクティブ初期設定 0がノンアクティブ 1がアクティブ
function OnFOLLOW_CMD ()
if (MyState ~= FOLLOW_CMD_ST and ActiveFlag == 1) then --アクティブから待機状態になる
MoveToOwner (MyID)
MyState = FOLLOW_CMD_ST
MyDestX, MyDestY = GetV (V_POSITION,GetV(V_OWNER,MyID))
MyEnemy = 0
MySkill = 0
ActiveFlag = 2
TraceAI ("OnFOLLOW_CMD")
else
if(ActiveFlag == 0 ) then --ノンアクティブからアクティブになる
ActiveFlag = 1
else --待機状態からノンアクティブの通常動作になる
ActiveFlag = 0
end
MyState = IDLE_ST
MyEnemy = 0
MySkill = 0
TraceAI ("FOLLOW_CMD_ST --> IDLE_ST")
end
end
function GetMyEnemy (myid)
local result = 0
if ( ActiveFlag == 1 ) then
result = GetMyEnemyB (myid)
else
result = GetMyEnemyA (myid)
end
return result
end
- 984 :(○口○*)さん :06/03/24 18:22
- スレ終盤だからこそ。PG目指すならわかりやすさ第一で書けるようにしとけー。
一つのシステムを自分だけが見るなんて学生時代くらいだから。
ひとりよがりのコーディングは仕事では通用しないぞー。
- 985 :(○口○*)さん :06/03/24 18:43
- スレ終盤だから恥ずかしくなく質問。ソースの書き方の話で
function IsPlant (target)
if (target == 草) then
return true
else
return false
end
end
みたいなルーチン組んでるときに
if IsPlant(target) then -- 草の場合
という記述できる?上のほう見てると
nil or それ以外 ていう判断しかできないように見えたんで
if (IsPlant(target) == true) then -- 草の場合
今この手の処理全部こんな書きかたしてるから、上の記述でいけるなら直そうかと
- 986 :(○口○*)さん :06/03/24 18:50
- >>985
できるよ〜。
というか、Is系関数使うならそうしとけ〜。
ついでに、984氏に続いて、年寄り元ソフト開発者からもつっこみだ〜。
ソフト書くなら、かならずコメント書いておけ〜。
コメントは人のためではなく、自分のためだ〜。
仕事だともちろん、きちんとした設計ドキュメントは要求されてあたりまえ。
でも往々にして、バグ対応や仕様変更が入った部分のドキュメントは更新が甘くなる。
半年もすれば自分の書いたソースだって「他人の作品」と変わらなくなるから、
しつこいくらいコメントを書くようにしたほうがいいよ〜。
- 987 :(○口○*)さん :06/03/24 18:51
- 次スレ立ててきた。
ホムンクルスのAIを語るスレ その4
http://enif.mmobbs.com/test/read.cgi/livero/1143193717/
- 988 :(○口○+) :06/03/24 19:27
- >>986
ごもっともです・・・っ!!(書いてなかった人。(1/20))
過去に書いたソースは見るだけで嫌になってくる・・・
IsMonster は0か1かなんですよねぇ、返すの。
ほかの言語はともかく、Luaは両方真だから・・・
いっそのこと
IsMob ( id )
if IsMonster(id) == 0 then return false
else return true end
end
とか作っちゃうか。二度手間っぽいけど。
- 989 :牛乳 ◆1fBR9J/x5I :06/03/24 19:33
- そこでぬるぽですよ
- 990 :(○口○*)さん :06/03/24 20:25
- ぬるぽ牛乳1L34円
1日5Lまで
- 991 :(○口○*)さん :06/03/24 21:27
- 初歩的な質問ですいません
ローカル変数を使う機会が少ない方がガーベージコレクションはおきにくいですか?
- 992 :(○口○*)さん :06/03/24 23:37
- >>988
function IsMob ( id )
return (IsMonster(id) == 0)
end
でおk
>>991
まーどっちにしてもだんだん貯まってくるから、問題になるようなら
ほうっておくよりは定期的にcollectgarbage()で掃除してあげたほうがいいよ。
あんまりゴミを貯めないプログラミングを心がけても見入りが少ない希ガス
- 993 :(○口○*)さん :06/03/24 23:58
- 俺一月立つと自分のコードがぜんぜん読めんw
- 994 :(○口○*)さん :06/03/25 00:12
- 俺今日追加ソース部分すべて書き直したよ。さっぱり見やすくなって(・∀・)イイ!!
やっぱ継ぎ足しに継ぎ足しは良くないよなぁ。
- 995 :(○口○*)さん :06/03/25 00:21
- >>992
それだとMobでないときにTrue吐かない?
function IsMob ( id )
return (IsMonster(id) ~= 0)
end
ならMobだと真、そうでないと偽って返せると思った。
- 996 :(○口○*)さん :06/03/25 01:06
- return IsMonster(id) == 1
でいいじゃん。
- 997 :992 :06/03/25 02:18
- あ、すまん、 >>996 が正しいです
(ifの最初のブロックでtrue返してるとばかり・・・)
- 998 :(○口○*)さん :06/03/25 04:10
- >939
とりあえず簡易で実装
ttp://www.mmobbs.com/uploader/files/105.zip
ただしその機能の動作確認はまだやってないので注意
- 999 :(○□○*)さん :06/03/25 04:27
- 999
- 1000 :(○口○*)さん :06/03/25 04:28
- 999
- 1001 :1001 :Over 1000 Thre
- このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。