------------------------------------------------------------ -- burnAI Ver1.00 -- 最終更新日:2007/9/17 -- ※タブ幅4に最適化してあります。 ------------------------------------------------------------ require "./AI/additional.lua" -- 追加機能 require "./AI/Const.lua" require "./AI/ignore.lua" -- 無視リスト require "./AI/mobdata.lua" -- 敵データベース require "./AI/search.lua" -- 索敵アルゴリズム require "./AI/setting.lua" -- 設定ファイル require "./AI/Util.lua" -------------------------------------------------- -- 初期設定 -------------------------------------------------- ON = 1 -- 定数(オン) OFF = 0 -- 定数(オフ) YES = 1 -- 定数(イエス) NO = 0 -- 定数(ノー) HOM = 0 -- 定数(ホム) OWNER = 1 -- 定数(ケミ) WaitPosX = 0 --(未使用定数) WaitPosY = 0 --(未使用定数) ------------------------------------------------- -- ホムの状態 ------------------------------------------------- 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 -- 状態切替命令 -------------------------------------------------- -- グローバル変数 -------------------------------------------------- NO_POTION = 0 -- ポーション無しフラグ APP_COUNT = 1 -- ホムへのPP使用回数 APP_OWN_COUNT = 1 -- ケミへのPP使用回数 MC_Place = 0 -- モーションキャンセル位置フラグ FIRSTEXE = 1 -- AI初期設定フラグ FIRSTIDLE = 0 -- IDLE_ST初期設定フラグ -------------------------------------- 以下、GetActor関連の配列変数 Actors = {} -- 全オブジェクトリスト Mobs = {} -- 全Mobリスト Others = {} -- 他キャラリスト Enemys1 = {} -- ケミ攻撃Mobリスト Enemys2 = {} -- ホム攻撃Mobリスト Enemys3 = {} -- 攻撃可能なアクティブMobリスト Enemys4 = {} -- 攻撃可能な全Mobリスト -------------------------------------- 以下、プログラムの時間制御関連の変数 Times = 0 --現在時刻を格納する変数 Borntime = 0 --ホム生成直後を制御する変数 Packtime = 0 --プログラム全体を制御する変数 Acttime = 0 --オブジェクト取得を制御する変数 Getobjtime = 0 --オブジェクト再取得を制御する変数 Skilltime = 0 --ケミのスキル全体を制御する変数 TeletimeA = 0 --索敵テレポートを制御する変数 TeletimeB = 0 --強制テレポートを制御する変数 Exittime = 0 --自動ログアウトを制御する変数 ------------------------------------------------- -- ホムの属性を保存するグローバル変数 ------------------------------------------------- MyID = 0 -- ホム id MyState = BORN_ST -- ホムの状態 HOM_HP = 0 -- ホムPP開始時のHP HomHP = 0 -- ホムの現在HP HomSP = 0 -- ホムの現在SP HomMaxHP = 0 -- ホムの最大HP HomMaxSP = 0 -- ホムの最大SP HomX = 0 -- ホムの現在地 x座標 HomY = 0 -- ホムの現在地 y座標 MyDestX = 0 -- 目的位置 x座標 MyDestY = 0 -- 目的位置 y座標 MyEnemy = 0 -- 敵 id SKL = 0 -- ホムスキル使用判定 MySkill = 0 -- ホムの使用スキル MySkillLevel = 0 -- ホムの使用スキルレベル ATK_RANGE = 2 -- ホムの攻撃レンジ ------------------------------------------------- -- ケミの属性を保存するグローバル変数 ------------------------------------------------- MyOwner = GetV(V_OWNER,MyID) OWN_HP = 0 -- ケミPP開始時のHP OwnHP = 0 -- ケミの現在HP OwnSP = 0 -- ケミの現在SP OwnMaxHP = 0 -- ケミの最大HP OwnMaxSP = 0 -- ケミの最大SP OwnDelay = 0 -- ケミの基本詠唱ディレイ OwnX = 0 -- ケミの現在地 x座標 OwnY = 0 -- ケミの現在地 y座標 TomAtk = 0 -- 初撃トマホーク確認用グローバル変数 FBAtk = 0 -- 火宝剣ボルト確認用グローバル変数 CBAtk = 0 -- 氷宝剣ボルト確認用グローバル変数 ------------------------------------------------- -- 移動命令 (地面をALT+右クリック) ------------------------------------------------- ------------------------------------------------- function OnMOVE_CMD (x,y) MyDestX = x -- 目的位置の x座標を設定 MyDestY = y -- 目的位置の y座標を設定 if math.abs(x-HomX)+math.abs(y-HomY) > 15 then -- 目的地が遠いなら x = math.floor((x+HomX)/2) -- 中間点を仮目的地とする y = math.floor((y+HomY)/2) end Move (MyID,x,y) -- 目的地へ移動する if MyState ~= MOVE_CMD_ST then -- ホムが移動状態でなければ FormerState = MyState -- ホムの状態を保存 end MyState = MOVE_CMD_ST -- ホムを移動命令状態に変更 end ------------------------------------------------- -- 攻撃命令 (対象を ALT+右ダブルクリック or ALT+右クリ2回目) ------------------------------------------------- ------------------------------------------------- function OnATTACK_OBJECT_CMD (id) MyState = CHASE_ST -- ホムをターゲット追跡状態に変更 MyEnemy = id -- ホムの敵を設定 end ------------------------------------------------- -- スキル使用命令 (ホムの対象指定スキル使用) ------------------------------------------------- ------------------------------------------------- function OnSKILL_OBJECT_CMD (level,skill,id) SkillObject (MyID,level,skill,id) -- スキルを使用 if SKILL_ON_ATTACK >= ON then -- スキル命令と同時に攻撃を開始する場合 MyState = CHASE_ST -- ターゲット追跡状態へ MyEnemy = id -- ターゲットに指定 FirstAtk = 0 -- 初弾自動スキルフラグをオフ return -- 抜ける end end ------------------------------------------------- -- 状態切替命令 (ALT+T) -- 索敵状態(先攻型or非先攻型)と非索敵状態(無抵抗状態)を切り替える ------------------------------------------------- ------------------------------------------------- function OnFOLLOW_CMD () if MyState ~= FOLLOW_CMD_ST then -- ホムの状態が索敵状態の時、 Move(MyID,OwnX,OwnY) -- ケミの近くに移動させる MyState = FOLLOW_CMD_ST -- ホムを非索敵状態に変更 MyDestX,MyDestY = OwnX,OwnY -- 目的位置の座標をケミの座標に設定 MyEnemy = 0 -- ホムの敵設定をクリア else -- ホムが非索敵状態の時、 MyState = IDLE_ST -- ホムを索敵状態に変更 MyEnemy = 0 -- ホムの敵設定をクリア end end ------------------------------------------------- -- クライアントからの命令を解釈し、 -- 対応する関数へ渡す関数 -- 予約命令の場合も呼ばれる。 ------------------------------------------------- ------------------------------------------------- function ProcessCommand (msg,ShiftMsg) if (msg[1] == MOVE_CMD) then OnMOVE_CMD (msg[2],msg[3]) -- 移動命令 elseif (msg[1] == ATTACK_OBJECT_CMD) then OnATTACK_OBJECT_CMD (msg[2]) -- 攻撃命令 elseif (msg[1] == SKILL_OBJECT_CMD) then OnSKILL_OBJECT_CMD (msg[2],msg[3],msg[4],msg[5]) -- スキル使用命令 elseif (msg[1] == FOLLOW_CMD) then OnFOLLOW_CMD () -- 状態切替命令 end end ------------------------------------------------- -- ホムンクルス索敵状態 ------------------------------------------------- ------------------------------------------------- function OnIDLE_ST () LvUpCheck() --ホムケミのLvアップを確認 if FIRSTIDLE == 0 then -- 初回待機処理フラグがオフなら MyEnemy = 0 -- ターゲットをリセット MyDestX,MyDestY = HomX,HomY -- ホムの現在地を目的地に設定 FirstAtk = FIRST_SKILL -- 初弾設定を初期化 TomAtk = TOM_FIRST_ATT -- トマホークを初期化 FBAtk = FB_FIRST_ATT -- FB初弾設定を初期化 CBatk = CB_FIRST_ATT -- CB初弾設定を初期化 FIRSTIDLE = 1 -- 初回待機処理フラグをオン end local distance = GetDistanceFromOwner(MyID) -- ホムとケミの距離を得る if FollowMe() then -- ホムとケミの距離離れているなら if GetV(V_MOTION,MyOwner) ~= MOTION_SIT then -- ケミが座っていなければ FormerState = MyState -- ホムの状態を保存 MyState = FOLLOW_ST -- ホムをケミ追従状態に変更して FIRSTIDLE = 0 -- 初回待機処理フラグをオフ return -- 抜ける end end local object = Searching() -- 敵のIDを得る if object ~= 0 then -- 敵がいたら MyState = CHASE_ST -- ホムをターゲット追跡状態にして MyEnemy = object -- 対象をターゲットにして FIRSTIDLE = 0 -- 初回待機処理フラグをオフ return -- 抜ける else -- 敵がいなかったら Teleport(2,0,0) -- 索敵テレポートのチェック end end ------------------------------------------------- -- ケミ追従状態 ------------------------------------------------- ------------------------------------------------- function OnFOLLOW_ST () if false == FollowMe() then -- ケミとホムの距離が指定値以下の場合 MyState = FormerState -- ホムの状態を戻す return -- 抜ける else -- ケミとホムの距離が指定値より遠い場合 Move(MyID,OwnX,OwnY) -- ケミの近くへ移動する return -- 抜ける end end ------------------------------------------------- -- ターゲット追跡状態 ------------------------------------------------- ------------------------------------------------- function OnCHASE_ST () if MobAllCheck(MyEnemy) == false then -- 敵が攻撃可能でないならば MyState = IDLE_ST -- ホムを待機状態にする MyEnemy = 0 -- ターゲットをリセット MoveFlag = 0 MyDestX, MyDestY = HomX,HomY -- ホムの目的位置をクリアする return end if GetDistance2(MyEnemy,MyOwner) > BATTLE_RANGE then --敵が戦闘範囲外なら FormerState = MyState -- 状態を一時保存して MyState = FOLLOW_ST -- ホムを追尾状態にする return end if Times >= Skilltime then -- スキル使用時間なら if TomAtk >= 1 then --初撃トマホークを投げる SkillObject(MyID,1,337,MyEnemy) Skilltime = Times + 100 TomAtk = TomAtk -1 elseif FBAtk >= 1 then --初撃ボルトを投げる SkillObject(MyID,FB_LV,19,MyEnemy) Skilltime = Times + 700*OwnDelay*FB_LV + 800+200*FB_LV FBAtk = 0 elseif CBAtk >= 1 then --初撃ボルトを投げる SkillObject(MyID,CB_LV,14,MyEnemy) Skilltime = Times + 700*OwnDelay*CB_LV + 800+200*CB_LV CBAtk = 0 end end if FirstAtk >= 1 then -- 初弾設定オンなら AutoSkill(MyEnemy) -- 自動スキルを撃つ FirstAtk = 0 -- 初弾設定オフ end if IsInAttackRange(MyID,MyEnemy) then -- 敵がホムの攻撃範囲にいる場合 MoveFlag = 0 -- 移動フラグをリセット MyState = ATTACK_ST -- ホムをターゲット攻撃状態にする return -- 抜ける else -- 敵がホムの攻撃範囲外なら MyDestX, MyDestY = GetV(V_POSITION,MyEnemy) -- 敵の位置をホムの目的位置に設定 if GetDistance2(MyID,MyEnemy) > 15 then -- 敵とホムの距離が15マスより離れていたら MyDestX = math.floor((gotoX+HomX)/2) -- 敵とホムの中間点を目的位置に設定 MyDestY = math.floor((gotoY+HomY)/2) -- 敵とホムの中間点を目的位置に設定 end Move (MyID,MyDestX,MyDestY) -- ホムを敵の位置に移動させる MoveFlag = 1 -- 移動フラグをオン return -- 抜ける end end ------------------------------------------------- -- ターゲット攻撃状態 ------------------------------------------------- ------------------------------------------------- function OnATTACK_ST () if GetV(V_MOTION,MyOwner) == MOTION_ATTACK then -- ケミが攻撃モーションならば local target = GetV(V_TARGET,MyOwner) -- ケミのターゲットを得る if target ~= MyEnemy and target ~= 0 then -- ケミのターゲットがホムのターゲットと異なるなら if IsEnemy(target) then -- ケミのターゲットがモンスターであれば if OWNER_COVER >= ON then -- ケミ援護射撃がオンならば AutoSkill(target) -- ケミのターゲットへ自動スキル end if OWNER_TARGET >= ON then -- ケミのタゲを最優先する場合 MyEnemy = target -- ケミのターゲットをターゲットに設定 MyState = CHASE_ST -- ターゲット追跡状態へ return -- 抜ける end end end end if MobAllCheck(MyEnemy) == false then -- 敵が攻撃可能でないならば MyState = IDLE_ST -- ホムを待機状態にする MyEnemy = 0 -- ターゲットをリセット MoveFlag = 0 MyDestX, MyDestY = HomX,HomY -- ホムの目的位置をクリアする return end if GetDistance2(MyEnemy,MyOwner) > BATTLE_RANGE then -- 敵が索敵範囲外に出た場合 FormerState = MyState -- 状態を一時保存して MyState = FOLLOW_ST -- ケミ追従状態へ return end AutoSkill(MyEnemy) -- 自動スキル使用 if IsInAttackRange(MyID,MyEnemy) == false then -- 敵が攻撃範囲外にいる場合 MyState = CHASE_ST -- 追跡状態へ return end Attack(MyID,MyEnemy) -- 目標を攻撃 MotionCancel() -- 移動でモーションキャンセル end ------------------------------------------------- -- 移動命令状態 ------------------------------------------------- ------------------------------------------------- function OnMOVE_CMD_ST () if HomX == MyDestX and HomY == MyDestY then -- ホムの位置が目的位置である場合 MyState = FormerState -- ホムの状態を戻す else -- ホムが目的地に到着していないなら OnMOVE_CMD (MyDestX,MyDestY) -- 目的地に移動 end end ------------------------------------------------- -- 無抵抗追従状態 ------------------------------------------------- ------------------------------------------------- function OnFOLLOW_CMD_ST () MyEnemy = 0 -- ターゲットをリセット local d = GetDistance (OwnX,OwnY,HomX,HomY) -- ケミとホム待機位置の距離を計算する if d <= WAIT_RANGE then -- ケミとホムの距離が待機距離以下の場合 return -- 抜ける else -- ケミが遠い場合 Move(MyID,OwnX,OwnY) -- ホムをケミの近くに移動させて return -- 抜ける end end ------------------------------------------------- -- 生成状態 ------------------------------------------------- ------------------------------------------------- function OnBORN_ST() if Times >= Borntime then -- 生成時待機タイマーをチェック MyState = IDLE_ST -- 時間になったらホムを索敵状態にして return -- 抜ける end local motion = GetV(V_MOTION,MyOwner) -- ケミのモーションを取得 if motion ~= MOTION_STAND then -- ケミが直立でなければ MyState = IDLE_ST -- ホムを索敵状態にして return -- 抜ける end end ------------------------------------------------- -- メイン補助関数 ------------------------------------------------- ------------------------------------------------- -- 初期設定 function Firstexe(myid) MyID = myid --ホムのIDを取得 MyOwner = GetV(V_OWNER,MyID) --ケミのIDを取得 HomX,HomY = GetV(V_POSITION,MyID) --ホムの生成位置を取得 Move(MyID,HomX,HomY-2) --ホムを初期位置に移動 SKL = SkillSetting() --ホムタイプに合わせてスキルを変更 SettingCover() --設定ファイルの異常を回復する HomMaxHP = GetV(V_MAXHP,MyID) --ホムの最大HPを取得 HomMaxSP = GetV(V_MAXSP,MyID) --ホムの最大SPを取得 OwnMaxHP = GetV(V_MAXHP,MyOwner) --ケミの最大HPを取得 OwnMaxSP = GetV(V_MAXSP,MyOwner) --ケミの最大SPを取得 OwnDEL = 100+OwnDEL --詠唱速度変化を計算 OwnDelay = 1.0 - OwnDEX/150 * OwnDEL/100 --基本詠唱時間を計算 TeletimeA = Times + NoMobtele --索敵テレポート予定時刻を計算 TeletimeB = Times + Mobtele --強制テレポート予定時刻を計算 Exittime = Times + Autoexit --強制ログアウト予定時刻を計算 Borntime = Times + 300 --生成状態解除の時刻を計算 FIRSTEXE = 0 -- 初回処理済フラグをオン end -- 設定ファイルの異常を修正する function SettingCover() if Actclock > 3000 then Actclock = 3000 end -- オブジェクト取得時間を修正 if WAIT_RANGE > 14 then WAIT_RANGE = 14 end -- ケミから離れられる距離を修正 if ATK_PRIORITY2 > 3 then ATK_PRIORITY2 = 2 end -- 索敵順序を修正 if CHE_SEARCH_RANGE < 1 then CHE_SEARCH_RANGE = 1 end if CHE_SEARCH_RANGE > 14 then CHE_SEARCH_RANGE = 14 end if HOM_SEARCH_RANGE < 1 then HOM_SEARCH_RANGE = 1 end if HOM_SEARCH_RANGE > 14 then HOM_SEARCH_RANGE = 14 end if BATTLE_RANGE < 1 then BATTLE_RANGE = 1 end -- 戦闘範囲を修正 if BATTLE_RANGE > 14 then BATTLE_RANGE = 14 end if NEAR_PC_RANGE > 4 then NEAR_PC_RANGE = 4 end if SKILL_SP < 30 then SKILL_SP = 30 end -- スキル使用SPを修正 if SKILL_SPP < 30 then SKILL_SPP = 30 end if OwnDEX < 1 then OwnDEX = 1 end -- スキルディレイを修正 if OwnDEX > 150 then OwnDEX = 150 end if OwnDEL < -30 then OwnDEL = -30 end if OwnDEL > 30 then OwnDEL = 30 end if APP_HP > HomMaxHP then APP_HP = HomMaxHP end -- オートPPのHPが誤っていれば修正 if APP_OWN_HP > OwnMaxHP then APP_OWN_HP = OwnMaxHP end if APP_LV > 4 then APP_LV = 4 end -- オートPPのLvを修正 if APP_OWN_LV > 4 then APP_OWN_LV = 4 end if APP_STOP_COUNT < 2 then APP_STOP_COUNT = 2 end -- PP使用回数を修正 if APP_OWN_STOP_COUNT < 2 then APP_OWN_STOP_COUNT = 2 end -- PP使用回数を修正 if FB_LV > 3 then FB_LV = 3 end -- ボルト系Lvの修正 if CB_LV > 3 then CB_LV = 3 end if ADSL > 10 then ADSL = 10 end -- ADSのLvを修正 if GetobjClock < 1000 then GetobjClock = 1000 end -- テレポートの確認時間を修正 if Mobflood < 2 then Mobflood = 2 end -- テレポートの確認敵数を修正 end -- オブジェクト取得 function GetObjects() List.clear (Actors) --IDリストを初期化 Actors = GetActors() --グローバルID配列を更新 Acttime = Times + Actclock --次の動作時間を記録 if GetobjLv >= 1 then -- 緊急テレポのために確認するなら if Times >= Getobjtime then -- 時間になっていたら Detect() -- 緊急テレポのチェック Getobjtime = Times + GetobjClock --次のオブジェ取得時間を入力 end end end ------------------------------------------------- -- メイン関数 ------------------------------------------------- function AI(myid) if GetTick() <= Packtime then return end --稼動時間までループ Times = GetTick() --現在時間を取得 Packtime = Times + Packclock --次の稼動時間を取得 if FIRSTEXE ~= 0 then Firstexe(myid) end -- AI読み込み時1回だけ行う処理 HomHP,HomSP = GetV(V_HP,MyID),GetV(V_SP,MyID) --ホムの現在HPSPを更新 OwnHP,OwnSP = GetV(V_HP,MyOwner),GetV(V_SP,MyOwner) --ケミの現在HPSPを更新 HomX,HomY = GetV(V_POSITION,MyID) -- ホムの現在地を更新 OwnX,OwnY = GetV(V_POSITION,MyOwner) -- ケミの現在地を更新 if Times >= Acttime then GetObjects() end -- 時間になったらオブジェクトID取得 Teleport(1,0,0) -- 索敵テレポート・ログアウト local msg = GetMsg (myid) -- クライアントからの命令を得る local rmsg = GetResMsg (myid) -- クライアントからの予約命令を得る ProcessCommand (msg,rmsg) -- 命令処理を行う AutoOwnPP() -- ホムへの自動PPチェック AutoHomPP() -- ケミへの自動PPチェック Teleport(0,0,0) -- POT切れならログアウト ---------------------------------------------------------- 状態処理 if MyState == IDLE_ST then OnIDLE_ST () -- 待機状態の処理 end if MyState == CHASE_ST then OnCHASE_ST () -- ターゲット追跡状態の処理 end if MyState == ATTACK_ST then OnATTACK_ST () -- ターゲット攻撃状態の処理 end if MyState == FOLLOW_ST then OnFOLLOW_ST () -- ケミ追従状態の処理 end if MyState == MOVE_CMD_ST then OnMOVE_CMD_ST () -- 移動命令状態の処理 end if MyState == FOLLOW_CMD_ST then OnFOLLOW_CMD_ST () -- 無抵抗状態の処理 end if MyState == BORN_ST then OnBORN_ST() end end