0%

对于kb的研究报告

本文搬运自:https://wiki.kar.red/#!docs/对于kb的研究报告.md。原文链接需要ipv6地址才能访问
该转载未经过作者授权(因为也找不到作者在哪),如有侵权请联系仓鼠随时删除

为什么你服务器的击退那么糟糕:“脚本小子”对MC击退的研究成果

先挂一个人

挂人.png

会用vbs和cmd牛逼坏了?抱歉,您真不配。


该页面研究的是原版击退算法以及原版击退算法中的各值的作用。

通常我们在调整击退参数的时候,都是靠感觉去调的。Kar团队另辟蹊径,通过数据和代码的方式去理解和调整最合适的击退。为了贯彻我们     决心 (不是自称领头羊,是决心!!) 做中国PVP服领头羊的理念,我们决定将我们的研究成果分享出去。 (当然,为了防止我们的结果再一次被抄袭,然后国内出现一大批”中国最舒服kb的服务器”,我们不免费分享我们自己的击退算法和参数。)

EntityLiving类

由于在nms中部分变量经过了混淆,所以只能通过猜测得出这些变量的意义。

在EntityLiving中
当玩家受到伤害时
函数damageEntity中

EntityLiving1.png

d0为攻击者位置的X值减去受害者位置的X值,即为从受害者攻击者的向量的X值。
d1初始值为攻击者位置的Z值减去受害者位置的X值,即为从受害者攻击者的向量的Z值。
我们把d0称为x,d1称为z,则
若x²+z²<0.0001,则将d1设为一个-1至1之间的随机值*(见下方),再乘以0.01,同时将d0也进行一次这样的操作。
若x²+z²还是<0.0001,则再进行一次,直到不满足这个条件为止。
推测,这可能是两个玩家坐标一样或极度相近的时候,为防止产生0变量,生成一个随机的击退。为验证这个猜测,您可以tp一名玩家,此时您的坐标和这名玩家是一模一样的(其实会产生一点点差别)。接着打他一下,发现击退有时候不在您面前的方向,甚至有时候击退到身后去了。

*编个程统计一下这个随机数,进行100000000次(一亿次)模拟,发现其分布曲线是金字塔形。

分布是折线.png

它看起来大概是这样:

折线.png

设该折线的方程为 y = f(x), x∈(-1, 1)
很明显,该随机变量X落在(-x, x),x∈(0, 1)的几率为

1
$\frac{\int_{-n}^{n}f(x)dx}{\int_{-1}^{1}f(x)dx}=2x-x^2$

函数a中

EntityLiving2.png

其中的d0和d1即为上方所提的x和z
设一个变量f1为

EntityLiving3.png

即为该向量在水平面上投影的距离
变量f2为0.4,我们把该值称为水平倍数,或者Horizontal
再将motX、motY、motZ分别除以2,我们把该值称为Friction
接着将motX 减去 x / f1 * f2
将motY 加上 f2
将motZ 减去 z / f1 * f2
如果motY大于0.4,则设为0.4(这就是原版击退100附魔也无法飞天只能击远的原因)。我们把该值称为VerticalLimit。

以上即为当受害者受到伤害时的原始击退算法。详细讲解请看下方对原版击退算法的理解


##EntityHuman类
接着在攻击者的算法中,再次对产生的击退做出修正。

在EntityHuman类中
攻击者攻击别人时,受害者会受到以下击退

EntityHuman1.png

其中,i为攻击者手上武器击退附魔的等级,若没有,则为0。
如果攻击者正在疾跑,则i再加1
但是,在著名服务端mSpigot上,无论攻击者是否在疾跑,i的默认值都为1。

*mSpigot: 国内大部分PVP服务器用的都是该服务端。

yaw是攻击者的朝向的yaw值(欧拉角警告),是角度制,所以后面的乘以π除以180是转为弧度制。
entity.g(double motX, double motY, double motZ)函数为

Entity1.png

意思为,该实体目前的速度向量加上这三个值,再把成员ai改为true。
回到上面的击退计算,其中MathHelper是一个优化的数学工具人工具类
于是,该操作可写为

算法1.png