##EasyReadMore##

2009年12月27日 星期日

魔獸世界競技場 3.1 -正體中文版

.
地圖名稱:魔獸世界競技場 WoW_Allstars3.1-b5.w3x

類型:兩隊 對戰
推薦人數: 2v2 3v3 4v4 5v5

簡介:一個相當有趣刺激的對戰地圖,遊戲節奏明快重反應與隊友間的合作搭配
原作者是老外 官方論壇
http://arenawow.net/index.php?sid=cb2fa24337030beb6c86f48c97861ded
已經過多次改版,平衡度很高又不失多變與趣味性
目前1.24版wc3能玩又有中文化的最新版本是 3.1

遊戲模式介紹:
除了基本的競技場死鬥,先贏8場獲勝
還能輸入指令改變獲勝模式

新手入門小提醒:
技能熱鍵為 QWET  上排兩招 DR
T大多是 比較長CD或是招喚寵物技能等 不需要時常施放的技能
購買物品 左排的是 基本物品
建議先單機看好購裝順序
因為遊戲節奏超快 每次購物時間都非常短

目前已知推廣者 PTT上的 dioayu  (GGC上帳號dioger)

推薦給懷念魔獸世界的玩家,或者喜愛魔獸世界的玩家,魔獸爭霸愛好者也可換換地圖
換換口味一下!


下載地圖:
--載點請勿轉貼--
.

2009年12月22日 星期二

[教程] 通向DIY AI之路系列教程---之簡單的BUFF判斷讓AI司馬E不和郭嘉C衝突




文章網址:http://bbs.wow8.org/thread-131013-1-1.html

本帖最後由 ROUSTAR31 於 2009-11-7 11:26 編輯

我要說明的是,這個防止衝突不是100%的有效。因為技能的釋放有一定的時間,有可能司馬和郭嘉同時EC。看了下面的代碼講解我再詳細解釋為什麼吧。

部分代碼在0.51里有,只是我自己定義的沒有。

由於郭嘉的C和司馬的E的那個BUFF的ID都是一樣的,

所以我們只要一個BUFF判斷函數就可以了


定義一個判斷單位有司馬懿E和郭嘉C的BUFF的函數:
function IsbeiEC takes unit TheUnit returns boolean
return(GetUnitAbilityLevel(TheUnit,'BUim')>0)
endfunction


下面要做的就是在司馬和郭嘉與E和C相關的施法函數里加上這個判斷BUFF

if (IsLifeAlmostFull(HeroD) or EnemyHeroHP>1500) and MyHeroMP>300 and rangeToTowerD>1100 and rangeToHeroD<700  and can_sima_cast_ef()  then
  set zs_action_prioty_arry[52]=82

這是司馬EF的一個函數,加上後變成下面的

if (IsLifeAlmostFull(HeroD) or EnemyHeroHP>1500) and MyHeroMP>300 and rangeToTowerD>1100 and rangeToHeroD<700  and can_sima_cast_ef() and not IsbeiEC(HeroD) then
  set zs_action_prioty_arry[52]=82

其他地方大家可以這樣加。比如郭嘉的:

if HeroD!=null and (not IsJuFeng(HeroD))  and   can_guojia_cast_c() and (EnemyHeroHP<500 or zs_HeroPower>0 ) then
    set zs_action_prioty_arry[52]=89

加上後變成這樣的:

if HeroD!=null and (not IsJuFeng(HeroD))  and   can_guojia_cast_c() and (EnemyHeroHP<500 or zs_HeroPower>0 ) and not IsbeiEC(HeroD) then
    set zs_action_prioty_arry[52]=89

舉一反三而已。

看過了上面的應該知道為什麼不是100%有效吧?!但絕對不會有被司馬E住了的人郭嘉來個C或者郭嘉C住司馬來個E.

那麼怎麼讓曹仁C不C被自己睡住的人呢?

同樣是按照這種思路


[教程] 通向DIY AI之路系列教程---之關羽是如何實現完美貼人




文章網址:http://bbs.wow8.org/thread-130782-1-1.html

本帖最後由 ROUSTAR31 於 2009-11-5 14:42 編輯

大家一定覺得電腦關羽的風車貼人很犀利吧。

那麼我來剖析下關羽貼人在AI文件裡是怎麼一個原理。

下面來看關羽施法部分的貼人函數。由於牽扯到比較多的內容,我盡量詳細點。

if HeroD!=null  and IsImmune(mHero)  then
    set zs_action_prioty_arry[54]=90
endif
if HeroD!=null  and IsImmune(mHero) and mHeroLevel>11 and MyHeroHP>500  then
    set zs_action_prioty_arry[54]=103
endif

這是從關羽的施法條件函數里截取出來的。

HeroD是敵方英雄,mHero是AI自己。ISmmune是判斷目標是否魔法免疫

那麼綠色那部分意思就是:如果在檢測範圍內敵人武將存在,且自己是魔法免疫的那麼定義54號施法函數的優先級為90.

又牽扯到優先級的問題,基本這個是數字越大,優先級越高。優先級懂嗎?就是如果AI某個時間能同時做幾件事,那麼是那個優先級數字高的先起作用。

紅色那行其實就是對關羽血量和風車等級判斷後,讓54號施法函數優先級進一步提高到103。

好的,那麼看完了條件,我們來看動作。

