设为首页收藏本站

塞爱维(CIV)文明联盟

 找回密码
 注册
查看: 100590|回复: 91

[原创] 文明游戏机制拾遗

[复制链接]
发表于 2008-8-5 14:27:19 | 显示全部楼层 |阅读模式
自从发现文明4的SDK后,我就像一个闯进玩具店的小孩,对每一样玩具都爱不释手。但这个玩具店里的好东西太多了,实在无法一一尝试,我只好选择那些我最感兴趣的。我决定我的一些研究心得,主要是对于文明4里那些我觉得有趣的但零碎的不太重要的东西,集中在一起,都放在这个贴子里。由于我不确定什么东西我最感兴趣,碰到什么特别有趣,鼓捣一番,如果有点心得,就放到这里。所以更新则不能保证定时。

另外,我的C++学了后就没用都快忘光了,只是从研究SDK开始才重新拾起,python则根本没学过为了文明才开始学习,而唯一可以凭藉的就是对"Sid Meier's Civilization"的热爱。因此错误是难免的,我的这些东西,还望大家斧正。
 楼主| 发表于 2008-8-5 14:27:43 | 显示全部楼层
 楼主| 发表于 2008-8-5 14:28:04 | 显示全部楼层

宗教圣城的选择(BTS3.17)

当你(player)创立一个宗教时,电脑遍历你的所有城市,电脑按下述方法给每一城市一个数值,

(10+城市人口+随机抽取的从0到9的一个整数)/(城市当前拥有的宗教数量+1)
如果这个城市还是首都,那么还要将上述数值除以8。
然后在上面数字和1之间取大,就是最终数值。

最后,上述最终数值最大的城市会会雀屏中选成为圣城。


总结:由于计算上述数值时有一基础值10,那么城市当前拥有的宗教数量在决定圣城时起决定性作用。当不同城市当前拥有的宗教数量都最少时,人口越多机会越大。首都由于要额外除以8,正常游戏里只有有了分城就不可能是圣城了。不过你可以用WB将首都人口该为1000,看看发生了什么?
 楼主| 发表于 2008-8-5 14:29:11 | 显示全部楼层

宗教圣城的选择(BTS3.17)

  1. void CvPlayer::foundReligion(ReligionTypes eReligion, ReligionTypes eSlotReligion, bool bAward)
  2. {
  3.         CvCity* pLoopCity;
  4.         CvCity* pBestCity;
  5.         UnitTypes eFreeUnit;
  6.         bool bStarting;
  7.         int iValue;
  8.         int iBestValue;
  9.         int iLoop;

  10.         if (NO_RELIGION == eReligion)
  11.         {
  12.                 return;
  13.         }

  14.         if (GC.getGameINLINE().isReligionFounded(eReligion))
  15.         {
  16.                 if (isHuman())
  17.                 {
  18.                         CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_FOUND_RELIGION, eSlotReligion);
  19.                         if (NULL != pInfo)
  20.                         {
  21.                                 gDLL->getInterfaceIFace()->addPopup(pInfo, getID());
  22.                         }
  23.                 }
  24.                 else
  25.                 {
  26.                         foundReligion(AI_chooseReligion(), eSlotReligion, bAward);
  27.                 }

  28.                 return;
  29.         }

  30.         GC.getGameINLINE().setReligionSlotTaken(eSlotReligion, true);

  31.         bStarting = ((GC.getReligionInfo(eSlotReligion).getTechPrereq() == NO_TECH) || (GC.getTechInfo((TechTypes) GC.getReligionInfo(eSlotReligion).getTechPrereq()).getEra() < GC.getGameINLINE

  32. ().getStartEra()));

  33.         iBestValue = 0;
  34.         pBestCity = NULL;

  35.         for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
  36.         {
  37.                 if (!bStarting || !(pLoopCity->isHolyCity()))
  38.                 {
  39.                         iValue = 10;
  40.                         iValue += pLoopCity->getPopulation();
  41.                         iValue += GC.getGameINLINE().getSorenRandNum(GC.getDefineINT("FOUND_RELIGION_CITY_RAND"), "Found Religion");

  42.                         iValue /= (pLoopCity->getReligionCount() + 1);

  43.                         if (pLoopCity->isCapital())
  44.                         {
  45.                                 iValue /= 8;
  46.                         }

  47.                         iValue = std::max(1, iValue);

  48.                         if (iValue > iBestValue)
  49.                         {
  50.                                 iBestValue = iValue;
  51.                                 pBestCity = pLoopCity;
  52.                         }
  53.                 }
  54.         }

  55.         if (pBestCity != NULL)
  56.         {
  57.                 GC.getGameINLINE().setHolyCity(eReligion, pBestCity, true);

  58.                 if (bAward)
  59.                 {
  60.                         if (GC.getReligionInfo(eSlotReligion).getNumFreeUnits() > 0)
  61.                         {
  62.                                 eFreeUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(GC.getReligionInfo(eReligion).getFreeUnitClass())));

  63.                                 if (eFreeUnit != NO_UNIT)
  64.                                 {
  65.                                         for (int i = 0; i < GC.getReligionInfo(eSlotReligion).getNumFreeUnits(); ++i)
  66.                                         {
  67.                                                 initUnit(eFreeUnit, pBestCity->getX_INLINE(), pBestCity->getY_INLINE());
  68.                                         }
  69.                                 }
  70.                         }
  71.                 }
  72.         }
  73. }
