ProductionApi.isAvailableForProduction(objRules)

| Chrono Divide | 5 Reads

ProductionApi.isAvailableForProduction 的定義

在發佈的型別宣告中,ProductionApi 是用來管理建造佇列與相關邏輯的物件,isAvailableForProduction 判斷某單位/建築規則是否符合生產條件:

1015  export declare class ProductionApi {
1016      #private;
1017      isAvailableForProduction(objRules: TechnoRules): boolean;
1018      getAvailableObjects(queueType?: QueueType): TechnoRules[];
1019      getQueueTypeForObject(objRules: TechnoRules): QueueType;

其實作在壓縮後的 index.js 中,可以看到完整條件檢查:

isAvailableForProduction(e){
    return -1 !== e.techLevel &&
           e.techLevel <= this.maxTechLevel &&
           !(0 === e.buildLimit && !this.player.isAi) &&
           !(e.superWeapon &&
             this.rules.getSuperWeapon(e.superWeapon).disableableFromShell &&
             !this.gameOpts.superWeapons) &&
           this.hasFactoryFor(e) &&
           this.meetsPrerequisites(e)
}

其中 hasFactoryFor 會確認玩家是否擁有對應的工廠,而 meetsPrerequisites 則檢查建築的前置條件及竊取科技等狀態:

hasFactoryFor(i){
    if (i.owner.length) {
        let t = this.getFactoryTypeFor(i);
        return !![...this.player.buildings].find(
            e => e.factoryTrait?.type === t &&
                 (t !== ts.UnitType || e.rules.naval === i.naval) &&
                 !!e.rules.owner.find(e => i.owner.includes(e))
        );
    }
    return true;
}

meetsPrerequisites(e){
    let existing = [...this.player.buildings].map(b => b.name);
    for (var p of e.prerequisiteOverride)
        if ((p = p.toUpperCase()), existing.includes(p)) return true;
    if (!e.isAvailableTo(this.player.country)) return false;
    for (p of e.prerequisite)
        if ((p = p.toUpperCase()), Dl.has(p)) {
            var cat = Dl.get(p);
            if (cat === undefined) throw new Error(`Unknown prereqName ${p}`);
            var list = this.rules.general.prereqCategories.get(cat);
            if (list === undefined)
                throw new Error(`Missing prerequisite category ${cat} in rules`);
            let found = false;
            for (var item of list)
                if (existing.indexOf(item) !== -1) { found = true; break; }
            if (!found) return false;
        } else if (existing.indexOf(p) === -1) return false;
    return !!this.meetsStolenTech(e);
}

因此,isAvailableForProduction 綜合檢查科技等級、建造上限、超級武器是否啟用、是否擁有適當工廠,以及各種前置條件,最後回傳是否可投入生產。


在專案中的應用

queueController.ts 中,AI 會透過 productionApi.getAvailableObjects 取得當前可建造的所有選項,而該函式內部正是利用 isAvailableForProduction 來篩選:

68      this.queueStates = QUEUES.map((queueType) => {
69          const options = productionApi.getAvailableObjects(queueType);
70          const items = this.getPrioritiesForBuildingOptions(
71              game,
72              options,
73              threatCache,
74              playerData,
75              unitTypeRequests,
76              logger,
77          );

簡易示例

以下範例展示如何在遊戲開始時檢查某建築規則是否能生產,並列出所有可生產物件:

import { cdapi, Bot, GameApi, ProductionApi } from "@chronodivide/game-api";

class CheckProductionBot extends Bot {
    onGameStart(game: GameApi) {
        const prod = game.productionApi;  // 透過 GameApi 取得 ProductionApi
        const powerPlant = game.rulesApi.getBuildingRules("GAPOWR"); // 盟軍發電廠

        const canBuild = prod.isAvailableForProduction(powerPlant);
        console.log("Power plant buildable:", canBuild);

        // 查看目前所有可建造的單位/建築
        const available = prod.getAvailableObjects();
        available.forEach(r => console.log("Option:", r.name));
    }
}

async function main() {
    await cdapi.init(process.env.MIX_DIR!);
    await cdapi.createGame({
        agents: [new CheckProductionBot("Tester", "Americans")],
        mapName: "mp03t4.map",
        shortGame: true,
        online: false,
    });
}
main().catch(console.error);

此程式在遊戲開始時利用 isAvailableForProduction 檢查指定建築是否可建造,同時列出所有可生產的選項。透過上述邏輯,AI 能根據科技等級、工廠狀態及前置條件等資訊,決定何時將特定單位或建築加入佇列。

 

→返回《@chronodivide/game-api 使用教學與完整 API 對照表》

This article was last edited at