找回密码
 注册
搜索
查看: 1618|回复: 1

今天你打中对手了么?——COMBAT_D->do_attack之命中率分析(转帖仅作参考)

[复制链接]
门派:不明
发表于 2010-2-14 21:06:17 | 显示全部楼层 |阅读模式
与本站略有不同,请大家注意。



今天闲来无事,看了一下sj2002的代码。
主要过了一遍COMBAT_D->do_attack函数
原型为varargs void do_attack(object me, object victim, object weapon, int attack_type)

这个函数的作用就是对物理攻击(包括物理pfm)进行计算和处理

虽然是2002的代码,但是这么重要一个的函数在新代码里应该也不会做太多的改动。
相信还是有一定的参考价值。

在开始介绍前,先说明一下3个隐藏的属性:
事实上,每个ID都有3个隐藏的属性——attack_points,dodge_points和parry_points。
我们敲入score命令时列出的攻击,躲闪,招架的描述等级就是根据这3个值计算出来的。
而这3个值是通过一个名为skill_power的函数计算出来:
算法是:
attack_point=(攻击时使用技能之有效等级的2.5次方+exp/2)/30*后天臂力
dodge_point=(dodge有效等级的2.5次方+exp/2)/30*后天身法
parry_point=(parry有效等级的2.5次方+exp/2)/30*后天悟性

例如一个ID在500k时全技能170级,先天属性为bl 30, sf 10, gg 10, wx 30
则他的3个隐藏属性大约为
attack_point=1919754
dodge_point=1102837
parrty_point=1919754

这3个值正是在攻击中用来判断命中与否的依据

然后我把判断攻击命中部分的代码贴在这里,有兴趣的可以看看,没兴趣的就直接跳过到最后去看结论。
重点我用红色标示出来

代码中的ap,dp,pp分别是:攻方attack_point,守方dodge_point,守方parry_point


