设为首页收藏本站

塞爱维(CIV)文明联盟

 找回密码
 注册
楼主: ztjal

[原创] [BTS 3.19][娱乐型加强mod(anyfunmod)][v10.b12.Release][+SDK][12.07.17]

[复制链接]
 楼主| 发表于 2008-9-17 18:45:45 | 显示全部楼层
update v8b5

更新内容大量为对启用“大军事家不会战死”时,加强AI对大军指挥单位的应用

[ 本帖最后由 ztjal 于 2008-9-17 21:28 编辑 ]
发表于 2008-9-17 20:11:32 | 显示全部楼层
繼續膜拜樓主,MOD得這麼好。
发表于 2008-9-18 20:42:27 | 显示全部楼层
强烈建议增加单位编号,呵呵!
 楼主| 发表于 2008-9-18 20:58:38 | 显示全部楼层

回复 #63 shi791800 的帖子

显示单位的No. ?
这种需要有什么根据,或者应该是有什么需要的好处?知道之后想干什么?
发表于 2008-9-18 21:50:43 | 显示全部楼层
冒昧的提个意见,你现在这样东一榔头西一锤子,实在是浪费你的能力.
不如先构思一个主旨,再围绕其来mod,而不是像现在这样只是为了添加功能而mod,虽说添加那些功能或多或少的增强了游戏,但人的精力是有限的,在这些细枝末节上花太多功夫,实在是得不偿失.
如有冒犯,还望见谅.


另外,我对你对大军AI的修改颇感兴趣,不知能否展示一下源代码?
 楼主| 发表于 2008-9-18 22:18:34 | 显示全部楼层

回复 #65 Khyron 的帖子

其实不是,我只是想做一个比原版更加多选项的“选项”,而且我相信玩得这类游戏多的人,无例外地都有不同的想改变原版小小自己不满意的规则,就是我做这个东西的动力。
 楼主| 发表于 2008-9-18 22:28:38 | 显示全部楼层
