|
武侠类mud的精髓就在于战斗系统
平砍,busy,物理pfm,化学pfm,buff,大家天天用的,那么这些都是什么,你真的了解吗?
想深入了解武侠mud的战斗系统吗?
来吧,跟我一起来,从代码看起。
先随便去小熊泥苑里去找个武侠类的mud源码下载,能不能跑起来无所谓,我们只是去看看里面的文件。
以炎黄为例:
源码解压之后,找到kungfu/skill目录
这个目录下,有很多以技能为名字的.c文件和目录,其中.c文件就是这个技能的平砍描述文件,技能名目录下每个.c文件就是这个技能的一个pfm或者一个exert。
以炎黄的taiji-jian为例
kungfu/skill/taiji-jian.c
里面有很多这样格式的描述:
- ……
- ([ "action": "$N右腿半屈般蹲,一招「如封似闭」,剑尖虚指,转身撩向$n的$l",
- "force" : 135,
- "attack": 38,
- "dodge" : 185,
- "parry" : 220,
- "damage": 37,
- "lvl" : 240,
- "damage_type" : "刺伤"
- ]),
- ……
复制代码
当你在炎黄里用taiji-jian做攻击技能的时候,每次平砍出招的时候,都会随机从这些描述里挑一个满足lvl条件的一招,其中action就是你攻击时的出招描述,force是这一招的加力效果,attack是这一招的attack加成,dodge是这一招的dodge加成,parry是这一招的parry加成,damage是这一招的基本伤害,lvl是出招的技能level要求,damage_type会影响对手中招时的描述,比如刺伤就会是什么对穿而出之类的描述。
每个人物,战斗的时候,都会有一个基本的人物状态,包括attack,dodge,parry,damage等等,战斗平砍的时候,会把随机选出的招式的各种加成效果,加到人物的状态里,用攻击者的某个最终参数,和对手的某个最终参数进行某些算法的判断,判断成功就命中,判断失败就没有命中,命中之后,有一个最终的damage,具体算法,每个mud不同,一般都是在adm/daemons/combatd.c里。大家只要知道,每招的force会影响最终伤害,attack会影响命中和伤害,damage会影响最终伤害,dodge和parry会影响对手对自己的命中等等,数值越大,效果越明显。
炎黄里,taiji-jian的招式很多,但是基本damage都很小,前几招是0,后面的有些是个位数,最高的不过40。
作为对比,看看炎黄里的quanzhen-jian,最小damage是13,最高damage是135。
炎黄的设定和北侠的设定肯定有很大区别,但是taiji-jian作为一种攻弱守强的功夫,在各个mud里都差不多的,伤害非常低……
说完平砍,再来看pfm
pfm一般都是先判断是否满足出招条件,比如技能要求,手里武器要求,内力要求等等,满足条件之后,是命中判断,命中判断之后,是效果计算。
还是以炎黄里的taiji-jian为例:
busy类的chan:kungfu/skill/taiji-jian/chan.c里有这样的代码,其中level是攻击者taiji-jian的级别,可见一般的busy pfm的命中判断都是random(A)> B/C的格式,一般A和B是对等的,比如是双方exp,或者是攻击者的某攻击技能对被攻击者的某防守技能,C是一个系数,决定了同等条件下的命中几率。
- if (random(level) > (int)target->query_skill("parry", 1) / 2)
- {
- msg += HIR "结果$p" HIR "被$P" HIR "闹个手忙脚乱,"
- "惊慌失措,呆在当场,不知如何应对!\n" NOR;
- target->start_busy(level / 16 + 2);
- }
复制代码
后面的start_busy(level/16 + 2)就是命中之后的busy效果,一般是技能除以某个系数,然后加一个基本常数。
再来看物理连招,炎黄里的taiji-jian没有lian,有一个zhuan
物理连招的zhuan:kungfu/skill/taiji-jian/zhuan.c里有如下的代码,先是命中判断,这里的命中判断和chan的略微不同,用了A+random(B)>C的格式。命中之后,会计算连招数量,计算attack加成,然后,连续调用combatd.c里的底层攻击函数,连续攻击一定次数,最后,攻击完成之后,attack加成清除掉。因为这里的实际战斗是由combatd.c里计算出来的,所以是物理攻击,在北侠里是可以被挪移的。
- ap = me->query_skill("sword");
- dp = target->query_skill("parry");
- attack_time = 5;
- if (ap / 2 + random(ap * 2) > dp)
- {
- msg += HIY "结果$p" HIY "被$P" HIY
- "攻了个措手不及,连连后退不暇!\n" NOR;
- count = ap / 10;
- me->add_temp("apply/attack", count);
- attack_time += random(ap / 45);
- } else
- {
- msg += HIC "$n" HIC "见$N" HIC "这几剑并无破绽"
- ",不敢大意,小心应付。\n" NOR;
- count = 0;
- }
-
- message_combatd(msg, me, target);
- if (attack_time > 10)
- attack_time = 10;
- me->add("neili", -attack_time * 20);
- for (i = 0; i < attack_time; i++)
- {
- if (! me->is_fighting(target))
- break;
- COMBAT_D->do_attack(me, target, weapon, 0);
- }
- me->add_temp("apply/attack", -count);
- me->start_busy(1 + random(attack_time));
复制代码
再来看看化学类的pfm,炎黄里的taiji-quan的zhen
化学pfm的zhen:kungfu/skill/taiji-quan/zhen.c里有这样的代码,先是命中判断,和busy的类似,然后是伤害计算,这里是直接计算出damage,然后调用底层的函数把伤害apply到被攻击者身上,因为不经过底层的战斗计算,是直接伤害,所以不可以被挪移。
- if (random(me->query_skill("force")) > target->query_skill("force") / 2)
- {
- me->start_busy(3);
- target->start_busy(random(3));
-
- damage = (int)me->query_skill("force", 1);
- damage = damage / 2 + random(damage / 2);
-
- msg += COMBAT_D->do_damage(me, target, UNARMED_ATTACK, damage, 50,
- HIR "只见$N" HIR "这一拳变化无方,气劲"
- "封了$n" HIR "所有的退路,一拳正好命中"
- "。\n:内伤@?");
- } else
复制代码
最后再看一个buff类的,taiji-jian的sui
buff类pfm,sui:kungfu/skill/taiji-jian/sui.c里有这样的代码,buff类没用命中判断,只有计算效果,计算持续时间。随字诀是加defense,减attack的,状态更新完之后,加一个temp标记,防止重复buff,然后会调用一个call_out函数,这个函数的意思就是延后xx秒执行,也就是过一段时间之后,就执行remove_effect函数,清除buff效果,并且删除temp标记。
- skill = me->query_skill("taiji-jian", 1);
- me->add_temp("apply/defense", skill / 3);
- me->add_temp("apply/attack", -skill / 6);
- me->set_temp("tjj_sui", 1);
- me->start_call_out((: call_other, __FILE__, "remove_effect",
- me, skill / 3 :), skill / 3);
- me->add("neili", -100);
- if (me->is_fighting())
- me->start_busy(3);
- return 1;
- }
- void remove_effect(object me, int amount)
- {
- if (me->query_temp("tjj_sui"))
- {
- me->add_temp("apply/defense", -amount);
- me->add_temp("apply/attack", amount / 2);
- me->delete_temp("tjj_sui");
- tell_object(me, "你的" SUI "运行完毕,将内力收回丹田。\n");
- }
- }
复制代码
这样,各种基本pfm就讲完了,北侠里有些pfm是综合类的,比如yinfeng,比如kuang,无非就是这些基本pfm的组合而已。
讲完pfm,讲讲pfm里的bug,很多bug,都是因为pfm的文件里漏了东西,或者call_out的调用有问题。
用了pfm自身没busy的,那是因为代码里忘了加自身的busy惩罚
某些pfm必中的,那是因为命中判断里忘了加random
某些buff效果,用了以后没有call_out或者call_out的参数和开始加的参数不一致,或者没有加temp标记的,就造成了无穷buff的bug
等等等等
本文只是一个武侠类mud的战斗系统的基本介绍,只是一个参考,看不到北侠的代码,没法具体讲解,所以,看看就行了,请不要拿炎黄的代码来评论北侠…… |
评分
-
查看全部评分
|