do local _getactors = GetActors local IgnoreType = {[1590]=true} function GetActors() local actors = _getactors() local result = {} local i = 1 for _,v in ipairs(actors) do if not IgnoreType[GetV( V_HOMUNTYPE, v)] then result[i] = v i = i + 1 end end return result end end
すいません、mobdata2に乗り換えてみた工体AI使いのばにるなのですが なんかmobdataがうまく働いてないのか、SELF_SKILL_RIVAL_TABLEを設定してもあんまりボルトを連射しない気がします 前スレを見てAILIBにreturn GetMobData2( mv, id )とif v == name thenを前のを消して付け加えたのですが 移行方法何か間違ってたりしますか?お助けください(´・ω・`)
stuck=0 --グローバル変数 function Stuck () --待機から復帰させる 一回だけだと全く移動しないのでループ二回分FOLLOW_CMD_ST if MyState == FOLLOW_CMD_ST then if stuck>=100 then MyState = IDLE_ST stuck=0 end if stuck>=10 then stuck=100 end end -- 交戦中に10回連続でスカだったら待機させて主のとこに戻る if MyState == ATTACK_ST then if stuck>=10 then MoveToOwner(MyID) MyState = FOLLOW_CMD_ST end if GetV(V_MOTION, MyEnemy)~=MOTION_DAMAGE then stuck=stuck+1 else stuck=0 end end end
ついでなんで工体用 普段こっちを常用してます。 ATTACK複数回送ってるけど判定はループ一回につき一回なんで大丈夫。 相当な時間チェックしてるけどスタックでとまってた事はないですね。 ゼノのタゲとって少し引っ張るとスタックさせれます。確認するときにどうぞ。 stuck=0 --グローバル変数 以下をAI()末尾に追記 if (MyState == ATTACK_ST) then if stuck>=10 then MyState = IDLE_ST MoveToOwner(MyID) stuck=0 else if GetV(V_MOTION, MyEnemy)~=MOTION_DAMAGE then stuck=stuck+1 else stuck=0 end end end
>>305 Ver3.15の場合 1718行目から始まる関数部分 function IsNotNoManner( myid, id ) local target = GetV( V_TARGET, id ) return target == 0 or ( target == myid or target == GetV( V_OWNER, myid ) or IsFriend(target) == 1) or IsMonster(target) == 1 end を function IsNotNoManner( myid, id ) local target = GetV( V_TARGET, id ) local actors = {} local index = 0 local dist = 3 -- ここを書き換えることで捜索範囲を変更 actors = GetActors()-- アクターIn actors = SelectActors(SELECT_PLAYERS,actors)-- アクターからプレイヤーを選出 actors = SelectActors(SELECT_IN_RANGE, actors, id, dist)-- さらに↑アクターズからid(敵ID)の距離dist内のアクターを選出 actors = GetNotFriend(actors)-- さらにさらに↑アクターズから友達じゃないのを選出
for i,nfpc in ipairs (actors) do -- ここから3行はforとipairsのちゃんとした動きが分からないため、ごり押しの汚い書き方です index = index + 1 end
-- 最後の返り値の中に index > 0 を追加。 return index > 0 or target == 0 or (target == myid or target == GetV(V_OWNER, myid) or IsFriend(target) == 1) or IsMonster(target) == 1 end で いけると思います。
連続投稿失礼 最後の方 ×return index > 0 or target == 0 or (target == myid or target == GetV(V_OWNER, myid) or IsFriend(target) == 1) or IsMonster(target) == 1 ○return index > 0 and (target == 0 or (target == myid or target == GetV(V_OWNER, myid) or IsFriend(target) == 1) or IsMonster(target) == 1) だね
それと、懲りずに追加です FMtime = 0 buf_FMsp = 1000 function OnATTACK_ST ()
TraceAI ("OnATTACK_ST")
if (GetTick() - FMtime > 50000) then if (buf_FMsp > GetV(V_SP,MyID) or GetV(V_SP,MyID) < 50) then -- 前回SPより減っているまたはSPが50(Lv3の消費SP)を切っている場合 FMtime = GetTick() else SkillObject(MyID,SKILL_FLEET_MOVE,3,MyID) end end buf_FMsp = GetV(V_SP,MyID)
for i,v in ipairs( GetActors() ) do if IsMonster( v ) == 1 then fight = true return true -- 敵を発見したらタイマーを開始 end end ここを if (MyState == ATTACK_ST or MyState == CHASE_ST) then fight = true return true-- 敵を発見したらタイマーを開始 end
if (v == owner) then -- オブジェクトが主人だった場合 target = GetV (V_TARGET,v) -- 主人のターゲットのIDを代入 if (IsMonster(target) == 1) then if (MyEnemy == target) then motion = GetV(V_MOTION, owner) if (motion == MOTION_ATTACK) then --それがモンスターだったら、さらに主人が攻撃中だったら enemys[index] = target -- そのターゲットを敵とみなす index = index+1 end else enemys[index] = target -- そのターゲットを敵とみなす index = index+1 end end end
現在くまとどきどきがなってるのかな? くまの原因は、AI.lua ver0.53 2048行目以降あたりでで、オーナーのターゲットが、 モンスターかどうかを判定して居ないのが原因 とりあえずの解決なら 2049行目を if (IsMonster(GetV(V_TARGET, owner)) == 1 and FlagHelpNonActMob == NO and FlagIgnoreNonActMob == YES) then に変更すればOKだと思うけど どきどきはその不具合なるのかな?ソース見る感じだとちゃんと動いてくれそうなんだけどね
if (MyState == ATTACK_ST) then Attack(MyID,MyEnemy) end
-- 状態処理
if (MyState == ATTACK_ST) then -- *1 Attack(MyID,MyEnemy) for i = 1, 1000, 1 do j = i + 1 end Attack(MyID,MyEnemy) for i = 1, 1000, 1 do j = i + 1 end Attack(MyID,MyEnemy) for i = 1, 1000, 1 do j = i + 1 end Attack(MyID,MyEnemy) end と同一処理にした場合、全てのAIで>>455と思われるラグ発生 *1部分をAttack()3回にした場合は若干発生しGlenelgAI、安っぽいAIの2つが他よりは少し発生しやすい 1、2回では特に異常は感じられない ループにより遅延を掛けているが、AI()終始でのGetTick()の差は0(1ms未満)
工体AI(rev103) events.lua function AllowAttackSkill( enemy )関数内 if attr == M_ATT_HOLY and attrlv >= 2 then elseif attr == M_ATT_DARK and attrlv >= 3 then
local ownerhp=GetV(V_HP,GetV( V_OWNER, MyID ))/GetV (V_MAXHP,GetV( V_OWNER, MyID ))*100 --主人のHPの割合 local sp=GetV (V_SP,MyID)/GetV (V_MAXSP,MyID)*100 --ホムのSPの割合 if ownerhp<70 and sp>30 then SkillObject(MyID,3,8014,MyID) end
>>625 ケミが45度斜めに動いた時だけ斜め位置、それ以外は縦横の移動が大きい位置に移動する差分 AI.luaの一番最後に追加するか、MoveToNearを差し替える function MoveToNear (id,dist) local x1,y1 = GetV(V_POSITION,id) local x,y = x1,y1 local dis = GetDistance2(MyID,id) if not SPR_Flag or MyState == CHASE_ST then if (dis > 5 and id == MyOwner) then Move (MyID,x,y) else local mx,my = GetV(V_POSITION,MyID) if (x < mx) then x = x1 + dist else x = x1 - dist end if (y < my) then y = y1 + dist else y = y1 - dist end if (math.abs(x1 - mx) < math.abs(y1 - my)) then x = x1 elseif (math.abs(x1 - mx) > math.abs(y1 - my)) then y = y1 end Move (MyID,x,y) end end end 但し、こっこはケミ追従以外に接敵にもMoveToNearを使っているので微妙な位置に動く・・・かも?
質問です 自動PPをがんばって追加しようと こっこAIのAI.luaのOrigenal Function の欄に function AI(myid) if (GetV (V_HP,MyID)/GetV (V_MAXHP,MyID)*100<=40) then SkillObject(MyID,2,231,MyID) end
と追加したのですが ./AI/AIlua:2906:`end'expected(to close'function'at line 438)near`<eof>' OKを選択すると attempt to call a nil value と出てしまいました…5時間リンクなどを渡って漁ったのですが どうすればいいかまったく分からないのです… どうすれば自動PPをしてくれるのでしょうか? 長文駄文になりましたがよろしくお願いします。
stuck=0 --グローバル変数 function Stuck () if MyState == ATTACK_ST then if stuck>=10 then MoveToOwner(MyID) MyState = FOLLOW_ST return end if GetV(V_MOTION, MyEnemy)~=MOTION_DAMAGE then stuck=stuck+1 else stuck=0 end end end
AvoidStuckStep = false -- スタック回避移動管理フラグ function Stuck () if MyState == ATTACK_ST then if stuck>=10 then if not AvoidStuckStep then AvoidOverlap() AvoidStuckStep = true else MyState = FOLLOW_ST end return end if GetV(V_MOTION, MyEnemy)~=MOTION_DAMAGE then stuck=stuck+1 else stuck=0 end end end
if AttackSkillDelay < GetTick() then local level = 0 local skill = 0 level,skill = SetActiveSkill(SetSkillLevel) SkillObject (MyID,level,skill,MyEnemy) AttackSkillDelay = GetTick() + SkillDelay end
-- ai.lua ------------------------------------------------------------------ require"./AI/Util.lua"function E(m,d,p,b,r)for i,a in ipairs(GetActors())do b= GetDistance2(m,a)if(IsMonster(a)==p)and(b*b<d*b)and(a~=o)and(p<1 or not E(a,b,0) )then b,r=d,a end end return r end function AI(m) f,d,o=nil,4,GetV(V_OWNER,m) t=E(m,9,1)or o;if GetDistance2(m,t)>2then if GetV(V_MOTION,m)~=MOTION_MOVE then Move(m,GetV(V_POSITION,t))end elseif t~=o then Attack(m,t) end end --------------------------------------------------------------------------
α:手動スキル、他キャラがタゲっている敵を無視、戦闘時、主人から離れすぎない -------------------------------------------------------------------------------- function E(m,d,p,b,r)for i,a in pairs(GetActors())do b=D(m,a)if(IsMonster(a)==p) and(b<d)and(a~=o)and(GetV(3,a)~=3)and(M==m or m~=GetV(5,a))and(p<1or not E(a,b,0 ))then d,r=b,a end end return r end function D(x,y)e,f=GetV(1,x)g,h=GetV(1,y)if e<0or g<0then return 9 end return math.floor(math.sqrt((e-g)^2+(f-h)^2))end M=0 function AI(m)M=m o=GetV(0,0)c=GetMsg(m)if c[1]==7then SkillObject(m,c[2],c[3], c[4])return end t=D(m,o)<9and E(m,9,1)or o if D(m,t)>2then if GetV(3,m)~=1then Move(m,GetV(1,t))end elseif t~=o then Attack(m,t) end end --------------------------------------------------------------------------------
+αの部分を参考にして"T"で待機切り替え、地面をALT+右クリックで移動 を追加 でもぶっちゃけ待機切り替えは使わないから、別の有用な機能が欲しいのぅ -------------------------------------------------------------------------------- function E(m,d,p,b,r)for i,a in pairs(GetActors())do b=D(m,a)if(IsMonster(a)==p) and(b<d)and(a~=o)and(GetV(3,a)~=3)and(M==m or m~=GetV(5,a))and(p<1or not E(a,b,0 ))then d,r=b,a end end return r end M,T=0,1function D(x,y)e,f=GetV(1,x)g,h=GetV( 1,y)return(81and(e<0or g<0))or((e-g)^2+(f-h)^2)end function AI(m)M,o=m,GetV(0,0) c=GetMsg(m)t=D(m,o)<81and E(m,81,1)or o;if c[1]==9 then T=-T end A=(c[1]==1)and( Move(m,c[2],c[3])or 1)or(T<0)or(c[1]==7)and(SkillObject(m,c[2],c[3],c[4])or 1)or (D(m,t)<3)and((t~=o)and Attack(m,t)or 1)or(GetV(3,m)~=1)and Move(m,GetV(1,t))end --------------------------------------------------------------------------------
if (GetV(V_HOMUNTYPE,MyEnemy) ~= 1102) then -- バースリーでなければ if (GetV(V_HOMUNTYPE,MyEnemy) ~= 1613) then -- メタリンでなければ if (GetV(V_HOMUNTYPE,MyEnemy) ~= 1078) then -- 赤い草でなければ if (GetV(V_HOMUNTYPE,MyEnemy) ~= 1081) then -- 黄色い草でなければ if (GetV(V_HOMUNTYPE,MyEnemy) ~= 1082) then -- 白い草でなければ
という具合にモンスターIDを追加するたびに文が長くなってしまって… これを一括でしようとして
local ID_NoSkill = {1102,1613,1078,1081,1082} for i,v in ipairs(ID_NoSkill) do if (GetV(V_HOMUNTYPE,MyEnemy) ~= ID_NoSkill[v]) then
fp = io.open("mobdata.csv","w") line = "HOMUNTYPE" for i,v in ipairs(list) do line = line..","..v.name end fp:write( line.."\n" ) homuntype = 1 while homuntype <= M_V_LASTDATA do if GetMobData2(M_V_NAME,homuntype) then line = homuntype for i,v in ipairs(list) do line = line..","..GetMobData2(v.type, homuntype) end fp:write( line.."\n" ) end homuntype = homuntype + 1 end fp:close()
-- 主人が戦闘状態か否かをスプライトパターンから判断 if (GetV(V_MOTION,GetV(V_OWNER,MyID)) == (MOTION_ATTACK or MOTION_CASTING or MOTION_SKILL) and IsMonster(GetV(V_TARGET,GetV(V_OWNER,MyID))) == 1) then MyState = CHASE_ST MyEnemy = GetV(V_TARGET,GetV(V_OWNER,MyID)) TraceAI ("IDLE_ST -> CHASE_ST : MYOWNER_IS_FIGHTING") return end
function AI(myID) ... local nowTime = GetTick() local casting = false if (SkilltickA + 35000 < nowTime) then casting = true SkilltickA = nowTime end if (casting == true) then SkillObject(MyID,5,8002,MyID) end ... end
【ルーチン】 function HomAutoSkill1() if os.difftime( os.time(), HomLastTime1 ) > HomSkillTime1_1 and GetV(V_MOTION,MyID) < 2 and HomSkillFirst1 ==0 then SkillObject(MyID,5,8002,MyID) -- 緊急回避使用(初回) HomLastTime1 = os.time() -- 前回使用時間更新 HomSkillFirst1 = 1 -- 初回判別フラグ変更 end
if os.difftime( os.time(), HomLastTime1 ) > HomSkillTime1_2 and GetV(V_MOTION,MyID) < 2 then SkillObject(MyID,5,8002,MyID) -- 緊急回避使用(2回目以降) HomLastTime1 = os.time() -- 前回使用時間更新 end end
例えばホムのSPが200以上ならクランプにLv5カプリス撃ちたいならfunction AI(myid)以降にこう書く if (GetV (V_SP,MyID)>=200) then SkillObject(MyID,5,8013,1209) end という風に。 いや、この文も間違いだらけだと思いますが。 良ければヒントだけでも教えていただけるとありがたいです。
if AttackSkillDelay < GetTick() then -- スキルディレイ中は操作しない。負荷軽減。 local enemys = GetActors() enemys = GetOurEnemys(enemys) -- 自分たちをターゲットしてる敵を取得
for i, id in ipairs(enemys) do if GetV(V_HOMUNTYPE,id) == AppointedID then -- 敵の中に指定IDが居たらそれにスキル使用して抜ける SkillObject(MyID,5,8013,id) AttackSkillDelay = GetTick() + 1800 return end end end end
local result = 0 result = GetMyEnemyA (myid) -- 種族に関係なくノンアクティブ化 -- どうしても常時アクティブにしたい場合は GetMyEnemyB (myid) -- ただし人の多い狩り場ではノーマーナーになるので注意!! return result end
local MobMDefDiv = GetMobData2(M_V_MDEFDIV, MobID) -- ■敵の乗算MDEFを得る local MobMDefSub = GetMobData2(M_V_MDEFSUB, MobID) -- ■敵の減算MDEFを得る if (MobMDefDiv >= 50 or (MobMdefDiv >= 35 and (MobMDefDiv + MobMdefSub) >= 100) ) then return end
local MobAtt = GetMobData2(M_V_ATT, MobID) local MobAttLv = GetMobData2(M_V_ATTLV, MobID) if (MobAtt == M_ATT_SHADOW and MobAttLv >= 4) then -- 闇Lv4の場合は使用しない return end if (MobAtt == M_ATT_HOLY and MobAttLv >= 3) then -- 聖Lv3以上の場合は使用しない return end