NP获取

NP获取机制、99%NP进位以及NP值显示的说明

NP获取机制

影响NP值 的方式有四种:直接增加、直接减少、攻击时的主动获取NP和被攻击时的被动获取NP。涉及到计算的是后两种。
计算方式如下:

主动NP获取
1.从者卡牌基础NP获取率
×
2.(色卡倍率 × 3.位置加成 × 4.色卡性能BUFF + 5.首位加成)
×
6.敌方补正
×
7.NP获得量BUFF
×
8.暴击补正
×
9.OVER KILL补正



被动NP获取
10.从者被攻击基础NP值
×
11.敌方补正
×
12.NP获得量BUFF
×
13.受击NP获得量BUFF
×
9.OVER KILL补正

计算结果说明

在游戏内部,从者的 NP 值是 int 存储的, 10000 表示 100% NP。

显示时,直接向下取整:
int display = (int)(np / 100.0)
例如:

数值显示
999999%
1001%
990%


战斗过程中,每个单次攻击(例如一张蓝卡攻击)都会按照上面公式计算1次。

计算过程中,数值是用 float 存储的,得到计算结果后会直接向下取整,转换为 int。

每个单次攻击可能会分为若干 hit(即攻击动作时产生若干伤害数字),每次 hit 都会给调用 addNp() 函数给双方加上一个上述结果的 int 值。即单次攻击时,最终 NP 获取是 (int)上述计算结果 * hit数。

具体逻辑可以参考以下伪代码:

// 执行上述计算(但排除最后一步 overkill 补正),结果转换为 int
int attackNp = (int)actor.getAttackNp();
 int defenseNp = (int)target.getDefenseNp(); 
                                                                          
// 举例,此处蓝卡有 3hit,这里是每个 hit 造成的伤害。遍历每个hit值。
int[] hits = {3238, 2329, 8827};
for(int i = 0; i < hits.count; i++) { 
                                                      
     // 如果这次hit会导致被攻击者血量到达0,则从该 hit 开始都算是 overkill     
     bool isOverkill = target.resultDamage(hits[i]);
     // 即最后一步 overkill 补正,注意这里结果仍然是 int 类型
     if (isOverkill) {
         attackNp *= 1.5; 
         defenseNp * 1.5;
          }
         actor.addNp(attackNp); // 攻击者NP增加     
         target.addNp(defenseNp); //被攻击者NP增加
}

举例:

贞德蓝卡 hit 数为 2,
贞德身上有 2 个 buff:蓝卡性能提升 20%,NP获得量提升 30%。
敌人身上有 1 个 buff:蓝卡耐性提升 10%。
三张蓝卡连携,第 3 张卡产生了暴击,且暴击的第二 hit 是 overkill。
则第 3 张卡 NP 获取计算:


贞德蓝卡的基础NP获取率×(蓝卡色卡倍率 ×第3位位置加成 ×色卡性能BUFF +首位加成)×敌方补正×NP获得量BUFF×暴击补正
76×[3.0 × 2.0 × (1.0 + 0.2 - 0.1) + 1.0 ] × 1.0 × (1 + 0.3) ×2.0 =1501.76

即每 hit 都会获得 1501 NP(15.01%),
蓝卡 2 hits,且第二 hit 达成了 overkill,则该蓝卡总 NP 获取为 1501 + 1501 × 1.5 = 3752(37.52%),
显示出来就是 37% NP。

关于 99% NP 进位到 100% 的说明

