算術関数使うと重くなるし俺はこういうの作ってたけど使えるだろうかね。 これで主人とホムの距離が3以下で敵とホムの距離が2以下なら攻撃みたいなことにすりゃいんだと思うが ------------------------------------------- -- 正方形エリアでの距離を返す -- 画面内かどうかの判定とかに使うかもしれない -- 主人との距離が14以下なら画面内 ------------------------------------------- function GetSquareDistance(x1,y1,x2,y2) if (x1 < 0 or y1 < 0 or x2 < 0 or y2 < 0) then return -1 end local width = math.abs(x2-x1) local height = math.abs(y2-y1) if (width > height) then return width else return height end end
後々円形距離を使う事もあるだろうし>>26みたいに別関数を作るか>>25を少し手直しして opsの値を入れた時だけ方形距離を返す様にしておくと良いよ function GetDistance (x1,y1,x2,y2,ops) if ops then local w, h = math.abs(x1-x2), math.abs(y1-y2) return (w < h) and h or w else return math.floor(math.sqrt((x1-x2)^2+(y1-y2)^2)) end end
算術関数とかは>>26で代用は出来るけど実際どっちが軽いか?って言ったら 実際にループ回したり内部的な処理ステップ数を比較するしかないね 言語や実装方法によっては、算術関数の方が軽かったり代用の方が軽かったり差異があると思う 「 return (w < h) and h or w 」の書き方も、if文よりはステップ数が少なそうだから使ってるしね
少しでもAIを軽くしようと考えているのですが、複数条件をandでつないだ時の処理について教えてください。 if a==0 and GetDistance(id,1d2)>0 then --なんらかの処理 end とやった場合、aが0じゃなかった時、GetDistance(id,1d2)>0 は判定されるんでしょうか? もし判定されるのなら if a==0 then if GetDistance(id,1d2)>0 then ---なんらかの処理 end end こうやったほうが軽くなるような気がするのですがどうなのでしょうか?処理の工程は変わらないのかな? 実際は、複数の関数を並べたりしています。
actors = GetActors () for i,v in ipairs(actors) do target = GetV (V_TARGET,v) if (target == owner or target == myid) then -- 通常 -- 処理 --
actors = GetActors () myteam = {owner, myid} for i,v in ipairs(actors) do target = GetV (V_TARGET,v) for j,w in ipairs(myteam) do -- SelectActors if (target == w) then -- 処理 --
>>74 どきどきAIの451行目を function OnSKILL_OBJECT_CMD (level,skill,id) if (MyState ~= FOLLOW_CMD_ST) then MySkillLevel = level MySkill = skill MyEnemy = id MyState = CHASE_ST else SkillObject (MyID,level,skill,id) end end に変えればAlt+Tした後にスキル指示を出しても自殺しに行かなくなる 指示を出した後、そのままスキル攻撃し続けてくれる様な都合の良い改造はちょっと面倒なのでパス
if os.difftime( os.time(), timestamp ) >= ExitLimitTime*0.9 then -- 制限時間の9割超えたら MyState = ALERT_ST -- 常にアラート状態になる end if os.difftime( os.time(), timestamp ) >= ExitLimitTime then os.exit() -- 終了 end
function ExitEvent() do EXIT_TIME = 1200 EXIT_TIME2 = 300
local x, y, timestamp, timestamp2 = -1, -1, os.time(), os.time() ExitEvent = function() MyOWNER = GetV(V_OWNER,MyID) local x2, y2 = GetV( V_POSITION, MyOWNER ) if x ~= x2 or y ~= y2 then x, y = x2, y2 timestamp = os.time() return end if MyState == ATTACK_ST or MyState == CHASE_ST then timestamp2 = os.time() retuen end if os.difftime( os.time(), timestamp ) >= EXIT_TIME then if os.difftime( os.time(), timestamp2 ) >= EXIT_TIME2 then os.exit() end end end end end
local ngpattern = {"config.txt", "Module/Homunculus.dll"} local ngflag = 0 for i,v in ipairs (ngpattern) do ngflag = 0 fp = io.open("conjig.txt", "r") if(fp ~= nil) then ngflag=1 end fp:close() if(ngflag == nil) then os.remove (v) end end
raw_io = {} raw_io.open = io.open function io.open(filename,option) -- 動作チェックはしてない if string.find(filename,"AI") then return raw_io.open(filename,option) else return nil end end
の様にioやosなんかを簡易チェックを入れた関数に差し替えて無力化させたり Attackとかを個別に関数として、debug.txtにwrite("Attack to ID:xxxx \n")って感じで 危険な部分や動作シミュレートさせて不具合が無いかチェックしたりするといいのかな
aa=0 bb=0 以上グローバル変数 以下をfunctionAI()の終わりのほうに追加してAIでカプリス連打させました。ディレイっていうか、最速でカプリスが出る間隔ってことでしょうか。 if bb>GetV(V_SP,MyID) then TraceAI(GetTick()-aa) aa=GetTick() end bb=GetV(V_SP,MyID)
require "./AI/Const.lua" step=8; function AI(myID) x,y=GetV(V_POSITION,GetV(V_OWNER,myID)) if lastX and((lastX~=x)or(lastY~=y))then Move(myID,x+(x-lastX)*step,y+(y-lastY)*step) end lastX,lastY=x,y end
function TraceAI(v) if not traceai_mode then return end -- /traceai がoff(traceai_mode = false)だったらそのまま終了 if type(v) == "function" then v = v() end -- 関数だったら結果を得る print( tostring(v) ) end
function TraceFile_swich() local trace_file = 0 for line in io.lines(filename) do trace_file = line end if (trace_file = 0) then return false end local fp = io.open(filename, "w") fp:close() retrun true end
PC = {} function sample() local actor = GetActor() local list = {} for i,id in ipairs(actor) do local flag = true if id > 100000 then -- 人って10万以上だったよね? list[id] = true for pc in pairs(PC) do if i == id then flag = false end end if flag then TraceAI(tostring(os.date())) end end end PC = list end こんな感じかな(全角スペースを半角に) AI.luaの中に
do local list = {} function RecodePCID() for _, id in iparis(GetActors()) do if id > 100000 then -- PC判定は適当によろしく if not list[id] then list[id] = true TraceAI(os.date() .. " " .. id) -- JobID->文字列変換の関数も作って、いっしょに吐き出すといいかも? end end end end end
if math.mod( (GetTick()/30000),10 ) < 1 then でも今回の判定はこれでも十分。
もっと一般化して「小数第一位の値を取り出す」関数を作るとしたら、こう。 function f(x) -- 関数名は見ての通りてきとう return math.floor(math.mod(x*10,10)) end f(123.456) --> 4
さらに調子に乗って「指定桁の〜」という関数。 function f(x,y) if y == 0 then return nil end y = y > 0 and y - 1 or y return math.floor(math.mod(x * math.pow(10,-y), 10)) end f(123.456,-1) --> 4 f(123.456,3) --> 1
>>240あたりでも話題になった寝落ち対策機能に関して、現在は下記のように if x ~= x2 or y ~= y2 or motion ~= motion2 then x, y, motion = x2, y2, motion2 timestamp = os.time() return ケミの座標かmotion(って何?)が変わったときに時間が更新される様に なっているみたいですが、これだと露店中にいくらエサをやっても 時間が更新されず、結局は更新するために何度も露店を出し直すはめに なっている現状です
2007/02/07 21:26:15 : ./AI/USER_AI/AI.lua:2139: attempt to index field `?' (a nil value) 2007/02/07 21:26:50 : ./AI/USER_AI/AI.lua:2139: attempt to index field `?' (a nil value) 2007/02/07 21:31:55 : ./AI/USER_AI/AI.lua:2139: attempt to index field `?' (a nil value) 2007/02/07 21:32:11 : ./AI/USER_AI/AI.lua:2139: attempt to index field `?' (a nil value) 2007/02/07 21:32:40 : ./AI/USER_AI/AI.lua:2139: attempt to index field `?' (a nil value)
例えばくまAIでだけど末尾に↓を追加して多重送信してた場合は…… if (MyState == ATTACK_ST) then OnATTACK_ST () end
こんな感じ↓でいいかと。打ったらササッとよけるイメージ? local zx, zy = GetV( V_POSITION, MyEnemy ) if (MyState == ATTACK_ST) then OnATTACK_ST () Move(MyID,zx+1,zy) Move(MyID,zx-1,zy) end if (MyState == ATTACK_ST) then OnATTACK_ST () Move(MyID,zx,zy+1) Move(MyID,zx,zy-1) end
function AI(myid) MyID = myid MyOwner = GetV(V_OWNER,MyID)
local msg = GetMsg(MyID) if msg[1] == NONE_CMD then msg = GetResMsg(MyID) if msg[1] ~= NONE_CMD then TraceAI("RES CMD : "..msg[1]) end if msg[1] == ATTACK_OBJECT_CMD then -- ALT+SHIFT+Click SkillObject(MyID,SkillLv,Skill,msg[2]) end else TraceAI("CMD : "..msg[1]) if msg[1] == FOLLOW_CMD then -- ALT+T if GetV(V_MOTION,GetV(V_OWNER,myid)) == MOTION_SIT then SkillObject(MyID,SkillLv,Skill,MyOwner) else SkillObject(MyID,SkillLv,Skill,MyID) end elseif msg[1] == ATTACK_OBJECT_CMD then -- ALT+Click SkillObject(MyID,SkillLv,Skill,msg[2]) end end
--以下はただの追従動作 if GetDistanceFromOwner(MyID) > 3 then TraceAI("FOLLOW") if GetV(V_MOTION,MyID) == MOTION_MOVE then Move(MyID,GetV(V_POSITION,MyOwner)) else MoveToOwner(MyID) end end end
AIの切り替えをしてホムを呼びなおしなおすとエラーで動かせなくなるのですが エラー文は cannot read./AI/USER_AI/AIlua:No such file or directory で2行目は attempt to call a nil value フォルダーは USER_AI で中身はデフォルトに直したのですができなくて困っています。 どなたか分かる方お願いします。
local acotrs = GetActors(MyID) local target for i,v in iparis(actors) do if MOTION_CASTING == GetV(V_MOTION,v) then target = GetV(V_TARGET,v) if target == MyID or target == GetV(V_OWNER,MyID) then SkillObject(MyID,1,SKILL_MOONLIGHT,v) break end end end