整張地圖的完整狀態(WorldState):.units .players .items .clock .me,max_age 秒內重複呼叫會回傳同一份。 ⚠ 進了金礦的工人不在表裡;預設全圖可見(鎖步模型在本機什麼都有),Game(fair=True) 才依視野過濾。
底層 W3P 世界區塊 Local\War3World_<pid>(執行環境每 50 ms 推送,seqlock)
由 python -m openwar3 catalog --write 從程式碼產生,和 SDK 同步更新 —— 模型不必猜哪個方法存在、哪個真的能用。同一份資料也以 JSON 提供,可以直接交給 Agent。
讀取狀態,不改變遊戲。絕大多數直接讀取推送快照,零等待。
整張地圖的完整狀態(WorldState):.units .players .items .clock .me,max_age 秒內重複呼叫會回傳同一份。 ⚠ 進了金礦的工人不在表裡;預設全圖可見(鎖步模型在本機什麼都有),Game(fair=True) 才依視野過濾。
底層 W3P 世界區塊 Local\War3World_<pid>(執行環境每 50 ms 推送,seqlock)
最後一次看見的敵方(或 'creep' 野怪、或某個玩家編號)單位:[(單位當時的樣子, 當時的遊戲時鐘, 過了幾秒)],新的在前。 看見它死了就從表裡刪掉。公平模式和一般模式都依「我方此刻看得見」來記錄 —— 這就是玩家腦中的那張地圖: 偵察到的兵力、上次看見對方英雄在哪裡、對面分礦什麼時候開的。max_age:只要這麼多遊戲秒以內的。
底層 推送快照的 visibleTo(每次更新快照時記下看得見的敵方/野怪單位)
這一局的地形表 MapInfo:.walkable(x,y) .buildable(x,y) .at(x,y) .bounds(可玩區).starts(出生點).cells(bit0 不能走、bit1 不能蓋)。 開局後要幾秒才算好,還沒算好時回傳 None。樹不在裡面(用 trees())。
底層 W3P 地圖區塊 Local\War3Map_<pid>(開局後由執行環境分批計算,IsTerrainPathable 行走/建造)
{'gold','lumber','food_used','food_cap','gold_gathered','lumber_gathered'};player 預設為我方,任何玩家都讀得到。 讀不到時回傳 None,別當成 0。
底層 世界區塊 players[16]
全部 16 個玩家欄位:Player(id, gold, lumber, food_used, food_cap, gold_gathered, lumber_gathered, race, known)。
底層 世界區塊 players[16]
依擁有者/類型篩選單位。owner:'me' / 'enemy' / 'creep' / 'all' / 玩家編號。types:四字碼集合。
底層 世界區塊 units[]
沒工作的工人:沒有訂單、也沒有任務(這一拍剛被你派了工作的不算)。 ⚠ 對有任務的工人重新下採集令會打斷採集週期(收入歸零)。
底層 推送快照(訂單欄位 + 任務欄位)
這個工人是不是正在蓋房子(或正走去蓋 / 正在幫忙修;含這一拍剛派的)。挑建造工人時要跳過它,否則上一座地基會停工。
底層 推送快照(訂單 = 建築四字碼,或施工令/修理令)
這座建築還沒蓋完(血沒滿)。⚠ 被打殘的建築也不是滿血 —— 開局判斷夠用,開打之後要結合時間來看。
底層 推送快照(地基的血量從很低一路漲到滿)
{'hp','hp_max','mana','mana_max'}(浮點數,引擎原始值)。u 用快照裡拿到的單位即可(會換成最新的一份)。
底層 世界區塊單位 hp/hpMax/mana/manaMax
[{code, level, cooldown, flags}];buff 在 buffs(u)。只有「有細節」的單位才有(英雄 > 玩家單位 > 野怪,最多 256 個)。
底層 世界區塊細節:技能(代碼/等級/旗標/剩餘冷卻)
單位身上的 buff 代碼(例如 'BHds' 神聖護盾、'Bslo' 減速)。代碼對應什麼效果見 data/game/buffs.json。
底層 世界區塊細節:B 開頭的技能物件
這個技能還要冷卻幾秒(遊戲秒);0 = 可以施放;沒有這個技能(或這個單位沒有細節)時回傳 None。
底層 世界區塊細節:技能剩餘冷卻(技能計時器)
{'order','target','x','y'}:單位手上的這條訂單(order 是 0x000D00xx 或建築四字碼,0 = 閒置)。 target 是控制代碼對,用 g.unit(target) 換成單位。
底層 世界區塊單位 order / 訂單目標 / 訂單目標點
單位**實際在打/在追**的那個單位(沒有則回傳 None)。 ⚠ 攻擊令下完後訂單欄位很快就變空,攻擊掛在任務上 —— 判斷「在打誰」用這個,別用 current_order。
底層 世界區塊單位任務目標
這座建築正在做什麼:Production(kind, queue, duration, elapsed, blocked, progress, remaining…),沒在做則回傳 None。 kind 'queue'(訓練/研究/英雄,queue 最多 7 格,[0] 是正在做的)/ 'construction'(建造中)/ 'upgrade'(升級大廳/塔); blocked = 有排隊但沒開始(多半是人口不夠 —— 該蓋農場了);progress 0..1。 對手的建築也能看(公平模式下只有看得見的建築才有)。
底層 世界區塊生產表(Aque/ABnP/AUnP 技能物件 + 執行環境追蹤的已進行時間;實測誤差 < 0.2 遊戲秒)
全部正在進行的生產 [(建築, Production)]。owner 同 units():'me' / 'enemy' / 玩家編號 / 'all'。 職業用法:看對手在訓練什麼兵、研究什麼科技、什麼時候升級主城(偵察到建築時)。
底層 世界區塊生產表
地面單位從 a 走到 b 的路程(a、b 給單位或 (x,y));走不到則為 None。島嶼地圖上判斷「這個野點/分礦地面過不過得去」用它, 比直線距離可靠(繞樹林、繞懸崖、繞建築)。精度為一格 128;窄於一格的縫隙判定為不通。
底層 地圖區塊(引擎 IsTerrainPathable)+ 樹區塊 + 建築占地,SDK 端 A*(128 一格)
路徑轉折點 [(x,y)...](最後一點是 b);搭配 path(units, 點列表) 讓部隊沿這條路走(繞開塔、走小路)。
底層 同上
維護費檔位:{'level': 'none'/'low'/'high', 'income': 1.0/0.7/0.4, 'next_at': 下一檔的人口(沒有 = None)}。 職業常識:升到第三級主城、做攻防升級時停在 50 人口,決戰前才上 80。
底層 1.27 固定規則:0~50 人口不收、51~80 收入 ×0.7、81~100 ×0.4
把場上(看得見的)野怪聚成營地:[{'x','y','units','level','hp','max_level'}],依離我方主基地由近到遠排序。 level = 營地總等級(衡量打野難度的常用標準),hp = 總血量。搭配 time_to_kill / path_distance 挑點。
底層 推送快照(野怪依 600 的距離連成一群)+ units.json 等級
buff 代碼是什麼:{'ability','effect','dur','hero_dur','targets'}(例 'Bslo' -> 減速)。一個代碼對應多行時給第一行。
底層 data/game/buffs.json(AbilityData.slk 的 BuffID -> 技能/效果/時長)
單位的戰鬥屬性 combat.UnitStats:生命/魔力上限、護甲(含攻防升級、英雄敏捷)、護甲類型、移動速度、白天/夜裡視野、 武器(能打什麼、射程、攻擊間隔、傷害區間、攻擊類型、濺射)。u 給單位(自動用它擁有者的科技、英雄等級)或四字碼(player 預設為我方)。 再搭配 .dps_vs(對方) / .hits_to_kill(對方) / combat.time_to_kill(一群, 對方)。⚠ 不含物品、光環、buff。
底層 資料表(UnitBalance/UnitWeapons/UpgradeData/MiscGame)+ 即時科技等級 + 英雄等級
這群單位一起打 target 要幾遊戲秒(用 target 目前的血量;算入克制、護甲、攻防升級;不算走位、濺射、治療)。 職業用法:集火先打「最快能打死」的那個(time_to_kill 最小),而不是最近的那個。打不到 = None。
底層 stats() + 即時血量
遊戲內時間(小時,0~24)。開局是早上 8 點;一整天 = 480 遊戲秒(白天、黑夜各 240 秒,依晝夜流速縮放)。 讀不到(舊版執行環境 / 不在局內)時回傳 None。
底層 世界區塊擴充區:GetFloatGameState(GAME_STATE_TIME_OF_DAY)
現在是不是夜裡(18:00~6:00)。職業打法:夜裡野怪睡著(先手打野不會被包圍)、所有單位視野變短(偷襲的好時機), 夜精靈的哨兵/單位夜裡在樹旁會隱形。讀不到時回傳 None。
底層 世界區塊擴充區(6~18 點為白天)
離遊戲內時間 hour 點還有幾遊戲秒(例如 seconds_until(18) = 離天黑還有多久,規劃夜裡打野時用)。
底層 世界區塊擴充區 + 一天 480 秒(實測 20 遊戲秒/小時)
地上的物品 [Item(addr, handle_lo, handle_hi, type, x, y, life)]。撿走/用掉會發 item.removed 事件。
底層 世界區塊 items[](只含地上的:持有者控制代碼全為 FF)
活著的樹(DestructableData 裡 targType 含 tree 的),給了 (x,y) 就依距離由近到遠排序,最多 limit 棵。 每棵是 Tree(addr, handle_lo, handle_hi, type, x, y, life),可以直接交給 gather 去伐木。
底層 樹區塊 Local\War3Trees_<pid>(每 2 秒更新)
上次呼叫之後發生的事:unit.appeared / unit.died / unit.removed / unit.damaged / order.changed / hero.levelup / owner.changed / item.appeared / item.removed / game.started(這些依發布比對得出,精度 = 發布週期 50 ms), 以及引擎層級的 damage / killed(執行環境在遊戲執行緒上當場記下,**每一下**都有): damage:handle = 挨打的,.source_addr = 打它的(用 snapshot().unit_by_addr 換成單位),.value = 實際扣掉的血, .raw_damage = 護甲前的傷害,.attack_type(normal/pierce/siege/magic/chaos/hero/spell),.damage_type killed:這一下把它打死了,.source_addr = 兇手 以及執行環境追蹤生產表得出的 production.done(精度 = 發布週期):單位 = 建築,.done_code = 完成的四字碼, .done_kind = 'training'(兵/英雄/復活)/ 'research' / 'construction'(建築蓋好)/ 'upgrade'(升級主城/升級塔),.value = 花了幾遊戲秒 09-25 補齊: spell.cast:單位 = 施法者,.spell 技能四字碼,b 等級,value 冷卻秒數,x,y 施法點(在技能開始冷卻時辨識出來,精度 = 發布週期) player.left:.player 離開 / 被判定落敗移除的玩家編號;game.ended:離開對局 selection.changed:本機玩家的選取變了(用 g.selection() 取得單位) message:螢幕訊息框裡的一條(遊戲提示、聊天、系統):.text 全文,.frame 訊息框編號, .chat = {'channel', 'sender', 'text'}(是聊天時;玩家在聊天框輸入的文字就從這裡讀取) ui.click / ui.hover / hotkey / mouse.world:介面與輸入(g.ui),.key 是畫板 key / 熱鍵寫法 每筆是 Event(seq, kind, clock, addr, handle, type, owner, a, b, x, y, value, extra)。 公平模式(fair=True)只給:自己單位的事件、此刻看得見(或 1 秒內還看得見)的單位的事件、打我方/我方打的傷害, 以及本機的介面 / 訊息 / 對局類事件。
底層 事件環 Local\War3Events_<pid>(發布比對 + 執行環境擷取的傷害事件)
本機玩家目前選取的單位(主單位排第一;最多 12 個)。選取一有變化就會發出 selection.changed 事件。
底層 W3P 世界區塊擴充區 selAddrs(執行環境每次發布時帶上本機玩家的選取)
上次呼叫之後螢幕訊息框裡新出現的訊息:[{'text', 'frame', 'repeat', 'seq', 'game_ms'}]。 遊戲提示(「需要更多的農場」「不能在那裡建造」)、聊天、系統訊息都在這裡;frame 區分是哪一個訊息框。 和事件流裡的 message 事件是同一批(各有各的游標)。
底層 共用記憶體 Local\War3Msgs_<pid>(執行環境擷取的螢幕訊息)
研究等級 / 已建成的建築數(升級鏈算在內:城堡也算 htow)。player 預設為我方,任何玩家都能查。
底層 W3P 查詢 q_tech(引擎的玩家科技計數)
引擎的可行性裁決:0/220 可以下令;3 人口 8 缺金 9 缺木 32 佇列滿 183 缺前置 185 祭壇正在復活 221 沒有這一項/建造中。 ⚠ 對工人建造建築一律回 221,不能用來判斷落點(用 build_near)。
底層 W3P 查詢 q_feasible(引擎可行性檢查)
一次問很多個 can_do:pairs = [(單位, 四字碼), ...],回傳同樣順序的裁決碼列表(問不到的是 None)。 規劃一拍要蓋/訓練什麼時先整體問一遍,比逐個 can_do 快 N 倍(參考大腦 09-23:建造規劃 76 -> 25 ms)。
底層 W3P 查詢 q_feasible × N,一批提交
一次查很多個科技/建築計數:{四字碼: 數量或 None}。
底層 W3P 查詢 q_tech × N,一批提交
這一點我方現在看不看得見(不在迷霧/黑區裡)。公平模式的 bot 應該只用看得見的敵人。
底層 W3P 查詢 q_visible(看得見 / 迷霧 / 黑區)
電腦 AI 的隊長:它帶兵要去哪裡(出門前就知道要打你家哪裡)。只對電腦對手有效;沒跟著隊長走時回傳 None。
底層 W3P 查詢 q_captain(敵兵跟隨的電腦隊長)
單位目前的訂單,**含你這一拍剛下的**(快照還沒跟上時,用回執裡的新訂單)。 ⚠ 09-23 實機:hello_bot 剛派農民去蓋農場,同一拍 rush_bot 從快照裡看它「閒置」又派去蓋兵營,農場一次次半途而廢。 挑「閒著的/沒在蓋房子的」單位時,用這個而不是 u.order。
底層 快照訂單 + 本行程剛被接下的命令(回執)
現在的金/木夠不夠買 code(單位、建築;依 units.json 的價格)。價格表裡沒有的一律當作買得起。 ⚠ 升級主城的四字碼在表裡是累計價格,這裡會偏保守;最終以引擎的回執為準。
底層 推送快照的我方資源 + units.json 的價格
目前這張地圖的資料(openwar3.mapdata.MapData):name_of('HC07') 自訂單位/物品/技能的名稱、hero_names、tooltip。 RPG 地圖的單位大多是地圖自己做的,內建名稱表裡沒有;不是由啟動器開啟的遊戲(找不到地圖檔案)回傳 None。
底層 地圖檔案(啟動器 --map 的路徑):w3u/w3t/w3a + wts,受保護的地圖讀取圖內的 TXT
讓單位做事。約一幀生效,每條都有回執。
把一拍裡的命令合成一批: with g.batch() as b: g.attack(archers, target) # 回傳 Pending,區塊結束後才變成回執 g.move(wounded, *home) g.cast(hero, "thunderclap") print(b.sent, b.wait_ms, [r.reason for r in b.receipts]) 每條命令單獨送出都要等遊戲執行緒處理一次(約 10 ms);一批只等一次 —— 參考大腦 09-23 靠這個把一輪從 48 -> 26 ms。 * 仲裁照舊逐條進行(被占用的單位當場得到 held 回執,不進入批次); * 區塊裡的命令回傳 Pending:區塊結束前讀它的 .ok 會拋出錯誤(回執還不存在),區塊結束後和 Receipt 用法一樣; * 區塊裡拋出例外 = 整批作廢(status 97 cancelled),被占用的單位會放回去; * 查詢(can_do / tech / visible …)和 build_near、buy 不進入批次,照舊當場詢問 —— 它們的結果當場就要用; 要一次問很多個就用 can_do_many / tech_many; * 巢狀的 with g.batch() 併入最外層的那一批;超過 16 條時執行環境會自動分成幾段(每段等待一次)。
底層 區塊裡的命令累積成一批,區塊結束時一次提交(同一幀執行、只等一次遊戲執行緒)
走到 (x,y),路上不打人(撤退用這個)。可以傳一個單位或一個列表(同一幀一起下令)。 queue='after':做完手上這件再去(接在目前訂單後面)。回執 values[0] = 下令後這個單位排著幾條訂單(含正在做的)。
底層 W3P point:move(extra 位元 = 排隊方式)
攻擊移動(A 地面):路上遇敵就打。queue 同 move。
底層 W3P point:attack 對點
打 target。預設用右鍵(對敵人 = 攻擊這一個,09-23 實測訂單目標/任務目標都是它)。 ⚠ 目標必須在視野內,看不見的會被拒(原因碼 1001)。 force=True 用攻擊令 0x0F(打自己人/中立小動物時需要它)—— 實測它只換上攻擊令、不記住目標, 會去打附近別的敵人,要打特定目標時別用它。
底層 W3P target:目標命令(右鍵 smart)
攻擊地面:用砲對一塊地方開火(打隱形單位、打樹林後面的敵人、封鎖路口)。只有能攻擊地面的單位接受。
底層 W3P point:attackground(攻城單位 / 迫擊砲 / 投石車)
依序走過一串點(Shift 連點:路徑點、繞開塔、偵察路線)。attack=True 時每段都是攻擊移動。 一次提交;每個點一張回執(依 points 順序)。
底層 一批:第一段立即執行,其餘倒序用 queue='after' 插入(引擎只能插在目前訂單後面)
採金/伐木(target 是金礦或 trees() 裡的樹)。⚠ 只派閒置的工人(idle_workers):對有任務的工人重新下令會打斷採集週期。 職業用法:蓋完房子回去採礦 = build(...) 之後 gather(worker, mine, queue='after')。
底層 W3P target:harvest(金礦或樹)
讓工人在 (x,y) 蓋 code(座標對齊 32 格)。回執接下 = 工人的訂單已經是這座建築(或開工令); queue='after' 時 = 已排進工人的訂單佇列(回執 values[0] 為排隊數)。 ⚠ 接下 ≠ 蓋得成:樹林裡的點引擎也會當場接下,工人走到了才失敗(09-23 實測);錢被別處花掉也會讓地基出不來。 不知道哪裡放得下就用 build_near(它會追蹤結果、把失敗的點列入黑名單)。連蓋幾座用 build_queue。
底層 W3P build:建造訂單,同一幀讀回工人訂單以確認
一個工人依序連蓋幾座(Shift 連蓋):plan = [(四字碼, x, y), ...]。一次提交;回執依 plan 順序。 ⚠ 錢是開工時才扣的(排隊時不扣)—— 排了 3 座但錢只夠 1 座,後兩座會在工人走到時失敗。
底層 一批:第一座立即執行,其餘倒序 queue='after'
在 (x,y) 周圍由近到遠找一個放得下的點蓋 code。**不阻塞**,每拍呼叫都可以: * 這種建築有一次還在進行中(工人走在路上)-> 回傳那個點,不重複下令; * 上一次成功了(地基出現)-> 這次視需要再找新點; * 上一次失敗了(工人走到才發現放不下,訂單被引擎撤掉、沒有地基)-> 那個點列入黑名單 45 秒,換下一個; * 錢不夠 -> 直接回傳 None(不嘗試、不列入黑名單);全部試完了回傳 None。 ⚠ 為什麼要追蹤:09-23 實機,樹林裡的點引擎**當場接下**、工人走到了才失敗(同一幀的回執判斷不出來); 而引擎的落點檢查對工人建造建築一律回 221,也沒辦法先「查」再蓋。只有明顯被占用的點(大廳正中央)會當場拒絕。
底層 逐點 build + 追蹤(地基出現 = 成功;工人放棄訂單又沒有地基 = 這個點列入黑名單)
訓練單位 / 研究科技 / 升級大廳(升級主城 = 對大廳本身下目標大廳的四字碼,例如 'hkee')。 被拒時回執的 reason 會說明原因(人口不夠、缺金、缺木、佇列滿、缺前置……)。
底層 W3P immediate:四字碼,被拒時帶有可行性原因碼
施放技能。spell 是訂單名('thunderbolt' 風暴之錘、'blizzard'、'holybolt' 聖光術…,見 data/order-ids.txt)或訂單編號。 給 target = 對單位;給 x,y = 對地面;都不給 = 無目標(雷霆一擊、神聖護盾、召喚水元素)。 回執接下只代表引擎接受了;有沒有放出來要看 cooldown() 有沒有進入冷卻、buffs() 有沒有出現。
底層 W3P target / point / immediate(依參數選擇)
設定集結點(對點,或對一個單位/金礦)。
底層 W3P rally
在祭壇復活陣亡的英雄(不給 hero 就復活表裡的第一個)。 被拒的常見原因(回執 reason 裡會寫):人口不夠(英雄也占人口)、錢不夠、剛陣亡不久(陣亡後約 3 遊戲秒才能復活)、 復活已在進行(接下時引擎當場清掉那一格)。
底層 W3P revive:陣亡英雄表 -> 祭壇對陣亡英雄施放復活
英雄去撿地上的物品(item 來自 items_on_ground)。撿到後物品欄裡會出現,地上發 item.removed 事件。
底層 W3P target:右鍵物品
使用物品欄第 slot 格(0~5)的物品;可帶目標單位或目標點。 ⚠ 對點使用物品(例如象牙塔)引擎成功也回 0,回執一律算接下 —— 要看物品欄那一格空了沒有。
底層 W3P use_item(依格位編號)
把物品欄第 slot 格的東西丟在 (x,y)(英雄走過去放下)。
底層 W3P item_drop(照抄 JASS UnitDropItemPoint:dropitem 0xD0021 對點 + 物品即時目標)
把物品欄第 slot 格的東西交給 to(別的英雄/單位,走過去遞給它)。給商店 = 賣掉(見 sell_item)。
底層 W3P item_drop(照抄 JASS UnitDropItemTarget:dropitem 對單位)
把物品欄第 slot 格的東西賣給商店(英雄要走到商店旁邊;可販售的物品才收,退回一半價錢)。
底層 同 give_item,目標是商店(實測避難權杖賣 125 金)
物品欄裡換格子(第 slot 格移到第 to_slot 格;兩格都有東西就互換)。整理快捷鍵位置時用。
底層 W3P target:訂單 0xD0022+格位編號,目標 = 物品(照抄 JASS UnitDropItemSlot)
人類的戰鬥號召:農民變民兵(第一級的城鎮大廳沒有這個技能,只對主城/城堡有效)。
底層 W3P immediate:townbellon/off
遊戲速度、暫停、發布週期、頭頂氣泡、畫板、介面與輸入、訊息。
介面與輸入(openwar3.ui.UI):可點擊的按鈕和選項卡片、熱鍵、點地面選位置、滑鼠指著哪裡。 點在按鈕上的那一下遊戲收不到;純本機輸入 + 本機繪製,多人局也安全。
底層 W3P 74 input_enable + 共用記憶體 Local\War3Input_<pid>(執行環境接收視窗輸入)
世界狀態的發布週期(16~1000 毫秒,預設 50)。一次採集約 0.5 ms,33 ms 也沒問題;整台機器共用一個值,以最後寫入的為準。
底層 世界區塊 requestedPeriodMs
單位頭頂冒出一個聊天氣泡(直播/除錯用,不影響遊戲)。沒冒出來會回傳 False,原因在 g.last_say_error。
底層 動作 56
畫板:在遊戲畫面上畫文字框、面板、進度條、圖片、地上的圈和路線(openwar3.canvas.Canvas)。 由執行環境自行繪製,不建立遊戲控制代碼、不改變遊戲狀態 —— 多人局也安全;樣式隨你定(中文、圓角、半透明)。
底層 W3P 73 canvas_enable + 共用記憶體 Local\War3Canvas_<pid>(執行環境每幀在遊戲畫滑鼠游標之前繪製,游標蓋在上面)
在「按下任意鍵以繼續」的載入畫面上按一下空白鍵。很多 RPG / 劇情地圖載入完成後要按鍵才會開始(09-24 WarChasers 實測: 不按就一直停在載入畫面,遊戲時鐘為 0、快車道不會清空)。openwar3.run 等待進入對局時會自己按,一般不用手動呼叫。
底層 PostMessage WM_KEYDOWN/UP 空白鍵到遊戲視窗(不搶焦點)
JASS 通道:建立單位、設定盟友、改名、顯示文字……供 RPG 輔助和玩伴使用;只有在單人局、本機工具中才能改動世界。
依名稱呼叫任意 JASS native:g.jass.CreateUnit(g.jass.Player(1), "Hpal", x, y, 270.0)。 參數 I/R/B/S/H 自動轉換(單位/物品物件直接傳入),多人局裡只能呼叫唯讀的。詳見 openwar3/jass.py 和 docs/COMPANION_ZH.md。
底層 W3P 70 jass(執行環境依名稱查詢 native 表,1291 個)
16 個玩家槽位:controller(user 真人 / computer / neutral…)、state(empty / playing / left)、human、me、ally(和我是不是盟友)。 在 RPG 地圖裡找空槽位放玩伴、判斷是不是單人局,都用它。
底層 JASS GetPlayerController / GetPlayerSlotState / IsPlayerAlly
在 (x,y) 建立一個單位(player 預設為本機玩家),回傳快照裡的單位(要等下一次世界發布,約 50 ms);建立失敗時回傳 None。 回傳的單位多一個屬性 jass_handle。⚠ 只能在單人局使用(多人局會不同步)。
底層 JASS CreateUnit + W3P 72 控制代碼 -> 單位
設定玩家 a 對 b 的同盟關係:allied = 不互相攻擊 + 互相求援;vision 共享視野;control 共享單位控制權(b 能指揮 a 的單位); xp 分享經驗。both=True 兩個方向一起設定(control 只設定 a -> b)。
底層 JASS SetPlayerAlliance
修改玩家名稱(計分板、聊天、盟友面板裡顯示的那個)。用來幫玩伴取名字。
底層 JASS SetPlayerName
在畫面左下角顯示一行字(地圖觸發器用的那種文字),預設顯示給本機玩家。支援 |cffRRGGBB 顏色碼。
底層 JASS DisplayTimedTextToPlayer
連線狀態與純計算工具。
沒有符合的 API。試試其他關鍵字,或者在文件中搜尋。