复制代码

T

[ 本帖最后由 Khyron 于 2008-8-6 17:37 编辑 ]
 楼主| 发表于 2008-8-5 15:40:23 | 显示全部楼层

为什么能造工船却不能造军舰?(BTS3.17)

重新解释

首先说明湖海的区别,对于一片水域,由于LAKE_MAX_AREA_SIZE=9,如果格子数在1和9之间,那它就是淡水湖;如果有10格以上,那她就是海。

一个城市如果它所在的格子靠海,则这个城市临海。

1. 一个城市能建造灯塔这类需要临海(bwater=1)建筑,当且仅当这个城市临海。
2. 一个城市能训练军舰这类海军单位(Domain_Sea), 不但需要这个城市所在的格子靠水,还要这片水域的格子数大于iMinAreaSize。而基本上所有的海军单位的iMinAreaSize=20,所以要训练军舰,不但城市要靠海,还要靠着大海。
3. 对于工船,由于其iMinAreaSize=-1, 则需要的水域甚至可以只是一格淡水湖。但能否训练工船还有一个判定条件,就是其滨临的水域要有资源。正常游戏里只有海里才有资源。


所以当你的某个城市滨临一个只有10-19格的海洋时,且这海里还有资源时,这个城市能造工船却不能造军舰。

[ 本帖最后由 Khyron 于 2008-8-6 14:45 编辑 ]
 楼主| 发表于 2008-8-5 15:42:00 | 显示全部楼层

为什么能造工船却不能造军舰?(BTS3.17)

  1. bool CvPlot::canTrain(UnitTypes eUnit, bool bContinue, bool bTestVisible) const
  2. {
  3.     CvCity* pCity = getPlotCity();

  4.     ………………
  5.     ………………

  6.     if (GC.getUnitInfo(eUnit).isPrereqBonuses())
  7.     {
  8.         if (GC.getUnitInfo(eUnit).getDomainType() == DOMAIN_SEA)
  9.         {
  10.             bool bValid = false;

  11.             for (int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)
  12.             {
  13.                 CvPlot* pLoopPlot = plotDirection(getX_INLINE(), getY_INLINE(), ((DirectionTypes)iI));

  14.                 if (pLoopPlot != NULL)
  15.                 {
  16.                     if (pLoopPlot->isWater())
  17.                     {
  18.                         if (pLoopPlot->area()->getNumTotalBonuses() > 0)
  19.                         {
  20.                             bValid = true;
  21.                             break;
  22.                         }
  23.                     }
  24.                 }
  25.             }

  26.             if (!bValid)
  27.             {
  28.                 return false;
  29.             }
  30.         }
  31.         else
  32.         {
  33.             if (area()->getNumTotalBonuses() > 0)
  34.             {
  35.                 return false;
  36.             }
  37.         }
  38.     }

  39.     if (isCity())
  40.     {
  41.         if (GC.getUnitInfo(eUnit).getDomainType() == DOMAIN_SEA)
  42.         {
  43.             if (!isWater() && !isCoastalLand(GC.getUnitInfo(eUnit).getMinAreaSize()))
  44.             {
  45.                 return false;
  46.             }
  47.         }
  48.         else
  49.         {
  50.             if (area()->getNumTiles() < GC.getUnitInfo(eUnit).getMinAreaSize())
  51.             {
  52.                 return false;
  53.             }
  54.         }
  55.     }
  56.    
  57.     ………………
  58.     ………………
  59. }