if index==54 then
   if rangeToHeroD>400 and can_UseFeiXie(mHero) then
   set loc=GetLocBetweenTwoUnitsRangeToFirst(HeroD,mHero,-180)
   call UseFeiXie(loc)
   call RemoveLocation(loc)
   set loc=null
   endif
   if (rangeToHeroD>260 or GetUnitMoveSpeed(HeroD)>390) and can_TuiMoDao(mHero) then
    call UseTuiMoDao(HeroD)
   endif
  

先來看,這部分是什麼意思。

我來個翻譯吧。

假如施法函數號=54,那麼
  假如離敵人距離>400,且自己可以使用飛鞋,那麼
   設置點變量loc=獲取自己和敵人直線方向上距離敵人-180的點,方向為自己指向敵人。
   命令使用飛鞋飛到點loc。
   釋放點。
  清空點的handle.
  結束
假如離敵人距離大於260或者敵人移動速度>390 且自己可以使用退魔刀,那麼
   對敵人使用退魔刀
 

————————————偶是分割線————————————————————————
   set loc=GetLocBetweenTwoUnitsRangeToFirst(HeroD,mHero,-180)
   call gotoLocation(mHero,loc,30)
   call RemoveLocation(loc)
   set loc=null
   call Sleep(0.2)

——————————講解關鍵部分————————————
上面的就是跟人函數了,就是每隔0.2秒獲取自己和敵人180範圍內的點,然後走到這個點30範圍內。
無敵跟人就是這樣的了。


[教程] 通向DIY AI之路系列教程---之司馬懿怎麼S掉自己的N




文章網址:http://bbs.wow8.org/thread-130523-1-1.html

其實這個知識我再7月份發過一次,但現在還是來說下(注意:我基本引用的都是0.51的AI文件裡的函數)

下面我們來看0.51AI文件裡關於控制司馬懿S掉N的那個函數:在comonn.ai的2400行左右。

function CastTargetSkillByOderIdDelayed takes unit TheUnit,integer abilcode,integer Order ,unit TheTaget,real delay returns boolean
local player ThePlayer=ai_player
local integer PlayerID=GetPlayerId(ThePlayer)
local location Loc=null

local boolean Casted
set Loc=GetUnitLoc(TheTaget)

call SetPlayerAbilityAvailable(ThePlayer,abilcode,true)

set Casted=IssuePointOrderByIdLoc(TheUnit,Order,Loc)
call Sleep(delay-0.25)..............註釋:delay的值是2.00
     if not IsUnitInRangeLoc(TheTaget,Loc,250) then
    call IssueImmediateOrder(TheUnit,"stop")
    call debugstr("stop dazhao sima==========================")
    call SetPlayerAbilityAvailable(ThePlayer,abilcode,false)
    call RemoveLocation(Loc)
    set Loc=null
    return false
    endif
call Sleep(0.55)
call SetPlayerAbilityAvailable(ThePlayer,abilcode,false)
call RemoveLocation(Loc)
set Loc=null

return(Casted)
endfunction

函數開始都是jass自定義的局部變量。具體大家看紅色大字那三行。
其實意思是這樣:在AI司馬懿放技能過1.75秒後檢查敵人和技能釋放點的距離要是大於250就命令其S掉。

那麼我們可以在第2行加些限制條件,比如敵人HP小於100.那麼就變成了這樣:


call Sleep(delay-0.25)
     if not IsUnitInRangeLoc(TheTaget,Loc,250)  or GetHP(TheTarge)<100 then
    call IssueImmediateOrder(TheUnit,"stop")

這樣就實現了我的那個AI CN 版本中的敵人HP<100S掉大招


[教程] 關於AI躲限制技能的檢測問題




文章網址:http://bbs.wow8.org/thread-126747-1-1.html

關於AI躲限制技能的檢測問題

為了便於說明

我用的是我的2.0的AI文件

所有的都定義在這幾個函數下:
function Q6 takes nothing returns boolean
if not IsUnitEnemy(PG,V)then
return false
endif
return UG==852592and GetUnitTypeId(PG)==HV
endfunction///檢測諸葛放E
function S6 takes nothing returns boolean
if not IsUnitEnemy(PG,V)then
return false
endif
return UG==852127 and GetUnitTypeId(PG)==HV
endfunction///檢測諸葛放X
function T6 takes nothing returns boolean
if not IsUnitEnemy(PG,V)then
return false
endif
return UG==852224 and GetUnitTypeId(PG)==PV
endfunction///檢測司馬放N
function U6 takes nothing returns boolean
if not IsUnitEnemy(PG,V)then
return false
endif
if UG==852127and SM(NI,PG)<280 then
return true
endif
return false
endfunction///檢測諸葛放X自己離X位置距離???
function W6 takes nothing returns boolean
if PG==null then
return false
endif
if SM(NI,PG)>800 then
return false
endif
if not IsUnitEnemy(PG,V)then
return false
endif
if UG==852555and QG==NI then
return true
endif
if UG==852127and SM(NI,PG)<280 then
return true
endif
if UG==852095and QG==NI then
return true
endif
if UG==852592and GetUnitTypeId(PG)==HV then
return true
endif
return false
endfunction///檢測威嚴的T司馬的E等
function Y6 takes nothing returns boolean
if PG==null then
return false
endif
if SM(NI,PG)>1100 then
return false
endif
if not IsUnitEnemy(PG,V)then
return false
endif
if S6()or T6()then
return true
endif
if UG==852504and GetUnitTypeId(PG)==UV then
return true
endif
if UG==852555and GetUnitTypeId(PG)==QV then
return true
endif
return false
endfunction
function Z6 takes nothing returns boolean
return(S6()or T6())or(UG==852504and GetUnitTypeId(PG)==UV)or(UG==852555and GetUnitTypeId(PG)==QV)or(BY(GI)and M>300 and GW(GI))or(GW(GI)and GetUnitTypeId(GI)==KV and SM(GI,NI)<300)
endfunction

