收起左侧

[求助] 如何修改AI军事单位数量???

[复制链接]
huchuan626发表于 2024-1-31 01:43:14
之前参考小羽的修改人口上限教程后,把默认的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(" ");
*/
}

图片1.jpg
图片2.jpg

再详细解释一下;其实上限是由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);
}
图片3.jpg

然后下面是在后面加了个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);
}
图片4.jpg

图片5.jpg

こはね发表于 2024-2-6 20:20:19
还有一个重要的问题,AI需要建造许多房子才有这么多人口;如果就原来那20个房子+3个城镇中心,能出多少单位?这个问题自己想办法解决,我这边直接偷懒,懒得测试,只要不回复,没有新问题我就一直偷懒下去,因为不修改提供人口数量的话大概率又要修改AI。
  • huchuan626 : 这个 gMaxPop是指什么?是出兵人口还是难度?
  • huchuan626 : 还有,如果我只想改造兵人数,是否只要改 gMaxPop?
  • こはね 回复 huchuan626 : 總人口數量啊,我不是用紅色粗體說明了哪裡要修改?
跳转到