huchuan626 发表于 2024-1-31 01:43:14

如何修改AI军事单位数量???

之前参考小羽的修改人口上限教程后,把默认的200人口上调到了500,农民不占人口,但是发现即便是500人口上限,为什么AI最多还是一次性生产200个军事单位,如何才能让AI根据人口上限生产军事单位???

こはね 发表于 2024-2-6 19:27:48

我以前将单位改过0人口,AI会无限出兵,那么可以排除AI文件存在最大单位数量,那么只剩下一种可能AI是有人口上限设定;实测如此。
要修改的文件:AI3/aiMain.xs
(因为不知道怎样修改,最开始搜索关键词可以为train、pop、limit,还有“200”也可以作为关键词搜索)我经过反复测试找到建造上限设定如下;你需要有一定的编程基础才能看得懂,如果看不懂的话照抄红色加粗文字,
//==============================================================================
/* rule popManager

   Set population limits based on age, difficulty and control variable settings
*/
rule popManager
active
minInterval 15
{
   float difficulty = aiGetWorldDifficulty();
   int intDifficulty = difficulty;
   int cvPopLimit = 200;      // Used to calculate implied total pop limit based on civ, army and navy components.

   if ( (cvMaxCivPop >= 0) && (cvMaxArmyPop >= 0) && (cvMaxNavyPop >= 0) )    // All three are defined, so set a hard total
      cvPopLimit = cvMaxCivPop + cvMaxArmyPop + cvMaxNavyPop;

   int maxMil = -1;// The full age-5 max military size...to be reduced in earlier ages to control runaway spending.

   switch(intDifficulty)
   {
                case cDifficultySandbox: // Sandbox[游戏难度:自我练习]
                {// Typically 20 econ, 20 mil
                        gMaxPop = 40 + (30 * (difficulty - intDifficulty));   // Interpolate between integers
         if (gMaxPop > cvPopLimit)
            gMaxPop = cvPopLimit;
         aiSetEconomyPop(20);
         if ( (aiGetEconomyPop() > cvMaxCivPop) && (cvMaxCivPop >= 0) )
            aiSetEconomyPop(cvMaxCivPop);
         maxMil = gMaxPop - aiGetEconomyPop();
         setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);
                        break;
                }
                case cDifficultyEasy: // Easiest[游戏难度:简单]
                {// Typically 35 econ, 35 mil.
                        gMaxPop = 70 + (50 * (difficulty - intDifficulty));      // 70 at easy up to 120 at moderate
         if (gMaxPop > cvPopLimit)
            gMaxPop = cvPopLimit;
         aiSetEconomyPop(35);
         if (gSPC == true)
         {
            aiSetEconomyPop(25);
            gMaxPop = 55;
         }
         if ( (aiGetEconomyPop() > cvMaxCivPop) && (cvMaxCivPop >= 0) )
            aiSetEconomyPop(cvMaxCivPop);
         maxMil = gMaxPop - aiGetEconomyPop();
         setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);
                        break;
                }
                case cDifficultyModerate: // Moderate[游戏难度:中等]
                {// Typically 60 econ, 60 mil
                        gMaxPop = 120 + (80 * (difficulty - intDifficulty));      // 120 at moderate up to 200 at hard
         if (gMaxPop > cvPopLimit)
            gMaxPop = cvPopLimit;
         aiSetEconomyPop(60);
         if (gSPC == true)
         {
            aiSetEconomyPop(45);
            gMaxPop = 105;
         }
         if ( (aiGetEconomyPop() > cvMaxCivPop) && (cvMaxCivPop >= 0) )
            aiSetEconomyPop(cvMaxCivPop);
         maxMil = gMaxPop - aiGetEconomyPop();
         setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);
                        break;
                }
                case cDifficultyHard: // Hard[游戏难度:困难]
                {// Typically 80 econ, 120 mil.
         gMaxPop = 200;
         if (gMaxPop > cvPopLimit)
            gMaxPop = cvPopLimit;
         aiSetEconomyPop(80 - (10 * (difficulty -intDifficulty)));    // 80 at hard, down to 70 at hardest
         if (gSPC == true)
         {
            aiSetEconomyPop(65);
            gMaxPop = 185;
         }
            gMaxPop = 9999;/*困难级别上限;你自己喜欢设定多少就设定多少*/
         if ( (aiGetEconomyPop() > cvMaxCivPop) && (cvMaxCivPop >= 0) )
            aiSetEconomyPop(cvMaxCivPop);
         maxMil = gMaxPop - aiGetEconomyPop();
         setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);
                        break;
                }
                case cDifficultyExpert: // Expert[游戏难度:专家]
                {// Typically 70 econ, 130 mil.
         gMaxPop = 200;
         if (gMaxPop > cvPopLimit)
            gMaxPop = cvPopLimit;
            gMaxPop = 9999;/*专家级别上限:你自己喜欢设定多少就设定多少*/
         aiSetEconomyPop(70);
         if ( (aiGetEconomyPop() > cvMaxCivPop) && (cvMaxCivPop >= 0) )
            aiSetEconomyPop(cvMaxCivPop);
         maxMil = gMaxPop - aiGetEconomyPop();
         setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);
                        break;
                }
   }

   gGoodArmyPop = aiGetMilitaryPop() / 3;
   //if ( (kbGetAge() == cAge2) && ((xsGetTime() - gAgeUpTime) < 300000) )   // In the first five minutes of age 2, go with tiny armies.
   //   gGoodArmyPop = gGoodArmyPop / 2;

   /*
   aiEcho(" ");
   aiEcho("Population tests:");
   aiEcho("aiGetEconomyPop() "+ aiGetEconomyPop());
   aiEcho("aiGetMilitaryPop() "+ aiGetMilitaryPop());
   aiEcho("aiGetCurrentEconomyPop() "+ aiGetCurrentEconomyPop());
   aiEcho("aiGetAvailableEconomyPop() "+ aiGetAvailableEconomyPop());
   aiEcho("aiGetAvailableMilitaryPop() "+ aiGetAvailableMilitaryPop());
   aiEcho("kbGetPopCap() "+ kbGetPopCap());
   aiEcho("kbGetPop() "+ kbGetPop());
   aiEcho(" ");
   */
}