复制代码

T

[ 本帖最后由 Khyron 于 2008-8-6 17:36 编辑 ]
发表于 2008-8-5 15:45:24 | 显示全部楼层
懂代码的就是好啊……这方面我就是文盲

LZ有兴趣就研究一下这两个源码吧,算是CFC上的SDK mod代表

一个是超大城市范围
http://forums.civfanatics.com/showthread.php?t=241976

一个是Revolution + Dale's Combat Mod
http://forums.civfanatics.com/downloads.php?do=file&id=9984
还有个补丁在这一帖2楼
http://forums.civfanatics.com/showthread.php?t=271390

另外还有位仁兄把把这两个东西合起来的基础上又做了个大型MOD:Overlord 2,目前版本2.17
http://forums.civfanatics.com/showthread.php?t=236605

以上三个东西都附上了源码,可以尽情研究,我这个代码文盲就只能说声算了
发表于 2008-8-6 11:28:07 | 显示全部楼层
原帖由 Khyron 于 2008-8-5 15:40 发表
对于军舰,其iMinAreaSize=20,这意味着能造军舰的城市滨临的大海要至少有20格。 而工船,这一项却为0,所以对于滨临10-19格的水域的城市,能造工船却不能造军舰。

补充:工船能否造,只取决于城市滨临的水域 ...



所谓的濒临是城市文化滨临还是城市工作范围滨临?我怎么觉得没这个限制,只要靠海都可以造啊,只要城市的格子是coast就可以造ship
发表于 2008-8-6 13:10:58 | 显示全部楼层

回复 #19 ahandac 的帖子

所靠的海必须有20格以上的水域,大海,小海不行
发表于 2008-8-6 13:14:41 | 显示全部楼层

回复 #13 vesley1987 的帖子

那你学文科的想要搞懂Python干什么?
似乎没有必要把?
人家130ty还会hello world呢

[ 本帖最后由 fntty 于 2008-8-6 13:20 编辑 ]
 楼主| 发表于 2008-8-6 14:14:39 | 显示全部楼层
原帖由 ahandac 于 2008-8-6 11:28 发表



所谓的濒临是城市文化滨临还是城市工作范围滨临?我怎么觉得没这个限制,只要靠海都可以造啊,只要城市的格子是coast就可以造ship


这里指的是城市所在格。
我又重新解释了一下,这样就清楚多了。
发表于 2008-8-6 16:11:52 | 显示全部楼层
我感觉FFH中,首发宗教的机制可能不同。

每次混沌之灰烬,都会在我科技最高的科研城市被创立。弄到最后想造大恶魔都没产能,全是大房子,舍不得拆了建工厂。
 楼主| 发表于 2008-8-6 17:35:09 | 显示全部楼层

对野蛮人免费胜利的实质(BTS3.17)

在低难度游戏下,<iFreeWinsVsBarbs>大于零,这是否意味着我们面对野蛮人时前iFreeWinsVsBarbs次战斗必胜呢?答案是否定的。

为了便于讨论,我们称当iFreeWinsVsBarbs>0时,在与野蛮人的战斗为野蛮人修正战斗。如果这时的战斗杀死了野蛮人单位,此数值要减1。

如果一场战斗是野蛮人修正战斗,那么我们在这次战斗中每轮攻防的胜率将强制修正为不低于90%。不要小看这90%,这将极大的提高这次战斗的胜率。假设双方生命值都是100,这个修改能使warrior对knight的胜率到90%以上,如果再加上低难度下对野蛮人力量修正,那胜率更高了,大概warrior对infantry的胜率也会在80%以上。所以将野蛮人修正战斗称之为对野蛮人必胜也不为过。

但是,这是在我方单位满血的前提下。当我方单位的生命值比较低时,战斗的胜率就急剧下降。对于这点要注意。