能看懂嗎?

UG後面的數字是技能id轉換成數字後的。不明白的再WE裡自己轉換下

wonder並沒有定於檢測關羽的X。你可以在W6函數里加。

由於時間上的關係,只能說這麼多了

相應的命令AI躲的函數在NXV這個函數里,大家自己去研究


[教程] jass函數教學—解密AI文件



文章網址:http://bbs.wow8.org/viewthread.php?tid=119554&page=1&fromuid=308308#pid1705603

一段時間沒來,今天上論壇發現AI區和其他的區和別的區合併了。。。

AI區非常火爆

那麼我這個菜鳥也來為大家解密下AI文件

申明:我也不是個高手,難免說錯啊。那麼大家理解。
不懂WE和jass的可以無視下面的了。
1:先來說下jass函數的基本格式:
function [名稱] takes [參數列] returns [返回類型]
[函數體部分]
return[返回值]
endfunction 標誌一段function的結束
中括號裡的為我加的此處是些什麼東西加的註釋
那麼先來一個簡單的說明:
function YK takes unit u returns boolean
return GetPlayerController(GetOwningPlayer(u))==MAP_CONTROL_USER
endfunction
此函數名為:YK,參數為單位u,返回值為boolean真假型變量。
函數體部分的意思有WE基礎的很容易看懂吧
那麼基本格式說到這,有很多東西自己體會的,我講多了也沒什麼好處。
2:調用函數: call。這部分我直接引用GREEDWIND的jass基礎教程的講解
用於調用函數. 當使用 call MyFunction(), 則運行了函數MyFunction
    語法格式:
       call 函數名(參數1, 參數2, ...., 參數n)
()號內的的用逗號(,)分割開的參數表. 如果被調用的函數要求輸入參數, 則 call 語句中必須包含被調用函數要求輸入參數類型相同數據類型或用空值.
    這句另人費解的話用人類的模糊語言來說就是:
        我(被調用的函數)要愛情(參數)才可以工作, 你(call 過程)就不要給我麵包(傳遞的參數)
    這個是用jass寫的要愛情和麵包但什麼也不做而且還不高興的空函數:
    function isHappy takes unit whichunit, item needbread returns boolean
        return false    //函數返回值為"假"
    endfunction
    這個是用jass寫的總是高興傻笑的空函數:
    function IamAlwaysHappy takes nothing returns boolean
        return true //函數返回值為(真)
    endfunction
在函數中isHappy()要求傳遞2個參數, 參數數據類型分別是unit和item
    而函數IamAlwaysHappy()沒有要求傳遞任何參數, 就不要多此一舉給它愛情和麵包了
  
    假設girl是unit類型變量, bread是item類型變量. 我們可這樣調用:
    call isHappy(girl, bread)   //給了愛情又給麵包, 真是貼心人啊 。這才是正確的引用,下面的4個都是錯誤的
    call isHappy(null, bread)   //不給愛情只給麵包, 不要餓死他
    call isHappy(girl, null)    //給愛情不給麵包, 為了愛情故, 我把麵包拋
    call isHappy(null, null)    //兩者皆不給, 反正給了也返回"假"值
    call IamAlwaysHappy()       //IamAlwaysHappy()沒有要求任何參數
那麼講了這麼多,貌似沒講到AI部分。那我來結合WONDER的AI文件來慢慢講解
我的講解用的文件時wonder0.792的AI文件。
在AI文件的5000行左右,有類似下面的函數
1號函數:
function Z8 takes nothing returns nothing
call K7(1550,'n003','I024','I01N')
endfunction
2號函數:
function VVV takes nothing returns nothing
call K7(870,'n00S','I00G','I01N')
endfunction
3號函數:
function VEV takes nothing returns nothing
call T7(750,'I024','I00G',0,'n008','kybl')
endfunction
那麼我們先關注的是參數和返回值部分。都為nothing,那麼此函數為過程函數。調用的時候()不要求加任何東西
這是什麼呢?
不知道大家有沒有看過roustar31的解密wonderAI文件這個帖子,他舉得一個裝備合成的例子是玄武,那麼上面這個是衣服。
看函數體部分;三個函數都是調用函數,1和2調用的是同一個:K7,那麼我們來看下這個函數名為K7的函數。
K7函數:
function K7 takes integer L7,integer Q5,integer WP,integer M7 returns nothing
set KR=YW(V)
if KR0 or(M7>0 and VQ(NI,M7)>0)then
return
endif
if EL(NI)<1 then
call H7()
endif
if EL(NI)>0 then
call O7(Q5,WP,1)
endif
endfunction
由於加密的原因,大家是不是看得雲裡霧裡的呢?
用monking提供的解密技術還原的如下:
function zs_buyHiItem takes integer gold,integer shopid,integer itemid,integer enditemid returns nothing
set mGold=GetPlayerGold(ai_player)
if mGold0 or GetNumberOfItemByID(mHero,enditemid)>0 then 
return
endif
  if GetSlotsFreeOnUnit(mHero)<1 then
  call sellLowPrice()
  endif
   if GetSlotsFreeOnUnit(mHero)>0 then
  call buyDueNumberOfItem(shopid,itemid,1)
  endif