再详细解释一下;其实上限是由maxMil = gMaxPop - aiGetEconomyPop();决定的;maxMil等于gMaxPop减去AI经济单位人口总数;然后 setMilPopLimit(maxMil/8, maxMil/4, maxMil/2, maxMil, maxMil);调用函数setMilPopLimit,五个值分别是五个时代的设定(时代1设定八分之一,时代2设定四分之一,时代3设定二分之一,时代4与时代5不变),具体函数如下:
可能有点乱,开头带c的变量是游戏内置变量,例如cAge1、cAge2、cAge3、...,而其他的则是编程指定的,你设定什么就是什么,例如limit、age1、age2、age3、...;其中age1-age5由setMilPopLimit设定,如果setMilPopLimit没有设定则采用默认值(下面的绿色字体)
void setMilPopLimit(int age1=10, int age2=30, int age3=80, int age4=120, int age5=130)
{
   int limit = 10;
   int age = kbGetAge();/*kbGetAge()获取AI当前时代;返回1-6*/
   if (age == cvMaxAge)
      age = cAge5;   // If we're at the highest allowed age, go for our full mil pop.
      // This overrides the normal settings, so an SPC AI capped at age 3 can use his full
      // military pop.
   switch(age)
   {
      case cAge1:/*cAge1=1;cAge1=2;cAge3=3...*/      {
         limit = age1;/*注意这里不是时代,而是变量*/
         break;
      }
      case cAge2:
      {
         limit = age2;
         break;
      }
      case cAge3:
      {
         limit = age3;
         break;
      }
      case cAge4:
      {
         limit = age4;
         break;
      }
      case cAge5:
      {
         limit = age5;
         break;
      }
   }

/*不知道是什么设定,可能是某些预留?游戏输出cvMaxArmyPop=-1,cvMaxNavyPop=-1;以下两个判断式不成立*/
   if ( (cvMaxArmyPop >= 0) && (cvMaxNavyPop >= 0) && (limit > (cvMaxArmyPop + cvMaxNavyPop)) )
      limit = cvMaxArmyPop+cvMaxNavyPop;   // Manual pop limits have been set

   if ( (cvMaxNavyPop <= 0) && (cvMaxArmyPop < limit) && (cvMaxArmyPop >= 0) )// Only army pop set?
      limit = cvMaxArmyPop;

/*最终设定军事单位人口上限的就是aiSetMilitaryPop这个内置函数*/
   aiSetMilitaryPop(limit);
}