// add PLAYEROPTION_GREAT_GENERAL_UNDEAD
        int iBaseExp = 0;
    int iBaseLead = 1;
    int iNowLead = 0;

    if (GC.afmIniPublicCheckBox("AFMGAMEOPTION","enables_great_general_undead"))
    {
        std::vector<CvUnit*> targetUnit;
        int iLoop;
        for (CvUnit* pLoopUnit = kOwner.firstUnit(&iLoop); pLoopUnit; pLoopUnit = kOwner.nextUnit(&iLoop))
        {
            if (pLoopUnit->isHasPromotion((PromotionTypes)GC.getInfoTypeForString("PROMOTION_LEADER")))
            {
                iNowLead += 1;
                continue;
            }

            UnitClassTypes pUnitClassTypes = pLoopUnit->getUnitClassType();
            CvUnitInfo& pUnitInfo = GC.getUnitInfo(pLoopUnit->getUnitType());

            if (
                (pUnitClassTypes == GC.getInfoTypeForString("UNITCLASS_SETTLER")) ||
                (pUnitClassTypes == GC.getInfoTypeForString("UNITCLASS_WORKER")) ||
                (pUnitClassTypes == GC.getInfoTypeForString("UNITCLASS_MARINE")) ||
                (pUnitClassTypes == GC.getInfoTypeForString("UNITCLASS_PARATROOPER")) ||
                (pUnitInfo.getDefaultUnitAIType() == GC.getInfoTypeForString("UNITAI_MISSIONARY")) ||
                (pUnitInfo.getDefaultUnitAIType() == GC.getInfoTypeForString("UNITAI_EXPLORE")) ||
                (pUnitInfo.getDropRange() > 0) || (pUnitInfo.getDomainType() != DOMAIN_LAND) ||
                (pUnitInfo.getWithdrawalProbability() > 0) || (pUnitInfo.isOnlyDefensive()) ||
                (pUnitInfo.isNoCapture()) || (pUnitInfo.isNoDefensiveBonus())
                )
            {
                continue;
            }

            targetUnit.push_back(pLoopUnit);
        }

        if (GC.getGameINLINE().getSorenRandNum(iBaseLead + iNowLead, "AI General Lead") == 0)
        {
            bNeedLeader = true;
        }
        else
        {
            return false;
        }

        if (bNeedLeader)
        {
            int iBestStrength = 0;
            for (int iU = 0; iU < (int)targetUnit.size(); iU++)
            {
                if (canLead(targetUnit[iU]->plot(), targetUnit[iU]->getID()))
                {
                    if (AI_plotValid(targetUnit[iU]->plot()))
                    {
                        if (!(targetUnit[iU]->plot()->isVisibleEnemyUnit(this)))
                        {
                            if (generatePath(targetUnit[iU]->plot(), 0, true))
                            {
                                int iCombatStrength = targetUnit[iU]->currCombatStr(NULL, NULL);
                                int iNowExp = targetUnit[iU]->getExperience();
                                if (iCombatStrength >= iBestStrength && iNowExp >= iBaseExp)
                                {
                                    if (iCombatStrength == iBestStrength && iNowExp == iBaseExp)
                                    {
                                        continue;
                                    }

                                    iBestStrength = iCombatStrength;
                                    pBestUnit = targetUnit[iU];
                                    pBestPlot = targetUnit[iU]->plot();
                                    iBaseExp = iNowExp;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    else
    {
    // end add


只是在原有的基础上增加一些,而且现在很傻的用这种方法计有多少单位有大军晋升,准备试试用内存记录有大军单位。

排除方面只是排除那些无前途的,和无关人士,减少循环时间。
但是用排除列表好还是放行列表好,还未最终定下来。

最后,不要来笑我。
发表于 2008-9-18 22:58:03 | 显示全部楼层

回复 #67 ztjal 的帖子

这是对CvUnitAI::AI_lead的改进, 但很遗憾,电脑大军不肯附身的瓶颈不在这里.

瓶颈在CvUnitAI::AI_generalMove()中
(iDanger > 0)在正常情形下很少见.
而AREAAI_OFFENSIVE对一个Team更不常见,从而(bOffenseWar && (GC.getGameINLINE().getSorenRandNum(2, "AI General Lead") == 0))也基本是假.

对于AI_lead,这个函数原来也基本上能找到pBestUnit.
这么说吧,只要电脑有UNITAI_ATTACK和UNITAI_COUNTER类型的单位,且调用了AI_lead, 相应的大军就会附身.

所以你这个修改基本上不能让电脑更愿意附身.
 楼主| 发表于 2008-9-18 23:02:49 | 显示全部楼层
CvUnitAi.cpp

3681



        if (iDanger > 0)
        {
                aeUnitAITypes.clear();
                aeUnitAITypes.push_back(UNITAI_ATTACK);
                aeUnitAITypes.push_back(UNITAI_COUNTER);
                if (AI_lead(aeUnitAITypes))
                {
                        return;
                }
        }

    // add PLAYEROPTION_GREAT_GENERAL_UNDEAD
    if (GC.afmIniPublicCheckBox("AFMGAMEOPTION","enables_great_general_undead"))
    {
        if (AI_lead(aeUnitAITypes))
        {
            return;
        }
    }
    // end add

        if (AI_construct(1))
        {
                return;
        }
发表于 2008-9-18 23:29:34 | 显示全部楼层

回复 #69 ztjal 的帖子

这样电脑的大军的确更愿意附身了.

不过你现在的搜索算法是想力量优先还是经验优先?

比如两个单位分别是Str2Exp10,Str10Exp2,你本来的想法是选那个? 现在的算法我看两个谁在前,谁就被选,而且Str5Exp5也可以被选,这恐怕不是你的本意吧?
 楼主| 发表于 2008-9-18 23:47:43 | 显示全部楼层
目的是力和经验最高者优先,现在的执行理论应该是谁前是谁,改成或吧,再加两个如果小于就闪
发表于 2008-9-19 13:43:23 | 显示全部楼层

回复 #71 ztjal 的帖子

你这个搜索算法大有问题, 比如对于候选单位分别为S10E2,S2E10,S5E5时, 谁在前谁就成为pBestUnit.
改成或也不行,那样谁靠后,谁中选.

你必须先确立力量和经验值谁优先. 比如力量优先时, 我会这样做,
if (iCombatStrength >= iBestStrength)
{
    int iNowExp = targetUnit[iU]->getExperience();
    if (iNowExp > iBaseExp || iCombatStrength > iBestStrength)  
    {
        iBestStrength = iCombatStrength;
        pBestUnit = targetUnit[iU];
        pBestPlot = targetUnit[iU]->plot();
        iBaseExp = iNowExp;
    }
}
外加再最开始iBaseExp = -1, 否则如果所有单位的经验都是0,照你的算法会找不着候选人的. 当然一般情形下,能有大军,就不会这样.

另外pBestPlot不用每次都重新赋值, 最后找到pBestUnit!=Null时,直接用pBestPlot=pBestUnit.plot()就行了.
说实在,Firaxis原来的代码,很多地方,连我这个完完全全的外行人都觉得可以优化, 可想而知其效率了.

[ 本帖最后由 Khyron 于 2008-9-19 14:24 编辑 ]
 楼主| 发表于 2008-9-19 19:17:06 | 显示全部楼层

回复 #72 Khyron 的帖子

忘记那个吧,之前贪心想两边都一齐来,没想细一些。现在改掉了,也不用那个临时的数组了。

[ 本帖最后由 ztjal 于 2008-9-19 21:21 编辑 ]
 楼主| 发表于 2008-9-24 18:47:25 | 显示全部楼层
ver.8.b7 update

[ 本帖最后由 ztjal 于 2008-9-24 20:37 编辑 ]
发表于 2008-9-26 17:51:18 | 显示全部楼层
用不了啊,怎么后三个新的选项里什么都没有呢?空的。。。。汗以个
 楼主| 发表于 2008-9-26 18:36:50 | 显示全部楼层

回复 #75 jukic 的帖子

恭喜你,你是第二个反映这个问题。

先确认你放mod的路径正确?

xxxxxx\Beyond the Sword\Mods\anyfunmod\

anyfunmod目录下就是Assets目录

xxxxxx\Beyond the Sword\Mods\anyfunmod\Assets
发表于 2008-9-26 19:46:08 | 显示全部楼层
这个mod很强大啊,在第一贴加点屏幕截图吧?
发表于 2008-9-26 20:08:35 | 显示全部楼层
希望增加攻下敌方城市后保留原文明的UU,UB 选项
http://www.civclub.net/bbs/viewthread.php?tid=31470
 楼主| 发表于 2008-9-26 20:45:39 | 显示全部楼层
原帖由 poyuzhe 于 2008-9-26 19:46 发表
这个mod很强大啊,在第一贴加点屏幕截图吧?



其实也没什么值得截图,

基本上看了名字就知道作用了,就当是减少第一贴的读取速度



原帖由 jakey 于 2008-9-26 20:08 发表
希望增加攻下敌方城市后保留原文明的UU,UB 选项
http://www.civclub.net/bbs/viewthread.php?tid=31470



这个很有创意,同时也有源码,那么就冇问题了
发表于 2008-9-28 07:56:51 | 显示全部楼层
要无限造传教士应该怎么改?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 07:24

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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