本篇教程由作者设定未经允许禁止转载。

一时兴起做了这篇教程教程?,由于本人的数学水平犹如学前班,所以可能会存在纰漏,还望大家指出。

文章末尾有 excel 公式,不愿意看的可以直接拉到最底下拿走用。


先看源码:

public static float calcCutoffDamage(float damage, float cutoff) {
  float p = 1f;
  float d = damage;
  damage = 0f;
  while(d > cutoff) {
    damage += p * cutoff;
    // safety for ridiculous values
    if(p > 0.001f) {
      p *= 0.9f;
    }
    else {
      damage += p * cutoff * ((d / cutoff) - 1f); // 最终伤害1
      return damage;
    }
    d -= cutoff;
  }
  damage += p * d;  // 最终伤害2
  return damage;
}

 

函数的输入有两个,一个是应用完所有特性后的伤害数值:damage 以及 cutoff。

匠魂原版的cutoff参考:

rapier

13

battle axe

30

cleaver

25

long sword

18

default

15

 

假设循环的次数是n,每次循环时damage的数值共同组成了一个数列A,a1=cutoff,a_n=a_(n-1)+p^(n-1)*cutoff = 10 * cutoff-10 * cutoff * 0.9 ^ n。


应用最终伤害1的条件为p < 0.001f,可得0.9^(n-1)<0.001,解得n > 66.563,也就是说,在66次循环的时候就会结束循环并得到最终伤害1。

 

最终伤害2的范围更广,在damage小于cutoff时,最终伤害2就等于damage,在p<0.001之前结束循环时,设循环次数为x,x=damage / cutoff(向下取整),最终伤害2的值为 10 * cutoff – 10 * cutoff * 0.9 ^ x + 0.9 ^ x * d % cutoff。


最后再来一段长到让人感叹的excel公式:

=IF(POWER(0.9,MIN(66, ROUNDDOWN(B1/B2, )))>0.01,10*B2-10*B2*POWER(0.9, MIN(66, ROUNDDOWN(B1/B2, )))+POWER(0.9,MIN(66, ROUNDDOWN(B1/B2, )))*IF(POWER(0.9,MIN(66, ROUNDDOWN(B1/B2, )))>0.01,IF(MOD(B1,MIN(66, ROUNDDOWN(B1/B2, )))>0,MOD(B1,MIN(66, ROUNDDOWN(B1/B2, ))),B1/MIN(66, ROUNDDOWN(B1/B2, ))),B1-B2*(MIN(66, ROUNDDOWN(B1/B2, ))-1)),10*B2-10*B2*POWER(0.9, MIN(66, ROUNDDOWN(B1/B2, )))+POWER(0.9,MIN(66, ROUNDDOWN(B1/B2, )))*B2*((IF(POWER(0.9,MIN(66, ROUNDDOWN(B1/B2, )))>0.01,IF(MOD(B1,MIN(66, ROUNDDOWN(B1/B2, )))>0,MOD(B1,MIN(66, ROUNDDOWN(B1/B2, ))),B1/MIN(66, ROUNDDOWN(B1/B2, ))),B1-B2*(MIN(66, ROUNDDOWN(B1/B2, ))-1))/B2)-1))

此处的B1为damage,B2为cutoff。

掌握了这个就知道怎么用虚金拉皮和别人爽快击剑了!