--[[ アミストルオブトゥルーサイト(笑)AI Ver.080413 http://pretty.pc3merchant.net/  自PCのローカルなファイルは削除しました。  今後使う事はありませんのでデバッグなどのサポートはできませんしするつもりもありません。 http://shion00.exblog.jp/7740503/  で晒されたあとチートであるという意見が多いので  チートではない証明のためAIを公開します。 構造化エディタ( http://www008.upp.so-net.ne.jp/momotan/index.html )を使用して編集しています 構造化エディタで開くとファンクション毎に分けて表示されますので 解析作業が楽になりますからお勧めです。 情報表示に showstate_HTA ライブラリの情報表示アプリが必要です。 ライブラリはこのAI自身に埋め込んであるため必要ありません。 showstate_HTA ライブラリ:http://pretty.pc3merchant.net/index.php?e=180 を手動で導入するか、初回AIインストーラで初回AIごと入れてしまうと楽に動きます。 マスターのIDは情報収集用AI:SageOwlを利用して集めました。 SageOwl 0.9 : http://pretty.pc3merchant.net/index.php?e=207 ]] --スキルIDの定義 -- リーフ SKILL_TOUCH_OF_HEAL = 8001 --   癒しの手 SKILL_EMERGENCY_AVOID = 8002 --   緊急回避 SKILL_MENTAL_CHANGE = 8004 --   メンタルチェンジ -- アミストル SKILL_CASTLING = 8005 --   キャスリング SKILL_DEFFENCE = 8006 --   ディフェンス SKILL_BLOOD_LUST = 8008 --   ブラッドラスト -- フィーリル SKILL_MOONLIGHT = 8009 --   ムーンライト SKILL_FLEET_MOVE = 8010 --   フリットムーブ SKILL_OVERED_SPEED = 8011 --   オーバードスピード SKILL_SBR44 = 8012 --   S.B.R.44 -- バニルミルト SKILL_CAPRICE = 8013 --   カプリス SKILL_CHAOTIC_VENEDICTION = 8014 --   カオティックベネットディクション SKILL_BIO_EXPLOSION = 8016 --   バイオエクスプロージョン ------------------------------------------------------------ -- 設定 ------------------------------------------------------------ dif_time = 2000 -- list2の目撃報告間隔[単位 _秒] dif_time2 = 1600 -- list1のハイド報告間隔[単位 _秒] AlertSkill = SKILL_CASTLING -- ハイド炙りスキル(羊) --AlertSkill = SKILL_MOONLIGHT -- ハイド炙りスキル(鳥) --AlertSkill = SKILL_CAPRICE -- ハイド炙りスキル(バニル) --AlertSkill = SKILL_TOUCH_OF_HEAL -- ハイド炙りスキル(リーフ:要赤スリム) --AlertSkill = nil -- ハイド炙り無効 SpellBreak = nil -- EMCの詠唱妨害 -- 羊に攻撃スキルないから実際に使ったことはありません。ちゃんと動作するか不明です。 -- 攻撃スキルを指定しておいてください。 -- 監視対象設定 -- チェイスEMCリスト -- 監視対象が複数みつかった場合は、IDが大きいほうが優先されます。 --xxxxxxxは実際には別AIにて収集したIDが入ります。 targetchar ={ [xxxxxxx]="●●連合 チェイサEMCマスター", [xxxxxxx]="●●連合 チェイサEMCマスター", } -- 発見だけ報告するリスト -- EMC持ち、Bossc持ちなど。 targetchar2 ={ [xxxxxxx]="●●連合 残影 EMCマスター", [xxxxxxx]="●●連合 リンカー EMCマスター", [xxxxxxx]="●●連合 Ax EMCマスター", [xxxxxxx]="金ゴス", } -- 詠唱を報告するリスト targetchar3={ [xxxxxxx]="●●連合 残影 EMCマスター", [xxxxxxx]="●●連合 リンカー EMCマスター", [xxxxxxx]="●●連合 Ax EMCマスター", } -- const (定数) -------------------------------- -- GetV関数のモード指定の引数の定義 -------------------------------- V_OWNER = 0 -- 召喚者の ID V_POSITION = 1 -- 座標 (x、y) V_TYPE = 2 -- タイプ (未実装) V_MOTION = 3 -- 現在の命令 V_ATTACKRANGE = 4 -- 物理攻撃範囲 (未実装。現在は1セルに固定) V_TARGET = 5 -- 攻撃、スキル使用対象の ID V_SKILLATTACKRANGE = 6 -- スキル攻撃範囲 (未実装) V_HOMUNTYPE = 7 -- ホムンクルスの種類 V_HP = 8 -- HP (ホムンクルスと召喚者) V_SP = 9 -- SP (ホムンクルスと召喚者) V_MAXHP = 10 -- 最大 HP (ホムンクルスと召喚者) V_MAXSP = 11 -- 最大 SP (ホムンクルスと召喚者) --------------------------------- ------------------------------------------------- -- GetV(V_MOTION, id)の戻り値(オブジェクトの行動状態) ------------------------------------------------- MOTION_STAND = 0 -- 立っている MOTION_MOVE = 1 -- 移動中 MOTION_ATTACK = 2 -- 攻撃中 MOTION_DEAD = 3 -- 死亡 MOTION_DAMAGED = 4 -- 被弾 MOTION_PICKUP = 5 -- 拾う MOTION_SIT = 6 -- 座っている MOTION_SKILL = 7 -- スキル攻撃中 MOTION_CASTING = 8 -- 詠唱 MOTION_ATTACK2 = 9 -- 攻撃する ------------------------------------------------- ------------------------------------------------- -- GetMsg(id),GetResMsg(id)によって得られる命令番号 ------------------------------------------------- NONE_CMD = 0 -- 命令無し MOVE_CMD = 1 -- 移動 STOP_CMD = 2 -- 停止 ATTACK_OBJECT_CMD = 3 -- 攻撃 ATTACK_AREA_CMD = 4 -- 設置型攻撃 PATROL_CMD = 5 -- パトロール HOLD_CMD = 6 -- 待機 SKILL_OBJECT_CMD = 7 -- スキル使用 SKILL_AREA_CMD = 8 -- 設置型スキル使用 FOLLOW_CMD = 9 -- 状態切替 ------------------------------------------------- -------------------------------- -- スキルデータ -------------------------------- -- 攻城戦用にディレイ1500_秒以下のものは1500_秒に変更してあります SKILL_SP = 1 SKILL_DELAY = 2 SKILL_SUSTAIN = 3 SKILL_NAME = 4 SKILLDATA = {} SKILLDATA[8001] = {} -- ■癒しの手■ディレイ不明 SKILLDATA[8001][1] = {13,1500,0,"癒しの手 Lv.1"} SKILLDATA[8001][2] = {16,1500,0,"癒しの手 Lv.2"} SKILLDATA[8001][3] = {19,1500,0,"癒しの手 Lv.3"} SKILLDATA[8001][4] = {22,1500,0,"癒しの手 Lv.4"} SKILLDATA[8001][5] = {25,1500,0,"癒しの手 Lv.5"} SKILLDATA[8002] = {} -- ■緊急回避 SKILLDATA[8002][1] = {20,35300,40000,"緊急回避 Lv1"} SKILLDATA[8002][2] = {25,35300,35000,"緊急回避 Lv2"} SKILLDATA[8002][3] = {30,35300,30000,"緊急回避 Lv3"} SKILLDATA[8002][4] = {35,35300,25000,"緊急回避 Lv4"} SKILLDATA[8002][5] = {40,35300,20000,"緊急回避 Lv5"} SKILLDATA[8004] = {} -- ■メンタルチェンジ SKILLDATA[8004][1] = {100,600300,60000,"メンタルチェンジ Lv.1"} SKILLDATA[8004][2] = {100,900300,180000,"メンタルチェンジ Lv.2"} SKILLDATA[8004][3] = {100,1200300,300000,"メンタルチェンジ Lv.3"} SKILLDATA[8005] = {} -- ■キャスリング SKILLDATA[8005][1] = {10,1500,0,"キャスリング"} SKILLDATA[8005][2] = {10,1500,0,"キャスリング"} SKILLDATA[8005][3] = {10,1500,0,"キャスリング"} SKILLDATA[8005][4] = {10,1500,0,"キャスリング"} SKILLDATA[8005][5] = {10,1500,0,"キャスリング"} SKILLDATA[8006] = {} -- ■ディフェンス SKILLDATA[8006][1] = {20,30300,40000,"ディフェンス Lv.1"} SKILLDATA[8006][2] = {25,30300,35000,"ディフェンス Lv.2"} SKILLDATA[8006][3] = {30,30300,30000,"ディフェンス Lv.3"} SKILLDATA[8006][4] = {35,30300,25000,"ディフェンス Lv.4"} SKILLDATA[8006][5] = {40,30300,20000,"ディフェンス Lv.5"} SKILLDATA[8008] = {} -- ■ブラッドラスト SKILLDATA[8008][1] = {120,300300,60000,"ブラッドラスト Lv.1"} SKILLDATA[8008][2] = {120,600300,180000,"ブラッドラスト Lv.2"} SKILLDATA[8008][3] = {120,900300,300000,"ブラッドラスト Lv.3"} SKILLDATA[8009] = {} -- ■ムーンライト SKILLDATA[8009][1] = {4,2800,0,"ムーンライト Lv.1"} SKILLDATA[8009][2] = {8,2800,0,"ムーンライト Lv.2"} SKILLDATA[8009][3] = {12,2800,0,"ムーンライト Lv.3"} SKILLDATA[8009][4] = {16,2800,0,"ムーンライト Lv.4"} SKILLDATA[8009][5] = {20,2800,0,"ムーンライト Lv.5"} SKILLDATA[8010] = {} -- ■フリットムーブ SKILLDATA[8010][1] = {30,1500,60000,"フリットムーブ Lv.1"} SKILLDATA[8010][2] = {40,1500,55000,"フリットムーブ Lv.2"} SKILLDATA[8010][3] = {50,1500,50000,"フリットムーブ Lv.3"} SKILLDATA[8010][4] = {60,1500,45000,"フリットムーブ Lv.4"} SKILLDATA[8010][5] = {70,1500,40000,"フリットムーブ Lv.5"} SKILLDATA[8011] = {} -- ■オーバードスピード SKILLDATA[8011][1] = {30,1500,60000,"オーバードスピード Lv.1"} SKILLDATA[8011][2] = {40,1500,55000,"オーバードスピード Lv.2"} SKILLDATA[8011][3] = {50,1500,50000,"オーバードスピード Lv.3"} SKILLDATA[8011][4] = {60,1500,45000,"オーバードスピード Lv.4"} SKILLDATA[8011][5] = {70,1500,40000,"オーバードスピード Lv.5"} SKILLDATA[8012] = {} -- ■S.B.R.44 SKILLDATA[8012][1] = {1,1500,0,"S.B.R.44 Lv.1"} SKILLDATA[8012][2] = {1,1500,0,"S.B.R.44 Lv.2"} SKILLDATA[8012][3] = {1,1500,0,"S.B.R.44 Lv.3"} SKILLDATA[8013] = {} -- ■カプリス SKILLDATA[8013][1] = {22,1500,0,"カプリス Lv.1"} SKILLDATA[8013][2] = {24,1500,0,"カプリス Lv.2"} SKILLDATA[8013][3] = {26,1500,0,"カプリス Lv.3"} SKILLDATA[8013][4] = {28,1600,0,"カプリス Lv.4"} SKILLDATA[8013][5] = {30,1800,0,"カプリス Lv.5"} SKILLDATA[8014] = {} -- ■カオティックベネットディクション SKILLDATA[8014][1] = {40,1500,0,"カオティックベネットディクション Lv.1"} SKILLDATA[8014][2] = {40,1500,0,"カオティックベネットディクション Lv.2"} SKILLDATA[8014][3] = {40,1500,0,"カオティックベネットディクション Lv.3"} SKILLDATA[8014][4] = {40,1500,0,"カオティックベネットディクション Lv.4"} SKILLDATA[8014][5] = {40,1500,0,"カオティックベネットディクション Lv.5"} SKILLDATA[8016] = {} -- ■バイオエクスプロージョン SKILLDATA[8016][1] = {1,1500,0,"バイオエクスプロージョン"} SKILLDATA[8016][2] = {1,1500,0,"バイオエクスプロージョン"} SKILLDATA[8016][3] = {1,1500,0,"バイオエクスプロージョン"} -------------------------------- -- 変数宣言 -------------------------------- -- このグローバル変数どもを片付けたいけど自分の腕じゃ無理だった orz MyID =0 -- ホムのID保存 MyState = 0 -- ホムの状態管理 SkillDelay = GetTick() -- ホムスキルディレイ MyOwner= GetV(V_OWNER,MyID) -- 召喚したアルケミスト(オーナー)を記憶する定数。 local target = -1 -- 監視対象 local tx,ty = -1,-1 -- 監視対象の座標 local rep_time = {} -- 前回報告した時間記録用テーブル local stateCount = 0 -- 状態出力 local USE_BUFF = true; local showstate_buff={} local buffsize = 0; function CreateStatus( state , mode ,writemode) -- ステータス表示実体。 -- 指定された文字列のステータスをユーザーに見せる。 if state~=nil then -- ステータスが mode = mode or 0 -- mode が指定されて無いときは0を代入。 buffsize = buffsize +1 ; showstate_buff[buffsize]={mode,state} TraceAI("set buf[".. mode .."]="..state ,5) if not USE_BUFF then -- バッファモードでないときはそのまま書き込み TraceAI("not USE_BUFF",5) writemode = true end end if writemode and buffsize > 0 then -- 書き込みバッファがある場合で書き込みモードならばファイル作成 local name = "./AI/temp/ShowState/"..string.format("%010d", stateCount + 1 ) local fp = io.open( name, "w") if not fp then return end for k, v in pairs(showstate_buff) do fp:write(string.format( "%s=%s\n",v[1],v[2])) end fp:close() stateCount = stateCount + 1 showstate_buff = {} buffsize = 0; end end function UseSkill(...) --function UseSkill(level,skill,targetID) ----引数の数によって処理を分岐させようとしてた名残。 ------------------------------------------------- --スキル使用関数。 -- 対象指定の攻撃スキル。スキル使用に成功したらtrue、失敗したらfalseする予定なんだけど -- 今のところ戻り値は有効に利用してないし、スキルに失敗してもtrue返すこともある。 ------------------------------------------------- if (GetTick() < SkillDelay) then --スキルディレイ中ならスキル使用しない return false end if ( GetV(V_SP,MyID) < SKILLDATA[arg[2]][arg[1]][SKILL_SP] ) then -- 消費SPより現在SPが少ないなら使用中止。 return false end SkillObject (MyID,arg[1],arg[2],arg[3]) SkillDelay = GetTick() + SKILLDATA[arg[2]][arg[1]][SKILL_DELAY] --ディレイ終了時間を記録 return true end function MsgProc() local msg = GetMsg(MyID) -- クライアントからの命令を得る -- 移動命令 if (msg[1] == MOVE_CMD) then Move (MyID,msg[2],msg[3]) TraceAI ("MOVE_CMD") elseif (msg[1] == ATTACK_OBJECT_CMD) then TraceAI ("ATTACK_OBJECT_CMD") elseif (msg[1] == SKILL_OBJECT_CMD) then TraceAI ("SKILL_OBJECT_CMD") elseif (msg[1] == FOLLOW_CMD) then TraceAI ("FOLLOW_CMD") end end function Search() local actors=GetActors() local now_target = target local watchflag = false for i,v in ipairs(actors) do if targetchar[v] then -- vがターゲットならば watchflag = true if v~=target then target = v if rep_time[v]==nil then rep_time[v]=0 end if (GetTick() - rep_time[v] > dif_time) then CreateStatus(string.format("%s %sを発見。監視対象に設定します。",os.date("%H:%M:%S"),targetchar[v]),dif_time) rep_time[v]=GetTick() end end elseif targetchar2[v] then if rep_time[v]==nil then rep_time[v]=0 end if (GetTick() - rep_time[v] > dif_time) then x,y = GetV(V_POSITION,v) CreateStatus(string.format("%s %sを発見",os.date("%H:%M:%S"),targetchar2[v]),dif_time+500) rep_time[v]=GetTick() end end if targetchar3[v] then if GetV(V_MOTION,v) == MOTION_CASTING then CreateStatus(string.format("==WARNING==%sが詠唱中",targetchar3[v]),dif_time) SpellBreaker(v) end end end if watchflag == false then if target ~= -1 then target = -1 tx,ty = 0,0 CreateStatus("対象なし",0) end end end function WatchTarget() if target == -1 then return end x,y = GetV(V_POSITION,target) if (x== -1 and y==-1) then CreateStatus(string.format("(ハイド中)%s ",targetchar[target]),0) if (GetTick() - rep_time[target] > dif_time2) then Alart(target) rep_time[target]=GetTick() end tx,ty = x,y elseif tx ~= nx or ty ~= ny then CreateStatus(string.format("%s",targetchar[target]),0) tx,ty = x,y end end function SpellBreaker(t) if SpellBreak ~= nil then UseSkill(1,SpellBreak,t) end end function Alert(t) if AlertSkill ~= nil then UseSkill(1,AlertSkill,t) end end function AI(myid) MyID = myid MsgProc() Search() -- 監視 WatchTarget() CreateStatus(nil,nil,true) -- 出力バッファの内容を書き出す。 end CreateStatus( "" , -3 ) -- メッセージビュアーの掃除 CreateStatus( "" , 0 )