所以对野蛮人免费胜利的实质是在我们杀死iFreeWinsVsBarbs个野蛮人前,也野蛮人的战斗都是胜率极高的,但不保证为100%。

[ 本帖最后由 Khyron 于 2008-8-9 13:39 编辑 ]
 楼主| 发表于 2008-8-6 17:35:51 | 显示全部楼层

对野蛮人免费胜利的实质(BTS3.17)

  1. if (kDefender.isBarbarian())
  2.         {
  3.                 if (GET_PLAYER(getOwnerINLINE()).getWinsVsBarbs() < GC.getHandicapInfo(GET_PLAYER(getOwnerINLINE()).getHandicapType()).getFreeWinsVsBarbs())
  4.                 {
  5.                         iTheirOdds = std::min((10 * GC.getDefineINT("COMBAT_DIE_SIDES")) / 100, iTheirOdds);
  6.                 }
  7.         }
  8.         if (isBarbarian())
  9.         {
  10.                 if (GET_PLAYER(kDefender.getOwnerINLINE()).getWinsVsBarbs() < GC.getHandicapInfo(GET_PLAYER(kDefender.getOwnerINLINE()).getHandicapType()).getFreeWinsVsBarbs())
  11.                 {
  12.                         iTheirOdds =  std::max((90 * GC.getDefineINT("COMBAT_DIE_SIDES")) / 100, iTheirOdds);
  13.                 }
  14.         }
复制代码

T

[ 本帖最后由 Khyron 于 2008-8-6 17:37 编辑 ]
发表于 2008-8-6 18:05:38 | 显示全部楼层
潜力贴,留个名。。。

想了几个课题,楼主不妨研究下:
⑴ AI送科技、送城:可能和ai个性、关系、被送者的科技和发展水平 等都有关系;
⑵ 基于3.17的AI宣战机制、性格研究:以前看过孟大和gowang大的ai研究,可资参考;
⑶ AI的科技路线:什么原因制约着ai研究这个、而不研究那个,曾看到有个ai抢首发自由主义,当别的ai首发后,该ai马上把科技研究换成了别的;
⑷ AI的奇迹建设:

[ 本帖最后由 囧囧囧囧囧 于 2008-8-6 19:46 编辑 ]
 楼主| 发表于 2008-8-7 15:44:40 | 显示全部楼层

种子和随机数(BTS3.17)

1. 每调用一次随机数,新种子=(1103515245*旧种子+12345) mod 2^32。
设最新种子是RandSeed,则当前的从0到N(不包括N)的随机整数为
[[RandSeed/2^16]*N/(65535+1)]

2. 如果在游戏设置里选了New RandomSeed on Reload,那么每次读档后将时间设为当前种子。

3. 经初步测试,没发现按此方法生成的随机数有什么明显的不随机的地方。

(1)一部分测试结果参见附图。其中initSeed=初始种子, RandNum=随机数范围, Times=随机数产生次数
(2)initSeed=5555, RandNum=10, Times=1000时,0-9出现的频率分别如下
{99, 111, 100, 86, 112, 96, 101, 102, 96, 97}


总结:试图通过旧随机数来预测新的随机数的行为可以休矣。比如上一次战斗无论是你的坦克被人家的矛兵戳死了还是你的棒棒敲死了敌人的机械化步兵,都不能使你的下一次战斗的随机数变好或变坏。

[ 本帖最后由 Khyron 于 2008-8-8 17:15 编辑 ]

评分

1

查看全部评分

 楼主| 发表于 2008-8-7 15:45:02 | 显示全部楼层

种子和随机数(BTS3.17)

附测试结果, 点击放大后会比较清楚

1.initSeed=9999, RandNum=100, Times=50

2.initSeed=5555, RandNum=10, Times=100

3.initSeed=1234567, RandNum=1000, Times=1000


