MapApi.getTileResourceData(tile) / getAllTilesResourceData()
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/1233
MapApi.getTileResourceData(tile)
和 getAllTilesResourceData()
均由套件 @chronodivide/game-api
提供,用來查詢地圖上資源(礦石、寶石或礦井)的資訊。
在型別定義檔可看到這兩個方法的宣告,回傳型別為 TileResourceData
:
isVisibleTile(tile: Tile, playerName: string, tileElevation?: number): boolean;
getTileResourceData(tile: Tile): TileResourceData | undefined;
getAllTilesResourceData(): TileResourceData[];
TileResourceData
結構包含資源位置與數量等欄位:
export declare interface TileResourceData {
tile: Tile;
/** Number of gem bails */
gems: number;
/** Number of ore bails */
ore: number;
/** Is this a mining drill? (tiberium tree) */
spawnsOre: boolean;
}
實作摘要
在編譯後的程式碼中,getTileResourceData
會先檢索目標格上的物件,只要該物件是資源覆蓋層(Tiberium overlay)或會產生資源的地形,即會將其轉換成 TileResourceData
;若找不到則回傳 undefined
。getAllTilesResourceData
則遍歷全地圖所有物件並收集上述資料:
...getTileResourceData(e){
e = Op(this,Cp,"f").getObjectsOnTile(e)
.find(e => e.isOverlay() && e.isTiberium() || e.isTerrain() && e.rules.spawnsTiberium);
return e ? Op(this,Ap,"m",Bp).call(this,e) : void 0;
}
getAllTilesResourceData(){
var e;
let t = [];
for (e of Op(this,Ip,"f").getWorld().getAllObjects()) {
var i = Op(this,Ap,"m",Bp).call(this,e);
i && t.push(i);
}
return t;
}
Bp = function(t){
let i;
if (t.isOverlay() && t.isTiberium()) {
let e = t.traits.get(Qa);
var s = e.getTiberiumType(), r = e.getBailCount();
i = {
tile: t.tile,
ore: s === la.Ore ? r : 0,
gems: s === la.Gems ? r : 0,
spawnsOre: !1
};
} else if (t.isTerrain() && t.rules.spawnsTiberium) {
i = {
tile: t.tile,
ore: 0,
gems: 0,
spawnsOre: !0
};
}
return i;
}
使用實例
本專案在尋找最近的礦石位置時,會先取得全部資源資料並比對距離:
var closeOre: Tile | undefined;
var closeOreDist: number | undefined;
let allTileResourceData = game.mapApi.getAllTilesResourceData();
for (let i = 0; i < allTileResourceData.length; ++i) {
let tileResourceData = allTileResourceData[i];
if (tileResourceData.spawnsOre) {
let dist = GameMath.sqrt(
(selectedLocation.x - tileResourceData.tile.rx) ** 2 +
(selectedLocation.y - tileResourceData.tile.ry) ** 2,
);
if (closeOreDist == undefined || dist < closeOreDist) {
closeOreDist = dist;
closeOre = tileResourceData.tile;
}
}
}
簡易 bot 範例
下例說明如何在遊戲開始時取得指定格子的資源資料,以及列出全地圖的資源分布:
import { cdapi, Bot, GameApi, Tile } from "@chronodivide/game-api";
class ResourceScannerBot extends Bot {
onGameStart(game: GameApi) {
const tile = game.mapApi.getTile(40, 30);
if (tile) {
const data = game.mapApi.getTileResourceData(tile);
if (data) {
console.log(`(40,30) ore=${data.ore}, gems=${data.gems}, spawner=${data.spawnsOre}`);
} else {
console.log("No resource on (40,30)");
}
}
const all = game.mapApi.getAllTilesResourceData();
console.log(`Total resource tiles: ${all.length}`);
all.forEach(d => {
if (d.spawnsOre) {
console.log(`Spawning tile at (${d.tile.rx},${d.tile.ry})`);
}
});
}
}
async function main() {
await cdapi.init(process.env.MIX_DIR!);
await cdapi.createGame({
agents: [new ResourceScannerBot("Miner", "Americans")],
mapName: "mp03t4.map",
shortGame: true,
online: false,
});
}
main().catch(console.error);
getTileResourceData
讓 bot 能直接檢查某格是否含有礦物或是否為「礦脈」生成格;
getAllTilesResourceData
則一次列出地圖上所有相關地塊,適合在建造礦場或搜尋最佳採集地點時使用。
兩者搭配可迅速掌握資源分布,並據此做出戰略規劃。
→返回《@chronodivide/game-api 使用教學與完整 API 對照表》
This article was last edited at