こはね 发表于 2024-2-6 20:14:09

然后,以下代码可能是AI一次性出兵最大限制数量,按单位个数来算,而不是按人口数量。注意,我说的是可能,因为我测试次数不够,不确定准确效果是什么。如果后面有人看到,测试如果真的是这样,建议回复一下。不可能,绝对不可能,不会有人回复的。

//==============================================================================
/*
   Military Manager

   Create maintain plans for military unit lines.Control 'maintain' levels,
   buy upgrades.
*/
//==============================================================================
rule militaryManager
inactive
minInterval 30
{

   static bool init = false;   // Flag to indicate vars, plans are initialized
   int i = 0;
   int proto = 0;
   int planID = -1;


   if (init == false)
   {   
                // Need to initialize, if we're allowed to.
      if (cvOkToTrainArmy == true)
      {
         init = true;
         if (cvNumArmyUnitTypes >= 0)
            gNumArmyUnitTypes = cvNumArmyUnitTypes;
         else
            gNumArmyUnitTypes = 3;
         gLandUnitPicker = initUnitPicker("Land military units", gNumArmyUnitTypes, 1, 30, -1, -1, 1, true);

         // now the goal
         // wmj -- hard coded for now, but this should most likely ramp up as the ages progress
         aiSetMinArmySize(15);

         gMainAttackGoal = createSimpleAttackGoal("AttackGoal", aiGetMostHatedPlayerID(), gLandUnitPicker, -1, cAge2, -1, gMainBase, false);
         aiPlanSetVariableInt(gMainAttackGoal, cGoalPlanReservePlanID, 0, gLandReservePlan);
      }
   }

      if(gLandUnitPicker != -1)
      {

      setUnitPickerPreference(gLandUnitPicker); // Update preferences in case btBiasEtc vars have changed, or cvPrimaryArmyUnit has changed.

                if(kbGetAge() == cAge3)/*堡垒时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);   //Min is really managed by scoring system.
                                                                  // An ally or trigger-spawned mission should 'go' even if it's very small.
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 550);
                }
                if(kbGetAge() == cAge4)/*工业时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 700);
                }
                if(kbGetAge() == cAge5)/*帝王时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 900);
                }
      }

   switch(kbGetAge())
   {
      case cAge1:
      {
         break;
      }
      case cAge2:
      {
         aiSetMinArmySize(8); // Now irrelevant?(Was used to determine when to launch attack, but attack goal and opp scoring now do this.)
         break;
      }
      case cAge3:
      {
         aiSetMinArmySize(15);
         break;
      }
      case cAge4:
      {
         aiSetMinArmySize(25);
         break;
      }
      case cAge5:
      {
         aiSetMinArmySize(30);
         break;
      }
   }
}



这是默认值的结果,数了一下有86个单位,时代5上限90个
                if(kbGetAge() == cAge3)/*堡垒时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);   //Min is really managed by scoring system.
                                                                  // An ally or trigger-spawned mission should 'go' even if it's very small.
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 55);
                }
                if(kbGetAge() == cAge4)/*工业时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 70);
                }
                if(kbGetAge() == cAge5)/*帝王时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 90);
                }


然后下面是在后面加了个0;具体有多少个单位我不知道
                if(kbGetAge() == cAge3)/*堡垒时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);   //Min is really managed by scoring system.
                                                                  // An ally or trigger-spawned mission should 'go' even if it's very small.
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 550);
                }
                if(kbGetAge() == cAge4)/*工业时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 700);
                }
                if(kbGetAge() == cAge5)/*帝王时代*/
                {
                        kbUnitPickSetMinimumNumberUnits(gLandUnitPicker, 1);
                        kbUnitPickSetMaximumNumberUnits(gLandUnitPicker, 900);
                }






こはね 发表于 2024-2-6 20:20:19

还有一个重要的问题,AI需要建造许多房子才有这么多人口;如果就原来那20个房子+3个城镇中心,能出多少单位?这个问题自己想办法解决,我这边直接偷懒,懒得测试,只要不回复,没有新问题我就一直偷懒下去{:4_88:},因为不修改提供人口数量的话大概率又要修改AI。
页: [1]
查看完整版本: 如何修改AI军事单位数量???