if (me->query_temp("lost_attack") > 0)
{
                //如果迷失攻击则将ap设为1
                me->add_temp("lost_attack", -1);
                ap = 1;
        }
        else if (me->is_lost()) ap = 1;
        else {
                // Check AP.
                //如果是dzxy的bishen则增加dzxy等级/5至apply/attack(附加命中)
                if( flag ) me->add_temp("apply/attack", me->query_skill("douzhuan-xingyi")/5);
                ap = skill_power(me, flag?"parry":attack_skill, SKILL_USAGE_ATTACK);        //如果flag则以parry有效等级来计算

skill_power,否则以attack_skill来计算
                if( flag ) me->add_temp("apply/attack", -me->query_skill("douzhuan-xingyi")/5);
        }

        if (ap < 1) ap = 1;
        // add by snowman@SJ 28/02/2000
        if(victim->query_temp("must_be_hit"))
                dp = 1;
        else {
                // Check DP.
                if (userp(me) && intp(action["dodge"]))
                        me->set_temp("fight/dodge", action["dodge"]);
                if (userp(me) && intp(action["parry"]))
                        me->set_temp("fight/parry", action["parry"]);

                dp = skill_power(victim, "dodge", SKILL_USAGE_DEFENSE);        //dp取对方dodge的skill_power

                // 空手攻兵器的,兵器躲闪降低 yuj 2000-11-05
                if (!weapon && vweapon) dp /= 2;        //进攻方无weapon,防守方有weapon,则防守方dp减半

                if (victim->is_busy())
                        dp = 1;                        //对方busy的情况下dp降为1
                if (dp < 1) dp = 1;
        }

        // Dodge, modified by snowman.
        if (random(ap + dp) < dp && living(victim))
        {
                .......
                //这里是处理dodge成功的情况(增加dodge技能经验或者exp)
        }

        else
        {
                //dodge失败,检验parry
                if( victim->query_temp("must_be_hit") )        //if victim 有"must_be_hit"属性,则设置pp=1
                        pp = 1;
                else
                {
                        // Check PP.
                        if (vweapon)
                        {        //对方持兵器的情况

                                pp = skill_power(victim, "parry", SKILL_USAGE_DEFENSE);                //pp=防守方的parry point
                                if (!weapon && !victim->is_busy())
                                        //在对方有兵器,本方无兵器,且对方不busy的情况下,pp*2
                                        pp *= 2;
                        }
                        else
                        {        //对方未持兵器的情况
                                
                                prepare = victim->query_skill_prepare();
                                if (!prepare) prepare = ([]);
                                if ( sizeof(prepare) == 0) foo = "unarmed";
                                if ( sizeof(prepare) == 1) foo = (keys(prepare))[0];
                                if ( sizeof(prepare) == 2) foo = (keys(prepare))[victim->query_temp("action_flag")];        //为

互备而写的代码
                                pp = skill_power(victim, foo, SKILL_USAGE_DEFENSE);

                                if (weapon)
                                {        //我方持有兵器

                                        if (victim->is_busy())        //对方busy的情况下,先降一下pp
                                                pp = pp/3 + random(pp/2);
                                        if ((int)victim->query_temp("fight/parry") > 40 )        //如果招式的parry>40,则pp/4(

非常不幸,招式parry过40的空手武功寥寥可数)
                                                pp /= 4;
                                        else                //如果招式parry值<=40,将pp置0
                                                pp = 0;
                                }
                        }

                        if (victim->is_busy())                //对方busy的情况下pp减半
                                pp /= 2;
                        if (pp < 1) pp = 1;
                }

                // Parry. modified by snowman
                if (random(ap + pp) < pp && living(victim))
                {
                        .......
                        //这里是处理parry成功的情况(增加parry技能经验或exp,)
                }

                // Hit! modified by snowman
                else
                {
                        //parry仍然失败,则被打中
                        .......
                        //以下就是打中的情况,进行伤害值计算以及另外一个重点——双方dodge parry force各个技能的auto pfm计算


可以看出:
一个ID的attack_point越高,也就是有效技能等级和后天臂力越高,那么他的命中率就越高。
所以兵器的命中和身法有关这一说是不可信的(化学pfm不在讨论之列)

我们可以简单的把
attack_point理解为命中率
dodge_point理解为躲闪率
parry_point理解为招架率


下面对各个不同情况做一下解释

正常情况下——两方都无busy;都是空手,或都有兵器;无lost_attack、must_be_hit等状态
1.闪躲成功的机率为  (守方dp)/(攻方ap)+(守方dp)
2.若闪躲失败,那么招架的机率为  (守方pp)/(攻方ap)+(守方pp)


空手攻击兵器的情况
1.兵器的dp减半,闪躲成功的机率变为  (守方dp/2)/(攻方ap)+(守方dp/2)
2.兵器的pp翻倍,招架成功的机率变为  (守方pp*2)/(攻方ap)+(守方pp*2)

兵器攻击空手的情况
1.闪躲成功机率依然是  (守方dp)/(攻方ap)+(守方dp)
2.如果空手使用的招式其"parry"属性大于40,则pp/4(减为四分之一); 否则pp=0(也就是必中)

所以大部分的空手武功如果没有闪躲掉兵器的攻击,那么几乎就是必中了,没有parry可言。
而兵器若没有躲过空手的攻击,则还有相当的可能将其格挡掉。


顺便说一句,在sj2002的代码里所有空手武功中招式parry能上40的好象只有太极拳,美女拳,天罗地网式等寥寥可数的几个。


另外补充一点。在发大部分物理pfm的时候,会有一个暂时的加成至攻击技能的有效等级,所以命中率会有所提升。
OVER
门派:不明
发表于 2011-8-10 14:41:28 | 显示全部楼层
这种好帖子 必须顶一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|书剑永恒MUD ( 闽ICP备14012032号|闽公网安备 35050202000162号 )

GMT+8, 2025-7-15 00:45 , Processed in 0.054746 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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