endfunction
那麼重點看得是參數列部分;依次是:integer gold(整數型變量gold),integer shopid(整數型變量shopid),integer itemid(整數型變量itemid)integer enditemid(整數型變量enditemid).不懂嗎?
那麼我來一個一個得解釋;第一個是買的東西的要多少黃金。第2個是要買的東西所在商店的ID代碼。第3個是物品的ID代碼。第三個是要合成的物品的ID代碼。
現在來對照1號函數和2號函數。他調用K7函數,那麼括號裡的當然要輸入這些參數,而且要按照順序。1號函數是買什麼的呢?玄武甲?對了
玄武甲價格1550,買它的商店的代碼是n003,物品ID代碼是I024,要合成的是衣服的ID代碼是I01N.
那麼T7函數自己也照我的思路來研究吧
那麼我今天就寫這麼多了
此帖會天天更新的,那麼大家多關注。
會有更多的解密哦、。。
哈哈


[教程] 想要完美移植wonderAI文件的看過來了,終極解密(絕對強大)




文章網址:http://bbs.wow8.org/thread-118676-1-1.html

本帖最後由 ROUSTAR31 於 2009-8-5 09:13 編輯

藥水,退魔,風暴之杖,禽獸杖之所以會失蹤,是wonder的AI文件裡有個函數:
此函數無比邪惡

其實說白了當電腦購買這些東西的時候wonder會刪掉,給電腦一個效果一樣,圖標也一樣的道具。
由於大家要移植的地圖裡並沒有這些道具,所以就。。。會


為了說明方便,現在我們把3.9d裡的原有的物品叫做A,wonder給電腦加的物品叫B.

那麼,如何解決呢?

有3種方法:

1:刪掉這個無比邪惡的函數!!

2:在自己要移植的地圖裡加入這些物品(僅對SLK地圖有效)

3:自己創建類似的物品,再改函數,把B物品的ID改成自己創建的 物品。

大家一起研究吧,破解AI的日子就要來了。。。。

有很多證據可以證明我的理論:

遊戲中,你拿起AI的紅藍是沒法使用的,你把自己的紅藍給電腦,不會和電腦身上的紅藍重貼。。

而且在我的版本貌似電腦的藍說明文字美修正,進一步說明電腦身上的藥水和我們的是不同的

下面是wonder地圖提取的電腦用的風杖的說明:

[I00N]
Name=風暴之杖
Hotkey=N
Tip=風暴之杖
Ubertip=智慧+20,法力再生+100%。可以使用颶風術。|n可使用5次。
Description=智慧+20,法力再生+100%。可以使用颶風術。|n可使用5次。
Art=ReplaceableTextures\CommandButtons\BTNStaffOfNegation.blp

貌似沒問題,真實玩家用的是下面這個:

[sneg]
Name=風暴之杖
Hotkey=N
Tip=風暴之杖
Ubertip=|c水過,支持~~FBF00物品效果:|r|c0055aaff智慧+20,提升100%的法力恢復速度|r|n|c水過,支持~~5aaff使用五次後該物品不會消失|r
Description=|c水過,支持~~FBF00物品效果:|r|c0055aaff智慧+20,提升100%的法力恢復速度|r|n|c水過,支持~~5aaff使用五次後該物品不會消失|r
Art=ReplaceableTextures\CommandButtons\BTNStaffOfNegation.blp

注意了:他們有什麼不同

是的!!!哈哈,除了說明文字不同,物品其實不是一個:ID不同!電腦用的是I00N.而我們用的是sneg.


呀,有頭緒了!!!我在圖裡添加了新物品導致很多物品錯亂,但ID並沒什麼問題,應該就出在AI文件裡了。

很奇怪的現象:我新加入兩個製作書(飛行翼製作書、先鋒盾製作書)。遊戲剛開始時,AI買完藥消失後就突然變出2個飛行翼製作書,而飛行翼製作書它們能當藍喝掉,而AI出門前買的藍藥正好2瓶!!!

遊戲進行一段時間後,AI買了多少紅就會換成多少先鋒盾製作書,而其也能當紅藥喝掉!!!

好像14E的AI也是這種情況,藥消失後被其他東西代替,但仍有藥的效果!


哈哈,
我知道原因了,你新加的物品的ID核wonder的那個B物品ID相同,所以。。。。。
此帖一出,江湖上完美移植的AI圖會熱來熱多。
希望你第一個搞出來。
我看好你



[轉帖][WE JASS] AI腳本初級教程




文章網址: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,




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日 星期六

暴雪星際II官網關於地圖編輯器的官方問答集合






文章網址:http://sc2bbs.uuu9.com/read.php?tid=2296891

感謝蕾妮桑的翻譯!!

這個帖子收錄了blz的sc2官網上一切有關地圖編輯器的官方問答。前幾樓更新的是大塊的問答集合,後面則會更新些零碎問答。

注意:問答集的作者都是BN論壇斑竹Karune.


星際爭霸II Q&A第18彈:地圖編輯器系列問答1

祝大家週末愉快!這一彈,我很榮幸地向大家介紹地圖編輯器系列問答。這一特殊系列會週期性地夾雜在我
們的普通問答之中,以便地圖製作者們能對我們星際爭霸II的強力地圖編輯器有所領略。我知道你們當中有
很多人對星際爭霸II的地圖和改版有著極大的期待。因此我迫不及待地想向你們透露有關下一代編輯器的更
多細節。

至於負責回答問題的人,有我們的星際爭霸II高級軟件工程師佈雷特·伍德。不過他更著名的稱號是「有時是
白天的死程,有時是夜晚的忍者,他的真實身份是好渣的編輯器的熱辣締造者。」


