|
与本站略有不同,请大家注意。
今天闲来无事,看了一下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 |
|