战斗时对于从者的 NP 的变动(例如攻击时每hit增加NP、使用技能减少NP),
都会调用到 addNp(int npAdd) 这个函数,
而这个函数内有个特殊判断(C#代码):

if (0 < npAdd && (float)this.lineMaxNp * 0.99f <= (float)this.np && this.np < this.lineMaxNp)  {    this.np = this.lineMaxNp; }

从代码本意上看,盐川想要的效果是:
如果 np 增加后,其值处于 [9900,9999](即99%NP范围内),则自动向上进位至 10000(100%)。但是中间这句判断是有问题的:

(float)this.lineMaxNp * 0.99f <= (float)this.np

C# 运算时,float 会自动转为 double 进行对比,左侧数字由于浮点数精度问题,会变为 9900.00009536743,如果右侧是 9900.0 ,则会对比失败,这就会导致 99% NP 的状态。
修复问题的办法是把 C# 代码改为整形判断: 

this.lineMaxNp * 99 / 100 <= this.np

对于 Unity 程序,Android 是用 mono 虚拟机跑的 C# dll,而 iOS 则是用 il2cpp 编译为原生的 C++ 代码。编译后 C++ 代码反而是正确的: 

(!(((float)((float)((float)(((float)((float)lineMaxNp)))*(float)(0.99f)))) <= ((float)(((float)((float)np))))))

所以,实现的结果是:只有iOS在NP增加为99%时进位100%,安卓在正好为99.00%时不会进位,仍显示99%。
日服1.40.0(2018.6.13)将float类型全部改为double,修复了这一问题,iOS和Android表现一致,NP增加时都会从99%进位100%。

if (0 < npAdd && (double)this.lineMaxNp * 0.99 <= (double)this.np && this.np < this.lineMaxNp) {
this.np = this.lineMaxNp;
}

关于 NP 显示的问题

在显示时,NP 处理逻辑如下(C#)

public static int npGauge(int now) {    

    int lineCount = 3;    

    int max = 3 * 10000;    

    return (int)Math.Floor((float)now / (float)max * 100f * (float)lineCount);

}

这段代码在 C# 下运行是没有问题的,即在 Android 平台上,NP显示是正确的。

但是,当编译为 iOS 项目时,Unity 会把 C# 转换为 C++ 代码:

int npGauge(int now) {    float npGauge = now / 30000.f;
    npGauge *= 100.0f;
    npGauge *= 3;    return (int)floor(npGauge);
}

这就会存在精度丢失的问题,导致某些数值会出现错误,例如 10700 会返回 106.999992。

即在 iOS 上会出现如下显示错误:

实际值显示值
29%28%
49%48%
58%57%
98%97%
107%106%
116%115%
125%124%
159%158%
177%176%
193%192%
196%195%
211%210%
214%213%
229%228%
232%231%
250%249%
253%252%

修复办法是全程改用 long 计算,先乘,后除,避免丢失精度。

计算公式说明

1.从者卡牌基础NP获取率

每个从者的的每张卡,都有一个基础 NP 值,
例如白贞德A卡0.76%,B卡0.76%,Q卡0.76%,EX卡0.76%,宝具卡0.76%
对于大部分从者来说,不同卡牌的基础 NP 是相同的。

2.色卡倍率

蓝卡:3.0,红卡:0.0,绿卡:1.0,EX卡:1.0。
宝具卡也按上述颜色取值。

3.位置加成

第1位1.0,第2位1.5,第3位2.0。
如果这张卡是宝具卡、EX卡,则不算位置加成,取值 1.0。

4.色卡性能BUFF

该模块计算方式为 1.0 + 攻击者色卡性能BUFF - 防御者色卡耐性BUFF
如果该模块最终结果小于 0.0,则修改为 0.0。

攻击者色卡性能BUFF包括:

图标效果
5ed7c3f2ffa7c9f9e45bd41651de37bd.jpgQuick 指令卡NP获得提升/性能提升
d0b1a1129697d0092c1846542f16f8c0.jpgArts 指令卡NP获得提升/性能提升
a4d2e42869ff6ed923fe4dbad89ddff6.jpgBuster 指令卡NP获得提升/性能提升
f733f91362b841558d19927437bd2711.jpgQuick 指令卡NP获得下降/性能下降
ffb0d2b204d019454c0d2d6d0cf9c2b8.jpgArts 指令卡NP获得提升/性能下降
110ee7e250fb2104aedee5edb5d33f09.jpgBuster 指令卡NP获得下降/性能下降

攻击者色卡性能BUFF计算方式为:

float rate = 1.0 + (upBuff1 + upBuff2 + ...) - (downBuff1 + downBuff2 + ...);
if (rate > 5.0) rate = 5.0; // 上限
if (rate < 0.001) rate = 0.001; // 下限

防御者色卡耐性BUFF包括:

图标效果
7640739d74877b84f072e2a9afdc2181.jpgQuick 指令卡耐性提升
b365321783fb51a00c75ebdc692eaf31.jpgArts 指令卡耐性提升
4ede6a03f4ab2ccbc02dde4fc4c797f0.jpgBuster 指令卡耐性提升
5c04504d7fae20c62b19d245361d480e.jpgQuick 指令卡耐性下降
9247f121849681f1be0a9e27361fbed4.jpgArts 指令卡耐性下降
021be6ef3ed703ee0383425db21740b5.jpgBuster 指令卡耐性下降

防御者色卡耐性BUFF计算方式为:

float rate = 1.0 + (upBuff1 + upBuff2 + ...) - (downBuff1 + downBuff2 + ...);
if (rate > 5.0) rate = 5.0; // 上限

举例:
蓝卡攻击,我方有 Arts卡性能提升50%,Arts卡NP获得下降30% 2个Buff,
对方有 Arts卡耐性下降20% Buff,
则计算结果是 1.0 + (1.0 + 0.5 - 0.3) - (1.0 - 0.2) = 1.4

5.首位加成

如果这次攻击的第一张卡是蓝色,则取值 1.0。否则取值 0.0。
宝具卡不参与该运算(即此处取值 0.0),但可以当做"首蓝"给其他普通卡和EX卡提供加成。

6.敌方补正

敌方从者身上带有的一个值 (downTdRate),通常在 0.8~1.2 之间。
通常来说,Rider、Caster 大于1.0、Assassin、Berserker 小于1.0。

该值仅当进入战斗后才会由服务端下发,其值并不确定。
注意,攻击和被击时的敌方补正是分开的两个数字,但通常数值相等。

7.NP获得量BUFF

该模块计算方式为 1.0 + 攻击者NP获得量提升BUFF - 攻击者NP获得量下降BUFF

float rate = 1.0 + (upBuff1 + upBuff2 + ...) - (downBuff1 + downBuff2 + ...);
if (rate > 5.0) rate = 5.0; // 下限
if (rate < 0.001) rate = 0.001; // 下限

图标效果
b21c3aaaeb703cabe53a06d2cee9702a.jpgNP获得量提升
e8ed889a1f427dcbe6d5b18445e3d19e.jpgNP获得量下降


8.暴击补正

如果该卡暴击判定成功,则此处取值 2.0。
如果该卡没有暴击、或者该卡是宝具卡,则取值 1.0。

9.OVER KILL补正

如果该 hit 是 over kill,则此处取值 1.5,否则取值 1.0。

10.从者被攻击基础NP值

每个从者都有一个固定的被攻击基础NP值,例如贞德为 300。

11.敌方补正

敌方从者身上带有的一个值 (downTdRate),通常在 0.8~1.2 之间。
通常来说,Rider、Caster 大于1.0、Assassin、Berserker 小于1.0。

该值仅当进入战斗后才会由服务端下发,其值并不确定。
注意,攻击和被击时的敌方补正是分开的两个数字,但通常数值相等。

12.NP获得量BUFF

该模块计算方式为 1.0 + 被攻击者NP获得量提升BUFF - 被攻击者NP获得量下降BUFF

float rate = 1.0 + (upBuff1 + upBuff2 + ...) - (downBuff1 + downBuff2 + ...);
if (rate > 5.0) rate = 5.0; // 下限
if (rate < 0.001) rate = 0.001; // 下限

图标效果
f9388a391fc2797acbfb0dbdae5c4262.jpgNP获得量提升
6a990c86cb367e7a6ec543da59b0c122.jpgNP获得量下降


13.受击NP获得量BUFF

该模块计算方式为 1.0 + 被攻击者受击时NP获得量提升 - 被攻击者受击时NP获得量下降

float rate = 1.0 + (upBuff1 + upBuff2 + ...) - (downBuff1 + downBuff2 + ...);
if (rate > 5.0) rate = 5.0; // 下限
if (rate < 0.001) rate = 0.001; // 下限

图标效果
4cac12862f6b96c1457ba14733b67d0e.jpg受到攻击时NP获得量提升
b2812cdb7e18c6abac804500bd310b34.jpg受到攻击时NP获得量下降

例如茶茶的技能黄金律(凶)所带来的效果受到攻击时NP获得量提升20%~50%


    • 最新评论
    • 热门评论

用户评论 (0)


  • 沙发空缺

热门排行

  • 伤害计算

  • 抽卡展示

  • NP获取

  • SL操作

  • 星星分配

  • 技能与BUFF

  • 宝具效果

  • 星星发生

  • Overkill判定