1]裝飾物的放置上限會有所提高麼?(總比以前25個(SC1)的上限多吧?)

[佈雷特·伍德]裝飾物的放置上限我們計劃參考魔獸爭霸III標準,我記得好像是10000個左右,反正肯定是多
過25個。


2]區域/觸發器的上限會提高麼?目前(SC1)對區域的限制實在是讓人發揮不起來。

[佈雷特·伍德]區域和觸發器的數量限制至少是上千個。


3]觸發編輯器會包括所有的觸發功能麼?

[佈雷特·伍德]對。甚至比魔獸爭霸III地圖編輯器還完全。我們努力讓所有的腳本功能都能在觸發編輯器裡實
現。


4]單位數量上限會提高麼?目前(SC1)地圖裡的單位數量上限真的很土,我想沒人老喜歡看見CCMU(無
法創建更多單位)的提示。

[佈雷特·伍德]我不記得星際I具體的單位上限了,不過星際爭霸II的上限應該是比魔獸爭霸III的還高很多的。
具體數據目前還未定,尚需參考項目完工前(意思是發售前)的優化成果。


5]新地圖編輯器會包括棄置單位麼?比如墜毀的偵察機、炮塔、蛋、核彈、聖甲蟲、墜毀的指揮中心之類
的?第三方地圖編輯器可能會用到它們。

[佈雷特·伍德]數據定義文件裡的所有單位都會出現在編輯器裡。我記得魔獸爭霸III已經是這樣了。


星際爭霸II Q&A第22彈:地圖編輯器系列問答2

今天我們繼續進行數周前發起的地圖編輯器系列。達斯汀·布勞德和我們的高級軟件工程師佈雷特·伍德將回
答來自地圖編輯器論壇的問題。您若有任何關於自定義地圖或者改版的問題,也可在這個帖子裡回復,他們
將會在系列3中進行回答。

開發者訪談:其實至今為止我們收到的關於UMS地圖/改版問題中最常見一個是:會有Dota SC2版麼?如果
你沒聽說過這名字,Dota(守護遠古之樹)是一張很流行的魔獸爭霸III UMS地圖。相比起魔獸爭霸III來,星
際爭霸系列完全不注重英雄,英雄和普通單位也沒有經驗升級機制。很難想像像Dota這種地圖能在星際爭霸
系列中再現。然而,在跟我們的開發組談過以後,我們得知英雄/單位的經驗升級機制其實已經內建在地圖編
輯器內,儘管單人戰役和標準多人對戰中並不會出現。附帶一提,這些單位還能設置是否擁有物品欄。這同
樣也是Dota這類UMS地圖的必要特性。有了這兩個附加特性,我們只需安心坐等我們聰明的地圖製作者們
搞定其餘部分,做出帥呆的自定義地圖了。


1]現在到底能不能採用混合地形呢?還是只能用單一的地形主題,比如「叢林」,「黎明」之類的?

[達斯汀·布勞德]對,現在可以用混合地形了,甚至連地形主題都能混用。[佈雷特·伍德]實際上,你可以在編
輯器裡定義你自己的地形主題,這是連魔獸爭霸III都不具備的功能。


2]新編輯器支持彩色文字,自定義單位顏色,以及「12號玩家」(是說SC1里的中立玩家)麼?

[達斯汀·布勞德]對,全部支持。


3]地圖會大於256x256麼?

[佈雷特·伍德]最大尺寸還是256x256,我們也沒計劃擴展它。


4]新地圖編輯器支持地圖加密麼?我們不喜歡老是被盜版。

[達斯汀·布勞德]對,我們計劃支持這一功能。希望這一特性能鼓勵大家創造更多真正屬於自己的地圖。


5]新編輯器支持調整建築的地面貼圖麼?

[達斯汀·布勞德]對。用戶可以使用地圖編輯器做出任何形狀任何大小的建築地面貼圖。


星際爭霸II Q&A第30彈:地圖編輯器系列3(2008年2月15日)

為配合我們本月論壇討論主題:地圖編輯器建議收集。我們再度展開地圖編輯器系列問答以替大家指明討論方向。

開發者訪談:我們再次邀請了佈雷特·伍德來回答論壇上的地圖編輯器問題。目前大家對星際爭霸II UMS領域
巨大的潛力還沒有足夠深刻的理解,而我們真心希望帶給大家真正需要的工具,為星際爭霸II的遊戲性帶來
更精彩的額外體驗。

一如以往,如果您對開發組和我表現感到滿意,請不要吝惜您的掌聲!


1]能不能做出攔截飛來的法術/導彈的效果。

用自定義技能/或是用觸發器都能辦到。


2]所有單位都有男版/女版可供選擇麼?

不,這個真沒有。我們沒打算做這個。


3]是否有選項能讓玩家在遊戲裡切換武器?

我們沒打算給這個提供界面支持,但利用目前自由度極高的技能系統,這還是能做到的。


4]能不能把幾張多人地圖連起來,做出多人戰役來?

可以,我們計劃實現多人戰役和多人地圖的連接。


5]我們可以針對某個特定建築禁用科技樹麼?

通過自定義數據/或是觸發器可以完全隨心地設置科技。


6]某項研究,或者在某個特定地點使用某個特定技能這種,都能作為科技解鎖的條件麼?比如研究完興奮劑
後就可以造工廠?

可以,科技樹和科技升級系統是完全自由的。


7]可以對AI發佈研究技能和科技,在某地造東西,在某地造兵,進攻撤退之類的命令麼?

可以,新的AI腳本系統完全支持這些。


