-- 2005-07-19AI require "./AI/Const.lua" require "./AI/Util.lua" ----------------------------- -- ホムンクルス状態定数 ----------------------------- IDLE_ST = 0 -- 待機状態 FOLLOW_ST = 1 -- アルケミスト追従状態 CHASE_ST = 2 -- ターゲット追跡状態 ATTACK_ST = 3 -- 攻撃状態 MOVE_CMD_ST = 4 -- 移動コマンド受付状態 STOP_CMD_ST = 5 -- 停止コマンド受付状態 ATTACK_OBJECT_CMD_ST = 6 -- 対象指定攻撃コマンド受付状態 ATTACK_AREA_CMD_ST = 7 -- 範囲攻撃コマンド受付状態 PATROL_CMD_ST = 8 -- パトロール(往復移動)コマンド受付状態 HOLD_CMD_ST = 9 -- ホールドコマンド受付状態 SKILL_OBJECT_CMD_ST = 10 -- 対象指定スキルコマンド受付状態 SKILL_AREA_CMD_ST = 11 -- 範囲スキルコマンド受付状態 FOLLOW_CMD_ST = 12 -- 追従コマンド受付状態 ---------------------------- ------------------------------------------ -- グローバル変数(プログラム全体で共通で使うフラグみたいなもの) ------------------------------------------ MyState = IDLE_ST -- ホムの現在状態(初期値は待機状態) MyEnemy = 0 -- ホムがターゲットしている敵のキャラクターID MyDestX = 0 -- ホムの目標座標X(移動先 / スキル使用座標) MyDestY = 0 -- ホムの目標座標Y(移動先 / スキル使用座標) MyPatrolX = 0 -- ホムがパトロール(往復移動)する始点座標X MyPatrolY = 0 -- ホムがパトロール(往復移動)する始点座標Y -- (ケミが先行で複数コマンド入力した場合、ここに順番に記憶されます) ResCmdList = List.new() -- 先行入力コマンドリスト MyID = 0 -- ホム自身のキャラクターID MySkill = 0 -- ホムが使おうとしているスキル MySkillLevel = 0 -- ホムが使おうとしているスキルレベル ------------------------------------------ ------------- コマンドごとの処理 --------------------- ------------------------------------------- -- 移動コマンドを受け付けた場合の処理 -- <引数> X : 移動指定X座標 -- Y : 移動指定Y座標 ------------------------------------------- function OnMOVE_CMD (x,y) TraceAI ("OnMOVE_CMD") -- デバッグ文出力 if ( x == MyDestX and y == MyDestY and MOTION_MOVE == GetV(V_MOTION,MyID)) then return -- ホムの座標が移動先目標座標と同じで、かつホムが移動モーションならば何もしない。 end -- ケミとホムの間の距離を取得 (x,y) local curX, curY = GetV (V_POSITION,MyID) -- ケミとホムの距離が15マス以上のとき 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) -- (x,y)座標にホム移動開始 MyState = MOVE_CMD_ST -- ホム状態を移動コマンド受付状態にする MyDestX = x -- 移動先x座標をxにする MyDestY = y -- 移動先y座標をyにする MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MySkill = 0 -- タゲにしている敵がいたらタゲ解除 end ------------------------------------------- -- 停止コマンドを受け付けた場合の処理 ------------------------------------------- function OnSTOP_CMD () TraceAI ("OnSTOP_CMD") -- デバッグ文出力 -- ホムが立ちモーションでなければ if (GetV(V_MOTION,MyID) ~= MOTION_STAND) then Move (MyID,GetV(V_POSITION,MyID)) -- ホムの現在位置で停止 end MyState = IDLE_ST -- ホム状態を待機状態にする MyDestX = 0 -- 目標x座標をクリア MyDestY = 0 -- 目標y座標をクリア MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MySkill = 0 -- 使用しようとしているスキルがあったらキャンセル end ------------------------------------------- -- 対象指定攻撃コマンドを受け付けた場合の処理 -- <引数> id : 攻撃対象のキャラクターid ------------------------------------------- function OnATTACK_OBJECT_CMD (id) TraceAI ("OnATTACK_OBJECT_CMD") -- デバッグ文出力 MySkill = 0 -- 使用しようとしているスキルがあったらキャンセル MyEnemy = id -- idの敵をターゲットにする MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする end ------------------------------------------- -- 対象指定攻撃コマンドを受け付けた場合の処理 -- <引数> x : 攻撃範囲の中心x座標 -- y : 攻撃範囲の中心y座標 ------------------------------------------- function OnATTACK_AREA_CMD (x,y) TraceAI ("OnATTACK_AREA_CMD") -- デバッグ文出力 -- ホムの座標が目標座標と違うか、ホムが移動モーションでなければ if (x ~= MyDestX or y ~= MyDestY or MOTION_MOVE ~= GetV(V_MOTION,MyID)) then Move (MyID,x,y) -- (x,y)座標にホム移動開始 end MyDestX = x -- 目標x座標をxにする MyDestY = y -- 目標y座標をyにする MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MyState = ATTACK_AREA_CMD_ST -- ホム状態を範囲攻撃コマンド受付状態にする end ------------------------------------------- -- パトロールコマンドを受け付けた場合の処理 -- パトロールでは、ホムは現在位置と指定位置を往復する -- <引数> x : パトロールx座標 -- y : パトロールy座標 ------------------------------------------- function OnPATROL_CMD (x,y) TraceAI ("OnPATROL_CMD") -- デバッグ文出力 -- ホムの現在座標をパトロール開始座標にする MyPatrolX , MyPatrolY = GetV (V_POSITION,MyID) MyDestX = x -- 目標x座標をxにする MyDestY = y -- 目標y座標をyにする Move (MyID,x,y) -- (x,y)座標にホム移動開始 MyState = PATROL_CMD_ST -- ホム状態をパトロールコマンド受付状態にする end ------------------------------------------- -- ホールドコマンドを受け付けた場合の処理 ------------------------------------------- function OnHOLD_CMD () TraceAI ("OnHOLD_CMD") -- デバッグ文出力 MyDestX = 0 -- 目標x座標をクリア MyDestY = 0 -- 目標y座標をクリア MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MyState = HOLD_CMD_ST -- ホム状態をホールドコマンド受付状態にする end ------------------------------------------- -- 対象指定スキルコマンドを受け付けた場合の処理 -- <引数> level : 使用スキルレベル -- skill : 使用スキル -- id : 対象のキャラクターid ------------------------------------------- function OnSKILL_OBJECT_CMD (level,skill,id) TraceAI ("OnSKILL_OBJECT_CMD") -- デバッグ文出力 MySkillLevel = level -- 使用スキルレベルを指定 MySkill = skill -- 使用スキル MyEnemy = id -- idの敵をターゲットにする MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする end ------------------------------------------- -- 範囲スキルコマンドを受け付けた場合の処理 -- <引数> level : 使用スキルレベル -- skill : 使用スキル -- x : スキル指定x座標 -- y : スキル指定y座標 ------------------------------------------- function OnSKILL_AREA_CMD (level,skill,x,y) TraceAI ("OnSKILL_AREA_CMD") -- デバッグ文出力 Move (MyID,x,y) -- (x,y)座標にホム移動開始 MyDestX = x -- 目標x座標をxにする MyDestY = y -- 目標y座標をyにする MySkillLevel = level -- 使用スキルレベルを指定 MySkill = skill -- 使用スキル MyState = SKILL_AREA_CMD_ST -- 範囲スキルコマンド受付状態にする end ------------------------------------------- -- 追従コマンドを受け付けた場合の処理 ------------------------------------------- function OnFOLLOW_CMD () -- 待機コマンドは、待機状態と追従コマンド受付状態を交互に繰り返す if (MyState ~= FOLLOW_CMD_ST) then -- 追従コマンド受付状態ではないなら MoveToOwner (MyID) -- ケミのところまで移動開始 MyState = FOLLOW_CMD_ST -- 追従コマンド受付状態 MyDestX, MyDestY = GetV (V_POSITION,GetV(V_OWNER,MyID)) -- ケミがいる位置を目標座標にする MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MySkill = 0 -- 使用しようとしているスキルがあったらキャンセル TraceAI ("OnFOLLOW_CMD") -- デバッグ文出力 else -- 追従コマンド受付状態のとき MyState = IDLE_ST -- ホム状態を待機状態にする MyEnemy = 0 MySkill = 0 TraceAI ("FOLLOW_CMD_ST --> IDLE_ST") -- デバッグ文出力 end end ------------------------------------------- -- コマンド入力の振り分け処理 ------------------------------------------- function ProcessCommand (msg) -- ケミの入力が以下のコマンドの時、対応するコマンド受付処理を呼び出す。 if (msg[1] == MOVE_CMD) then -- 移動コマンド OnMOVE_CMD (msg[2],msg[3]) TraceAI ("MOVE_CMD") elseif (msg[1] == STOP_CMD) then -- 停止コマンド OnSTOP_CMD () TraceAI ("STOP_CMD") elseif (msg[1] == ATTACK_OBJECT_CMD) then -- 対象指定攻撃コマンド OnATTACK_OBJECT_CMD (msg[2]) TraceAI ("ATTACK_OBJECT_CMD") elseif (msg[1] == ATTACK_AREA_CMD) then -- 範囲攻撃コマンド OnATTACK_AREA_CMD (msg[2],msg[3]) TraceAI ("ATTACK_AREA_CMD") elseif (msg[1] == PATROL_CMD) then -- パトロールコマンド OnPATROL_CMD (msg[2],msg[3]) TraceAI ("PATROL_CMD") elseif (msg[1] == HOLD_CMD) then -- ホールドコマンド OnHOLD_CMD () TraceAI ("HOLD_CMD") elseif (msg[1] == SKILL_OBJECT_CMD) then -- 対象指定スキルコマンド OnSKILL_OBJECT_CMD (msg[2],msg[3],msg[4],msg[5]) TraceAI ("SKILL_OBJECT_CMD") elseif (msg[1] == SKILL_AREA_CMD) then -- 範囲スキルコマンド OnSKILL_AREA_CMD (msg[2],msg[3],msg[4],msg[5]) TraceAI ("SKILL_AREA_CMD") elseif (msg[1] == FOLLOW_CMD) then -- 追従コマンド OnFOLLOW_CMD () TraceAI ("FOLLOW_CMD") end end -------------- ホム状態ごとの処理 -------------------- ------------------------------------------- -- 待機状態の処理 ------------------------------------------- function OnIDLE_ST () TraceAI ("OnIDLE_ST") local cmd = List.popleft(ResCmdList) if (cmd ~= nil) then -- コマンド入力があれば ProcessCommand (cmd) -- 対応するコマンドの受付処理を行う return end 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 object = GetMyEnemy (MyID) -- ホムの敵のキャラクターidを取得 if (object ~= 0) then -- ホムの敵がいるならば MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする MyEnemy = object -- objectの敵をターゲットにする TraceAI ("IDLE_ST -> CHASE_ST : ATTACKED_IN") return -- 戻る end local distance = GetDistanceFromOwner(MyID) -- ケミとの距離を取得 if ( distance > 3 or distance == -1) then -- ケミまでの距離が距離が3より遠いか視界外ならば MyState = FOLLOW_ST -- ホム状態を追従状態にする TraceAI ("IDLE_ST -> FOLLOW_ST") return; -- 戻る end end ------------------------------------------- -- 追従状態の処理 ------------------------------------------- function OnFOLLOW_ST () TraceAI ("OnFOLLOW_ST") if (GetDistanceFromOwner(MyID) <= 3) then -- ケミとの距離が3以内ならば MyState = IDLE_ST -- ホム状態を待機状態にする TraceAI ("FOLLOW_ST -> IDLW_ST") return; -- ケミとの距離が3以内じゃなくて、ホムのモーションが立ちモーションならば elseif (GetV(V_MOTION,MyID) == MOTION_STAND) then MoveToOwner (MyID) -- ケミのところまで移動開始 TraceAI ("FOLLOW_ST -> FOLLOW_ST") return; end end ------------------------------------------- -- ターゲット追跡状態の処理 ------------------------------------------- function OnCHASE_ST () TraceAI ("OnCHASE_ST") if (true == IsOutOfSight(MyID,MyEnemy)) then -- 敵が視界外に出たならば MyState = IDLE_ST -- ホム状態を待機状態にする MyEnemy = 0 -- タゲにしている敵がいたらタゲ解除 MyDestX, MyDestY = 0,0 -- 目標座標があればクリア TraceAI ("CHASE_ST -> IDLE_ST : ENEMY_OUTSIGHT_IN") return end if (true == IsInAttackSight(MyID,MyEnemy)) then -- 敵が攻撃範囲に入ったら MyState = ATTACK_ST -- ホム状態を攻撃状態にする TraceAI ("CHASE_ST -> ATTACK_ST : ENEMY_INATTACKSIGHT_IN") return end local x, y = GetV (V_POSITION,MyEnemy) -- 敵の座標を取得する if (MyDestX ~= x or MyDestY ~= y) then -- 目標座標に敵がいなければ MyDestX, MyDestY = GetV (V_POSITION,MyEnemy); -- 敵の座標を目標座標にする Move (MyID,MyDestX,MyDestY) -- 敵の座標へ移動開始 TraceAI ("CHASE_ST -> CHASE_ST : DESTCHANGED_IN") return end end ------------------------------------------- -- 攻撃状態の処理 ------------------------------------------- function OnATTACK_ST () TraceAI ("OnATTACK_ST") if (true == IsOutOfSight(MyID,MyEnemy)) then -- 敵が視界外に出た時 MyState = IDLE_ST -- ホム状態を待機状態にする TraceAI ("ATTACK_ST -> IDLE_ST") return end if (MOTION_DEAD == GetV(V_MOTION,MyEnemy)) then -- 敵が死にモーションになったら MyState = IDLE_ST -- ホム状態を待機状態にする TraceAI ("ATTACK_ST -> IDLE_ST") return end if (false == IsInAttackSight(MyID,MyEnemy)) then -- 敵が攻撃視界の外に出た時 MyState = CHASE_ST -- ホム状態を追跡状態にする MyDestX, MyDestY = GetV (V_POSITION,MyEnemy); -- 敵の座標を目標座標にする Move (MyID,MyDestX,MyDestY) -- 敵の座標へ移動開始 TraceAI ("ATTACK_ST -> CHASE_ST : ENEMY_OUTATTACKSIGHT_IN") return end if (MySkill == 0) then -- 使おうとしているスキルがなければ Attack (MyID,MyEnemy) -- 敵を攻撃 else -- 使おうとしているスキルがあれば SkillObject (MyID,MySkillLevel,MySkill,MyEnemy) -- 敵に対して対象指定スキル発動 MySkill = 0 -- 以後使用しようとしているスキルがあればキャンセル end TraceAI ("ATTACK_ST -> ATTACK_ST : ENERGY_RECHARGED_IN") return end ------------------------------------------- -- 移動コマンド受付状態の処理 ------------------------------------------- function OnMOVE_CMD_ST () TraceAI ("OnMOVE_CMD_ST") local x, y = GetV (V_POSITION,MyID) -- ホムの現在座標を取得 if (x == MyDestX and y == MyDestY) then -- 目標座標にいれば MyState = IDLE_ST -- ホム状態を待機状態にする end end ------------------------------------------- -- 停止コマンド受付状態の処理 ------------------------------------------- function OnSTOP_CMD_ST () end ------------------------------------------- -- 対象指定攻撃コマンド受付状態の処理 ------------------------------------------- function OnATTACK_OBJECT_CMD_ST () end ------------------------------------------- -- 範囲攻撃コマンド受付状態の処理 ------------------------------------------- function OnATTACK_AREA_CMD_ST () TraceAI ("OnATTACK_AREA_CMD_ST") local object = GetOwnerEnemy (MyID) -- ケミを攻撃している敵のキャラクターidを取得 if (object == 0) then -- ケミを攻撃している敵がいなければ object = GetMyEnemy (MyID) -- ホムの敵のキャラクターidを取得 end if (object ~= 0) then -- 敵がいれば(ケミが攻撃するまたは攻撃される) MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする MyEnemy = object -- objectの敵をターゲットにする return end local x , y = GetV (V_POSITION,MyID) -- ホムの現在座標を取得 if (x == MyDestX and y == MyDestY) then -- 目標座標にいれば MyState = IDLE_ST -- ホム状態を待機状態にする end end ------------------------------------------- -- パトロールコマンド受付状態の処理 ------------------------------------------- function OnPATROL_CMD_ST () TraceAI ("OnPATROL_CMD_ST") local object = GetOwnerEnemy (MyID) -- ケミを攻撃している敵のキャラクターidを取得 if (object == 0) then -- ケミを攻撃している敵がいなければ object = GetMyEnemy (MyID) -- ホムの敵のキャラクターidを取得 end if (object ~= 0) then -- 敵がいれば MyState = CHASE_ST -- ホム状態をターゲット追跡状態にする MyEnemy = object -- objectの敵をターゲットにする TraceAI ("PATROL_CMD_ST -> CHASE_ST : ATTACKED_IN") return end local x , y = GetV (V_POSITION,MyID) -- ホムの現在座標を取得 if (x == MyDestX and y == MyDestY) then -- 目標座標にいれば MyDestX = MyPatrolX -- パトロール始点座標を新しい目標座標にする MyDestY = MyPatrolY MyPatrolX = x -- 現在位置を新しいパトロール始点座標にする MyPatrolY = y Move (MyID,MyDestX,MyDestY) -- 目標座標へ移動開始 end end ------------------------------------------- -- ホールドコマンド受付状態の処理 -- 敵を順番に攻撃する ------------------------------------------- function OnHOLD_CMD_ST () TraceAI ("OnHOLD_CMD_ST") if (MyEnemy ~= 0) then -- 交戦中の敵がいれば local d = GetDistance(MyEnemy,MyID) -- ホムと敵との距離を取得 -- 敵が視界内にいて攻撃範囲に入っていれば if (d ~= -1 and d <= GetV(V_ATTACKRANGE,MyID)) then Attack (MyID,MyEnemy) -- 敵を攻撃 else -- それ以外ならば MyEnemy = 0; -- 敵をタゲから外す end return -- 戻る end local object = GetOwnerEnemy (MyID) -- ケミを攻撃している敵のキャラクターidを取得 if (object == 0) then -- ケミを攻撃している敵がいなければ object = GetMyEnemy (MyID) -- ホムの敵のキャラクターidを取得 if (object == 0) then -- ホムの敵がいなければ return -- 戻る end end MyEnemy = object -- 取得した敵をタゲにする end ------------------------------------------- -- 対象指定スキルコマンド受付状態の処理 ------------------------------------------- function OnSKILL_OBJECT_CMD_ST () end ------------------------------------------- -- 範囲スキルコマンド受付状態の処理 ------------------------------------------- function OnSKILL_AREA_CMD_ST () TraceAI ("OnSKILL_AREA_CMD_ST") local x , y = GetV (V_POSITION,MyID) -- ホムの現在座標を取得 -- 指定座標が、使おうとしているスキルの射程範囲内ならば if (GetDistance(x,y,MyDestX,MyDestY) <= GetV(V_SKILLATTACKRANGE,MyID,MySkill)) then -- 範囲スキルを発動する SkillGround (MyID,MySkillLevel,MySkill,MyDestX,MyDestY) MyState = IDLE_ST -- ホム状態を待機状態にする MySkill = 0 -- 使用しようとしているスキルがあればキャンセル end end ------------------------------------------- -- 追従コマンド受付状態の処理 ------------------------------------------- function OnFOLLOW_CMD_ST () TraceAI ("OnFOLLOW_CMD_ST") local ownerX, ownerY, myX, myY ownerX, ownerY = GetV (V_POSITION,GetV(V_OWNER,MyID)) -- ケミの座標を取得する myX, myY = GetV (V_POSITION,MyID) -- ホムの座標を取得する local d = GetDistance (ownerX,ownerY,myX,myY) -- ホムとケミとの距離を計算する if ( d <= 3) then -- 距離が3以内ならば return -- 戻る end -- ホムが移動中で移動先がケミから離れていたら、移動をキャンセルしてケミに追従する local motion = GetV (V_MOTION,MyID) if (motion == MOTION_MOVE) then -- 戚疑掻 d = GetDistance (ownerX, ownerY, MyDestX, MyDestY) if ( d > 3) then -- 距離が3より離れていたら MoveToOwner (MyID) -- ケミのところまで移動開始 MyDestX = ownerX -- ケミの座標を目標座標にする MyDestY = ownerY return -- 戻る end else -- 移動中じゃなければ MoveToOwner (MyID) -- ケミのところまで移動開始 MyDestX = ownerX -- ケミの座標を目標座標にする MyaDestY = ownerY return end end ------------------------------------------- -- ケミを攻撃している敵のうち、ホムから一番近い敵のキャラクターidを取得する -- <戻り値> 敵のキャラクターid ------------------------------------------- function GetOwnerEnemy (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 and v ~= myid) then -- ケミかホム自身じゃなければ target = GetV (V_TARGET,v) -- そのキャラクターのタゲを取得 if (target == owner) then -- タゲがケミだったら if (IsMonster(v) == 1) then -- モンスターだったら enemys[index] = v -- 敵のリストに追加 index = index+1 -- インデックスを1増やす else -- モンスターじゃなければ local motion = GetV(V_MOTION,i) -- そのキャラクターのモーションを取得 -- モーションが攻撃モーションだったら if (motion == MOTION_ATTACK or motion == MOTION_ATTACK2) then enemys[index] = v -- 敵のリストに追加 index = index+1 -- インデックスを1増やす end end end end end 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 ------------------------------------------- -- ホムの敵を取得する -- <戻り値> 敵のキャラクターid ------------------------------------------- function GetMyEnemy (myid) local result = 0 -- 敵のキャラクターid local type = GetV (V_HOMUNTYPE,myid) -- ホムのタイプを取得する -- ホムが LIF か AMISTR ならば if (type == LIF or type == LIF_H or type == AMISTR or type == AMISTR_H) then result = GetMyEnemyA (myid) -- 敵取得タイプA(非先攻型) -- ホムが FILIR か VANILMIRTH ならば elseif (type == FILIR or type == FILIR_H or type == VANILMIRTH or type == VANILMIRTH_H) then result = GetMyEnemyB (myid) -- 敵取得タイプB(先攻型) end return result -- ターゲットを返す end ------------------------------------------- -- 敵取得タイプA(非先攻型) ------------------------------------------- function GetMyEnemyA (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 and v ~= myid) then -- ケミかホム自身じゃなければ target = GetV (V_TARGET,v) -- そのキャラクターのタゲを取得 if (target == myid) then -- タゲがホム自身ならば enemys[index] = v -- 敵のリストに追加 index = index+1 -- インデックスを1増やす end end end 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 ------------------------------------------- -- 敵取得タイプB(先攻型) ------------------------------------------- function GetMyEnemyB (myid) local result = 0 -- 敵のキャラクターid local owner = GetV (V_OWNER,myid) -- ケミ自身のキャラクターid local actors = GetActors () -- 周りのキャラクターidを全部取得 local enemys = {} -- 敵のリスト local index = 1 -- インデックス番号(初期値1) local type -- (未使用) -- (1,actors[1])、(2,actors[2])、…のペアを繰り返す -- 周りのキャラクターidをひとつひとつチェックして、そのキャラクターが -- モンスターだったら、敵として敵リストに追加する 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 -- インデックスを1増やす end end end 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 ------------------------------------------- -- ホムンクルスAIメイン処理 ------------------------------------------- function AI(myid) MyID = myid -- ホム自身のキャラクターid local msg = GetMsg (myid) -- ケミが入力したコマンド local rmsg = GetResMsg (myid) -- 先行入力されたコマンド -- コマンドごとの振り分け処理 if msg[1] == NONE_CMD then -- 新規コマンド入力がなければ if rmsg[1] ~= NONE_CMD then -- 先行入力されたコマンドがあれば if List.size(ResCmdList) < 10 then -- 先行入力コマンドが10個未満ならば List.pushright (ResCmdList,rmsg) -- 先行入力コマンドリストに追加 end end else -- 新規コマンド入力があれば List.clear (ResCmdList) -- 先行入力コマンドリストをクリア ProcessCommand (msg) -- ホムのステータスを更新する end -- ホム状態ごとの処理を呼び出す if (MyState == IDLE_ST) then -- 待機状態 OnIDLE_ST () elseif (MyState == CHASE_ST) then -- ターゲット追跡状態 OnCHASE_ST () elseif (MyState == ATTACK_ST) then -- 攻撃状態 OnATTACK_ST () elseif (MyState == FOLLOW_ST) then -- アルケミスト追従状態 OnFOLLOW_ST () elseif (MyState == MOVE_CMD_ST) then -- 移動コマンド受付状態 OnMOVE_CMD_ST () elseif (MyState == STOP_CMD_ST) then -- 停止コマンド受付状態 OnSTOP_CMD_ST () elseif (MyState == ATTACK_OBJECT_CMD_ST) then -- 対象指定攻撃コマンド受付状態 OnATTACK_OBJECT_CMD_ST () elseif (MyState == ATTACK_AREA_CMD_ST) then -- 範囲攻撃コマンド受付状態 OnATTACK_AREA_CMD_ST () elseif (MyState == PATROL_CMD_ST) then -- パトロールコマンド受付状態 OnPATROL_CMD_ST () elseif (MyState == HOLD_CMD_ST) then -- ホールドコマンド受付状態 OnHOLD_CMD_ST () elseif (MyState == SKILL_OBJECT_CMD_ST) then -- 対象指定スキルコマンド受付状態 OnSKILL_OBJECT_CMD_ST () elseif (MyState == SKILL_AREA_CMD_ST) then -- 範囲スキルコマンド受付状態 OnSKILL_AREA_CMD_ST () elseif (MyState == FOLLOW_CMD_ST) then -- 追従コマンド受付状態 OnFOLLOW_CMD_ST () end end