local owner = GetV(V_OWNER,MyID) local target = GetV(V_TARGET,owner) local motion = GetV(V_MOTION,owner) if motion == MOTION_ATTACK or motion == MOTION_ATTACK2 then return target end
----------------------------------------------------- --ケミorホムのHP,SP残存量をパーセンテージで返す --idがケミorホムでなかった場合、返り値 -1,-1 --それ以外は HP = 0〜1,SP = 0〜1 ----------------------------------------------------- function GetPer(id) local HpPer=0 local SpPer=0
if (id ~= V_OWNER and id ~= MyID) then return -1,-1 else HpPer=(GetV(V_HP,id)/GetV(V_MAXHP,id)) SpPer=(GetV(V_SP,id)/GetV(V_MAXSP,id)) return HpPer,SpPer end end
-------------------------------------------------- --id1から見たid2の角度をradで返す --東を0とする --失敗した場合、返り値 nil --同座標の場合、返り値 -1 -------------------------------------------------- function GetRad(id1,id2) local rad=0 local x1=nil local y1=nil local x2=nil local y2=nil
>>207-208 atan2を使えば面倒なことしなくていいかと。 -------------------------------------------------------- --2点間の角度を求める function GetRadP(x1, y1, x2, y2) if(x1<0 or x2<0 or y1<0 or y2<0) then --座標がマイナス return nil end if(x1==x2 and y1==y2) then --二点が同座標 return -1 end return math.atan2(y2-y1, x2-x1) --0〜2πを返す end
--id1から見たid2の角度を求める function GetRad(id1, id2) local x1 local y1 local x2 local y2
----------------------------------------------------- --ケミorホムのHPorSPの残存量をmax値に対する比率で返す --mode="H"でHP、mode="S"でSP --idがケミorホムでなかった場合、返り値 -1 --それ以外は HP = 0〜1,SP = 0〜1 ----------------------------------------------------- function GetRateHS(id,mode) if (id ~= GetV(V_OWNER,MyID) and id ~= MyID) then return -1 elseif(mode == "H")then return (GetV(V_HP,id)/GetV(V_MAXHP,id)) elseif(mode == "S")then return (GetV(V_SP,id)/GetV(V_MAXSP,id)) else return -1 end end
-------------------------------------------------- --(x1,y1)の座標から見た(x2,y2)の座標の角度をradで返す --東を0とする --失敗した場合、返り値 nil --同座標の場合、返り値 -1 -------------------------------------------------- function GetRadP(x1,y1,x2,y2) local rad if(x1 >= 0 and y1 >= 0 and x2 >= 0 and y2 >= 0)then --0以上の数字のみ if(x1 == x2 and y1 == y2)then return -1 else rad=math.atan2(y2-y1,x2-x1) if(rad < 0)then rad=math.pi*2+rad end return rad end else return nil end end
--------------------------------------------------- --id1から見たid2の角度をradで返す --他、仕様はGetRadPに従う --------------------------------------------------- function GetRad(id1,id2) local x1 local y1 local x2 local y2
>>272 597行目の if(〜or type == AMISTR_H2)をif(〜or type == AMISTR_H2 or type == FILIR or type == VANILMIRTH) にして。 599行目の条件式から type == FILIR と type == VANILMIRTH を削除するのはどうだろうか。
283 :(○口○*)さん :06/03/14 15:46 ID:mho/SuSr
この2箇所修正しとけば、さしあたって問題ないでしょうか?
・function GetOwnerEnemy (myid)内 local motion = GetV(V_MOTION,i) → local motion = GetV(V_MOTION,v) ・function GetMyEnemy (myid)内 result = GetMyEnemyB (myid) → result = GetMyEnemyA (myid)
target = GetV (V_TARGET,v) -- vの標的を取得 if (target == owner) then -- 標的が主人なら if (IsMonster(v) == 1) then -- vがモンスターなら enemys[index] = v -- 敵とみなす index = index+1 else -- vがモンスター以外なら local motion = GetV(V_MOTION,v) -- vの行動を取得 if (motion == MOTION_ATTACK or motion == MOTION_ATTACK2) then -- 攻撃行動を取っているなら enemys[index] = v -- 敵とみなす index = index+1 end end end
それぞれ ・vの標的が主人で、vがモンスターなら、敵とみなす。 ・vの標的が主人で、vがモンスターではなく、vの行動が攻撃なら、敵とみなす。 と言ってるはずだから i は v に直すべきだと思う。
local x, y, timestamp = -1, -1, os.time() ExitEvent = function() local x2, y2 = GetV( V_POSITION, MyID ) if x ~= x2 or y ~= y2 then x, y = x2, y2 timestamp = os.time() return end if os.difftime( os.time(), timestamp ) >= EXIT_TIME then os.exit() end end end
if (1 == IsMonster(v)) then -- モンスターだったら +if ( GetV(V_MOTION,v) ~= 2 or GetV(V_MOTION,v) ~= 9 ) then enemys[index] = v -- 敵のリストに追加 index = index+1 -- インデックスを1増やす +end
if (v == owner ) then target = GetV (V_TARGET,v) if (IsMonster(target) == 1) then enemys[index] = target index = index+1 end elseif (v ~= owner and v ~= myid) then --以下略
local casting = false local type = GetV(V_HOMUNTYPE, MyID)
-- フィーリルのフリートムーブ if (type == FILIR or type == FIRIR2 or type == FILIR_H or type == FILIR_H2) then if (FleetMoveDelay == 0) then if (GetV(V_SP, MyID) > 70) then -- レベル5で必要なSP FleetMoveDelay = GetTick() + 4500 -- 次にかけ直すまでの時間 casting = true end else if (FleetMoveDelay >= GetTick()) then if (GetV(V_SP, MyID) > 70) then -- レベル5で必要なSP FleetMoveDelay = GetTick() + 4500 -- 次にかけ直すまでの時間 casting = true end end end
if (casting == true) then -- フリートムーブレベル5使用 SkillObject(MyID, 5, IN_SKILL_FLEETMOVE, MyID) end end
>>416 GetMyEnemyA or GetMyEnemyB を自分をターゲットしてるものを優先に変更して 攻撃処理内でターゲットがこっちを向いていたら、ケミからみて敵と逆側に移動するようにした 違う場所から書いてるので変数は適当だけど、ケミの裏に逃げるようになったが タゲがケミに移らなかった・・・ if ( GetV(V_TARGET,MyEnemy) then local ox,oy = GetV(V_POS,GetOwnerID(MyID)) local ex,ey = GetV(V_POS,MyEnemy) if ( ox < ex ) then ox = ox -1 else ox = ox +1 end if ( oy < ey ) then oy = oy -1 else oy = oy +1 end Move(MyID,ox,oy) end
if (MySkill == 0) then のところの『end』と『if (MySkill == 0) then 』の列に間に
--カスタム local IN_SKILL_CAPRICE = 8013 local casting = 0 local type = GetV(V_HOMUNTYPE, MyID)
if (type == VANILMIRTH2 or type == VANILMIRTH_H2 or type == VANILMIRTH or type == VANILMIRTH_H) then if (SKILL_TIME == 0) then if (GetV(V_SP, MyID) > 40) then -- レベル5で必要なSP SKILL_TIME = os.time() casting = 1 end else local PREV_TIME = SKILL_TIME+ 2 if ( os.time() >= PREV_TIME) then if (GetV(V_SP, MyID) > 40) then -- レベル5で必要なSP SKILL_TIME = os.time() casting = 1 end end end if (casting == 1) then SkillObject(MyID, 5, IN_SKILL_CAPRICE, MyEnemy) return end end --カスタム を入れる。 これで動いたんだけど、どうでしょ?
local casting = false local castTime_FleetMove = 0 … casting , castTime_FleetMove = SkillObjectB(MyID,5,IN_SKILL_FLEETMOVE,MyID,70,castTime_FleetMove,4500)
て感じでしかべき場所いれればイイと思う でログインできないまま適当に書いてみたコード↓
function SkillObjectB( id,level,skill,target,sp,castTime,delay ); if( (os.time() < castTime) or ( GetV(V_SP,id) < sp) ) then return ( false,time ) end else SkillObject(id,level,skill,target) return ( true,os.time()+delay ) end end
function SkillObjectB( id,level,skill,target,sp,castTime,delay ) if( (os.time() < castTime) or ( GetV(V_SP,id) < sp) ) then return ( false,castTime ) end else SkillObject(id,level,skill,target) return ( true,os.time()+delay ) end end
function AI (myid) MyID = myid local msg = GetMsg (MyID)
if (msg[1] == EAT_CMD) then Eat () MyState = EAT_CMD_ST end if (MyState == IDLE_ST) then local distance = GetDistanceFromOwner(MyID) if ( distance > 3 or distance == -1) then MyState = FOLLOW_ST end elseif (MyState == FOLLOW_ST) then if (GetDistanceFromOwner(MyID) <= 2) then MyState = IDLE_ST elseif (GetV (V_MOTION, MyID) == MOTION_STAND) then MoveToOwner (MyID) end elseif (MyState == EAT_CMD_ST) then MyState = IDLE_ST end end
function GetMyEnemyB (myid) local result = 0 local owner = GetV (V_OWNER,myid) local actors = GetActors () local enemys = {} local index = 1 local type local enemy_motion for i,v in ipairs(actors) do if (v ~= owner and v ~= myid) then if (1 == IsMonster(v)) then enemy_motion = GetV(V_MOTION,v) if (MOTION_ATTACK ~= enemy_motion and MOTION_ATTACK2 ~= enemy_motion) 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
for i,v in ipairs(actors) do if (v ~= owner and v ~= myid) then local enemy_target = GetV(V_TARGET,v) if (1 == IsMonster(v) and enemy_target == 0) then -- モンスターががタゲを取ってないなら enemys[index] = v -- 敵をみなす index = index+1 eiseif (enemy_target == MyID) then -- ホム自身をタゲにしているなら enemy_motion = GetV(V_MOTION,v) if (MOTION_ATTACK ~= enemy_motion or MOTION_ATTACK2 ~= enemy_motion) then -- 攻撃行動を起こしているなら enemys[index] = v -- 敵とみなす index = index+1 end end end end
個人的にはデフォのOnFOLLOW_ST内を書き換えるんじゃなく、 function OnFOLLOW_ST2 () TraceAI ("OnFOLLOW_ST2") if (GetDistanceFromOwner(MyID) <= 3) then MyState = IDLE_ST TraceAI ("FOLLOW_ST -> IDLW_ST") return; elseif (GetV(V_MOTION,MyID) == MOTION_STAND or GetV(V_MOTION,MyID) == MOTION_MOVE) then local x,y = GetV(V_POSITION,MyOWNER) Move (MyID,x,y) return; end end これをどっかに書き加えた後、--状態処理の下にあるOnFOLLOW_ST ()をOnFOLLOW_ST2 ()に書き換えるのがスマートだと思う。問題発生した時も戻しやすいし。
SkillObjectB、ログインしてやってみたらエラーでまくってびっくり else の前の end と return のあとの括弧を取り除けば動くはずだけど スキルの定数しらないから保留
ところでtable関数になかったので↓の関数を作ってみました -- IsIn function IsIn( Value, ... ) local i = 1 local result = false while (arg[i+1] ~= nil ) do result = result or ( arg[i] == Value ) i = i + 1 end return result end
Value につづく引数にValueが含まれてたらtrueを返します 例) IsIn( 0,1,3,4,5,0,4,3 ) この結果は true です
-- IsIn function IsIn( Value, ... ) local i local result = false for i = 1, arg.n , 1 do result = result or ( arg[i] == Value ) i = i + 1 end return result end
for i,v in ipairs(actors) do if (v ~= owner and v ~= myid) then if (1 == IsMonster(v)) then if (5 >= GetDistance2 (myid, v)) then enemys[index] = v index = index+1 end end end end
local casting = false local type = GetV(V_HOMUNTYPE, MyID)
if (type == LIF or type == LIF2 or type == LIF_H or type == LIF_H2) then if (EmergencyAvoidDelay == 0) then -- 初回 if (GetV(V_SP, MyID) == GetV(V_MAXSP, MyID)) then -- SP満タン時 EmergencyAvoidDelay = GetTick() + 3500 -- 次にかけ直すまでの時間 casting = true end else if (EmergencyAvoidDelay <= GetTick()) then -- 前回発動後一定時間経過 if (GetV(V_SP, MyID) == GetV(V_MAXSP, MyID)) then -- SP満タン時 EmergencyAvoidDelay = GetTick() + 3500 -- 次にかけ直すまでの時間 casting = true end end end
if (casting == true) then
SkillObject(MyID, 3, IN_SKILL_EMERGENCYAVOID, MyID) -- 緊急回避レベル3使用 end end
>>640だと敵を殴ってても使っちゃうので、攻撃中は使わないように改良 if (GetV(V_SP, MyID) == GetV(V_MAXSP, MyID)) then -- SP満タン時 → if (GetV(V_SP, MyID) == GetV(V_MAXSP, MyID) and MyState ~= ATTACK_ST) then -- SP満タン&非攻撃時
function Target_Chack() local target = GetV(V_HOMUNTYPE,MyEnemy) -- MOBのIDを取得 if(target >= 1078 and target <= 1085) then -- ターゲットが 草 or きのこ の場合 return 1 -- スキル使用禁止 elseif(target == 1008 or target == 1047 or target == 1047 or target == 1097) then -- ターゲットが無抵抗MOBの場合 return 1 -- スキル使用禁止 end return 0 -- スキル使用可 end
ターゲットIDは元々MyEnemyに格納されてるのでそれを使用。 判定は以下の位置に追加。
local Dice = math.floor(math.random(100)) if (Dice < AutoSkillPer and Target_Chack() == 0) then SkillObject (MyID,MySkillLevel,MySkill,MyEnemy) -- スキル攻撃 else Attack (MyID,MyEnemy) end
>>649 敵から逃げる、でもたぶんそのまま何処かへ・・ それ以前に動作テストしてないから動かないかもしれないけど function nige() local acts = GetActors() local x = 0 local y = 0 local cnt = 0 for i,v in iparts(acts) do if ( v ~= GetV(V_OWNER,MyID) and v ~= MyID and GetDistance2(MyID,v) <= 3) then if ( GetV(V_TARGET,v) == MyID ) then local ex,ey = GetV(V_POSITION,v) x = x + ex y = y + ey cnt = cnt + 1 end end end local mx,my = GetV(V_POSITION,MyID) if( cnt ~= 0 )then x = mx - (x / cnt) y = my - (y / cnt) else return mx,my end local r = sqrt(x*x+y*y) if( x == 0 and y == 0 ) then return mx+1,my else mx = mx + x * r * 4 my = my + y * r * 4 end return mx,my end
elseif (GetV(V_MOTION,MyID) == MOTION_STAND or GetV(V_MOTION,MyID) == MOTION_MOVE) then local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID)) local mx,my = GetV(V_POSITION,MyID) if (x < mx) then x = x + 1 elseif (x > mx) then x = x - 1 end if (y < my) then y = y + 1 elseif (y > my) then y = y - 1 end Move (MyID,x,y) return
>>608 そのフラフラするMoveToOwner (MyID)の性質を生かして、簡単に主人のまわりをうろちょろさせることができるな。 if (GetV(V_MOTION,GetV(V_OWNER,MyID)) == 6 and GetV(V_HP,GetV(V_OWNER,MyID)) == GetV(V_MAXHP,GetV(V_OWNER,MyID))) then MoveToOwner (MyID) end ↑をOnIDLE_ST ()内に書き加えれば、主人が座っててかつHPが満タンの時ホムが周囲を動き回るようになる。
elseif (GetV(V_MOTION,MyID) == MOTION_STAND or GetV(V_MOTION,MyID) == MOTION_MOVE) then local x,y = GetV(V_POSITION,GetV(V_OWNER,MyID)) if (GetDistanceFromOwner(MyID) > 5) then Move (MyID,x,y) else local mx,my = GetV(V_POSITION,MyID) if (x < mx) then x = x + 1 elseif (x > mx) then x = x - 1 end if (y < my) then y = y + 1 elseif (y > my) then y = y - 1 end Move (MyID,x,y) end return
------------------------------------------- -- 座標x1,y1の正反対の座標を出す -- x1,y1 自身の座標 -- x2,y2 対象の座標 -- dis 移動する距離 ------------------------------------------- function GetReversePosition(x1,y1,x2,y2,dis) local x,y if (dis == nil) then -- 未指定ならとりあえず8セル dis = 8 end
if (y2 > y1) then if (x2 > x1) then -- 右上 x = x1 - floor(dis / 1.414) y = y1 - floor(dis / 1.414) elseif (x2 < x1) then -- 左上 x = x1 + floor(dis / 1.414) y = y1 - floor(dis / 1.414) else -- 上 x = x1 y = y1 - dis end
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
function AutoUseEmr() local motion = GetV(V_MOTION,GetV(V_OWNER,MyID)) if(motion == 0 or motion == 1 or motion == 2 or motion == 9)then if ((GetV(V_SP,MyID) - Emr_SP)/GetV(V_MAXSP,MyID)*100.0 >= Emr_UseSP) then Emr_Timer2 = GetTick() if ( Emr_Timer2 - Emr_Timer1 >= Emr_Time * 1000 ) then Emr_Timer1 = GetTick() SkillObject(MyID,Emr_LV,Emr_ID,MyID) end end end return end
function OnAUTOEA_CMD_ST () local object = GetOwnerEnemy (MyID) local casting = false local type = GetV(V_HOMUNTYPE, MyID) local AlchemyHP = GetV (V_OWNER_HP,MyID) local AlchemyMaxHP = GetV (V_OWNER_HP,MyID)
if (object ~= 0) then if (type == AMISTR or type == AMISTR_H) then if (CastlingDelay == 0) then if (AlchemyHP =< AlchemyMaxHP / 3) then casting = true end end end
function GetOwnerEnemyEx(id) local result = 0 local owner = GetV(V_OWNER, myid) local actors = GetActors() local enemys = {} local index = 1 local target local count = 0 for i,v in ipairs(actors) do if (v ~= owner and v ~= myid) then target = GetV(V_TARGET, v) if (target == owner) then if (IsMonster(v) == 1) then enemys[index] = v index = index + 1 count = count + 1 else local motion = GetV(V_MOTION, i) if (motion == MOTION_ATTACK or motion == MOTION_ATTACK2) then enemys[index] = v index = index + 1 count = count + 1 end 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, count end
function FirstAttackMoonLight(level, usesp, spPer)
-- 既に使った if MoonLightFlag == 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_MSP, MyID) if ((sp / msp) * 100) < spPer then return end
local type = GetV(V_HOMUNTYPE, MyID)
if (type == FILIR or type == FIRIR2 or type == FILIR_H or type == FILIR_H2) then SkillObject(MyID, level, IN_SKILL_MOONLIGHT, MyEnemy) MoonLightFlag = 1 end
local actors = GetActors () -- 周りのキャラクターidを全部取得 local owner = GetV (V_OWNER,MyID) -- ケミ自身のキャラクターid local way,dis local waylist = {0,0,0,0,0,0,0,0,0} local debug = "" for i,v in ipairs(actors) do if (v ~= owner and v ~= MyID) then -- 主人かホム自身じゃなければ type = GetV (V_HOMUNTYPE,v) dis = GetDistance2(MyID,v) if (type == 1002 and dis < 4) then -- ポリーンが近くにいたら way = GetWay2(MyID,v) -- 居る方角を取得 waylist[way] = waylist[way] + 1 -- リストに追加 end end end max_cnt = 0 for w,c in ipairs(waylist) do -- 敵が最も居る方角を取得 if (c > max_cnt) then max_cnt = c way = w end end if (max_cnt > 0) then -- 移動先を決めて移動 ここで方角に応じた移動処理 end
------------------------------------------- -- 座標x1,y1から見たx2,y2の方角を返す -- x1,y1 自身の座標 -- x2,y2 対象の座標 -- 戻り値:方角定数(numキー配列に準拠) ------------------------------------------- function GetWay(x1,y1,x2,y2) local way = WAY_UNKNOWN
if(math.abs(y2 - y1) < 3) then if (math.abs(x2 - x1) < 3) then -- 近接 way = WAY_HERE elseif (x2 > x1) then -- 右 way = WAY_RIGHT else -- x2 < x1 -- 左 way = WAY_LEFT end
elseif (y2 > y1) then if (math.abs(x2 - x1) < 3) then -- 上 way = WAY_UP elseif (x2 > x1) then -- 右上 way = WAY_RIGHTUP else -- x2 < x1 -- 左上 way = WAY_LEFTUP end
else -- y2 < y1 if (math.abs(x2 - x1) < 3) then -- 下 way = WAY_DOWN elseif (x2 > x1) then -- 右下 way = WAY_RIGHTDOWN else -- x2 < x1 -- 左下 way = WAY_LEFTDOWN end
function RandomUseCaprice(level, usesp, spPer, usePer)
-- SP足りないので終了 local sp = GetV(V_SP, MyID) if (sp < usesp) then return end
-- 一定率以上じゃないと使用しない local msp = GetV(V_MSP, MyID) if ((sp /msp * 100) < spPer) then return end
-- 乱数発生させて使用するかチェック if math.random(1,100) > usePer then return end
local type = GetV(V_HOMUNTYPE, MyID)
if (type == VANILMIRTH or type == VANILMIRTH2 or type == VANILMIRTH_H or type == VANILMIRTH_H2) then -- 戦闘中である場合のみ if (MyEnemy ~= 0) and (MyState == CHASE_ST or MyState == ATTOCK_ST) then local skillCaprice = 8013 SkillObject(MyID, level, skillCaprice, MyEnemy) end end
-- 初撃必ずランダムボルト 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_MSP, 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
>>864 そちらのコードを入れてみたところAI切り替え直後に MyState = CHASE_STの行で「'then' expected near 'MYState'」とエラーが出ます
thenがどうのこうの言ってるっぽいんで前の行を if ( RUNAWAY_HP >= HPper ) then と追加してみたら、AI切り替え直後にエラーは出なくなりましたが 変わりに、敵を発見して近づいて攻撃しようとする際に if ( RUNAWAY_HP >= HPper ) thenの行で 「attempt to compare number with nil」とエラーが出ました
attempt to compare number with nil が出る人は その辺の変数をまとめてトレースしてみよう。
if (value1 == nil) then TraceAI("value1 is nil") end if (value2 == nil) then TraceAI("value2 is nil") end if (value3 == nil) then TraceAI("value3 is nil") end
OnATTACK_ST() の部分の -- 賽を投げる local Dice = math.floor(math.random(100)) if (Dice < AutoSkillProbability and Target_Chack() == 0) then -- 追加ここから SkillObject (MyID,MySkillLevel,MySkill,MyEnemy) else Attack (MyID,MyEnemy) end -- 追加ここまで if (AutoSkillProbability > Dice) then SkillObject (MyID,MySkillLevel,MySkill,MyEnemy) -- スキル攻撃 ActionFlag = 1 -- 行動済みフラグを立てる TraceAI ("ATTACK_ST -> ATTACK_ST : AUTO_SKILL") end
追加ここから〜追加ここまで を追記し、
OnATTACK_ST()のすぐ上に
function Target_Chack() local target = GetV(V_HOMUNTYPE,MyEnemy) -- MOBのIDを取得 if(target >= 1078 and target <= 1085) then -- ターゲットが 草 or きのこ の場合 return 1 -- スキル使用禁止 elseif(target == 1008 or target == 1047 or target == 1047 or target == 1097) then -- ターゲットが無抵抗MOBの場合 return 1 -- スキル使用禁止 end return 0 -- スキル使用可 end
local randX = OwnerX - math.randam(PatrolRange)*(math.randam(2)*2-3) local randY = OwnerY - math.randam(PatrolRange)*(math.randam(2)*2-3) Move (MyID,randX,randY)
FleetMoveDelay = 0 -- フリートムーブ間隔管理用 IN_SKILL_FLEETMOVE = 8010 -- スキルID function OnAUTOEA_CMD_ST () -- フリートムーブLv1を自動で使用 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 GetV(V_SP, MyID) < xx then return end if (FleetMoveDelay == 0) then -- 初回 if (HomunculusSP >= HomunculusMaxSP / 2 + xx) then --使用後SPが半分以下になるなら使用しない FleetMoveDelay = GetTick() + yy000 -- 次にかけ直すまでの時間 casting = true end else if (FleetMoveDelay <= GetTick()) then -- 前回発動後一定時間経過 if (HomunculusSP >= HomunculusMaxSP / 2 + xx) then --使用後SPが半分以下になるなら使用しない FleetMoveDelay = GetTick() + yy000 -- 次にかけ直すまでの時間 casting = true end end end if (casting == true) then SkillObject(MyID, z, IN_SKILL_FLEETMOVE, MyID) -- フリートムーブレベル1使用 end end end xx=各Lvでの消費SP yy=各Lvでの持続時間 z=スキルレベル スマートではないがこれで指定SP以下にならない限り常時掛けなおしてくれる。 恐らくオーバブーストにも使えると思うが重複して使えるかどうかは未確認。 後MAP移動、テレポ、その他AI初期化の度に時間に関係なく使うのはどうにかならんものか…
--[[ function TraceAI (string) end function MoveToOwner (id) end function Move (id,x,y) end function Attack (id,id) end function GetV (V_,id) end function GetActors () end function GetTick () end function GetMsg (id) end function GetResMsg (id) end function SkillObject (id,level,skill,target) end function SkillGround (id,level,skill,x,y) end function IsMonster (id) end -- idはモンスターか? yes -> 1 no -> 0
local x, y, timestamp = -1, -1, os.time() ExitEvent = function() local x2, y2 = GetV( V_POSITION, MyID ) if x ~= x2 or y ~= y2 then x, y = x2, y2 timestamp = os.time() return end if os.difftime( os.time(), timestamp ) >= EXIT_TIME then SkillObject(MyID,1,244,MyID) end end end end