8]地圖作者們能用天氣效果改變地形或是干擾玩家的遊戲進程麼?天氣效果是全局的還是可指定區域的?

天氣效果技術上講還未完成。然而就算天氣效果無法影響遊戲,你還是可以通過觸發器來實現。


星際爭霸II Q&A第39彈:地圖編輯器系列4

隨著星際爭霸II開發的不斷進行,地圖編輯器的功能也在隨之進化。星際爭霸II無疑將湧現出無數帥氣的地圖,
因此我們的Q&A中不會忽視您任何有關地圖編輯器的問題。繼續拿問題砸我吧!

開發者訪談:39彈主要集中於星際爭霸II地圖編輯器的開發,我再次有幸跟我們的地圖編輯器設計師佈雷特·
伍德進行了交談。佈雷特回答了我們相當多的問題。此外他還指出,星際爭霸II的地圖編輯器在各方面都超
越了魔獸爭霸III的地圖編輯器,還增加了許多新特性,如遊戲中的所有技能都是數據驅動的。佈雷特·伍德在
此舉了個例子說明了所有技能數據驅動的意義。

[佈雷特·伍德]比方說你有一個很酷的內爆術技能創意,該技能令目標單位迅速收縮,然後爆發出一陣能量波
傷害周圍一定範圍內的單位。可是呢,由於sc2里沒有這樣一種可以收縮目標單位的技能來讓你用作模板。
於是在war3時代就得用上觸發來實現這一效果了。而在sc2里,你完全可以直接通過修改數據文件來構造這
一效果而不必用到任何觸發或腳本。總體來說,在sc2里你通過修改數據來創造自定義技能和特效甚至要比
通過觸發方便快捷得多。當然,這一技術也需要一個學習的過程。


1]新地圖編輯器支持放置陷阱、門、之類的其它地形主題下的物體麼?(比如在叢林主題的地圖上放門、自
動炮塔、陷阱牆)

可以,數據文件中定義的所有物體都能放置在地圖上,無論你採用什麼樣的地形主題。


2]新地圖編輯器支持更高的科技級數麼?(比方說30級)

可以,科技數據可以自由擴展,其實魔獸爭霸III裡就行了。另外,科技現在終於可以通過觸發器來降級了
(輸入負數),這點可是魔獸爭霸III地圖作者們的一大怨念。


3]新編輯器依舊支持當前星際編輯器所有的功能麼?

這問題太含糊了。就我所知,SC1能做的一切,SC2都能做。


4]新編輯器有些什麼新特性?

我懷疑我全部扯完你都睡著了。粗略地說下好了,相對魔獸爭霸III最大的改進是我們的數據編輯器。數據編
輯器真正意義上的可供你修改遊戲中的任何數據。而觸發編輯器裡現在甚至可以使用自定義函數和庫。也就
是說無論哪一方面都相對we和se有所增強。


5]你們計劃吸取第三方編輯器的優點,並經常升級編輯器以順應廣大地圖製作者們的要求麼?

顯然如此。我們決心全力支持地圖/改版組織,我們也會關注網上各大論壇,隨時加入各種新的特性。


6]會有專門的工具來將WC3的模型轉換成SC2模型麼?

不會,畢竟星際爭霸II的引擎和魔獸爭霸III完全不同。


7]既然蟑螂的生命恢復速度十分之快,玩家可以改變Zerg單位的生命恢復速度麼?

當然可以。(誰問的這種傻問題?)


8]玩家能把Protoss的護盾和Zerg的恢復能力賜給正常情況下沒有這種能力的單位麼?比如能回血的狂劍
客,有護盾的幽靈之類的。

當然,如果你想你完全可以創造一個小強狂劍客。很多被動技能都可以相換的。


9]星際爭霸II的新地圖編輯器能讓我們通過混合三族的模型和技能創造出第四種族來麼?甚至通過編輯器加
入全新的單位?

當然可以,完全支持自定義種族,甚至可以在你玩對戰的時候選擇這些種族,只要你載入了該種族的定義文件。

就知道你們會喜歡這個的。


星際爭霸II Q&A第52彈:地圖編輯器系列5(2009年6月12日)


1]我們還用JASS麼,還是什麼強化版JASS?

星際爭霸II使用全新腳本語言,代號「銀河」。該語言和C非常相似,任何熟悉C語言的人都能很快上手。


2.該語言是事件驅動還是面向對象的?

該語言本身並非面向對象,但大部分本地函數是對遊戲對像進行操作。


3.相比起魔獸爭霸III的編輯器,新編輯器對遊戲界面的可自定義程度如何,有任何強化麼?(這點在魔獸爭霸I
II中被嚴重限制)

遊戲界面大部分可由數據文件定義,不過我們並沒有對那些文件提供直接的編輯器支持,因此自定義界面是
可能的,只是缺乏友善的GUI。


4. 星際爭霸II編輯器中有什麼可圈可點的新功能?還是只有些基本功能強化?

魔獸爭霸III中任何一處功能(無論大小)在星際爭霸2編輯器都有某種程度的強化。


5.觸發器中的事件通訊能力,如動作和條件,在新語言中有所增強麼?

觸發編輯器中一項顯著更新是動作和條件中對自定義函數的支持。意即你能創建自己的動作(具體通過其他
動作或自定義腳本創建),然後將其應用於你的觸發器裡。


6.相比起魔獸爭霸III編輯器,對「英雄」的支持有所變化麼?還是根本就一樣?

我們努力製作了一個全新的英雄系統,比魔獸爭霸III更具自由度。例如,地圖製作者可以添加任意數量的自
定義英雄屬性。


