文章網址:http://bbs.wow8.org/thread-3845-1-34.html BY 蚊子叮 JASS與C語言很類似,所以在閱讀以下內容之前,首先應該對TRIGGER JASS有著一定的瞭解。 瞭解JASS之後,你將很快的瞭解AI JASS。 AI JASS的概念 最主要的是理解AI線程(Threads)的概念。 線程是什麼? 線程就像TRIGGER的一個循環判斷語句,線程會不停的判斷在線程程序列表內所缺少的元素,並去按照線程的指令排放順序去完成它。 就像碗中的飯,有即吃,有即吃,有即吃,Loop...... 為什麼不用TRIGGER去完成電腦的人工智能呢? 由於使用TRIGGER相比之下可能會消耗大量的內存,所以,最好用AI線程來完成電腦的人工智能。 注意: 線程只針對單個玩家運作。 AI的類型(Melee AI 和 Campaign AI ) Melee AI 對戰AI基本上完全可以利用WORLDEDITOR自帶的AI編輯器(AI Edior)完成 Campaign AI 戰役AI(即「非對戰AI」),可以詳細瞭解以下內容即可製作一般常用的戰役AI 註:戰役AI的用途十分廣泛,完全可以利用其製作生存,3C,TD等類型的地圖,並且免除了不停使用TRIGGER創造單位所帶來的內存洩露。 線程(Threads)和觸發器(Trigger)的區別AI腳本只能使用JASS函數庫common.j和common.ai中的函數和量Trigger腳本只能使用common.j和Blizzard.j中的函數和量線程只應用於AI腳本(AI JASS), 不能用於觸發器腳本(Trigger Jass)觸發器只應用用於觸發器腳本(Trigger Jass),不能用於AI腳本(AI JASS) 通常, 當AI腳本開始運行時只創建一個線程, 創建更多的線程可以用comman.j的本地函數: native StartThread takes code func returns nothing 運行方式的區別在於線程一旦開啟即可自動運轉,觸發器必須調用或者借助事件的發生才可以運行。 調用 call StartThread(function myfunc) 將創建一個從函數myfunc開始執行的線程. 調用 call SleepForever() 使線程永久性的關閉 *每個玩家最多可以擁有6個線程(包括一開始執行的主線程在內,當一個玩家有6個線程數時, 調用StartThread()的語句將被忽略. ) *線程不能回收, 當你為某玩家創建了5個自定義線程, 將無法為該玩家創建更多的線程. *局域性的全局狀態,在同一玩家中的所有線程都共享全局狀態(包括變量). 即是修改某個全局變量, 修改後的值在此玩家的所有線程中都是可見的. *當新線程創建時, 線程立即生效. *當線程讓步執行時, 創建此線程的父線程將繼續執行. 線程在以下的情況讓步執行, 返回父線程 a) 當線程中的操作碼(opcode)超出限制, 線程會自動休眠 1 秒 當線程中用使用 Sleep(n), 線程將休眠 n 秒, 然後繼續執行. 線程在以下情況會中止, 返回父線程 a) 如果 call StartThread(null)中, 線程中止 當線程的主函數返回, 線程中止. (StartThread()中之間調用的函數就是主函數.) c) 當線程中使用沒有聲明的變量, 線程中止. 在使用之前, 變量必須聲明. d) 當線程中出現零為被除數時, 線程中止 e) 線程主函數出現語法錯誤. 注意: 雖然AI腳本可以使用大部分common.j的庫函數, 但有些類型的函數在AI不能正常工作, 如: a) 返回字符串類型(string)的本地函數, 如I2S(), SubString()等 需要以code, trigger, boolexpr 等類型數據為參數的本地函數, 如觸發器函數, 隊列函數(ForGroup, 等) 注意: AI中不可以使用Blizzard.j的函數, 觸發器中也不可以使用common.ai的函數, AI和觸發器都可以使用common.j的函數(當然, 對於AI, 還受上面所說的限制) common.ai和common.j是寫AI時可以調用和參考庫文件, 要研究AI, 先去讀這2個文件.****************************************************************** 3) 跨腳本通訊(Inter-Script Communication) 在遊戲中, 可能會有多個獨立的Jass腳本文件同時運行. 比如在對戰地圖中的遊戲, 運行觸發器腳本文件的同時, 也可能運行了每個電腦玩家的AI腳本文件. 每個腳本文件之間的全局變量不是共享的. 所以, 一個電腦玩家的AI腳本中設置的全局變量不會影響另一個電腦玩家的AI腳本的執行. 觸發器腳本也不可以和AI腳本共享全局變量. 但可以用傳遞命令的方法進行腳本之間的數據交換. 命令由一對數值型數據(integer)組成: 命令值(command value)和數據值(data value). 從觸發器腳本向AI腳本發出通訊命令, 可以使用common.j中定義的以下本地函數: native CommandAI takes player num, integer command, integer data returns nothing 參數: player num //玩家 integer command //命令 integer data //命令數據 常數: //-------------------------------------------------------------------- constant integer M1 = 60 實際上是時間! constant integer M2 = 2*60 constant integer M3 = 3*60 constant integer M4 = 4*60 constant integer M5 = 5*60 constant integer M6 = 6*60 constant integer M7 = 7*60 constant integer M8 = 8*60 constant integer M9 = 9*60 constant integer M10 = 10*60 constant integer M11 = 11*60 constant integer M12 = 12*60 constant integer M13 = 13*60 constant integer M14 = 14*60 constant integer M15 = 15*60 constant integer EASY = 1 constant integer NORMAL = 2 constant integer HARD = 3 constant integer INSANE = 4 // not used constant integer MELEE_NEWBIE = 1 constant integer MELEE_NORMAL = 2 constant integer MELEE_INSANE = 3 constant integer ATTACK_CAPTAIN = 1 constant integer DEFENSE_CAPTAIN = 2 constant integer BOTH_CAPTAINS = 3 constant integer BUILD_UNIT = 1 constant integer BUILD_UPGRADE = 2 constant integer BUILD_EXPAND = 3 constant integer UPKEEP_TIER1 = 50 constant integer UPKEEP_TIER2 = 80 JASS函數庫common.ai的全局變量(可以更改,也可以自行增加,以下內容會經常在AI腳本中使用): player ai_player //AI玩家 integer sleep_seconds //等待時間 integer total_gold = 0 //總計的金錢 integer total_wood = 0 //總計的木材 integer gold_buffer = 0 // usually for potion money integer difficulty = NORMAL //難度,默認為中等難度 integer exp_seen = 0 integer racial_farm = 'hhou' integer hero_id = 'Hamg' //第一個英雄的ID,默認為聖騎士 integer hero_id2 = 'Hmkg' //第二個英雄的ID,默認為山丘之王 integer hero_id3 = 'Hpal' //第三個英雄的ID,默認為大法 integer array skill integer array skills1 integer array skills2 integer array skills3 integer max_hero_level = 0 integer array harass_qty integer array harass_max integer array harass_units integer harass_length = 0 防守單位的全局變量 例子:防守單位defense_units[defense_length]的數量為defense_qty[defense_length] integer array defense_qty //設置防守單位的數量 integer array defense_units //設置防守的單位 integer defense_length = 0 //單位Index 建造的全局變量 為了區分建造的種類,BLZ為建造的全局變量設置了4類例子:建造單位build_type[build_length]的數量為build_qty[build_length] integer array build_qty //建造的數量 設置建造單位的數量 integer array build_type //建造的種類 普通單位類(包括單位和建築) integer array build_item //購買物品的種類 物品類 integer array build_town //建造基地的種類 基地類 integer build_length = 0 設置採集工人的數量 integer campaign_gold_peons = 5 //主基地採集金子的人數 integer campaign_wood_peons = 3 //住基地採集木材的人數 integer campaign_basics_speed = 5 integer min_creeps = -1 integer max_creeps = -1 遊戲初試設置的全局變量 boolean harvest_town1 = true boolean harvest_town2 = true boolean harvest_town3 = true boolean do_campaign_farms = true //自動製造戰役AI 提供人口的建築 boolean two_heroes = false //雙英雄 boolean allow_air_creeps = false //空中的中立單位(假如有,AI會針對性的發展) boolean take_exp = false //< 一般戰役AI常用函數 CampaignAI takes integer farms, code heroes returns nothing 是BLZ在COMMON.AI中設置的一個簡便函數,直接初始化戰役AI farms - 提供AI玩家人口的建築類型 heroes - 指向設置英雄的ID的CODE SetReplacements takes integer easy, integer med, integer hard returns nothing 尚未研究的函數,一般用法為: call SetReplacement( 2, 2, 4 ) easy - 遊戲難度為簡單所賦的值 med - 遊戲難度為普通所賦的值 hard - 遊戲難度為困難所賦的值 native SetCaptainHome takes integer which, real x, real y returns nothing 設置攻擊組隊長在家的點? which - 什麼的聚集點,參數有: constant integer ATTACK_CAPTAIN = 1 進攻的點 constant integer DEFENSE_CAPTAIN = 2 防禦的點 constant integer BOTH_CAPTAINS = 3 進攻和防禦的點 x - X坐標 Y - Y坐標 SetBuildUnit takes integer qty, integer unitid returns nothing 指令AI玩家製造(所有類型的建造,包括升級) qty - 數量 unitid - 單位類型 SetBuildUnitEx takes integer easy, integer med, integer hard, integer unitid returns nothing 指令AI玩家製造單位按照遊戲難度 easy - 簡單時候的數量 med - 普通時候的數量 hard - 困難時候的數量 unitid - 單位類型 CampaignDefender takes integer level, integer qty, integer unitid returns nothing 設置防守單位的數量 CampaignDefenderEx takes integer easy, integer med, integer hard, integer unitid returns nothing 設置防守單位的數量, 按難度 call WaitForSignal() 等待TRIGGER發出AI指令,當堆積的指令數量不等於0時,繼續進行AI線程 進攻組的指令 function InitAssaultGroup takes nothing returns nothing 初始化進攻組,設置全局變量harass_length = 0 CampaignAttacker takes integer level, integer qty, integer unitid returns nothing 增加進攻組的進攻單位 qty - 數量 unitid - 單位類型 CampaignAttackerEx takes integer easy, integer med, integer hard, integer unitid returns nothing 增加進攻組的進攻單位,按遊戲難度 easy - 簡單時候的數量 med - 普通時候的數量 hard - 困難時候的數量 unitid - 單位類型 SuicideOnPoint takes integer seconds, player p, integer x, integer y returns nothing 設置進攻的玩家的點seconds 發起進攻等待的時間, 常量參數有 constant integer M1 = 60 constant integer M2 = 260 constant integer M3 = 360 constant integer M4 = 460 constant integer M5 = 560 constant integer M6 = 660 constant integer M7 = 760 constant integer M8 = 860 constant integer M9 = 960 constant integer M10 = 1060 constant integer M11 = 1160 constant integer M12 = 1260 constant integer M13 = 1360 constant integer M14 = 1460 constant integer M15 = 1560 p - 目標玩家 SuicideOnUnits takes integer seconds, player p returns nothing 設置進攻的目標玩家seconds 一般戰役AI的製作方案 參看BLZ在戰役中所製作的AI腳本「n08_green.ai」來瞭解怎麼製作AI //變量 進攻的目標玩家 globals player user = Player(1) endglobals function main takes nothing returns nothing //AI初試設置 call CampaignAI(ZIGGURAT_1,null) call SetReplacements(2,2,4) call SetCaptainHome(ATTACK_CAPTAIN,4161,-4668 ) call SetCaptainHome(DEFENSE_CAPTAIN,5218,-6441 ) set campaign_wood_peons = 2 //需要建造的建築以及單位 call SetBuildUnit( 1, NECROPOLIS_1 ) call SetBuildUnit( 1, ACOLYTE ) call SetBuildUnit( 1, UNDEAD_MINE ) call SetBuildUnit( 1, GRAVEYARD ) call SetBuildUnit( 8, ZIGGURAT_1 ) call SetBuildUnit( 2, CRYPT ) call SetBuildUnit( 1, UNDEAD_ALTAR ) call SetBuildUnit( 1, NECROPOLIS_2 ) call SetBuildUnit( 2, SLAUGHTERHOUSE ) call SetBuildUnit( 1, DAMNED_TEMPLE ) call SetBuildUnit( 1, NECROPOLIS_3 ) call SetBuildUnit( 2, BONEYARD ) call SetBuildUnit( 5, ACOLYTE ) call SetBuildUnit( 8, ZIGGURAT_2 ) //防守單位 call CampaignDefenderEx( 1,1,2, ABOMINATION ) call CampaignDefenderEx( 1,1,1, GARGOYLE ) call CampaignDefenderEx( 1,1,1, FROST_WYRM ) call CampaignDefenderEx( 1,1,1, CRYPT_FIEND ) call CampaignDefenderEx( 1,1,1, DREAD_LORD ) //TRIGGER發出指令就開始進行下面的AI進程 call WaitForSignal() //進攻,製造 //WAVE 1 call InitAssaultGroup() call CampaignAttackerEx( 6,6,8, GARGOYLE ) call SuicideOnPlayerEx(M5,M5,M3,user) call SetBuildUpgrEx( 1,1,1, UPG_FIEND_WEB ) call SetBuildUpgrEx( 1,1,1, UPG_CANNIBALIZE ) call SetBuildUpgrEx( 1,1,1, UPG_UNHOLY_STR ) call SetBuildUpgrEx( 1,1,1, UPG_CR_ATTACK ) //WAVE 2 call InitAssaultGroup() call CampaignAttackerEx( 6,6,8, GARGOYLE ) call CampaignAttackerEx( 2,2,4, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, FROST_WYRM ) call SuicideOnPlayerEx(M6,M6,M4,user) //WAVE 3 call InitAssaultGroup() call CampaignAttackerEx( 6,6,8, GARGOYLE ) call CampaignAttackerEx( 2,2,4, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, FROST_WYRM ) call CampaignAttackerEx( 1,1,1, DREAD_LORD ) call SuicideOnPlayerEx(M6,M6,M4,user) call SetBuildUpgrEx( 2,2,2, UPG_UNHOLY_STR ) call SetBuildUpgrEx( 2,2,2, UPG_CR_ATTACK ) call SetBuildUpgrEx( 1,1,1, UPG_SKEL_LIFE ) call SetBuildUpgrEx( 1,1,1, UPG_WYRM_BREATH ) //WAVE 4 call InitAssaultGroup() call CampaignAttackerEx( 2,2,3, GARGOYLE ) call CampaignAttackerEx( 5,5,6, CRYPT_FIEND ) call CampaignAttackerEx( 1,1,2, |
暴雪英霸是未來很看好的遊戲! 站長最近都玩 英雄聯盟 或 Mstar 。 以前站長擅長幫熱門的 魔獸3 地圖加入 AI, 可以和電腦英雄對戰,電腦懂的和人對話。
##EasyReadMore##
2009年12月22日 星期二
[轉帖][WE JASS] AI腳本初級教程
2009年12月21日 星期一
某ai編輯器教程
文章網址:http://bbs.wow8.org/thread-112964-1-8.html 開始一個簡單的人工智能 其實這東西本來是隨便看看的。。。 。。。但是沒想到人家把1大段翻譯出那麼多拉。。。所以就全部中文上來吧 MB下 u9翻譯組的米小粒姐姐55 由於很多都是自己翻+猜譯的所以完全不保證準確率。 不過也沒啥技術含量。。。用來做ai編輯器的入門吧 By moyack 來源:http://www.wc3c.net/showthread.php?t=92915 導言 由於被人要求,我決定開始AI編輯器的教程。我會盡我所能,使之盡可能容易,反正如果您有任何問題,我會在這裡回答。 本文將參考此教程:http://www.wc3c.net/showthread.php?t=89199 開始吧。 進入AI編輯器 要啟動AI編輯器,你需要打開WE並且按F8或點上方的AI編輯器按鈕。這個編輯器並不像觸發或物體編輯器需要一個編輯中的地圖,相反,你用AI編輯器創建,編輯的AI是獨立於地圖的。但是,如果你正在編輯一個地圖,你可以注入地圖的信息,使AI可以使用你的自定義單位。此選項將隨後解釋。 當你打開AI編輯器以後你會看到界面: AI編輯器-普通標籤 此界面顯示了普通標籤的內容,我們將用它來設置基本的智能和全局條件。當然我們希望盡快開始我們的AI,恩。。。我們先要建立的基本框架。 首先,我們需要確定要做什麼樣的AI。如果我們要作出自定義地圖AI,我們應該選擇在對戰中各自的種族組合,或自定義。如果我們選擇普通的對戰,我們將無法使用其他地圖的單位。在另一方面,自定義AI輸入使我們能夠選擇有任何單位設置的物體編輯器。 開始一個新AI 學習的過程中,模仿典例是個很好的開端,所以我們來倣傚一個著名的人類戰術:女巫流。這個戰術靠的是快速升2本生產女巫,接著升3本訓練大師級,然後這個戰術就無敵了()。那麼我們需要什麼呢?除了女巫,還需要一些兵營出的單位:1.主要是一本時期的步兵,三本的時候可以換成騎士 2.迫擊炮小隊,作為攻城的主力 3.一些特殊的兵種比如牧師 4.一個對部隊有用的英雄,在這種情況下就是有水元素以及輝煌光環的大法了。我見過幾次這種戰術第二英雄出血法的(因為能提供傷害和減速),所以我會加到這個戰術裡。 我們的第一次~ 現在已經確定戰術了,在普通標籤裡我選了人族,然後給AI起名為「綿羊控」。這些設置好了,我們直接來到建築標籤。 我們看到了什麼?主要由兩個相似的界面組成,左邊是用來定義建築列表的,右邊用來定義採集資源列表。 建築標籤 為什麼被稱作建築列表?那是什麼東西? AI會按照列表的順序來依次建造單位,但是如果之前的單位或者建築被KO了,AI會根據列表順序重新補上那個被KO的單位。 既然知道了列表這個概念是怎樣運作的,我們開始往表裡加一些單位。如你所見,列表裡預先給出了主基地和5個農民,這幾個單位是遊戲開始就有的,有了他們我們就能造建築了。首先,我們要造兵營,農場和國王祭壇。於是我們選擇列表裡最後一個單位,鼠標右擊,出現了一個有很多選項的菜單。我們選添加設置,然後彈出一個單位類型的對話框 增加新建造單位 單位類型對話框 這裡有兩個部分: 城鎮:在這裡選擇在哪個主基地造建築或單位。選項分別是:任何(默認的,建議這個),主基地(出生點的那個),分基地#(有基地的礦點),金礦#(指的是那個礦,不一定要有基地) 建造:在這裡選要訓練(建造)什麼單位。選項分別是:第一英雄,第二英雄,第三英雄(這個稍後解釋),分基地,指定的單位和指定升級 在例子裡,我們要讓AI造一個兵營,然後一個農場,然後國王祭壇,然後我們就必須讓AI再造幾個農民,讓他們伐木。於是我們選擇城鎮為任何,選擇建造為指定單位,然後選擇兵營,點確定。用同樣的方式設置好其它的建築和單位。 我們的第一個建築 如你所見,我們想造個單位或者升級就必須把這些做一遍。問題是,有沒有更快的方式?答案當然是有。以農民為例,我只選最後一個農民,然後按CTRL+C(或者右擊選複製),然後按CTRL+V複製。做十遍就有10個農民了。 現在我看看你做的對不對。如果你加了10個農民,你會看見一樣的顯示,但是如果你粘貼了十次(或者更多,比如18個~牙哈哈哈 ),你就會顯示那樣 加入農民直到10個 生產農民超過了人口上限 如你所見,最後一個農民顯示為紅色,為什麼?因為界面指示說現在的食物上限不夠生產這個單位了,如果你讓這個列表在這個單位之前去造提供食物的建築,他就會重新被標記為黑色。 因為我們在這個時期不需要那麼多農民,我們刪掉一些,10個就夠了。之後我們擴張的時候會增加更多的農民。 OK,我想是時候給AI增加攻擊性單位了,讓我們增加3個步兵和第一英雄吧。首先增加一個農場,然後右擊列表裡最後一個單位,選擇添加設置,在單位設置對話框裡選擇建造為第一英雄,然後點進去。在那之後增加步兵,我建議三個就夠了。做完了以後,全列表應該看上去像那樣。 AI的第一個戰鬥單位 我們的第一次測試 有了這個小的進展,我們可以測試這個AI了。你可以按CTRL + F9或測試按鈕。在人工智能的編輯對話框。此命令默認用我們的AI運行掠奪島地圖。當AI啟動時,你會看到序列的建設進程: 首先將開始兵營,然後一個農場,然後再國王祭壇。好。 基地不會訓練任何農民,直到它已開始之前的所有建築物(按優先次序),一旦國王祭壇開始建造,AI就會造農民。這種情況可能不利於AI,因為是時間浪費很大,AI可以在這時可以訓練軍隊。我們稍後會討論如何解決這個問題。 國王祭壇完成後,AI開始訓練一個隨機英雄。 當英雄的培訓時,它會嘗試開新的基地。如果AI不能戰勝敵人,它會撤退,並等待戰鬥力恢復,之後它將再試一次,再次,再次,再次,直到打敗這一目標(然後去打下一個 )。 現在,我們必須解決幾個問題:我們應該如何控制隨機選擇一個英雄,並控制英雄學習技能? ?如何消除這些「時間死區」 ,使AI更快的培訓單位/建築? ?如何控制AI的進攻? ?正如Spellbreaker所說:觀賞和學習。 英雄設置 眾所周知,在WC3的英雄是一個非常重要的組成部分,一張地圖,他們的技能和屬性使它們獨一無二,影響了整個遊戲是好還是壞。英雄在遊戲中的效果取決於以下因素: 英雄的選擇和次序(英雄的培訓有三個) 所有英雄的技能選擇 對於AI而言,英雄有其他的作用:他們是攻擊隊伍的首領。如果沒有AI英雄,有很多時候AI不會攻擊而是保持不動,直到它被攻擊(不包括相關的反應)。 現在,我們瞭解英雄的AI設置是如何重要了,我們要檢查英雄的界面。選擇英雄標籤,你會看到這個 : 英雄標籤 列舉下這些選項的作用: 「使用英雄」選項,在這裡選到的英雄可以被AI培訓。 「訓練命令」部分,我們有不同的英雄組合,我們可以設置每種組合在遊戲中出現的概率大小。 最終在「技能選擇」一節,我們確定其中英雄技能的學習順序。如你所見,每個英雄的技能,可以根據不同的等級學習,一目瞭然。 現在,我們如何才能配置出我們想要的例子?你記得,我們只需要2個英雄。我們可以將指定的使用英雄一節的第三英雄設置成無。當你這麼做,編輯器會自動禁用某些選項(很方便 )。在那之後,選擇在第一英雄大法師,第二英雄血法師。然後設定100 %機會讓AI先訓練大法師,然後血法師。你會發現第二個選項(第一血法第二大法的順序 )自動設置為0 %了。現在的界面看起來應該 : -設置英雄的例子第1步 最後我們確定每個英雄的技能學習順序。選擇英雄:選擇框的英雄(大法),我們要修改的技能順序,使用選擇和修改其位置的上移和下移按鈕。例如對我們的AI例子,我將修改大法師的技能順序,如: 設置英雄的例子第2步 在這種情況下,我認為血法師的技能順序還不錯,但如果你想改變它們也可以繼續 現在,我們知道如何為我們的AI設置英雄了,我們還要處理其他重要的AI編輯功能:條件句。 條件 條件句是AI編輯器中最重要的功能之一。它們可以用來幫助人工智能採取正確的決定,根據情況在某些時候,更「聰明」 。 在哪裡可以套用條件?它們可用於: 普通選項卡: 條件 建築標籤: 建造列表 採集列表 攻擊標籤: 當前單位組 目標設置 如何在句子中添加條件?"只要選擇所需的項目,並用鼠標右鍵單擊它,你會看到修改條件... 選項。當你點擊它,你會看到對話框。 有條件的菜單 條件對話框 設置條件對話框,默認情況下,此對話框中設置為無。要創建一個新的條件,我們必須單擊列表框,並選擇自定義,這將使設置條件按鈕變得可點擊。現在,你可以按下它,一個新的對話框出現。在這你可能覺得有點熟悉,它的類似於觸發編輯器的條件選擇,唯一的區別是什麼樣的數據比較,你可以選擇它。比較分為: 設置條件對話框 布爾值比較 整數比較 And 和 Or 或 最後二種比較And和Or,可以連接兩個比較,所以用他們組合你能夠製作出比較複雜的條件。完整的條件類別可以參考Av3n的AI編輯教程。 我認為這是時候為我們的例子增加條件了。以前,系統直到已建立10個農民和一個農場後才會製造第一英雄,如你所見,把AI等到這是浪費時間,如果一旦祭壇國王建立,我們的英雄就開始訓練會更好。因此,我們必須改變英雄在列表的位置在第六個農民以前。但是如果我們就這樣完了,其他5農民將無法訓練,直到英雄開始在國王祭壇上訓練。所以我們要設置AI一旦國王祭壇建設完成後就訓練第一英雄,如果還沒,它將跳過英雄先建造其他單位和建築物。 首先,我們必須把第一英雄的順序放在祭壇之後,然後我們選中它,用鼠標右鍵單擊這個選項並修改條件... 在選擇條件以後,我們改變條件列表框到自定義。我們會看到,按鈕設置條件已啟用。 在「設置條件」的彈出窗口上在這一點,我們選擇整數 ,我們會看到一個文本鏈接顯示0 等於 0 。我們點擊第一個0 。 用點開整數對話框時,我們瀏覽下整數的選擇項目,選擇單位-已完成單位總數然後按確定。 現在我們已經選擇了判斷的項目,我們必須確定用來判斷的單位類型。在這種情況下,我們要檢查國王祭壇的個數。我們點鏈接文字,這將打開此窗口。 好了,我們選定了單位類型,我們將看到填充後的對話框。在這之後按確定。就有了這個我們所要的第一個比較元素。 現在讓我們來確定比較操作符。選擇操作符的連接。打開此對話框。再選擇適當的比較操作符(在此情況下選大於),確定~ 因為我們需要做的比較大於0 就可以了,所以我們沒有修改第二個對比對象的價值。但是,如果你需要更改該值,只需按一下並改變他的值就好。設定完了條件按確定。 恭喜!你的第一個條件完成了!現在是時候將它保存了,所以請條件對話框按下確定吧。 . . |
2009年12月19日 星期六
[教程] 禁止AI的技能對小兵釋放
文章網址:http://bbs.wow8.org/thread-114679-1-5.html 我就是不懂如何讓AI不隨便放技能和讓AI主動優先攻擊敵對英雄。。。。。。 一般來看限制放技能似乎主要用的是,不給予單位此技能,等觸發條件滿足後用觸發給予技能,用完了再刪除技能。。。 主動優先攻擊敵對英雄不是很好嗎為什麼不要 像諸葛那G 他是只要判斷是對小兵還是英雄 是英雄就無做用 是小兵可以判斷他的魔法值再讓他放 。至於那冰 電腦是不會亂放 大也是 那麼就只要禁止一個變天的技能就可以了... 上面說的那附件 被全JASS化了 我調試發現了許多錯誤 所以沒發 。 用其它的發個算了 。 wonder 的ai中將自己的英雄交給電腦控制後,物品全部不可用,技能消失.... 玩家控制電腦 物品不可以用好做 技能不能釋放還是好做 但像樓主所說 隱藏 我還沒試驗 ==去看一下 自己摸索出來 再發個演示吧 畢竟本人說了有問就答.. 一般來看限制放技能似乎主要用的是,不給予單位此技能,等觸發條件滿足後用觸發給予技能,用完了再刪除技能。。。 好笑的原因是這樣會把CD 刷新 難道你要靠許多變量 來記錄時間? 其實wonder 的ai中將自己的英雄交給電腦控制後,物品全部不可用,技能消失.... 是用禁用某項技能來完成的。 (物品禁用沒做出來! ) 禁用技能和刪除技能的本質原理是一樣的,不讓單位的ai認為這個技能存在 禁用可以自己保持cd,而刪除則可以應用到多英雄的場面 對於刪除的cd控制,如果用jass就是一個timer到期開啟某觸發的技能判定,用了關閉之類 兩種動作可以隨自己需要選擇 而在單位發出命令的一刻命令停止,在活動頻繁的區域中資源消耗相對較高,技能的系統ai判定分多種,其中被攻擊,每間隔時間的響應是較頻繁的,命令單位做動作,這個動作也最好不要太密集,當然這個很方便 物品禁用沒想出什麼方便的 使用「禁用」動作不能禁止物品的技能,而在英雄獲得物品後找到物品對應的技能刪除之那麼物品就無法使用了(系統資源是怎麼算的就不知道了) 不習慣JASS 物品禁用不了 剛也試了 那確實 只能用刪除 用MH (全圖) 進 wonder 的真三 和DOTA發現他們 和我的想法一樣 用的是禁用技能。。。 至於wonder 裡面的物品不能用 那是馬甲 物品 我自己買的紅 可以用他事先買的失效了而且無法重疊.. 關於禁止的好還是刪除的好 禁止方便些 懶得去計下那煩人的CD..... 話說樓主會DOTA的3條路線移動嗎 就是逃跑的時候隨機路線逃跑啊 你搞個隨機(整數 ,實數)數 去就行了 其實要看什麼情況 具體很難說清楚 要多設置些觸發才行 你像 如果單位在上路(真三) 距離兵營處 被打成紅血 而觸發要求他回生命之泉那麼他就會 選擇最近的路線 有可能就跑從 上路那口子跑到中路再回去了。 一時也說不清 反正這問題是做AI最基本的了。 這個沒必要做 演示了。 就是命令單位再多少血的時候移動 你搞三條線 難道你還要單位從上路跑到下路再回家?。。。 學習了,看了樓主的演示終於明白我錯誤在哪了。範圍技能和指定目標技能OK了,但那些無目標技能如何禁止對小兵施放呢?如:狂戰、戰爭踐踏等。 你之前做的真三AI T演示裡,英雄會頂兵,還有不會根據周圍小兵情況進或退。樓主可以再出這兩方面的演示麼? 對小兵禁止施法和我做的一樣,都是命令停止,但這樣有很大的弊端。就是如果是範圍技能,如暴風雪、火焰雨,當對英雄施放時,旁邊有一個小兵就會被命令停止了。。。(你的條件錯了)/這...是最簡單的. 但效率很低... 再判斷電腦學習技能的時候 禁用他的技能.. 然後用條件判斷什麼時候該放此技能在 設置該技能狀態為允許放完後再禁用 照我看這是又簡便又是有效率最好的了。 不要亂說啊 電腦遇到敵人很多自然會退走 如果兵的數量不大於2個 電腦是會頂著打(這個你可以自己設置) 目前是發現下路徘迴BUG 沒有其它的了 我特意把 撤退和小兵畏懼 AI 分開了 我也學到點東西了 可AI連擊還是不太行 你以前發的AI連擊演示我決定只適合在地圖上已有的單位 還沒有在地圖上的單位怎麼配和連擊還不是太清楚 額,的確,那演示我只是選地圖上的單位。那至於地圖上沒出現,需要選擇出的英雄,那用變量吧。用 單位類型 數組賦值。 悲劇啊,AI連技我在正式圖裡也不好使。你在真三圖裡試過了嗎?按照樓主的禁止對小兵施放技能,司馬會一直S。 用變量可以,不過好麻煩啊 我沒試過真三 我在隋唐裡面試的 LZ的禁止還不錯吧 就是AI萎縮不怎麼強大 無論近戰的還是遠戰的都很好殺AI 要是能做到跟真三AI萎縮差不多那就好了。 |
2009年12月13日 星期日
基於神經網絡的人機對抗人工智能系統 part3
|
基於神經網絡的人機對抗人工智能系統 part3 文章網址:http://www.playdota.com/forums/2597/22522-20110-31070-32463-32593-32476-30340-20154-26426-23545-25239-20154-24037-26234-33021-31995-32479-65288-29702-35770-65289-a/ 附錄 目前整個系統已完成控制系統,和巡查系統部分功能。 已經完成的DOTA AI代碼如下(JASS語言,以DOTA 6.59為基礎): Code: globals boolean AI_Start=false integer UNIT_GROUP_MAX_LIMIT=20 integer HERO_GROUP_MAX_LIMIT=4 integer ORDER_SEQUENCE_MAX_LIMIT=10 integer AIPlayer_Count=0 real AIPlayer_TimeScale=0.5 real AIPlayer_TimeSize=2 trigger AIPlayer_Respond_Trigger trigger AIPlayer_Trigger integer NONE=0 integer UNLIMITED=-10 integer AGGRESSIVE=1 integer WATCHFULNESS=2 integer FARM=3 integer RESPONSIVE=4 integer COMPREHENSIVENESS=5 integer SENTINEL=1 integer SCOURGE=2 integer NEUTRAL=3 integer NEUTRALCREEP=4 integer NEUTRALSHOP=5 integer PLACE=6 integer ENTRANCE=7 integer RIVERWAY=8 integer FOUNTAIN=9 integer ROSHAN=10 integer POWERUP=11 integer CREEPMEETING=12 integer TOPLANE=13 integer MIDDLELANE=14 integer BOTTOMLANE=15 integer CROSSING=16 integer RIGHTCLICK=851971 integer STOP=851972 integer DISABLED=851973 integer ATTACK=851983 integer PATROL=851990 integer HOLD=851993 integer WAIT=1 integer FARMCREEPTO=2 integer FARMNEUTRALTO=3 integer MOVETO=4 integer ATTACKTO=5 integer SPELLTO=6 integer GANKTO=7 integer MIDDLE=1 integer LEFT=2 integer RIGHT=3 integer TOP=4 integer BOTTOM=5 boolean array Sentinel_AIPlayer_AI player array Sentinel_AIPlayer_PlayerHandle real array Sentinel_AIPlayer_Coefficient_Aggressive real array Sentinel_AIPlayer_Coefficient_Watchfulness real array Sentinel_AIPlayer_Coefficient_Farm real array Sentinel_AIPlayer_Coefficient_Responsive real array Sentinel_AIPlayer_Coefficient_Comprehensiveness integer Sentinel_AIPlayer_Captian group array Sentinel_AIPlayer_UnitGroup location array Sentinel_AIPlayer_UnitLastLoc integer array Sentinel_AIPlayer_UnitGroup_Count integer array Sentinel_AIPlayer_UnitGroup_Sequence_Count integer array Sentinel_AIPlayer_UnitGroup_Order_Sequence unit array Sentinel_AIPlayer_UnitGroup_TargetUnit_Sequence location array Sentinel_AIPlayer_UnitGroup_TargetLoc_Sequence real array Sentinel_AIPlayer_UnitGroup_Order_Sequence_Timer integer array Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe integer array Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe_Target group array Sentinel_AIPlayer_HeroGroup location array Sentinel_AIPlayer_HeroLastLoc integer array Sentinel_AIPlayer_HeroGroup_Count integer array Sentinel_AIPlayer_HeroGroup_Sequence_Count integer array Sentinel_AIPlayer_HeroGroup_Order_Sequence unit array Sentinel_AIPlayer_HeroGroup_TargetUnit_Sequence location array Sentinel_AIPlayer_HeroGroup_TargetLoc_Sequence real array Sentinel_AIPlayer_HeroGroup_Order_Sequence_Timer integer array Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe integer array Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe_Target group array Sentinel_AIPlayer_Nearby_AllyHeroGroup group array Sentinel_AIPlayer_Nearby_EnemyHeroGroup group array Sentinel_AIPlayer_Nearby_AllyCreepGroup group array Sentinel_AIPlayer_Nearby_EnemyCreepGroup group array Sentinel_AIPlayer_Nearby_AllyStructureGroup group array Sentinel_AIPlayer_Nearby_EnemyStructureGroup integer array Sentinel_AIPlayer_Nearby_AllyHeroGroup_Count integer array Sentinel_AIPlayer_Nearby_EnemyHeroGroup_Count integer array Sentinel_AIPlayer_Nearby_AllyCreepGroup_Count integer array Sentinel_AIPlayer_Nearby_EnemyCreepGroup_Count integer array Sentinel_AIPlayer_Nearby_AllyStructureGroup_Count integer array Sentinel_AIPlayer_Nearby_EnemyStructureGroup_Count boolean array Scourge_AIPlayer_AI player array Scourge_AIPlayer_PlayerHandle real array Scourge_AIPlayer_Coefficient_Aggressive real array Scourge_AIPlayer_Coefficient_Watchfulness real array Scourge_AIPlayer_Coefficient_Farm real array Scourge_AIPlayer_Coefficient_Responsive real array Scourge_AIPlayer_Coefficient_Comprehensiveness integer Scourge_AIPlayer_Captian group array Scourge_AIPlayer_UnitGroup location array Scourge_AIPlayer_UnitLastLoc integer array Scourge_AIPlayer_UnitGroup_Count integer array Scourge_AIPlayer_UnitGroup_Sequence_Count integer array Scourge_AIPlayer_UnitGroup_Order_Sequence unit array Scourge_AIPlayer_UnitGroup_TargetUnit_Sequence location array Scourge_AIPlayer_UnitGroup_TargetLoc_Sequence real array Scourge_AIPlayer_UnitGroup_Order_Sequence_Timer integer array Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe integer array Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe_Target group array Scourge_AIPlayer_HeroGroup location array Scourge_AIPlayer_HeroLastLoc integer array Scourge_AIPlayer_HeroGroup_Count integer array Scourge_AIPlayer_HeroGroup_Sequence_Count integer array Scourge_AIPlayer_HeroGroup_Order_Sequence unit array Scourge_AIPlayer_HeroGroup_TargetUnit_Sequence location array Scourge_AIPlayer_HeroGroup_TargetLoc_Sequence real array Scourge_AIPlayer_HeroGroup_Order_Sequence_Timer integer array Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe integer array Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe_Target group array Scourge_AIPlayer_Nearby_AllyHeroGroup group array Scourge_AIPlayer_Nearby_EnemyHeroGroup group array Scourge_AIPlayer_Nearby_AllyCreepGroup group array Scourge_AIPlayer_Nearby_EnemyCreepGroup group array Scourge_AIPlayer_Nearby_AllyStructureGroup group array Scourge_AIPlayer_Nearby_EnemyStructureGroup integer array Scourge_AIPlayer_Nearby_AllyHeroGroup_Count integer array Scourge_AIPlayer_Nearby_EnemyHeroGroup_Count integer array Scourge_AIPlayer_Nearby_AllyCreepGroup_Count integer array Scourge_AIPlayer_Nearby_EnemyCreepGroup_Count integer array Scourge_AIPlayer_Nearby_AllyStructureGroup_Count integer array Scourge_AIPlayer_Nearby_EnemyStructureGroup_Count rect array Rect_PowerUP rect Rect_Roshan rect array Rect_Riverway_Entrance rect Rect_TopLane_CreepMeeting rect Rect_MiddleLane_CreepMeeting rect Rect_BottomLane_CreepMeeting rect array Rect_Riverway_Sentinel_Crossing rect Rect_Fountain_Sentinel rect array Rect_TopLane_Sentinel_Entrance rect array Rect_MiddleLane_Sentinel_Entrance rect array Rect_BottomLane_Sentinel_Entrance rect array Rect_NeutralCreep_Sentinel rect array Rect_NeutralCreep_Sentinel_Entrance rect array Rect_NeutralShop_Sentinel rect array Rect_NeutralShop_Sentinel_Entrance rect array Rect_Riverway_Scourge_Crossing rect Rect_Fountain_Scourge rect array Rect_TopLane_Scourge_Entrance rect array Rect_MiddleLane_Scourge_Entrance rect array Rect_BottomLane_Scourge_Entrance rect array Rect_NeutralCreep_Scourge rect array Rect_NeutralCreep_Scourge_Entrance rect array Rect_NeutralShop_Scourge rect array Rect_NeutralShop_Scourge_Entrance gamecache OOII //CXV boolean I1II //Normal Mode boolean array I //NOV unit array OII0 //B_V integer array I101OO //YFV player OOO0O=null boolean array O0O0O real OOI0O=0 force I010 //Ally Force force IIO0 //Enemy Force unit I1I1IO //'n008' unit I1I11O //'ntav' unit I11OOO //'n01D' unit I11O0O //'n01N' unit I11OIO //'n007' unit I11O1O //'n005' unit I110OO //'n01B' unit I1100O //'n01P' endglobals function IOIOO0O takes nothing returns boolean return false endfunction function O1OOOI takes player TempPlayer returns nothing endfunction function IOIOOIO takes nothing returns nothing endfunction function O01I0I takes handle TempHandle returns integer return TempHandle return 0 endfunction function OI100I takes player OI10II returns boolean if(GetPlayerSlotState(OI10II)==PLAYER_SLOT_STATE_PLAYING)then if(GetPlayerController(OI10II)==MAP_CONTROL_USER) or (GetPlayerController(OI10II)==MAP_CONTROL_COMPUTER) then return true endif endif return false endfunction function OI101I takes player OI10II returns boolean if(GetPlayerSlotState(OI10II)==PLAYER_SLOT_STATE_PLAYING or GetPlayerSlotState(OI10II)==PLAYER_SLOT_STATE_LEFT)then if(GetPlayerController(OI10II)==MAP_CONTROL_USER) or (GetPlayerController(OI10II)==MAP_CONTROL_COMPUTER) then return true endif endif return false endfunction function OI1IOI takes player OI10II returns boolean if GetPlayerSlotState(OI10II)==PLAYER_SLOT_STATE_LEFT then if(GetPlayerController(OI10II)==MAP_CONTROL_USER) or (GetPlayerController(OI10II)==MAP_CONTROL_COMPUTER) then return true endif endif return false endfunction function H2I takes handle TempHandle returns integer return TempHandle return 0 endfunction function H2S takes handle TempHandle returns string return I2S(H2I(TempHandle)) endfunction function StoInt takes string TempString1,string TempString2,integer TempInt returns nothing call StoreInteger(OOII,TempString1,TempString2,TempInt) endfunction function StoReal takes string TempString1,string TempString2,real TempReal returns nothing call StoreReal(OOII,TempString1,TempString2,TempReal) endfunction function StoBoolean takes string TempString1,string TempString2,boolean TempBoolean returns nothing call StoreBoolean(OOII,TempString1,TempString2,TempBoolean) endfunction function StoString takes string TempString1,string TempString2,string TempString3 returns nothing call StoreString(OOII,TempString1,TempString2,TempString3) endfunction function StoHandle takes string TempString1,string TempString2,handle TempHandle returns nothing call StoreInteger(OOII,TempString1,TempString2,H2I(TempHandle)) endfunction function GetStoInt takes string TempString1,string TempString2 returns integer return GetStoredInteger(OOII,TempString1,TempString2) endfunction function GetStoReal takes string TempString1,string TempString2 returns real return GetStoredReal(OOII,TempString1,TempString2) endfunction function GetStoBoolean takes string TempString1,string TempString2 returns boolean return GetStoredBoolean(OOII,TempString1,TempString2) endfunction function GetStoString takes string TempString1,string TempString2 returns string return GetStoredString(OOII,TempString1,TempString2) endfunction function GetStoUnit takes string TempString1,string TempString2 returns unit return GetStoredInteger(OOII,TempString1,TempString2) return null endfunction function GetStoGroup takes string TempString1,string TempString2 returns group return GetStoredInteger(OOII,TempString1,TempString2) return null endfunction function GetStoPlayer takes string TempString1,string TempString2 returns player return GetStoredInteger(OOII,TempString1,TempString2) return null endfunction function IsStoInt takes string TempString1,string TempString2 returns boolean return HaveStoredInteger(OOII,TempString1,TempString2) endfunction function IsStoReal takes string TempString1,string TempString2 returns boolean return HaveStoredReal(OOII,TempString1,TempString2) endfunction function IsStoBoolean takes string TempString1,string TempString2 returns boolean return HaveStoredBoolean(OOII,TempString1,TempString2) endfunction function IsStoString takes string TempString1,string TempString2 returns boolean return HaveStoredString(OOII,TempString1,TempString2) endfunction function ClearSto takes string TempString returns nothing call FlushStoredMission(OOII,TempString) endfunction function LL takes string TempString returns nothing call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,AIPlayer_TimeScale,"|cffffcc00"+TempString+"|r") endfunction function Filter_True takes nothing returns boolean return true endfunction function IsNumIn takes integer WhichNum,integer Num1,integer Num2 returns boolean if WhichNum>Num1 and WhichNum return true else return false endif endfunction function RectCenter2Loc takes rect TempRect returns location return Location(GetRectCenterX(TempRect),GetRectCenterY(TempRect)) endfunction function RectRandomLoc takes rect TempRect,integer TempCenterX,integer TempCenterY,real TempSizeCent returns location local real RectCenterX local real RectCenterY local real RectXSize=GetRectMinX(TempRect)+GetRectMaxX(TempRect) local real RectYSize=GetRectMinY(TempRect)+GetRectMaxY(TempRect) local real RectXMin local real RectXMax local real RectYMin local real RectYMax if TempCenterX==MIDDLE then set RectCenterX=RectXSize/2 elseif TempCenterX==LEFT then set RectCenterX=RectXSize/4 elseif TempCenterY==RIGHT then set RectCenterX=RectXSize*3/4 endif if TempCenterY==MIDDLE then set RectCenterY=RectCenterY/2 elseif TempCenterY==TOP then set RectCenterY=RectCenterY/4 elseif TempCenterY==BOTTOM then set RectCenterY=RectCenterY*3/4 endif if TempCenterX==MIDDLE and TempCenterY==MIDDLE then set TempSizeCent=TempSizeCent*2 endif set RectXMin=RectCenterX-RectXSize*TempSizeCent/4 set RectXMax=RectCenterX+RectXSize*TempSizeCent/4 set RectYMin=RectCenterY-RectYSize*TempSizeCent/4 set RectYMax=RectCenterY+RectYSize*TempSizeCent/4 return Location(GetRandomReal(RectXMin,RectXMax),GetRandomReal(RectYMin,RectYMax)) endfunction function GetMapData takes integer PlayerForce,integer PlaceDes1,integer PlaceDes2,integer PlaceNum returns rect if PlayerForce==NEUTRAL then if PlaceDes1==POWERUP and IsNumIn(PlaceNum,1,2) then return Rect_PowerUP[PlaceNum] elseif PlaceDes1==ROSHAN then return Rect_Roshan elseif PlaceDes1==RIVERWAY and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_Riverway_Entrance[PlaceNum] elseif PlaceDes1==TOPLANE and PlaceDes2==CREEPMEETING then return Rect_TopLane_CreepMeeting elseif PlaceDes1==MIDDLELANE and PlaceDes2==CREEPMEETING then return Rect_MiddleLane_CreepMeeting elseif PlaceDes1==BOTTOMLANE and PlaceDes2==CREEPMEETING then return Rect_BottomLane_CreepMeeting endif elseif PlayerForce==SENTINEL then if PlaceDes1==RIVERWAY and PlaceDes2==CROSSING and IsNumIn(PlaceNum,1,4) then return Rect_Riverway_Sentinel_Crossing[PlaceNum] elseif PlaceDes1==FOUNTAIN then return Rect_Fountain_Sentinel elseif PlaceDes1==TOPLANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_TopLane_Sentinel_Entrance[PlaceNum] elseif PlaceDes1==MIDDLELANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_MiddleLane_Sentinel_Entrance[PlaceNum] elseif PlaceDes1==BOTTOMLANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_BottomLane_Sentinel_Entrance[PlaceNum] elseif PlaceDes1==NEUTRALCREEP and PlaceDes2==PLACE and IsNumIn(PlaceNum,1,6) then return Rect_NeutralCreep_Sentinel[PlaceNum] elseif PlaceDes1==NEUTRALCREEP and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,14) then return Rect_NeutralCreep_Sentinel_Entrance[PlaceNum] elseif PlaceDes1==NEUTRALSHOP and PlaceDes2==PLACE and IsNumIn(PlaceNum,1,2) then return Rect_NeutralShop_Sentinel[PlaceNum] elseif PlaceDes1==NEUTRALSHOP and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,3) then return Rect_NeutralShop_Sentinel_Entrance[PlaceNum] endif elseif PlayerForce==SCOURGE then if PlaceDes1==RIVERWAY and PlaceDes2==CROSSING and IsNumIn(PlaceNum,1,5) then return Rect_Riverway_Scourge_Crossing[PlaceNum] elseif PlaceDes1==FOUNTAIN then return Rect_Fountain_Scourge elseif PlaceDes1==TOPLANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_TopLane_Scourge_Entrance[PlaceNum] elseif PlaceDes1==MIDDLELANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_MiddleLane_Scourge_Entrance[PlaceNum] elseif PlaceDes1==BOTTOMLANE and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,2) then return Rect_BottomLane_Scourge_Entrance[PlaceNum] elseif PlaceDes1==NEUTRALCREEP and PlaceDes2==PLACE and IsNumIn(PlaceNum,1,6) then return Rect_NeutralCreep_Scourge[PlaceNum] elseif PlaceDes1==NEUTRALCREEP and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,10) then return Rect_NeutralCreep_Scourge_Entrance[PlaceNum] elseif PlaceDes1==NEUTRALSHOP and PlaceDes2==PLACE and IsNumIn(PlaceNum,1,2) then return Rect_NeutralShop_Scourge[PlaceNum] elseif PlaceDes1==NEUTRALSHOP and PlaceDes2==ENTRANCE and IsNumIn(PlaceNum,1,3) then return Rect_NeutralShop_Scourge_Entrance[PlaceNum] endif endif return null endfunction function IsPlayerAI takes integer PlayerForce,integer PlayerNumber returns boolean if PlayerForce==SENTINEL then return Sentinel_AIPlayer_AI[PlayerNumber] else return Scourge_AIPlayer_AI[PlayerNumber] endif endfunction function IsUnitDisabled takes unit TempUnit returns boolean return GetUnitCurrentOrder(TempUnit)==DISABLED or GetUnitCurrentOrder(TempUnit)==851975 or GetUnitCurrentOrder(TempUnit)==851987 endfunction function IsOrderDisabled takes integer TempInt returns boolean return TempInt==DISABLED or TempInt==851975 or TempInt==851987 endfunction function IsUnitStopped takes unit TempUnit returns boolean return GetUnitCurrentOrder(TempUnit)==0 endfunction function IsOrderStopped takes integer TempInt returns boolean return TempInt==0 endfunction function GetAIPlayerNumber takes player TempPlayer returns integer local integer i=1 local integer TempInt=0 loop if TempPlayer==Sentinel_AIPlayer_PlayerHandle[i] or TempPlayer==Scourge_AIPlayer_PlayerHandle[i] then set TempInt=i endif set i=i+1 exitwhen TempInt!=0 endloop return TempInt endfunction function SetAIPlayerCaptian takes integer PlayerForce,integer PlayerNumber returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_Captian=PlayerNumber else set Scourge_AIPlayer_Captian=PlayerNumber endif endfunction function GetAIPlayerHandle takes integer PlayerForce,integer PlayerNumber returns player if PlayerForce==SENTINEL then return Sentinel_AIPlayer_PlayerHandle[PlayerNumber] else return Scourge_AIPlayer_PlayerHandle[PlayerNumber] endif endfunction function GetAIPlayerCaptian takes integer PlayerForce returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_Captian else return Scourge_AIPlayer_Captian endif endfunction function AIPlayer_Filter_Player takes nothing returns nothing local integer PlayerNumber=1 loop if PlayerNumber<7> set Sentinel_AIPlayer_AI[PlayerNumber]=false if GetPlayerSlotState(Player(PlayerNumber))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(PlayerNumber))==MAP_CONTROL_COMPUTER then set AIPlayer_Count=AIPlayer_Count+1 set Sentinel_AIPlayer_AI[PlayerNumber]=true set Sentinel_AIPlayer_PlayerHandle[PlayerNumber]=Player(PlayerNumber) endif else set Scourge_AIPlayer_AI[PlayerNumber-6]=false if GetPlayerSlotState(Player(PlayerNumber))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(PlayerNumber))==MAP_CONTROL_COMPUTER then set AIPlayer_Count=AIPlayer_Count+1 set Scourge_AIPlayer_AI[PlayerNumber-6]=true set Scourge_AIPlayer_PlayerHandle[PlayerNumber-6]=Player(PlayerNumber) endif endif set PlayerNumber=PlayerNumber+1 if PlayerNumber==6 then set PlayerNumber=7 endif exitwhen PlayerNumber>11 endloop endfunction function SetAIPlayerCoefficient takes integer PlayerForce,integer PlayerNumber,integer Coefficient,real TempReal returns nothing if PlayerForce==SENTINEL then if Coefficient==AGGRESSIVE then set Sentinel_AIPlayer_Coefficient_Aggressive[PlayerNumber]=TempReal elseif Coefficient==WATCHFULNESS then set Sentinel_AIPlayer_Coefficient_Watchfulness[PlayerNumber]=TempReal elseif Coefficient==FARM then set Sentinel_AIPlayer_Coefficient_Farm[PlayerNumber]=TempReal elseif Coefficient==RESPONSIVE then set Sentinel_AIPlayer_Coefficient_Responsive[PlayerNumber]=TempReal elseif Coefficient==COMPREHENSIVENESS then set Sentinel_AIPlayer_Coefficient_Comprehensiveness[PlayerNumber]=Sentinel_AIPlayer_Coefficient_Aggressive[PlayerNumber]*Sentinel_AIPlayer_Coefficient_Watchfulness[PlayerNumber]*Sentinel_AIPlayer_Coefficient_Farm[PlayerNumber]*Sentinel_AIPlayer_Coefficient_Responsive[PlayerNumber] endif else if Coefficient==AGGRESSIVE then set Scourge_AIPlayer_Coefficient_Aggressive[PlayerNumber]=TempReal elseif Coefficient==WATCHFULNESS then set Scourge_AIPlayer_Coefficient_Watchfulness[PlayerNumber]=TempReal elseif Coefficient==FARM then set Scourge_AIPlayer_Coefficient_Farm[PlayerNumber]=TempReal elseif Coefficient==RESPONSIVE then set Scourge_AIPlayer_Coefficient_Responsive[PlayerNumber]=TempReal elseif Coefficient==COMPREHENSIVENESS then set Scourge_AIPlayer_Coefficient_Comprehensiveness[PlayerNumber]=Scourge_AIPlayer_Coefficient_Aggressive[PlayerNumber]*Scourge_AIPlayer_Coefficient_Watchfulness[PlayerNumber]*Scourge_AIPlayer_Coefficient_Farm[PlayerNumber]*Scourge_AIPlayer_Coefficient_Responsive[PlayerNumber] endif endif endfunction function GetAIPlayerCoefficient takes integer PlayerForce,integer PlayerNumber,integer Coefficient returns real local real TempReal if PlayerForce==SENTINEL then if Coefficient==AGGRESSIVE then set TempReal=Sentinel_AIPlayer_Coefficient_Aggressive[PlayerNumber] elseif Coefficient==WATCHFULNESS then set TempReal=Sentinel_AIPlayer_Coefficient_Watchfulness[PlayerNumber] elseif Coefficient==FARM then set TempReal=Sentinel_AIPlayer_Coefficient_Farm[PlayerNumber] elseif Coefficient==RESPONSIVE then set TempReal=Sentinel_AIPlayer_Coefficient_Responsive[PlayerNumber] elseif Coefficient==COMPREHENSIVENESS then set TempReal=Sentinel_AIPlayer_Coefficient_Comprehensiveness[PlayerNumber] endif else if Coefficient==AGGRESSIVE then set TempReal=Scourge_AIPlayer_Coefficient_Aggressive[PlayerNumber] elseif Coefficient==WATCHFULNESS then set TempReal=Scourge_AIPlayer_Coefficient_Watchfulness[PlayerNumber] elseif Coefficient==FARM then set TempReal=Scourge_AIPlayer_Coefficient_Farm[PlayerNumber] elseif Coefficient==RESPONSIVE then set TempReal=Scourge_AIPlayer_Coefficient_Responsive[PlayerNumber] elseif Coefficient==COMPREHENSIVENESS then set TempReal=Scourge_AIPlayer_Coefficient_Comprehensiveness[PlayerNumber] endif endif return TempReal endfunction function AIPlayer_Set_Character takes nothing returns nothing local integer PlayerForce local integer PlayerNumber=1 local real TempReal1=0 local integer TempInt1=0 local real TempReal2=0 local integer TempInt2=0 loop set PlayerForce=SENTINEL if IsPlayerAI(PlayerForce,PlayerNumber)==true then call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,AGGRESSIVE,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,WATCHFULNESS,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,FARM,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,RESPONSIVE,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,COMPREHENSIVENESS,NONE) if TempReal1==0 or TempReal1 set TempReal1=GetAIPlayerCoefficient(PlayerForce,PlayerNumber,COMPREHENSIVENESS) set TempInt1=PlayerNumber endif endif set PlayerForce=SCOURGE if IsPlayerAI(PlayerForce,PlayerNumber)==true then call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,AGGRESSIVE,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,WATCHFULNESS,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,FARM,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,RESPONSIVE,GetRandomInt(75,99)/100) call SetAIPlayerCoefficient(PlayerForce,PlayerNumber,COMPREHENSIVENESS,NONE) if TempReal2==0 or TempReal2 set TempReal2=GetAIPlayerCoefficient(PlayerForce,PlayerNumber,COMPREHENSIVENESS) set TempInt2=PlayerNumber endif endif set PlayerNumber=PlayerNumber+1 exitwhen PlayerNumber>5 endloop if TempInt1>0 then call SetAIPlayerCaptian(SENTINEL,TempInt1) endif if TempInt2>0 then call SetAIPlayerCaptian(SCOURGE,TempInt2) endif endfunction function AIPlayer_Speak takes integer PlayerForce,integer PlayerNumber,string TempString returns nothing local player TempPlayer local string AIPlayer_PlayerName local force TempForce set TempPlayer=GetAIPlayerHandle(PlayerForce,PlayerNumber) set TempForce=I010 set AIPlayer_PlayerName=GetPlayerName(TempPlayer) call DisplayTimedTextToForce(TempForce,10,AIPlayer_PlayerName+":"+TempString) set TempPlayer=null set TempForce=null endfunction function AIPlayer_RandomChoose takes player TempPlayer returns nothing local player OI10II=TempPlayer local trigger t set OOO0O=OI10II if IOIOO0O()and O0O0O[GetPlayerId(OI10II)]==false then set O0O0O[GetPlayerId(OI10II)]=true call O1OOOI(OI10II) call DisplayTimedTextToPlayer(OI10II,0,OOI0O,10,(GetObjectName((1848653633)))) set t=CreateTrigger() call TriggerRegisterTimerEvent(t,6,false) call TriggerAddCondition(t,Condition(function IOIOOIO)) call StoreInteger(OOII,((I2S(O01I0I((t))))),("p"),O01I0I((OI10II))) endif set t=null endfunction function AIPlayer_Choose_Hero takes nothing returns nothing local integer i=1 local boolean TempBoolean loop if IsPlayerAI(SENTINEL,i) then call AIPlayer_Speak(SENTINEL,i,"-random") call AIPlayer_RandomChoose(Sentinel_AIPlayer_PlayerHandle[i]) endif if IsPlayerAI(SCOURGE,i) then call AIPlayer_Speak(SCOURGE,i,"-random") call AIPlayer_RandomChoose(Scourge_AIPlayer_PlayerHandle[i]) endif call TriggerSleepAction(GetRandomReal(1,3)) set i=i+1 exitwhen i>5 endloop endfunction function AIPlayer_MakeSure_ItemBuild takes nothing returns nothing endfunction function GetUnitSequenceIndex takes integer PlayerNumber,integer UnitNumber,integer IndexNumber returns integer local integer Index set Index=UnitNumber+(PlayerNumber-1)*HERO_GROUP_MAX_LIMIT if IndexNumber!=0 then set Index=(Index-1)*ORDER_SEQUENCE_MAX_LIMIT+IndexNumber endif return Index endfunction function SetUnitSequenceCount takes integer PlayerForce,integer UnitIndex,integer TempCount returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_UnitGroup_Sequence_Count[UnitIndex]=TempCount else set Scourge_AIPlayer_UnitGroup_Sequence_Count[UnitIndex]=TempCount endif endfunction function SetUnitSequence takes integer PlayerForce,integer UnitSequenceIndex,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_UnitGroup_Order_Sequence[UnitSequenceIndex]=TempOrder set Sentinel_AIPlayer_UnitGroup_TargetUnit_Sequence[UnitSequenceIndex]=TempTargetUnit set Sentinel_AIPlayer_UnitGroup_TargetLoc_Sequence[UnitSequenceIndex]=TempTargetLoc set Sentinel_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex]=TempTimer set Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe[UnitSequenceIndex]=TempDescribe set Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe_Target[UnitSequenceIndex]=TempDescribeTarget else set Scourge_AIPlayer_UnitGroup_Order_Sequence[UnitSequenceIndex]=TempOrder set Scourge_AIPlayer_UnitGroup_TargetUnit_Sequence[UnitSequenceIndex]=TempTargetUnit set Scourge_AIPlayer_UnitGroup_TargetLoc_Sequence[UnitSequenceIndex]=TempTargetLoc set Scourge_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex]=TempTimer set Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe[UnitSequenceIndex]=TempDescribe set Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe_Target[UnitSequenceIndex]=TempDescribeTarget endif endfunction function SetUnitSequenceTimer takes integer PlayerForce,integer UnitSequenceIndex,real TempTimer returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex]=TempTimer else set Scourge_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex]=TempTimer endif endfunction function GetUnitSequenceCount takes integer PlayerForce,integer UnitIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Sequence_Count[UnitIndex] else return Scourge_AIPlayer_UnitGroup_Sequence_Count[UnitIndex] endif endfunction function GetUnitSequenceOrder takes integer PlayerForce,integer UnitSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Order_Sequence[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_Order_Sequence[UnitSequenceIndex] endif endfunction function GetUnitSequenceTargetUnit takes integer PlayerForce,integer UnitSequenceIndex returns unit if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_TargetUnit_Sequence[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_TargetUnit_Sequence[UnitSequenceIndex] endif endfunction function GetUnitSequenceTargetLoc takes integer PlayerForce,integer UnitSequenceIndex returns location if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_TargetLoc_Sequence[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_TargetLoc_Sequence[UnitSequenceIndex] endif endfunction function GetUnitSequenceTimer takes integer PlayerForce,integer UnitSequenceIndex returns real if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_Order_Sequence_Timer[UnitSequenceIndex] endif endfunction function GetUnitSequenceDescribe takes integer PlayerForce,integer UnitSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe[UnitSequenceIndex] endif endfunction function GetUnitSequenceDescribeTarget takes integer PlayerForce,integer UnitSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Order_Sequence_Describe_Target[UnitSequenceIndex] else return Scourge_AIPlayer_UnitGroup_Order_Sequence_Describe_Target[UnitSequenceIndex] endif endfunction function ClearUnitSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,boolean CompletelyClear returns nothing local integer TempInt local integer TempCount local integer UnitIndex local integer UnitSequenceIndex set UnitIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,0) if CompletelyClear==false then call SetUnitSequenceCount(PlayerForce,UnitIndex,1) endif set TempInt=1 set TempCount=GetUnitSequenceCount(PlayerForce,UnitIndex) loop set UnitSequenceIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempInt) call SetUnitSequence(PlayerForce,UnitSequenceIndex,HOLD,null,null,UNLIMITED,WAIT,NONE) set TempInt=TempInt+1 exitwhen TempInt>TempCount endloop endfunction function ReplaceUnitSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer UnitSequenceIndex set UnitSequenceIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,1) call SetUnitSequence(PlayerForce,UnitSequenceIndex,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) endfunction function InsertUnitSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer UnitIndex local integer UnitSequenceIndex1 local integer UnitSequenceIndex2 local integer UnitSequenceOrder local unit UnitSequenceTargetUnit local location UnitSequenceTargetLoc local real UnitSequenceTimer local integer UnitSequenceDescribe local integer UnitSequenceDescribeTarget local integer TempCount set UnitIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,0) set TempCount=GetUnitSequenceCount(PlayerForce,UnitIndex)+1 call SetUnitSequenceCount(PlayerForce,UnitIndex,TempCount) loop exitwhen TempCount==1 set UnitSequenceIndex1=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempCount) set UnitSequenceIndex2=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempCount-1) set UnitSequenceOrder=GetUnitSequenceOrder(PlayerForce,UnitSequenceIndex2) set UnitSequenceTargetUnit=GetUnitSequenceTargetUnit(PlayerForce,UnitSequenceIndex2) set UnitSequenceTargetLoc=GetUnitSequenceTargetLoc(PlayerForce,UnitSequenceIndex2) set UnitSequenceTimer=GetUnitSequenceTimer(PlayerForce,UnitSequenceIndex2) set UnitSequenceDescribe=GetUnitSequenceDescribe(PlayerForce,UnitSequenceIndex2) set UnitSequenceDescribeTarget=GetUnitSequenceDescribeTarget(PlayerForce,UnitSequenceIndex2) call SetUnitSequence(PlayerForce,UnitSequenceIndex1,UnitSequenceOrder,UnitSequenceTargetUnit,UnitSequenceTargetLoc,UnitSequenceTimer,UnitSequenceDescribe,UnitSequenceDescribeTarget) set TempCount=TempCount-1 endloop call SetUnitSequence(PlayerForce,UnitSequenceIndex2,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) set UnitSequenceTargetUnit=null set UnitSequenceTargetLoc=null endfunction function AddUnitSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer UnitIndex local integer UnitSequenceIndex local integer TempCount local integer OrderSequence set UnitIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,0) set TempCount=GetUnitSequenceCount(PlayerForce,UnitIndex)+1 set UnitSequenceIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempCount) call SetUnitSequence(PlayerForce,UnitSequenceIndex,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) call SetUnitSequenceCount(PlayerForce,UnitIndex,TempCount) endfunction function NextUnitSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber returns nothing local integer TempInt local integer TempCount local integer UnitIndex local integer UnitSequenceIndex1 local integer UnitSequenceIndex2 local integer UnitSequenceOrder local unit UnitSequenceTargetUnit local location UnitSequenceTargetLoc local real UnitSequenceTimer local integer UnitSequenceDescribe local integer UnitSequenceDescribeTarget set UnitIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,0) set TempCount=GetUnitSequenceCount(PlayerForce,UnitIndex) if TempCount==1 then call ClearUnitSequenceOrder(PlayerForce,PlayerNumber,UnitNumber,false) else set TempInt=2 loop set UnitSequenceIndex1=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempInt-1) set UnitSequenceIndex2=GetUnitSequenceIndex(PlayerNumber,UnitNumber,TempInt) set UnitSequenceOrder=GetUnitSequenceOrder(PlayerForce,UnitSequenceIndex2) set UnitSequenceTargetUnit=GetUnitSequenceTargetUnit(PlayerForce,UnitSequenceIndex2) set UnitSequenceTargetLoc=GetUnitSequenceTargetLoc(PlayerForce,UnitSequenceIndex2) set UnitSequenceTimer=GetUnitSequenceTimer(PlayerForce,UnitSequenceIndex2) set UnitSequenceDescribe=GetUnitSequenceDescribe(PlayerForce,UnitSequenceIndex2) set UnitSequenceDescribeTarget=GetUnitSequenceDescribeTarget(PlayerForce,UnitSequenceIndex2) call SetUnitSequence(PlayerForce,UnitSequenceIndex1,UnitSequenceOrder,UnitSequenceTargetUnit,UnitSequenceTargetLoc,UnitSequenceTimer,UnitSequenceDescribe,UnitSequenceDescribeTarget) set TempInt=TempInt+1 exitwhen TempInt>TempCount endloop call SetUnitSequence(PlayerForce,UnitSequenceIndex2,HOLD,null,null,UNLIMITED,WAIT,NONE) call SetUnitSequenceCount(PlayerForce,UnitIndex,TempCount-1) endif set UnitSequenceTargetUnit=null set UnitSequenceTargetLoc=null endfunction function UnitSequenceExecuteOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,unit UnitHandle returns nothing local integer TempIndex local integer TempOrder local unit TempTargetUnit local location TempTargetLoc set TempIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,1) set TempOrder=GetUnitSequenceOrder(PlayerForce,TempIndex) set TempTargetUnit=GetUnitSequenceTargetUnit(PlayerForce,TempIndex) set TempTargetLoc=GetUnitSequenceTargetLoc(PlayerForce,TempIndex) if TempTargetUnit==null then if TempTargetLoc==null then call IssueImmediateOrderById(UnitHandle,TempOrder) else call IssuePointOrderByIdLoc(UnitHandle,TempOrder,TempTargetLoc) endif else call IssueTargetOrderById(UnitHandle,TempOrder,TempTargetUnit) endif set TempTargetUnit=null set TempTargetLoc=null endfunction function UnitDealNewOrder takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,unit UnitHandle returns nothing local integer CurrentOrder=GetUnitCurrentOrder(UnitHandle) if IsOrderDisabled(CurrentOrder) then call ClearUnitSequenceOrder(PlayerForce,PlayerNumber,UnitNumber,true) elseif IsOrderStopped(CurrentOrder) then call NextUnitSequenceOrder(PlayerForce,PlayerNumber,UnitNumber) endif call UnitSequenceExecuteOrder(PlayerForce,PlayerNumber,UnitNumber,UnitHandle) endfunction function UnitCurrentOrderChanged takes integer PlayerForce,integer PlayerNumber,integer UnitNumber,unit UnitHandle returns boolean local integer CurrentOrder local integer OrderSequence local integer UnitSequenceIndex=GetUnitSequenceIndex(PlayerNumber,UnitNumber,1) local integer TempCount=GetUnitSequenceCount(PlayerForce,GetUnitSequenceIndex(PlayerNumber,UnitNumber,0)) local real TempTimer=GetUnitSequenceTimer(PlayerForce,UnitSequenceIndex) set TempTimer=TempTimer-AIPlayer_TimeSize call SetUnitSequenceTimer(PlayerForce,UnitSequenceIndex,TempTimer) set CurrentOrder=GetUnitCurrentOrder(UnitHandle) set OrderSequence=GetUnitSequenceOrder(PlayerForce,GetUnitSequenceIndex(PlayerNumber,UnitNumber,1)) if TempTimer==UNLIMITED then if CurrentOrder==0 and OrderSequence==HOLD then if TempCount==1 then return false else return true endif elseif CurrentOrder==OrderSequence then return false endif elseif TempTimer>0 then if CurrentOrder==OrderSequence then return false endif endif return true endfunction function AIPlayer_Unit_RespondOrder takes integer PlayerForce,integer PlayerNumber returns nothing local group TempGroup=CreateGroup() local unit UnitHandle local string TempString local integer UnitNumber if PlayerForce==SENTINEL then call GroupAddGroup(Sentinel_AIPlayer_UnitGroup[PlayerNumber],TempGroup) else call GroupAddGroup(Scourge_AIPlayer_UnitGroup[PlayerNumber],TempGroup) endif loop set UnitHandle=FirstOfGroup(TempGroup) exitwhen UnitHandle==null call GroupRemoveUnit(TempGroup,UnitHandle) set TempString=H2S(UnitHandle) set UnitNumber=GetStoInt(TempString,"UnitNumber") if UnitCurrentOrderChanged(PlayerForce,PlayerNumber,UnitNumber,UnitHandle) then call UnitDealNewOrder(PlayerForce,PlayerNumber,UnitNumber,UnitHandle) endif endloop call DestroyGroup(TempGroup) endfunction function CountGroupUnit takes integer PlayerForce,integer PlayerNumber returns integer local group TempGroup=CreateGroup() local integer UnitNumber=0 local unit TempUnit local string TempString if PlayerForce==SENTINEL then call GroupAddGroup(Sentinel_AIPlayer_UnitGroup[PlayerNumber],TempGroup) else call GroupAddGroup(Scourge_AIPlayer_UnitGroup[PlayerNumber],TempGroup) endif loop set TempUnit=FirstOfGroup(TempGroup) exitwhen TempUnit==null call GroupRemoveUnit(TempGroup,TempUnit) set UnitNumber=UnitNumber+1 set TempString=H2S(TempUnit) if IsStoInt(TempString,"UnitNumber")==false then call StoInt(TempString,"UnitNumber",UnitNumber) endif endloop call DestroyGroup(TempGroup) set TempGroup=null set TempUnit=null return UnitNumber endfunction function ClearAIPlayerUnitGroup takes integer PlayerForce,integer PlayerNumber returns nothing if PlayerForce==SENTINEL then call GroupClear(Sentinel_AIPlayer_UnitGroup[PlayerNumber]) else call GroupClear(Scourge_AIPlayer_UnitGroup[PlayerNumber]) endif endfunction function SetAIPlayerUnitGroupCount takes integer PlayerForce,integer PlayerNumber,integer TempInt returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_UnitGroup_Count[PlayerNumber]=TempInt else set Scourge_AIPlayer_UnitGroup_Count[PlayerNumber]=TempInt endif endfunction function GetAIPlayerUnitGroupCount takes integer PlayerForce,integer PlayerNumber returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_UnitGroup_Count[PlayerNumber] else return Scourge_AIPlayer_UnitGroup_Count[PlayerNumber] endif endfunction function GetHeroSequenceIndex takes integer PlayerNumber,integer HeroNumber,integer IndexNumber returns integer local integer Index set Index=HeroNumber+(PlayerNumber-1)*HERO_GROUP_MAX_LIMIT if IndexNumber!=0 then set Index=(Index-1)*ORDER_SEQUENCE_MAX_LIMIT+IndexNumber endif return Index endfunction function SetHeroSequenceCount takes integer PlayerForce,integer HeroIndex,integer TempCount returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_HeroGroup_Sequence_Count[HeroIndex]=TempCount else set Scourge_AIPlayer_HeroGroup_Sequence_Count[HeroIndex]=TempCount endif endfunction function SetHeroSequence takes integer PlayerForce,integer HeroSequenceIndex,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_HeroGroup_Order_Sequence[HeroSequenceIndex]=TempOrder set Sentinel_AIPlayer_HeroGroup_TargetUnit_Sequence[HeroSequenceIndex]=TempTargetUnit set Sentinel_AIPlayer_HeroGroup_TargetLoc_Sequence[HeroSequenceIndex]=TempTargetLoc set Sentinel_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex]=TempTimer set Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe[HeroSequenceIndex]=TempDescribe set Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe_Target[HeroSequenceIndex]=TempDescribeTarget else set Scourge_AIPlayer_HeroGroup_Order_Sequence[HeroSequenceIndex]=TempOrder set Scourge_AIPlayer_HeroGroup_TargetUnit_Sequence[HeroSequenceIndex]=TempTargetUnit set Scourge_AIPlayer_HeroGroup_TargetLoc_Sequence[HeroSequenceIndex]=TempTargetLoc set Scourge_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex]=TempTimer set Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe[HeroSequenceIndex]=TempDescribe set Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe_Target[HeroSequenceIndex]=TempDescribeTarget endif endfunction function SetHeroSequenceTimer takes integer PlayerForce,integer HeroSequenceIndex,real TempTimer returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex]=TempTimer else set Scourge_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex]=TempTimer endif endfunction function GetHeroSequenceCount takes integer PlayerForce,integer HeroIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Sequence_Count[HeroIndex] else return Scourge_AIPlayer_HeroGroup_Sequence_Count[HeroIndex] endif endfunction function GetHeroSequenceOrder takes integer PlayerForce,integer HeroSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Order_Sequence[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_Order_Sequence[HeroSequenceIndex] endif endfunction function GetHeroSequenceTargetUnit takes integer PlayerForce,integer HeroSequenceIndex returns unit if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_TargetUnit_Sequence[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_TargetUnit_Sequence[HeroSequenceIndex] endif endfunction function GetHeroSequenceTargetLoc takes integer PlayerForce,integer HeroSequenceIndex returns location if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_TargetLoc_Sequence[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_TargetLoc_Sequence[HeroSequenceIndex] endif endfunction function GetHeroSequenceTimer takes integer PlayerForce,integer HeroSequenceIndex returns real if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_Order_Sequence_Timer[HeroSequenceIndex] endif endfunction function GetHeroSequenceDescribe takes integer PlayerForce,integer HeroSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe[HeroSequenceIndex] endif endfunction function GetHeroSequenceDescribeTarget takes integer PlayerForce,integer HeroSequenceIndex returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Order_Sequence_Describe_Target[HeroSequenceIndex] else return Scourge_AIPlayer_HeroGroup_Order_Sequence_Describe_Target[HeroSequenceIndex] endif endfunction function ClearHeroSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,boolean CompletelyClear returns nothing local integer TempInt local integer TempCount local integer HeroIndex local integer HeroSequenceIndex set HeroIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,0) if CompletelyClear==false then call SetHeroSequenceCount(PlayerForce,HeroIndex,1) endif set TempInt=1 set TempCount=GetHeroSequenceCount(PlayerForce,HeroIndex) loop set HeroSequenceIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempInt) call SetHeroSequence(PlayerForce,HeroSequenceIndex,HOLD,null,null,UNLIMITED,WAIT,NONE) set TempInt=TempInt+1 exitwhen TempInt>TempCount endloop endfunction function ReplaceHeroSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer HeroSequenceIndex set HeroSequenceIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,1) call SetHeroSequence(PlayerForce,HeroSequenceIndex,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) endfunction function InsertHeroSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer HeroIndex local integer HeroSequenceIndex1 local integer HeroSequenceIndex2 local integer HeroSequenceOrder local unit HeroSequenceTargetUnit local location HeroSequenceTargetLoc local real HeroSequenceTimer local integer HeroSequenceDescribe local integer HeroSequenceDescribeTarget local integer TempCount set HeroIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,0) set TempCount=GetHeroSequenceCount(PlayerForce,HeroIndex)+1 call SetHeroSequenceCount(PlayerForce,HeroIndex,TempCount) loop exitwhen TempCount==1 set HeroSequenceIndex1=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempCount) set HeroSequenceIndex2=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempCount-1) set HeroSequenceOrder=GetHeroSequenceOrder(PlayerForce,HeroSequenceIndex2) set HeroSequenceTargetUnit=GetHeroSequenceTargetUnit(PlayerForce,HeroSequenceIndex2) set HeroSequenceTargetLoc=GetHeroSequenceTargetLoc(PlayerForce,HeroSequenceIndex2) set HeroSequenceTimer=GetHeroSequenceTimer(PlayerForce,HeroSequenceIndex2) set HeroSequenceDescribe=GetHeroSequenceDescribe(PlayerForce,HeroSequenceIndex2) set HeroSequenceDescribeTarget=GetHeroSequenceDescribeTarget(PlayerForce,HeroSequenceIndex2) call SetHeroSequence(PlayerForce,HeroSequenceIndex1,HeroSequenceOrder,HeroSequenceTargetUnit,HeroSequenceTargetLoc,HeroSequenceTimer,HeroSequenceDescribe,HeroSequenceDescribeTarget) set TempCount=TempCount-1 endloop call SetHeroSequence(PlayerForce,HeroSequenceIndex2,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) set HeroSequenceTargetUnit=null set HeroSequenceTargetLoc=null endfunction function AddHeroSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,integer TempOrder,unit TempTargetUnit,location TempTargetLoc,real TempTimer,integer TempDescribe,integer TempDescribeTarget returns nothing local integer HeroIndex local integer HeroSequenceIndex local integer TempCount local integer OrderSequence set HeroIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,0) set TempCount=GetHeroSequenceCount(PlayerForce,HeroIndex)+1 set HeroSequenceIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempCount) call SetHeroSequence(PlayerForce,HeroSequenceIndex,TempOrder,TempTargetUnit,TempTargetLoc,TempTimer,TempDescribe,TempDescribeTarget) call SetHeroSequenceCount(PlayerForce,HeroIndex,TempCount) endfunction function NextHeroSequenceOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber returns nothing local integer TempInt local integer TempCount local integer HeroIndex local integer HeroSequenceIndex1 local integer HeroSequenceIndex2 local integer HeroSequenceOrder local unit HeroSequenceTargetUnit local location HeroSequenceTargetLoc local real HeroSequenceTimer local integer HeroSequenceDescribe local integer HeroSequenceDescribeTarget set HeroIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,0) set TempCount=GetHeroSequenceCount(PlayerForce,HeroIndex) if TempCount==1 then call ClearHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,false) else set TempInt=2 loop set HeroSequenceIndex1=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempInt-1) set HeroSequenceIndex2=GetHeroSequenceIndex(PlayerNumber,HeroNumber,TempInt) set HeroSequenceOrder=GetHeroSequenceOrder(PlayerForce,HeroSequenceIndex2) set HeroSequenceTargetUnit=GetHeroSequenceTargetUnit(PlayerForce,HeroSequenceIndex2) set HeroSequenceTargetLoc=GetHeroSequenceTargetLoc(PlayerForce,HeroSequenceIndex2) set HeroSequenceTimer=GetHeroSequenceTimer(PlayerForce,HeroSequenceIndex2) set HeroSequenceDescribe=GetHeroSequenceDescribe(PlayerForce,HeroSequenceIndex2) set HeroSequenceDescribeTarget=GetHeroSequenceDescribeTarget(PlayerForce,HeroSequenceIndex2) call SetHeroSequence(PlayerForce,HeroSequenceIndex1,HeroSequenceOrder,HeroSequenceTargetUnit,HeroSequenceTargetLoc,HeroSequenceTimer,HeroSequenceDescribe,HeroSequenceDescribeTarget) set TempInt=TempInt+1 exitwhen TempInt>TempCount endloop call SetHeroSequence(PlayerForce,HeroSequenceIndex2,HOLD,null,null,UNLIMITED,WAIT,NONE) call SetHeroSequenceCount(PlayerForce,HeroIndex,TempCount-1) endif set HeroSequenceTargetUnit=null set HeroSequenceTargetLoc=null endfunction function HeroSequenceExecuteOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,unit HeroHandle returns nothing local integer TempIndex local integer TempOrder local unit TempTargetUnit local location TempTargetLoc set TempIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,1) set TempOrder=GetHeroSequenceOrder(PlayerForce,TempIndex) set TempTargetUnit=GetHeroSequenceTargetUnit(PlayerForce,TempIndex) set TempTargetLoc=GetHeroSequenceTargetLoc(PlayerForce,TempIndex) if TempTargetUnit==null then if TempTargetLoc==null then call IssueImmediateOrderById(HeroHandle,TempOrder) else call IssuePointOrderByIdLoc(HeroHandle,TempOrder,TempTargetLoc) endif else call IssueTargetOrderById(HeroHandle,TempOrder,TempTargetUnit) endif set TempTargetUnit=null set TempTargetLoc=null endfunction function HeroDealNewOrder takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,unit HeroHandle returns nothing local integer CurrentOrder=GetUnitCurrentOrder(HeroHandle) if IsOrderDisabled(CurrentOrder) then call ClearHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,true) elseif IsOrderStopped(CurrentOrder) then call NextHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber) endif call HeroSequenceExecuteOrder(PlayerForce,PlayerNumber,HeroNumber,HeroHandle) endfunction function HeroCurrentOrderChanged takes integer PlayerForce,integer PlayerNumber,integer HeroNumber,unit HeroHandle returns boolean local integer CurrentOrder local integer OrderSequence local integer HeroSequenceIndex=GetHeroSequenceIndex(PlayerNumber,HeroNumber,1) local integer TempCount=GetHeroSequenceCount(PlayerForce,GetHeroSequenceIndex(PlayerNumber,HeroNumber,0)) local real TempTimer=GetHeroSequenceTimer(PlayerForce,HeroSequenceIndex) set TempTimer=TempTimer-AIPlayer_TimeSize call SetHeroSequenceTimer(PlayerForce,HeroSequenceIndex,TempTimer) set CurrentOrder=GetUnitCurrentOrder(HeroHandle) set OrderSequence=GetHeroSequenceOrder(PlayerForce,GetHeroSequenceIndex(PlayerNumber,HeroNumber,1)) if TempTimer==UNLIMITED then if CurrentOrder==0 and OrderSequence==HOLD then if TempCount==1 then return false else return true endif elseif CurrentOrder==OrderSequence then return false endif elseif TempTimer>0 then if CurrentOrder==OrderSequence then return false endif endif return true endfunction function AIPlayer_Hero_RespondOrder takes integer PlayerForce,integer PlayerNumber returns nothing local group TempGroup=CreateGroup() local unit HeroHandle local string TempString local integer HeroNumber if PlayerForce==SENTINEL then call GroupAddGroup(Sentinel_AIPlayer_HeroGroup[PlayerNumber],TempGroup) else call GroupAddGroup(Scourge_AIPlayer_HeroGroup[PlayerNumber],TempGroup) endif loop set HeroHandle=FirstOfGroup(TempGroup) exitwhen HeroHandle==null call GroupRemoveUnit(TempGroup,HeroHandle) set TempString=H2S(HeroHandle) set HeroNumber=GetStoInt(TempString,"HeroNumber") if HeroCurrentOrderChanged(PlayerForce,PlayerNumber,HeroNumber,HeroHandle) then call HeroDealNewOrder(PlayerForce,PlayerNumber,HeroNumber,HeroHandle) endif endloop call DestroyGroup(TempGroup) endfunction function CountGroupHero takes integer PlayerForce,integer PlayerNumber returns integer local group TempGroup=CreateGroup() local integer HeroNumber=0 local unit TempUnit local string TempString if PlayerForce==SENTINEL then call GroupAddGroup(Sentinel_AIPlayer_HeroGroup[PlayerNumber],TempGroup) else call GroupAddGroup(Scourge_AIPlayer_HeroGroup[PlayerNumber],TempGroup) endif loop set TempUnit=FirstOfGroup(TempGroup) exitwhen TempUnit==null call GroupRemoveUnit(TempGroup,TempUnit) set HeroNumber=HeroNumber+1 set TempString=H2S(TempUnit) if IsStoInt(TempString,"HeroNumber")==false then call StoInt(TempString,"HeroNumber",HeroNumber) endif endloop call DestroyGroup(TempGroup) set TempGroup=null set TempUnit=null return HeroNumber endfunction function ClearAIPlayerHeroGroup takes integer PlayerForce,integer PlayerNumber returns nothing if PlayerForce==SENTINEL then call GroupClear(Sentinel_AIPlayer_HeroGroup[PlayerNumber]) else call GroupClear(Scourge_AIPlayer_HeroGroup[PlayerNumber]) endif endfunction function SetAIPlayerHeroGroupCount takes integer PlayerForce,integer PlayerNumber,integer TempInt returns nothing if PlayerForce==SENTINEL then set Sentinel_AIPlayer_HeroGroup_Count[PlayerNumber]=TempInt else set Scourge_AIPlayer_HeroGroup_Count[PlayerNumber]=TempInt endif endfunction function GetAIPlayerHeroGroupCount takes integer PlayerForce,integer PlayerNumber returns integer if PlayerForce==SENTINEL then return Sentinel_AIPlayer_HeroGroup_Count[PlayerNumber] else return Scourge_AIPlayer_HeroGroup_Count[PlayerNumber] endif endfunction function AIPlayerEnumUnits takes integer PlayerForce,integer PlayerNumber,player PlayerHandle returns nothing if PlayerForce==SENTINEL then call GroupEnumUnitsOfPlayer(Sentinel_AIPlayer_UnitGroup[PlayerNumber],PlayerHandle,Condition(function Filter_True)) else call GroupEnumUnitsOfPlayer(Scourge_AIPlayer_UnitGroup[PlayerNumber],PlayerHandle,Condition(function Filter_True)) endif endfunction function AIPlayer_FilterGroup takes integer PlayerForce,integer PlayerNumber returns nothing local group TempGroup=CreateGroup() local unit TempUnit if PlayerForce==SENTINEL then call GroupAddGroup(Sentinel_AIPlayer_UnitGroup[PlayerNumber],TempGroup) else call GroupAddGroup(Scourge_AIPlayer_UnitGroup[PlayerNumber],TempGroup) endif loop set TempUnit=FirstOfGroup(TempGroup) exitwhen TempUnit==null call GroupRemoveUnit(TempGroup,TempUnit) if IsUnitAliveBJ(TempUnit) and GetUnitTypeId(TempUnit)!='ncop' then if IsUnitType(TempUnit,UNIT_TYPE_HERO)then if PlayerForce==SENTINEL then call GroupRemoveUnit(Sentinel_AIPlayer_UnitGroup[PlayerNumber],TempUnit) call GroupAddUnit(Sentinel_AIPlayer_HeroGroup[PlayerNumber],TempUnit) else call GroupRemoveUnit(Scourge_AIPlayer_UnitGroup[PlayerNumber],TempUnit) call GroupAddUnit(Scourge_AIPlayer_HeroGroup[PlayerNumber],TempUnit) endif endif else if PlayerForce==SENTINEL then call GroupRemoveUnit(Sentinel_AIPlayer_UnitGroup[PlayerNumber],TempUnit) else call GroupRemoveUnit(Scourge_AIPlayer_UnitGroup[PlayerNumber],TempUnit) endif endif endloop call DestroyGroup(TempGroup) set TempGroup=null endfunction function AIPlayer_GroupCount takes integer PlayerForce,integer PlayerNumber returns nothing local player AIPlayer_PlayerHandle set AIPlayer_PlayerHandle=GetAIPlayerHandle(PlayerForce,PlayerNumber) call ClearAIPlayerUnitGroup(PlayerForce,PlayerNumber) call ClearAIPlayerHeroGroup(PlayerForce,PlayerNumber) call AIPlayerEnumUnits(PlayerForce,PlayerNumber,AIPlayer_PlayerHandle) call AIPlayer_FilterGroup(PlayerForce,PlayerNumber) call SetAIPlayerUnitGroupCount(PlayerForce,PlayerNumber,CountGroupUnit(PlayerForce,PlayerNumber)) call SetAIPlayerHeroGroupCount(PlayerForce,PlayerNumber,CountGroupHero(PlayerForce,PlayerNumber)) set AIPlayer_PlayerHandle=null endfunction function AIPlayer_Responding takes nothing returns nothing local integer PlayerForce local integer PlayerNumber=1 loop set PlayerForce=SENTINEL if IsPlayerAI(PlayerForce,PlayerNumber)==true then call AIPlayer_GroupCount(PlayerForce,PlayerNumber) if GetAIPlayerUnitGroupCount(PlayerForce,PlayerNumber)>0 then call AIPlayer_Unit_RespondOrder(PlayerForce,PlayerNumber) endif if GetAIPlayerHeroGroupCount(PlayerForce,PlayerNumber)>0 then call AIPlayer_Hero_RespondOrder(PlayerForce,PlayerNumber) endif endif set PlayerForce=SCOURGE if IsPlayerAI(PlayerForce,PlayerNumber)==true then call AIPlayer_GroupCount(PlayerForce,PlayerNumber) if GetAIPlayerUnitGroupCount(PlayerForce,PlayerNumber)>0 then call AIPlayer_Unit_RespondOrder(PlayerForce,PlayerNumber) endif if GetAIPlayerHeroGroupCount(PlayerForce,PlayerNumber)>0 then call AIPlayer_Hero_RespondOrder(PlayerForce,PlayerNumber) endif else endif set PlayerNumber=PlayerNumber+1 exitwhen PlayerNumber>5 endloop endfunction function AIPlayer_Unit_Clear takes nothing returns nothing if IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)==false or IsUnitIllusion(GetTriggerUnit())==true then call ClearSto(H2S(GetTriggerUnit())) endif endfunction function AIPlayer_TakeOver_HeroeControlling takes nothing returns nothing local integer i=1 local trigger t local string TempString loop set Sentinel_AIPlayer_UnitGroup_Count[i]=0 set Sentinel_AIPlayer_HeroGroup_Count[i]=0 if IsPlayerAI(SENTINEL,i)==true then set Sentinel_AIPlayer_UnitGroup[i]=CreateGroup() set TempString=H2S(Sentinel_AIPlayer_UnitGroup[i]) call StoInt(TempString,"PlayerForce",SENTINEL) set Sentinel_AIPlayer_HeroGroup[i]=CreateGroup() set TempString=H2S(Sentinel_AIPlayer_HeroGroup[i]) call StoInt(TempString,"PlayerForce",SENTINEL) set Sentinel_AIPlayer_Nearby_AllyHeroGroup[i]=CreateGroup() set Sentinel_AIPlayer_Nearby_EnemyHeroGroup[i]=CreateGroup() set Sentinel_AIPlayer_Nearby_AllyCreepGroup[i]=CreateGroup() set Sentinel_AIPlayer_Nearby_EnemyCreepGroup[i]=CreateGroup() set Sentinel_AIPlayer_Nearby_AllyStructureGroup[i]=CreateGroup() set Sentinel_AIPlayer_Nearby_EnemyStructureGroup[i]=CreateGroup() endif set Scourge_AIPlayer_UnitGroup_Count[i]=0 set Scourge_AIPlayer_HeroGroup_Count[i]=0 if IsPlayerAI(SCOURGE,i)==true then set Scourge_AIPlayer_UnitGroup[i]=CreateGroup() set TempString=H2S(Scourge_AIPlayer_UnitGroup[i]) call StoInt(TempString,"PlayerForce",SCOURGE) set Scourge_AIPlayer_HeroGroup[i]=CreateGroup() set TempString=H2S(Scourge_AIPlayer_HeroGroup[i]) call StoInt(TempString,"PlayerForce",SCOURGE) set Scourge_AIPlayer_Nearby_AllyHeroGroup[i]=CreateGroup() set Scourge_AIPlayer_Nearby_EnemyHeroGroup[i]=CreateGroup() set Scourge_AIPlayer_Nearby_AllyCreepGroup[i]=CreateGroup() set Scourge_AIPlayer_Nearby_EnemyCreepGroup[i]=CreateGroup() set Scourge_AIPlayer_Nearby_AllyStructureGroup[i]=CreateGroup() set Scourge_AIPlayer_Nearby_EnemyStructureGroup[i]=CreateGroup() endif set i=i+1 exitwhen i>5 endloop set t=CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH) call TriggerAddAction(t,function AIPlayer_Unit_Clear) set t=null endfunction function AIPlayer_CommandCenter takes nothing returns nothing local integer CurrentTime=GetTriggerEvalCount(AIPlayer_Trigger) local integer PlayerNumber=2 local integer PlayerForce local integer HeroNumber=1 local integer HeroIndex if CurrentTime>AIPlayer_TimeSize*10 then set AIPlayer_Respond_Trigger=CreateTrigger() call TriggerRegisterTimerEvent(AIPlayer_Respond_Trigger,AIPlayer_TimeScale,true) call TriggerAddAction(AIPlayer_Respond_Trigger,function AIPlayer_Responding) call DisableTrigger(AIPlayer_Trigger) set PlayerForce=SENTINEL loop if IsPlayerAI(PlayerForce,PlayerNumber)==true then call ClearHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,false) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_TopLane_Sentinel_Entrance[1]),UNLIMITED,MOVETO,TOPLANE) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_Riverway_Entrance[1]),UNLIMITED,MOVETO,RIVERWAY) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_PowerUP[1]),UNLIMITED,MOVETO,POWERUP) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_MiddleLane_CreepMeeting),UNLIMITED,MOVETO,MIDDLELANE) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_PowerUP[2]),UNLIMITED,MOVETO,POWERUP) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_MiddleLane_Sentinel_Entrance[1]),UNLIMITED,MOVETO,MIDDLELANE) call AddHeroSequenceOrder(PlayerForce,PlayerNumber,HeroNumber,RIGHTCLICK,null,RectCenter2Loc(Rect_Fountain_Sentinel),UNLIMITED,MOVETO,FOUNTAIN) endif set PlayerNumber=PlayerNumber+1 exitwhen PlayerNumber>5 endloop endif endfunction function AIPlayer_Start_HeroControlling takes nothing returns nothing set AIPlayer_Trigger=CreateTrigger() call TriggerRegisterTimerEvent(AIPlayer_Trigger,AIPlayer_TimeScale,true) call TriggerAddAction(AIPlayer_Trigger,function AIPlayer_CommandCenter) endfunction function StartAI takes nothing returns nothing call DestroyTrigger(GetTriggeringTrigger()) set AI_Start=true call AIPlayer_Filter_Player() call AIPlayer_Set_Character() call AIPlayer_Choose_Hero() call AIPlayer_MakeSure_ItemBuild() call AIPlayer_TakeOver_HeroeControlling() call AIPlayer_Start_HeroControlling() endfunction function InitAIData_Hero takes nothing returns nothing endfunction function InitAIData_Map takes nothing returns nothing set Rect_PowerUP[1]=Rect(-3104,2176,-2304,1632) set Rect_PowerUP[2]=Rect(2816,-2944,3520,-3296) set Rect_Roshan=Rect(2112,-448,2880,-1120) set Rect_Riverway_Entrance[1]=Rect(-5920,3168,-5312,2336) set Rect_Riverway_Entrance[2]=Rect(5024,-2976,5632,-3552) set Rect_TopLane_CreepMeeting=Rect(-6560,6112,-5344,4864) set Rect_MiddleLane_CreepMeeting=Rect(-1440,64,64,-1088) set Rect_BottomLane_CreepMeeting=Rect(4896,6272,-7040,-5792) set Rect_Riverway_Sentinel_Crossing[1]=Rect(-3168,1600,-2752,1280) set Rect_Riverway_Sentinel_Crossing[2]=Rect(-2240,864,-1696,576) set Rect_Riverway_Sentinel_Crossing[3]=Rect(-1440,-512,-640,-1088) set Rect_Riverway_Sentinel_Crossing[4]=Rect(1984,-2720,2368,-2976) set Rect_Fountain_Sentinel=Rect(-7260,-6500,-6560,-7230) set Rect_TopLane_Sentinel_Entrance[1]=Rect(-6880,-3328,-5824,-3744) set Rect_TopLane_Sentinel_Entrance[2]=Rect(-6848,-2176,-5952,-2400) set Rect_MiddleLane_Sentinel_Entrance[1]=Rect(-4544,-4288,-3872,-4928) set Rect_MiddleLane_Sentinel_Entrance[2]=Rect(-3936,-3168,-3072,-4128) set Rect_BottomLane_Sentinel_Entrance[1]=Rect(-3360,-6336,-3040,-7360) set Rect_BottomLane_Sentinel_Entrance[2]=Rect(-1376,-6720,-1152,-7296) set Rect_NeutralCreep_Sentinel[1]=Rect(2848,-3552,3424,-4288) set Rect_NeutralCreep_Sentinel[2]=Rect(2688,-4960,3392,-5568) set Rect_NeutralCreep_Sentinel[3]=Rect(1280,-3840,1984,-4480) set Rect_NeutralCreep_Sentinel[4]=Rect(-576,-3232,-64,-3680) set Rect_NeutralCreep_Sentinel[5]=Rect(-1440,-4256,-704,-4832) set Rect_NeutralCreep_Sentinel[6]=Rect(-3360,64,-2688,-608) set Rect_NeutralCreep_Sentinel_Entrance[1]=Rect(5376,-3648,5472,-4032) set Rect_NeutralCreep_Sentinel_Entrance[2]=Rect(5184,-4960,5344,-5728) set Rect_NeutralCreep_Sentinel_Entrance[3]=Rect(3456,-6144,4288,-6304) set Rect_NeutralCreep_Sentinel_Entrance[4]=Rect(2112,-3488,2496,-3680) set Rect_NeutralCreep_Sentinel_Entrance[5]=Rect(-480,-6048,1984,-6176) set Rect_NeutralCreep_Sentinel_Entrance[6]=Rect(896,-2752,1120,-3136) set Rect_NeutralCreep_Sentinel_Entrance[7]=Rect(32,-2880,256,-3264) set Rect_NeutralCreep_Sentinel_Entrance[8]=Rect(-672,-1376,-512,-2016) set Rect_NeutralCreep_Sentinel_Entrance[9]=Rect(-1216,-6496,-960,-6592) set Rect_NeutralCreep_Sentinel_Entrance[10]=Rect(-1760,-2624,-1376,-2944) set Rect_NeutralCreep_Sentinel_Entrance[11]=Rect(-2528,-3648,-2400,-4448) set Rect_NeutralCreep_Sentinel_Entrance[12]=Rect(-2496,224,-2112,0) set Rect_NeutralCreep_Sentinel_Entrance[13]=Rect(-3648,-1888,-3104,-2336) set Rect_NeutralCreep_Sentinel_Entrance[14]=Rect(-5664,-1440,-5504,-2464) set Rect_NeutralShop_Sentinel[1]=Rect(6752,-3936,7488,-4704) set Rect_NeutralShop_Sentinel[2]=Rect(-4896,1312,-4064,608) set Rect_NeutralShop_Sentinel_Entrance[1]=Rect(-3456,1088,-3264,832) set Rect_NeutralShop_Sentinel_Entrance[2]=Rect(-3936,-960,-3584,-1312) set Rect_NeutralShop_Sentinel_Entrance[3]=Rect(-5632,544,-5376,-32) set Rect_Riverway_Scourge_Crossing[1]=Rect(-3296,3744,-2624,3360) set Rect_Riverway_Scourge_Crossing[2]=Rect(-2144,3392,-1920,3008) set Rect_Riverway_Scourge_Crossing[3]=Rect(-1376,1216,-1152,832) set Rect_Riverway_Scourge_Crossing[4]=Rect(-576,64,64,-704) set Rect_Riverway_Scourge_Crossing[5]=Rect(2144,-1504,3552,-2048) set Rect_Fountain_Scourge=Rect(6150,6400,6950,5760) set Rect_TopLane_Scourge_Entrance[1]=Rect(1952,6336,2368,5312) set Rect_TopLane_Scourge_Entrance[2]=Rect(1120,6336,1376,5312) set Rect_MiddleLane_Scourge_Entrance[1]=Rect(3264,3392,3904,2784) set Rect_MiddleLane_Scourge_Entrance[2]=Rect(2528,2528,3424,1696) set Rect_BottomLane_Scourge_Entrance[1]=Rect(5952,2080,6848,1792) set Rect_BottomLane_Scourge_Entrance[2]=Rect(5952,864,6720,576) set Rect_NeutralCreep_Scourge[1]=Rect(-4704,3840,-4000,3200) set Rect_NeutralCreep_Scourge[2]=Rect(-3392,4608,-2688,4160) set Rect_NeutralCreep_Scourge[3]=Rect(-1824,2624,-1344,2144) set Rect_NeutralCreep_Scourge[4]=Rect(-640,3744,-64,3264) set Rect_NeutralCreep_Scourge[5]=Rect(960,3296,1472,2880) set Rect_NeutralCreep_Scourge[6]=Rect(4000,-2112,4928,-2816) set Rect_NeutralCreep_Scourge_Entrance[1]=Rect(-5600,4864,-5376,3264) set Rect_NeutralCreep_Scourge_Entrance[2]=Rect(-3680,5472,-3072,5216) set Rect_NeutralCreep_Scourge_Entrance[3]=Rect(-1472,3744,-832,3456) set Rect_NeutralCreep_Scourge_Entrance[4]=Rect(-992,2880,-768,2496) set Rect_NeutralCreep_Scourge_Entrance[5]=Rect(-960,5216,1152,4992) set Rect_NeutralCreep_Scourge_Entrance[6]=Rect(-448,1312,64,928) set Rect_NeutralCreep_Scourge_Entrance[7]=Rect(1152,2336,1504,1696) set Rect_NeutralCreep_Scourge_Entrance[8]=Rect(1184,4416,1504,3648) set Rect_NeutralCreep_Scourge_Entrance[9]=Rect(5024,-352,5152,-1632) set Rect_NeutralCreep_Scourge_Entrance[10]=Rect(3616,-1440,3872,1888) set Rect_NeutralShop_Scourge[1]=Rect(-7360,4608,-6720,3584) set Rect_NeutralShop_Scourge[2]=Rect(3008,160,3552,-352) set Rect_NeutralShop_Scourge_Entrance[1]=Rect(3392,992,4032,704) set Rect_NeutralShop_Scourge_Entrance[2]=Rect(4672,256,4864,-192) set Rect_NeutralShop_Scourge_Entrance[3]=Rect(3904,-640,4352,-992) endfunction function main takes nothing returns nothing local integer O00I1I=0 local integer O00III local trigger t call InitAIData_Map() call InitAIData_Hero() set t=CreateTrigger() call TriggerRegisterTimerEvent(t,18,false) call TriggerAddAction(t,function StartAI) set t=null if(GetPlayerController(Player(O00III))==MAP_CONTROL_COMPUTER and GetPlayerSlotState(Player(O00III))==PLAYER_SLOT_STATE_PLAYING)then set O00I1I=O00I1I+1 endif endfunction |
訂閱:
文章 (Atom)