[ 本帖最后由 Khyron 于 2008-8-7 15:51 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2008-8-7 15:46:40 | 显示全部楼层

种子和随机数(BTS3.17)

  1. #define RANDOM_A      (1103515245)
  2. #define RANDOM_C      (12345)
  3. #define RANDOM_SHIFT  (16)

  4. unsigned short CvRandom::get(unsigned short usNum, const TCHAR* pszLog)
  5. {
  6.         if (pszLog != NULL)
  7.         {
  8.                 if (GC.getLogging() && GC.getRandLogging())
  9.                 {
  10.                         if (GC.getGameINLINE().getTurnSlice() > 0)
  11.                         {
  12.                                 TCHAR szOut[1024];
  13.                                 sprintf(szOut, "Rand = %d on %d (%s)\n", getSeed(), GC.getGameINLINE().getTurnSlice(), pszLog);
  14.                                 gDLL->messageControlLog(szOut);
  15.                         }
  16.                 }
  17.         }

  18.         m_ulRandomSeed = ((RANDOM_A * m_ulRandomSeed) + RANDOM_C);

  19.         unsigned short us = ((unsigned short)((((m_ulRandomSeed >> RANDOM_SHIFT) & MAX_UNSIGNED_SHORT) * ((unsigned long)usNum)) / (MAX_UNSIGNED_SHORT + 1)));

  20.         return us;
  21. }
复制代码

  1. if (isOption(GAMEOPTION_NEW_RANDOM_SEED))
  2.         {
  3.                 if (!isNetworkMultiPlayer())
  4.                 {
  5.                         m_sorenRand.reseed(timeGetTime());
  6.                 }
  7.         }
复制代码
 楼主| 发表于 2008-8-8 16:47:27 | 显示全部楼层

科技交易中某些独特的科技(BTS3.17)

要从一个AI手里换到科技,有重重障碍。其中一项就是AI对科技的保密,当一个科技知道的国家越少,AI就越不肯开放这个科技的交换。大家经常碰到的AI说"We don't want to start trading away this technology just yet",就是这种情形。
但细心的玩家会发现,有些科技,比如一神君主制,即使它们只被一个AI掌握,那AI也肯交换它们。什么使这些科技与众不同呢?

对于一个科技,AI按以下方法判断是否对某国实行科技垄断。
1. AI根据这个科技和是否准备对此国开战来计算一个垄断价值。
2. 根据此AI领袖性格和游戏难度,进行修正。
3. 再根据已发现此科技的队伍数和此AI碰到的队伍数进行修正,均不包括此AI和想和此AI进行交易的队伍。

公式为:
(1)如果此AI碰到的队伍数>0, 且(已发现此科技的队伍数)/(此AI碰到的队伍数)<垄断价值*难度修正*AI性格修正, 则AI将玩科技垄断。
(2)如果此AI碰到的队伍数=0(比如这世界上就玩家和AI两支队伍), 垄断价值*难度修正*AI性格修正>0,则AI将玩科技垄断。

由此可见,当一个科技是AI的独门科技的时,已发现此科技的队伍数=0,那么垄断价值*难度修正*AI性格修正不为0,则AI将不肯放出此科技。恰恰有些科技很特别,它们的垄断价值为0。所以有了本文开头所述现象。
大致说一下一个科技的垄断价值,基本上只要它是战斗单位,非宗教建筑,奇迹,工程的前提科技,其垄断价值就要上升。而Monotheism, Monarchy刚好不是这些东东的前提。

附垄断价值为零的科技: Fishing, Agriculture, Mining, Animal Husbandry, Monothesim, Monarchy, Alphabet, Printing Press, Liberalism, Scientific Method。

另外,我们也知道为什么Mansa Musa这么特别,这是因为他是唯一一位AI性格修正为0的领袖。
 楼主| 发表于 2008-8-8 16:48:54 | 显示全部楼层

科技交易中某些独特的科技(BTS3.17)

  1. DenialTypes CvTeamAI::AI_techTrade(TechTypes eTech, TeamTypes eTeam) const
  2. {
  3.         ………………
  4.         ………………
  5.                 iKnownCount = 0;
  6.                 iPossibleKnownCount = 0;

  7.                 for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
  8.                 {
  9.                         if (GET_TEAM((TeamTypes)iI).isAlive())
  10.                         {
  11.                                 if ((iI != getID()) && (iI != eTeam))
  12.                                 {
  13.                                         if (isHasMet((TeamTypes)iI))
  14.                                         {
  15.                                                 if (GET_TEAM((TeamTypes)iI).isHasTech(eTech))
  16.                                                 {
  17.                                                         iKnownCount++;
  18.                                                 }

  19.                                                 iPossibleKnownCount++;
  20.                                         }
  21.                                 }
  22.                         }
  23.                 }

  24.                 iTechTradeKnownPercent = AI_techTradeKnownPercent();

  25.                 iTechTradeKnownPercent *= std::max(0, (GC.getHandicapInfo(GET_TEAM(eTeam).getHandicapType()).getTechTradeKnownModifier() + 100));
  26.                 iTechTradeKnownPercent /= 100;
  27.                
  28.                 iTechTradeKnownPercent *= AI_getTechMonopolyValue(eTech, eTeam);
  29.                 iTechTradeKnownPercent /= 100;

  30.                 if ((iPossibleKnownCount > 0) ? (((iKnownCount * 100) / iPossibleKnownCount) < iTechTradeKnownPercent) : (iTechTradeKnownPercent > 0))
  31.                 {
  32.                         return DENIAL_TECH_MONOPOLY;
  33.                 }
  34.         ………………
  35.         ………………
  36. }
复制代码

  1. int CvTeamAI::AI_getTechMonopolyValue(TechTypes eTech, TeamTypes eTeam) const
  2. {
  3.         int iValue = 0;
  4.         int iI;
  5.        
  6.         bool bWarPlan = (getAnyWarPlanCount(eTeam) > 0);
  7.        
  8.         for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
  9.         {
  10.                 UnitTypes eLoopUnit = ((UnitTypes)GC.getUnitClassInfo((UnitClassTypes)iI).getDefaultUnitIndex());

  11.                 if (eLoopUnit != NO_UNIT)
  12.                 {
  13.                         if (isTechRequiredForUnit((eTech), eLoopUnit))
  14.                         {
  15.                                 if (isWorldUnitClass((UnitClassTypes)iI))
  16.                                 {
  17.                                         iValue += 50;
  18.                                 }
  19.                                
  20.                                 if (GC.getUnitInfo(eLoopUnit).getPrereqAndTech() == eTech)
  21.                                 {
  22.                                         int iNavalValue = 0;
  23.                                        
  24.                                         int iCombatRatio = (GC.getUnitInfo(eLoopUnit).getCombat() * 100) / std::max(1, GC.getGameINLINE().getBestLandUnitCombat());
  25.                                         if (iCombatRatio > 50)
  26.                                         {
  27.                                                 iValue += ((bWarPlan ? 100 : 50) * (iCombatRatio - 40)) / 50;;
  28.                                         }

  29.                                         switch (GC.getUnitInfo(eLoopUnit).getDefaultUnitAIType())
  30.                                         {
  31.                                         case UNITAI_UNKNOWN:
  32.                                         case UNITAI_ANIMAL:
  33.                                         case UNITAI_SETTLE:
  34.                                         case UNITAI_WORKER:
  35.                                         break;

  36.                                         case UNITAI_ATTACK:
  37.                                         case UNITAI_ATTACK_CITY:
  38.                                         case UNITAI_COLLATERAL:
  39.                                                 iValue += bWarPlan ? 50 : 20;
  40.                                                 break;

  41.                                         case UNITAI_PILLAGE:
  42.                                         case UNITAI_RESERVE:
  43.                                         case UNITAI_COUNTER:
  44.                                         case UNITAI_PARADROP:
  45.                                         case UNITAI_CITY_DEFENSE:
  46.                                         case UNITAI_CITY_COUNTER:
  47.                                         case UNITAI_CITY_SPECIAL:
  48.                                                 iValue += bWarPlan ? 40 : 15;
  49.                                                 break;


  50.                                         case UNITAI_EXPLORE:
  51.                                         case UNITAI_MISSIONARY:
  52.                                                 break;

  53.                                         case UNITAI_PROPHET:
  54.                                         case UNITAI_ARTIST:
  55.                                         case UNITAI_SCIENTIST:
  56.                                         case UNITAI_GENERAL:
  57.                                         case UNITAI_MERCHANT:
  58.                                         case UNITAI_ENGINEER:
  59.                                                 break;

  60.                                         case UNITAI_SPY:
  61.                                                 break;

  62.                                         case UNITAI_ICBM:
  63.                                                 iValue += bWarPlan ? 80 : 40;
  64.                                                 break;

  65.                                         case UNITAI_WORKER_SEA:
  66.                                                 break;

  67.                                         case UNITAI_ATTACK_SEA:
  68.                                                 iNavalValue += 50;
  69.                                                 break;

  70.                                         case UNITAI_RESERVE_SEA:
  71.                                         case UNITAI_ESCORT_SEA:
  72.                                                 iNavalValue += 30;
  73.                                                 break;

  74.                                         case UNITAI_EXPLORE_SEA:
  75.                                                 iValue += GC.getGame().circumnavigationAvailable() ? 100 : 0;
  76.                                                 break;

  77.                                         case UNITAI_ASSAULT_SEA:
  78.                                                 iNavalValue += 60;
  79.                                                 break;

  80.                                         case UNITAI_SETTLER_SEA:
  81.                                         case UNITAI_MISSIONARY_SEA:
  82.                                         case UNITAI_SPY_SEA:
  83.                                                 break;

  84.                                         case UNITAI_CARRIER_SEA:
  85.                                         case UNITAI_MISSILE_CARRIER_SEA:
  86.                                                 iNavalValue += 40;
  87.                                                 break;

  88.                                         case UNITAI_PIRATE_SEA:
  89.                                                 iNavalValue += 20;
  90.                                                 break;

  91.                                         case UNITAI_ATTACK_AIR:
  92.                                         case UNITAI_DEFENSE_AIR:
  93.                                                 iValue += bWarPlan ? 60 : 30;
  94.                                                 break;

  95.                                         case UNITAI_CARRIER_AIR:
  96.                                                 iNavalValue += 40;
  97.                                                 break;

  98.                                         case UNITAI_MISSILE_AIR:
  99.                                                 iValue += bWarPlan ? 40 : 20;
  100.                                                 break;

  101.                                         default:
  102.                                                 FAssert(false);
  103.                                                 break;
  104.                                         }
  105.                                        
  106.                                         if (iNavalValue > 0)
  107.                                         {
  108.                                                 if (AI_isAnyCapitalAreaAlone())
  109.                                                 {
  110.                                                         iValue += iNavalValue / 2;
  111.                                                 }
  112.                                                 if (bWarPlan && !AI_isLandTarget(eTeam))
  113.                                                 {
  114.                                                         iValue += iNavalValue / 2;
  115.                                                 }
  116.                                         }
  117.                                 }
  118.                         }
  119.                 }
  120.         }

  121.         for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
  122.         {
  123.                 if (isTechRequiredForBuilding(eTech, ((BuildingTypes)iI)))
  124.                 {
  125.                         CvBuildingInfo& kLoopBuilding = GC.getBuildingInfo((BuildingTypes)iI);
  126.                         if (kLoopBuilding.getReligionType() == NO_RELIGION)
  127.                         {
  128.                                 iValue += 30;
  129.                         }
  130.                         if (isWorldWonderClass((BuildingClassTypes)kLoopBuilding.getBuildingClassType()))
  131.                         {
  132.                                 if (!(GC.getGameINLINE().isBuildingClassMaxedOut((BuildingClassTypes)kLoopBuilding.getBuildingClassType())))
  133.                                 {
  134.                                         iValue += 50;
  135.                                 }
  136.                         }
  137.                 }
  138.         }

  139.         for (iI = 0; iI < GC.getNumProjectInfos(); iI++)
  140.         {
  141.                 if (GC.getProjectInfo((ProjectTypes)iI).getTechPrereq() == eTech)
  142.                 {
  143.                         if (isWorldProject((ProjectTypes)iI))
  144.                         {
  145.                                 if (!(GC.getGameINLINE().isProjectMaxedOut((ProjectTypes)iI)))
  146.                                 {
  147.                                         iValue += 100;
  148.                                 }
  149.                         }
  150.                         else
  151.                         {
  152.                                 iValue += 50;
  153.                         }
  154.                 }
  155.         }
  156.        
  157.         return iValue;
  158.        
  159.        
  160. }
复制代码

T
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|塞爱维(CIV)文明联盟    

GMT+8, 2024-4-19 15:37

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表