7.這套編程語言有沒有公用API?

在魔獸爭霸三中擁有大量反映遊戲功能的的本地函數,可通過腳本進行二次開發,如果這就是你所謂的「公
用API」,那麼回答是「有」。


8.新語言中的垃圾回收機制有所改善麼?例如,JASS中所有的局部變量都需要在用完後置空,某些數據類型
用完後還需要手動從遊戲中刪除(例如點對像)以防內存洩露。

銀河擁有一套健壯的垃圾回收系統,適用於任何本地類型,相對魔獸爭霸III而言是極大的躍進(其實從技術上
講魔獸爭霸III跟本不具有垃圾回收機制)。魔獸爭霸III中的內存洩露問題將成為歷史。
觸發編輯器中一項顯著更新是動作和條件中對自定義函數的支持。意即你能創建自己的動作(具體通過其他
動作或自定義腳本創建),然後將其應用於你的觸發器裡。


一些從BN論壇上收集來的地圖編輯器的零散問答(2007-2009):


原版星際爭霸的單位會包括在星際爭霸II地圖編輯器中麼?

地圖編輯器中確實包含標準對戰模式中不存在的單位。包括許多星際爭霸I才有的單位,如Protoss龍騎兵。


遊戲中可以自定義隊伍顏色麼?

在用地圖編輯器中創建自定義地圖的過程中,可以為隊伍選擇任意顏色,即便是在多人對戰中,也有12-18
種預定義顏色可選。


牛頭機槍兵會出現在編輯器裡麼?

會。


目前看來地圖編輯器真的十分強力,對地圖製作者們的創意幾乎無所限制。那麼編輯器會否有可能更改某些
遊戲關鍵性功能比如尋路系統呢?如果真的可以的話,看起來這東西真的什麼極限都沒有了,至少是我們目
前想像得到的極限。

尋路系統,定義的是單位移動的方式,很遺憾這東西是寫死的代碼,是無法通過地圖編輯器修改的。不過地
圖作者可以通過修改腳印、單位尺寸等方式來影響單位的移動方式。


編輯器裡能使用單人戰役的3D即時演算機制(就像之前的視頻裡所展示的那些過場動畫一樣)製作電影麼?

可以,我們期望能看到更多出自玩家之手的精彩電影地圖。


最近放出的截圖() 展示了
一場雨夜的戰鬥。日夜效果和天氣效果是否僅限於戰役模式呢?它們能在地圖編輯器中使用麼?

日夜效果和下雨效果應該只會出現在戰役裡,不大可能出現在多人對戰中。至於地圖編輯器中自然是可用的。


你們有計劃向正規戰網ladder地圖中添加自定義地圖麼?

未來,地圖製作者將有機會讓自己的地圖進入戰網的ladder地圖庫。當然,我們會謹慎審查它們的質量。具
體而言就是多人遊戲時的競技性。


嗨,星際2裡至今還未見過任何海軍單位。顯然對戰裡是不會有海軍的,不過UMS地圖裡能有海軍麼?

需要一些觸發腳本來支持,在模型方面也要花點功夫,但總體來說是可行的。


星際爭霸II會有新的地形主題麼?星際I中有些地形主題會被刪除麼?

星際I中許多地形主題,如瑪薩拉,查爾,夏庫拉斯,以及空間站等等會回歸星際II。我們也增加了一些新的
地形主題,比如「戰爭摧殘後的城市」。


既然「好渣的編輯器」在各方面都打敗了魔獸爭霸III世界編輯器,你們有計劃在編輯器裡添加野怪麼?就算
算上SC1里的單位和戰役裡的特殊單位,星際II裡可供選擇的模型還是及不上魔獸爭霸III,除非你們專門替自
定義地圖設計一個模型庫或者一堆野怪。我們是不是可以期待能看到很多新的科幻模型,或者是從魔獸爭霸I
II導來的模型,用來擴充編輯器的模型庫?

不,除了遊戲裡用得到的,星際II不會有任何「額外」模型。當然還是會有些「彩蛋」模型的。不過要弄清楚,我們沒計劃添加任何多餘單位。


資源限制似乎也是地圖製作者們的一個大問題:不論是星際爭霸II還是魔獸爭霸III裡都只有兩種。需要UMS
地圖裡可能會需要氣體和水晶以外的資源,於是很多地圖可能被迫使用人口之類的數據來充當資源。那麼在
新的地圖編輯器中允許放置類似黃金和木頭之類的新資源麼?

對,我們最近使地圖編輯器可以支持一種新的自定義資源。至於將來能否支持更多還要看情況,不過目前還
沒那方面計劃。


請描述一下星際爭霸II中的AI,它相比起以前的AI會有什麼樣的進步呢?

我們的AI幾乎是純腳本驅動的。這次我們打算徹底地把它的特性抖出來讓大家瞧瞧。我們每次進行較大的平
衡性改動,都要回頭去看看AI的適應能力。目前我們困難難度的AI是相當強的,不過相比起我們計劃中要在
遊戲發售時達到的效果,這還只是個開始。它們會採取各種戰略和進攻路線,因此你一定會大吃一驚的。不
過在Beta以前我們還得將之全部重寫一遍。這畢竟不是個學習型AI,因此我們不得不進行大量的手動調整。
我們準備了多套算法,以根據當前數據預測玩家的動向。在AI方面,我們目前做的東西有一點跟以前完全不
同——我們以前的AI其實都是作弊的。星際爭霸I和魔獸爭霸III的AI都是開全圖的,這樣它們就能看到玩家在
造什麼做什麼。不過星際爭霸II的AI則必須自己靠偵察來瞭解情況,因此做起來難多了,不過到目前為止,
這個AI系統的效果十分明顯。



寫一下sc2編輯器目前已知的功能





文章網址:http://sc2bbs.uuu9.com/read.php?tid=2296889

關於名稱:
這個編輯器目前定名為Scumedit,而相應的模型工具的名字叫Startools(對應war3的Arttools)

關於腳本:
腳本是基於c語言的,所以大家趁早學習起c罷。雖然對於是c而不是面向對像c我有點怨念。當然不會編程也不要緊,觸發編輯器不會消失的,而且只會更加易用。

關於額外模型:
所有在SC2中被廢棄的SC1單位雖然不會出現在標準對戰中,但都會出現在編輯器中。另外有幾個牛頭人機槍兵的惡搞模型和戰役專用模型。此外並沒有更多的官方附加模型了。至少出來的時候不會有。

關於war3->sc2的模型轉換器:
官方不會出這東西,暴雪的說法是兩者模型格式相差過大

關於玩家設定:
可自定義玩家顏色,可以在所有可見光色中隨便選擇,普通對戰中最大玩家數依然是8個(目前),最大地圖尺寸還是256X256(目前)。自定義地圖額外支持中立玩家,至於自定義地圖最大玩家數,目前還blz還未定,但是基本方針為「至少12人」。

關於戰役英雄:
官方戰役英雄Raynor會在戰役中出場,不過直接參戰場數不多,畢竟他只是個凡人。而在以後將出的第一部資料片裡,Kerrigan直接出場的次數將會非常多,大部分關卡都是她個人秀。和星際1不同的是,相對普通單位,戰役英雄擁有更多獨特的技能。當然標準對戰裡還是沒有英雄。

關於英雄系統、物品系統、屬性系統。
星際2中內建了物品和經驗升級機制,雖然在標準對戰中未開放,但可以直接在UMS地圖中套用。普通單位的軍銜升級機制也在考慮中(不會出現在標準對戰中)。

對投射物的控制:
能夠更自由地控制飛行中的投射物。

關於3d引擎:
支持動態光影,
套用Havok物理引擎但只應用在不會影響平衡性的視覺方面。

關於天氣效果:
支持天氣和氣候效果。

關於地形的自定義:
有更完善的地形修改、混合和控制能力。甚至可以創建各種形狀的地形。

多人戰役:
支持多人連線的跨地圖戰役。

關於AI
強化的AI腳本支持。再也不是war3里那種不得不讓你用觸發器來模擬的死相AI了

關於數據編輯器:
數據編輯器是物體編輯器的更加強化版,幾乎可以修改遊戲中任何數據文件。
對遊戲中所有數據文件的徹底駕馭和修改,可以真正從源頭開始創造一個想要的技能而不需觸發來模擬。
雖然不具備武器更換界面,但你也可以通過全新的技能系統來實現這一點。

關於科技:
科技終於可以降級啦。

鏡頭控制:
更全面的鏡頭控制能力。

自定義遊戲界面:
支持自定義遊戲界面,但並無專門的界面編輯器。也許我們可以自己用vs2008shell做個界面編輯器。

自定義種族:
完全支持自定義新種族。

地圖版權:
計劃支持官方的地圖加密,以保護作者的版權,雖然具體形式還未定。

海戰:
關於以何種方式支持海戰的問題,還在研究中。


以上是目前確定的功能,然而beta還未開始,我們還有機會在beta期間繼續提改進建議。


未來功能:
在遊戲推出以後隨著版本的升級也會隨之更新地圖編輯器功能,在兩個計劃中的資料片發佈時都會對地圖編輯器進行大改進。比如第一個資料片出來以後就會對RPG系統進行進一步強化和支持,然後上面提到的自定義界面的界面編輯器。雖然原版中不會包括,今後的資料片可能加入。
另外還有前幾天說的中途加入遊戲功能,不過目前這個只是個盼頭而已。


---------------------------------------------------------------------
強大的SC2收費模式

文章網址:http://sc2bbs.uuu9.com/read.php?tid=2296942

在《星際爭霸2》中,自定義地圖將會分為兩個類別,免費的和收費的。至於到底是免費還是收費則由地圖創作者自己決定。如果是收費地圖的話,每當地圖被購買時他們就會獲得收入,當然暴雪也會在這種收入中抽取一部分。在這一次的暴雪嘉年華上,暴雪官方為我們演示了兩個由新的地圖編輯器所製作出來的自定義地圖。這兩個地圖一個是第三人稱的射擊遊戲,另一個則是縱版飛行遊戲。從這兩個地圖我們就能看出來新的地圖編輯器的強大--至於Dota?那當然更不是問題,或許Icefrog再也不用為他的創意因為地圖編輯器的限制而無法實現來發愁了。

BLZ的官方地圖對戰地圖別收錢就行了,RPG地圖BLZ是作不過玩家的

iphone的store翻版- -
iphone已經試水了。。這次SC2採取MOD作者自定義收費是個不太風險的舉動。對玩家和暴雪都是好事。



[教程] 禁止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





※怎麼下載?Xuite硬碟MediaFireBadongoSendSpace
※文章可以轉貼嗎?可以,不過要註明出處、標示本站連結。
※載點可以轉貼嗎?不可以,不能盜連。
※建議瀏覽器:Chrome 或 Firefox 或 Opera 或 IE7以上
!請按+1來支持本站!