hrbattle 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -642,6 +642,8 @@ export class BattleCore {
642
642
  else if (rep === -1) {
643
643
  stagger = Math.floor(stagger * 7000 / 10000);
644
644
  }
645
+ const takenRate = 10000 + this.effectSystem.getImbalanceTakenRate(target.id);
646
+ stagger = Math.max(0, Math.floor(stagger * takenRate / 10000));
645
647
  const max = this.computeImbalanceMax(target);
646
648
  const from = target.runtime.Imbalance;
647
649
  target.runtime.Imbalance = Math.min(max, from + stagger);
@@ -39,6 +39,7 @@
39
39
  "durationPerStack": 1,
40
40
  "onRoundEndDelta": -1,
41
41
  "expireRounds": 1,
42
+ "speedRateDelta": -1000,
42
43
  "applyOnElementBreakElements": ["water"]
43
44
  },
44
45
  {
@@ -89,7 +90,7 @@
89
90
  "durationPerStack": 1,
90
91
  "onRoundEndDelta": -1,
91
92
  "expireRounds": 1,
92
- "defDelta": -1000,
93
+ "allElementResistDelta": -1000,
93
94
  "applyOnElementBreakElements": ["dark"]
94
95
  },
95
96
  {
@@ -99,7 +100,7 @@
99
100
  "durationPerStack": 1,
100
101
  "onRoundEndDelta": -1,
101
102
  "expireRounds": 1,
102
- "defDelta": -1000
103
+ "defenseRateDelta": -1000
103
104
  },
104
105
  {
105
106
  "id": "def-break",
@@ -112,11 +113,12 @@
112
113
  },
113
114
  {
114
115
  "id": "pierce",
115
- "name": "穿透",
116
+ "name": "穿孔",
116
117
  "maxStacks": 1,
117
118
  "durationPerStack": 2,
118
119
  "onRoundEndDelta": -1,
119
- "expireRounds": 2
120
+ "expireRounds": 2,
121
+ "imbalanceTakenRateDelta": 2000
120
122
  },
121
123
  {
122
124
  "id": "counter",
@@ -138,12 +140,12 @@
138
140
  },
139
141
  {
140
142
  "id": "flash",
141
- "name": "闪光",
143
+ "name": "闪击",
142
144
  "maxStacks": 3,
143
145
  "durationPerStack": 1,
144
146
  "onRoundEndDelta": -1,
145
147
  "expireRounds": 1,
146
- "imbalanceRateDelta": 800,
148
+ "assistRateDelta": 1500,
147
149
  "critRateDelta": 1500
148
150
  },
149
151
  {
@@ -157,11 +159,13 @@
157
159
  },
158
160
  {
159
161
  "id": "will",
160
- "name": "意志",
162
+ "name": "惩戒",
161
163
  "maxStacks": 999,
162
164
  "durationPerStack": 999999999,
163
165
  "onRoundEndDelta": 0,
164
- "expireRounds": 999999999
166
+ "expireRounds": 999999999,
167
+ "defenseRateDelta": 300,
168
+ "effectHitDelta": 300
165
169
  },
166
170
  {
167
171
  "id": "rage",
@@ -170,7 +174,7 @@
170
174
  "durationPerStack": 999999999,
171
175
  "onRoundEndDelta": 0,
172
176
  "expireRounds": 999999999,
173
- "speedDelta": 1000
177
+ "speedRateDelta": 1000
174
178
  },
175
179
  {
176
180
  "id": "cook-restraint",
@@ -282,7 +286,6 @@
282
286
  "durationPerStack": 9999999,
283
287
  "onRoundEndDelta": 0,
284
288
  "expireRounds": 9999999,
285
- "speedDelta": 1000,
286
289
  "speedRateDelta": 1000
287
290
  },
288
291
  {
@@ -382,7 +385,7 @@
382
385
  "durationPerStack": 2,
383
386
  "onRoundEndDelta": -1,
384
387
  "expireRounds": 2,
385
- "defDelta": 2000
388
+ "defenseRateDelta": 2000
386
389
  },
387
390
  {
388
391
  "id": "pela-crit-up",
@@ -6,7 +6,7 @@
6
6
  "role": "歼灭",
7
7
  "skills": [
8
8
  { "id": "11011", "type": "basic", "mode": "hybrid", "energyCost": 0, "energyGain": 20, "cooldown": 0, "targetRule": "nearest", "element": "rock", "configTemplateId": "common.basic.single.50", "scriptId": "cook.basic.script", "level": 1 },
9
- { "id": "11012", "type": "core", "mode": "script", "energyCost": 0, "energyGain": 30, "cooldown": 2, "targetRule": "nearest", "element": "rock", "scriptId": "cook.core.script", "level": 1 },
9
+ { "id": "11012", "type": "core", "mode": "hybrid", "energyCost": 0, "energyGain": 30, "cooldown": 2, "targetRule": "nearest", "element": "rock", "configTemplateId": "cook.core.single", "scriptId": "cook.core.script", "level": 1 },
10
10
  { "id": "11014", "type": "ultimate", "mode": "hybrid", "energyCost": 70, "energyGain": 0, "cooldown": 4, "targetRule": "nearest", "element": "rock", "configTemplateId": "cook.ultimate.slash", "scriptId": "cook.ultimate.script", "level": 1 },
11
11
  { "id": "11013", "type": "passive", "mode": "script", "energyCost": 0, "energyGain": 0, "cooldown": 0, "targetRule": "self", "element": "rock", "scriptId": "cook.passive.script", "level": 1, "activateOnBattleStart": true }
12
12
  ]
@@ -17,9 +17,9 @@
17
17
  "element": "thunder",
18
18
  "role": "歼灭",
19
19
  "skills": [
20
- { "id": "11021", "type": "basic", "mode": "script", "energyCost": 0, "energyGain": 20, "cooldown": 0, "targetRule": "lowestHpEnemy", "element": "thunder", "scriptId": "miaoluo.basic.script", "level": 1 },
21
- { "id": "11022", "type": "core", "mode": "script", "energyCost": 0, "energyGain": 30, "cooldown": 2, "targetRule": "lowestHpEnemy", "element": "thunder", "scriptId": "miaoluo.core.script", "level": 1 },
22
- { "id": "11024", "type": "ultimate", "mode": "script", "energyCost": 60, "energyGain": 0, "cooldown": 4, "targetRule": "lowestHpEnemy", "element": "thunder", "scriptId": "miaoluo.ultimate.script", "level": 1 },
20
+ { "id": "11021", "type": "basic", "mode": "config", "energyCost": 0, "energyGain": 20, "cooldown": 0, "targetRule": "lowestHpEnemy", "element": "thunder", "configTemplateId": "miaoluo.basic.flash", "level": 1 },
21
+ { "id": "11022", "type": "core", "mode": "hybrid", "energyCost": 0, "energyGain": 30, "cooldown": 2, "targetRule": "lowestHpEnemy", "element": "thunder", "configTemplateId": "miaoluo.core.lowhp", "scriptId": "miaoluo.core.script", "level": 1 },
22
+ { "id": "11024", "type": "ultimate", "mode": "hybrid", "energyCost": 60, "energyGain": 0, "cooldown": 4, "targetRule": "lowestHpEnemy", "element": "thunder", "configTemplateId": "miaoluo.ultimate.triple", "scriptId": "miaoluo.ultimate.script", "level": 1 },
23
23
  { "id": "11023", "type": "passive", "mode": "script", "energyCost": 0, "energyGain": 0, "cooldown": 0, "targetRule": "self", "element": "thunder", "scriptId": "miaoluo.passive.script", "level": 1, "activateOnBattleStart": true }
24
24
  ]
25
25
  },
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "heroId": "blade",
40
- "heroName": "布莱德",
40
+ "heroName": "",
41
41
  "element": "water",
42
42
  "role": "歼灭",
43
43
  "skills": [
@@ -1,41 +1,43 @@
1
1
  [
2
2
  { "id": "common.basic.single.50", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
3
- { "id": "cook.ultimate.slash", "steps": [{ "kind": "damage", "ratio": 4, "scaleStat": "Att" }] },
4
- { "id": "miaoluo.basic.flash", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
5
- { "id": "miaoluo.core.lowhp", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }] },
3
+ { "id": "cook.ultimate.slash", "steps": [{ "kind": "damage", "ratio": 4, "ratioByLevel": [4, 4.6, 5.2, 5.8, 6.4], "scaleStat": "Att" }] },
4
+ { "id": "cook.core.single", "steps": [{ "kind": "damage", "ratio": 1, "ratioByLevel": [1, 1.15, 1.3, 1.45, 1.6], "scaleStat": "Att" }] },
5
+ { "id": "miaoluo.basic.flash", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
6
+ { "id": "miaoluo.core.lowhp", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }] },
7
+ { "id": "miaoluo.ultimate.triple", "steps": [{ "kind": "damage", "ratio": 0.6, "ratioByLevel": [0.6, 0.69, 0.78, 0.87, 0.96], "scaleStat": "Att", "repeat": 3 }] },
6
8
  { "id": "blade.basic.slow", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
7
- { "id": "blade.core.aoe", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
8
- { "id": "blade.ultimate.strike", "steps": [{ "kind": "damage", "ratio": 3, "scaleStat": "Att" }] },
9
- { "id": "luoluo.basic.will", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "dazzle", "fixedProb": 5000 }] },
10
- { "id": "luoluo.core.taunt", "steps": [{ "kind": "shield", "ratio": 0.1, "scaleStat": "Mhp" }] },
11
- { "id": "luoluo.ultimate.def-aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "taunt", "fixedProb": 5000 }] },
12
- { "id": "rudy.basic.single", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
13
- { "id": "rudy.core.stun", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "stun", "fixedProb": 6500 }] },
9
+ { "id": "blade.core.aoe", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
10
+ { "id": "blade.ultimate.strike", "steps": [{ "kind": "damage", "ratio": 3, "ratioByLevel": [3, 3.45, 3.9, 4.35, 4.8], "scaleStat": "Att" }] },
11
+ { "id": "luoluo.basic.will", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "dazzle", "fixedProb": 5000, "fixedProbByLevel": [5000, 5500, 6000, 6500, 7000] }] },
12
+ { "id": "luoluo.core.taunt", "steps": [{ "kind": "shield", "ratio": 0.1, "ratioByLevel": [0.1, 0.12, 0.14, 0.16, 0.18], "scaleStat": "Mhp" }] },
13
+ { "id": "luoluo.ultimate.def-aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "taunt", "fixedProb": 5000, "fixedProbByLevel": [5000, 5500, 6000, 6500, 7000] }] },
14
+ { "id": "rudy.basic.single", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
15
+ { "id": "rudy.core.stun", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "stun", "fixedProb": 6500, "fixedProbByLevel": [6500, 7000, 7500, 8000, 8500] }] },
14
16
  { "id": "rudy.core.defense-buff", "steps": [{ "kind": "buff", "ratio": 0, "buffId": "def-up", "fixedProb": 10000 }] },
15
17
  { "id": "rudy.ultimate.team-shield", "steps": [{ "kind": "shield", "ratio": 0.2, "ratioByLevel": [0.2, 0.26, 0.32, 0.38, 0.44], "scaleStat": "Mhp" }] },
16
- { "id": "es.basic.single", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
17
- { "id": "es.core.damage", "steps": [{ "kind": "damage", "ratio": 0.35, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "dazzle", "fixedProb": 5000 }] },
18
+ { "id": "es.basic.single", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
19
+ { "id": "es.core.damage", "steps": [{ "kind": "damage", "ratio": 0.35, "ratioByLevel": [0.35, 0.4, 0.46, 0.51, 0.56], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "dazzle", "fixedProb": 5000, "fixedProbByLevel": [5000, 5500, 6000, 6500, 7000] }] },
18
20
  { "id": "es.core.heal", "steps": [{ "kind": "heal", "ratio": 0.4, "ratioByLevel": [0.4, 0.48, 0.56, 0.64, 0.72], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "bless", "fixedProb": 10000 }] },
19
- { "id": "es.ultimate.light-aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }] },
20
- { "id": "kesi.basic.double-near", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
21
- { "id": "kesi.core.random", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
22
- { "id": "kesi.ultimate.dot-burst", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }] },
21
+ { "id": "es.ultimate.light-aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }] },
22
+ { "id": "kesi.basic.double-near", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
23
+ { "id": "kesi.core.random", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
24
+ { "id": "kesi.ultimate.dot-burst", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }] },
23
25
  { "id": "kleiwu.basic.single", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
24
- { "id": "kleiwu.basic.dual", "steps": [{ "kind": "damage", "ratio": 0.3, "scaleStat": "Att" }] },
25
- { "id": "kleiwu.core.backlash", "steps": [{ "kind": "damage", "ratio": 1.2, "scaleStat": "Att" }] },
26
- { "id": "kleiwu.core.split", "steps": [{ "kind": "damage", "ratio": 1.2, "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.4, "scaleStat": "Att" }] },
27
- { "id": "kleiwu.ultimate.aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.8, "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
28
- { "id": "ailisha.basic.fire", "steps": [{ "kind": "damage", "ratio": 0.7, "scaleStat": "Att" }] },
26
+ { "id": "kleiwu.basic.dual", "steps": [{ "kind": "damage", "ratio": 0.3, "ratioByLevel": [0.3, 0.35, 0.39, 0.44, 0.48], "scaleStat": "Att" }] },
27
+ { "id": "kleiwu.core.backlash", "steps": [{ "kind": "damage", "ratio": 1.2, "ratioByLevel": [1.2, 1.38, 1.56, 1.74, 1.92], "scaleStat": "Att" }] },
28
+ { "id": "kleiwu.core.split", "steps": [{ "kind": "damage", "ratio": 1.2, "ratioByLevel": [1.2, 1.38, 1.56, 1.74, 1.92], "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.4, "ratioByLevel": [0.4, 0.46, 0.52, 0.58, 0.64], "scaleStat": "Att" }] },
29
+ { "id": "kleiwu.ultimate.aoe", "steps": [{ "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.8, "ratioByLevel": [0.8, 0.92, 1.04, 1.16, 1.28], "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }, { "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
30
+ { "id": "ailisha.basic.fire", "steps": [{ "kind": "damage", "ratio": 0.7, "ratioByLevel": [0.7, 0.81, 0.91, 1.02, 1.12], "scaleStat": "Att" }] },
29
31
  { "id": "ailisha.core.share", "steps": [{ "kind": "buff", "ratio": 0, "buffId": "share-damage", "fixedProb": 10000 }] },
30
- { "id": "ailisha.ultimate.hp-aoe", "steps": [{ "kind": "damage", "ratio": 1.2, "scaleStat": "Att" }] },
31
- { "id": "luolai.basic.random", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }] },
32
- { "id": "luolai.core.hot", "steps": [{ "kind": "heal", "ratio": 0.1, "scaleStat": "Mhp" }, { "kind": "buff", "ratio": 0, "buffId": "condense", "fixedProb": 10000 }] },
33
- { "id": "luolai.ultimate.heal", "steps": [{ "kind": "heal", "ratio": 0.2, "scaleStat": "Mhp" }, { "kind": "buff", "ratio": 0, "buffId": "condense", "fixedProb": 10000 }] },
34
- { "id": "tier.basic.weathering", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 3000 }] },
35
- { "id": "tier.core.double", "steps": [{ "kind": "damage", "ratio": 0.6, "scaleStat": "Att", "repeat": 2 }, { "kind": "buff", "ratio": 0, "buffId": "pierce", "fixedProb": 3000 }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 3000 }] },
36
- { "id": "tier.ultimate.single", "steps": [{ "kind": "damage", "ratio": 2.5, "scaleStat": "Att" }] },
37
- { "id": "tier.ultimate.aoe", "steps": [{ "kind": "damage", "ratio": 0.7, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "def-break", "fixedProb": 8000 }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 10000 }] },
38
- { "id": "pela.basic.speed", "steps": [{ "kind": "damage", "ratio": 0.5, "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "speed-up", "fixedProb": 10000 }] },
32
+ { "id": "ailisha.ultimate.hp-aoe", "steps": [{ "kind": "damage", "ratio": 1.2, "ratioByLevel": [1.2, 1.38, 1.56, 1.74, 1.92], "scaleStat": "Att" }] },
33
+ { "id": "luolai.basic.random", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
34
+ { "id": "luolai.core.hot", "steps": [{ "kind": "heal", "ratio": 0.1, "ratioByLevel": [0.1, 0.12, 0.14, 0.16, 0.18], "scaleStat": "Mhp" }, { "kind": "buff", "ratio": 0, "buffId": "condense", "fixedProb": 10000 }] },
35
+ { "id": "luolai.ultimate.heal", "steps": [{ "kind": "heal", "ratio": 0.2, "ratioByLevel": [0.2, 0.24, 0.28, 0.32, 0.36], "scaleStat": "Mhp" }, { "kind": "buff", "ratio": 0, "buffId": "condense", "fixedProb": 10000 }] },
36
+ { "id": "tier.basic.weathering", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 3000, "fixedProbByLevel": [3000, 3500, 4000, 4500, 5000] }] },
37
+ { "id": "tier.core.double", "steps": [{ "kind": "damage", "ratio": 0.6, "ratioByLevel": [0.6, 0.69, 0.78, 0.87, 0.96], "scaleStat": "Att", "repeat": 2 }, { "kind": "buff", "ratio": 0, "buffId": "pierce", "fixedProb": 3000, "fixedProbByLevel": [3000, 3500, 4000, 4500, 5000] }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 3000, "fixedProbByLevel": [3000, 3500, 4000, 4500, 5000] }] },
38
+ { "id": "tier.ultimate.single", "steps": [{ "kind": "damage", "ratio": 2.5, "ratioByLevel": [2.5, 2.88, 3.25, 3.63, 4], "scaleStat": "Att" }] },
39
+ { "id": "tier.ultimate.aoe", "steps": [{ "kind": "damage", "ratio": 0.7, "ratioByLevel": [0.7, 0.81, 0.91, 1.02, 1.12], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "def-break", "fixedProb": 8000, "fixedProbByLevel": [8000, 8500, 9000, 9500, 10000] }, { "kind": "buff", "ratio": 0, "buffId": "weathering", "fixedProb": 10000 }] },
40
+ { "id": "pela.basic.speed", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }, { "kind": "buff", "ratio": 0, "buffId": "speed-up", "fixedProb": 10000 }] },
39
41
  { "id": "pela.core.support", "steps": [{ "kind": "buff", "ratio": 0, "buffId": "damage-up", "fixedProb": 10000 }] },
40
42
  { "id": "pela.ultimate.team-buff", "steps": [{ "kind": "buff", "ratio": 0, "buffId": "attack-up", "fixedProb": 10000 }] },
41
43
  { "id": "m.basic.water.50", "steps": [{ "kind": "damage", "ratio": 0.5, "ratioByLevel": [0.5, 0.58, 0.66, 0.74, 0.82], "scaleStat": "Att" }] },
@@ -9,6 +9,7 @@ export declare class EffectSystem {
9
9
  getBuffs(unitId: UnitId): BuffInstance[];
10
10
  getBuffConfigs(): BuffConfig[];
11
11
  hasBuff(unitId: UnitId, buffId: string): boolean;
12
+ getImbalanceTakenRate(unitId: UnitId): number;
12
13
  getEffectiveStats(unit: UnitModel): UnitStats;
13
14
  addBuff(owner: UnitModel, sourceId: UnitId, buffId: string): void;
14
15
  removeBuff(owner: UnitModel, buffId: string): void;
@@ -21,6 +21,12 @@ export class EffectSystem {
21
21
  hasBuff(unitId, buffId) {
22
22
  return this.getBuffs(unitId).some((b) => b.id === buffId && b.stacks > 0);
23
23
  }
24
+ getImbalanceTakenRate(unitId) {
25
+ return this.getBuffs(unitId).reduce((total, buff) => {
26
+ const stacks = Math.max(1, buff.stacks);
27
+ return total + (buff.config.imbalanceTakenRateDelta ?? 0) * stacks;
28
+ }, 0);
29
+ }
24
30
  getEffectiveStats(unit) {
25
31
  const buffs = this.getBuffs(unit.id);
26
32
  const stat = { ...unit.stats };
@@ -54,11 +60,23 @@ export class EffectSystem {
54
60
  if (cfg.effectHitDelta) {
55
61
  stat.pEHR += cfg.effectHitDelta * stacks;
56
62
  }
63
+ if (cfg.assistRateDelta) {
64
+ stat.pAR += cfg.assistRateDelta * stacks;
65
+ }
57
66
  if (cfg.damageRateDelta) {
58
67
  stat.pBSDI += cfg.damageRateDelta * stacks;
59
68
  stat.pESDI += cfg.damageRateDelta * stacks;
60
69
  stat.pFSDI += cfg.damageRateDelta * stacks;
61
70
  }
71
+ if (cfg.allElementResistDelta) {
72
+ stat.pFDI_Def += cfg.allElementResistDelta * stacks;
73
+ stat.pTDI_Def += cfg.allElementResistDelta * stacks;
74
+ stat.pWDI_Def += cfg.allElementResistDelta * stacks;
75
+ stat.pRDI_Def += cfg.allElementResistDelta * stacks;
76
+ stat.pADI_Def += cfg.allElementResistDelta * stacks;
77
+ stat.pLDI_Def += cfg.allElementResistDelta * stacks;
78
+ stat.pDDI_Def += cfg.allElementResistDelta * stacks;
79
+ }
62
80
  if (cfg.vulnerabilityDelta) {
63
81
  stat.pVulnerability += cfg.vulnerabilityDelta * stacks;
64
82
  }
@@ -155,47 +155,43 @@ const bladeCoreScript = {
155
155
  };
156
156
  const luoluoBasicScript = {
157
157
  onCast(ctx) {
158
- ctx.api.addBuff(ctx.caster, ctx.caster, "will");
159
- return {
160
- skillId: ctx.skillId,
161
- casterId: ctx.caster,
162
- targets: ctx.targets,
163
- totalDamage: 0,
164
- totalHeal: 0,
165
- totalShield: 0,
166
- triggeredBy: ctx.trigger
167
- };
158
+ return buildEmptyResult(ctx, ctx.targets);
168
159
  }
169
160
  };
170
161
  // 洛洛核心技:获得10%生命值的护盾,每层【惩戒/意志】使护盾强度增加10%
171
162
  const luoluoCoreScript = {
172
163
  onCast(ctx) {
173
- // 护盾交由config模板结算,script层不再重复加盾
174
- return buildEmptyResult(ctx, ctx.targets);
164
+ const self = ctx.api.getUnit(ctx.caster);
165
+ if (!self) {
166
+ return buildEmptyResult(ctx, ctx.targets);
167
+ }
168
+ const willStacks = ctx.api
169
+ .getBuffs(ctx.caster)
170
+ .filter((buff) => buff.id === "will")
171
+ .reduce((total, buff) => total + buff.stacks, 0);
172
+ if (willStacks <= 0) {
173
+ return buildEmptyResult(ctx, ctx.targets);
174
+ }
175
+ // 基础护盾由 config 模板提供;这里补上每层惩戒额外 +10% 基础护盾强度。
176
+ const extraShield = Math.floor(self.stats.Mhp * 0.01 * willStacks);
177
+ const totalShield = ctx.api.shield(ctx.caster, extraShield);
178
+ return {
179
+ ...buildEmptyResult(ctx, ctx.targets),
180
+ totalShield,
181
+ hits: [buildShieldHit(ctx, ctx.caster, totalShield)]
182
+ };
175
183
  }
176
184
  };
177
185
  const miaoluoUltimateScript = {
178
186
  onCast(ctx) {
179
187
  const self = ctx.api.getUnit(ctx.caster);
180
- const target = ctx.api
181
- .getAliveUnits()
182
- .filter((unit) => self && unit.teamId !== self.teamId)
183
- .sort((a, b) => {
184
- if (a.runtime.Hp !== b.runtime.Hp) {
185
- return a.runtime.Hp - b.runtime.Hp;
186
- }
187
- return a.position - b.position;
188
- })[0];
188
+ const targetId = ctx.targets[0];
189
+ const target = targetId ? ctx.api.getUnit(targetId) : undefined;
189
190
  let totalDamage = 0;
190
191
  const hits = [];
191
192
  if (self && target) {
192
193
  ctx.api.addBuff(ctx.caster, ctx.caster, "miaoluo-ultimate-focus");
193
194
  hits.push(buildBuffHit(ctx, ctx.caster, "miaoluo-ultimate-focus"));
194
- for (let i = 0; i < 3; i += 1) {
195
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.6));
196
- totalDamage += r.damage;
197
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
198
- }
199
195
  if (ctx.api.hasBuff(target.id, "imbalance-vulnerability")) {
200
196
  const r2 = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.3));
201
197
  totalDamage += r2.damage;
@@ -211,56 +207,21 @@ const miaoluoUltimateScript = {
211
207
  };
212
208
  const miaoluoBasicScript = {
213
209
  onCast(ctx) {
214
- const self = ctx.api.getUnit(ctx.caster);
215
- const target = ctx.api
216
- .getAliveUnits()
217
- .filter((unit) => self && unit.teamId !== self.teamId)
218
- .sort((a, b) => {
219
- if (a.runtime.Hp !== b.runtime.Hp) {
220
- return a.runtime.Hp - b.runtime.Hp;
221
- }
222
- return a.position - b.position;
223
- })[0];
224
- let totalDamage = 0;
225
- const hits = [];
226
- if (self && target) {
227
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.5));
228
- totalDamage += r.damage;
229
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
230
- }
231
- return {
232
- ...buildEmptyResult(ctx, target ? [target.id] : []),
233
- totalDamage,
234
- hits
235
- };
210
+ return buildEmptyResult(ctx, ctx.targets);
236
211
  }
237
212
  };
238
213
  const miaoluoCoreScript = {
239
214
  onCast(ctx) {
240
- const self = ctx.api.getUnit(ctx.caster);
241
- const target = ctx.api
242
- .getAliveUnits()
243
- .filter((unit) => self && unit.teamId !== self.teamId)
244
- .sort((a, b) => {
245
- if (a.runtime.Hp !== b.runtime.Hp) {
246
- return a.runtime.Hp - b.runtime.Hp;
247
- }
248
- return a.position - b.position;
249
- })[0];
250
- let totalDamage = 0;
215
+ const targetId = ctx.targets[0];
251
216
  const hits = [];
252
- if (self && target) {
253
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.8));
254
- totalDamage += r.damage;
255
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
256
- ctx.api.addBuff(ctx.caster, target.id, "static");
257
- hits.push(buildBuffHit(ctx, target.id, "static"));
217
+ if (targetId) {
218
+ ctx.api.addBuff(ctx.caster, targetId, "static");
219
+ hits.push(buildBuffHit(ctx, targetId, "static"));
258
220
  ctx.api.addBuff(ctx.caster, ctx.caster, "flash");
259
221
  hits.push(buildBuffHit(ctx, ctx.caster, "flash"));
260
222
  }
261
223
  return {
262
- ...buildEmptyResult(ctx, target ? [target.id] : []),
263
- totalDamage,
224
+ ...buildEmptyResult(ctx, targetId ? [targetId] : []),
264
225
  hits
265
226
  };
266
227
  }
@@ -294,25 +255,19 @@ const cookBasicScript = {
294
255
  const cookCoreScript = {
295
256
  onCast(ctx) {
296
257
  const self = ctx.api.getUnit(ctx.caster);
297
- const enemies = ctx.api
298
- .getAliveUnits()
299
- .filter((unit) => self && unit.teamId !== self.teamId)
300
- .sort((a, b) => {
301
- if (b.runtime.Hp !== a.runtime.Hp) {
302
- return b.runtime.Hp - a.runtime.Hp;
303
- }
304
- return a.position - b.position;
305
- });
306
- const target = enemies[0];
258
+ const targetId = ctx.targets[0];
259
+ const target = targetId ? ctx.api.getUnit(targetId) : undefined;
307
260
  let totalDamage = 0;
308
261
  const hits = [];
309
262
  if (self && target) {
310
263
  const lostHp = Math.max(0, self.stats.Mhp - self.runtime.Hp);
311
264
  const lostStepCount = Math.floor((lostHp * 10) / Math.max(1, self.stats.Mhp));
312
- const multiplier = 1 + lostStepCount * 0.05;
313
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * multiplier));
314
- totalDamage += r.damage;
315
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
265
+ const extraRatio = lostStepCount * 0.05;
266
+ if (extraRatio > 0) {
267
+ const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * extraRatio));
268
+ totalDamage += r.damage;
269
+ hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
270
+ }
316
271
  }
317
272
  return {
318
273
  ...buildEmptyResult(ctx, target ? [target.id] : []),
@@ -81,9 +81,12 @@ const m19052Script = {
81
81
  // 驱散1个负面效果(简化:移除第一个debuff)
82
82
  const debuffs = ctx.api.getBuffs(ally.id).filter(b => {
83
83
  const c = b.config;
84
- return (c.defDelta && c.defDelta < 0) || (c.speedRateDelta && c.speedRateDelta < 0) ||
84
+ return (c.defDelta && c.defDelta < 0) || (c.defenseRateDelta && c.defenseRateDelta < 0) ||
85
+ (c.speedRateDelta && c.speedRateDelta < 0) ||
85
86
  (c.vulnerabilityDelta && c.vulnerabilityDelta > 0) || c.stun || c.dotRatio ||
86
- (c.effectResDelta && c.effectResDelta < 0);
87
+ (c.effectResDelta && c.effectResDelta < 0) ||
88
+ (c.allElementResistDelta && c.allElementResistDelta < 0) ||
89
+ (c.imbalanceTakenRateDelta && c.imbalanceTakenRateDelta > 0);
87
90
  });
88
91
  if (debuffs.length > 0) {
89
92
  ctx.api.removeBuff(ally.id, debuffs[0].id);
@@ -327,9 +330,12 @@ const m19074Script = {
327
330
  const newBuff = buffs.find(b => b.id === data.buffId);
328
331
  if (newBuff) {
329
332
  const c = newBuff.config;
330
- const isDebuff = (c.defDelta && c.defDelta < 0) || (c.speedRateDelta && c.speedRateDelta < 0) ||
333
+ const isDebuff = (c.defDelta && c.defDelta < 0) || (c.defenseRateDelta && c.defenseRateDelta < 0) ||
334
+ (c.speedRateDelta && c.speedRateDelta < 0) ||
331
335
  (c.vulnerabilityDelta && c.vulnerabilityDelta > 0) || c.stun || c.dotRatio ||
332
- (c.effectResDelta && c.effectResDelta < 0);
336
+ (c.effectResDelta && c.effectResDelta < 0) ||
337
+ (c.allElementResistDelta && c.allElementResistDelta < 0) ||
338
+ (c.imbalanceTakenRateDelta && c.imbalanceTakenRateDelta > 0);
333
339
  if (isDebuff) {
334
340
  ctx.api.removeBuff(ctx.caster, data.buffId);
335
341
  }
@@ -361,7 +367,8 @@ const m19075Script = {
361
367
  (c.defenseRateDelta && c.defenseRateDelta > 0) ||
362
368
  (c.speedRateDelta && c.speedRateDelta > 0) ||
363
369
  (c.damageRateDelta && c.damageRateDelta > 0) ||
364
- (c.critRateDelta && c.critRateDelta > 0);
370
+ (c.critRateDelta && c.critRateDelta > 0) ||
371
+ (c.assistRateDelta && c.assistRateDelta > 0);
365
372
  if (isBeneficial) {
366
373
  ctx.api.removeBuff(ctx.caster, b.id);
367
374
  }
@@ -87,11 +87,14 @@ export interface BuffConfig {
87
87
  critDamageDelta?: number;
88
88
  healEffectDelta?: number;
89
89
  effectHitDelta?: number;
90
+ assistRateDelta?: number;
90
91
  damageRateDelta?: number;
91
92
  effectResDelta?: number;
93
+ allElementResistDelta?: number;
92
94
  energyRecoveryRateDelta?: number;
93
95
  vulnerabilityDelta?: number;
94
96
  imbalanceRateDelta?: number;
97
+ imbalanceTakenRateDelta?: number;
95
98
  damageShareToSourceRatio?: number;
96
99
  reactiveCounter?: boolean;
97
100
  reactiveCounterPriority?: number;
package/dist/index.d.ts CHANGED
@@ -10,4 +10,4 @@ export { ConfigSkillEngine, ScriptSkillEngine, SkillExecutor } from "./battle/sk
10
10
  export { designedScripts } from "./battle/script/designedScripts";
11
11
  export { loadBattleJsonConfigBundle, validateBattleJsonConfigBundle, buildBattleUnitsFromJsonBundle } from "./battle/config/jsonConfigLoader";
12
12
  export type { BattleJsonConfigBundle, HeroInput } from "./battle/config/jsonConfigLoader";
13
- export type { BattleScriptApi, BattleConfig, BattleInitUnit, BuffConfig, ISkillScript, SkillDefinition, SkillExecMode, SkillTemplate, UnitModel, UnitStats } from "./battle/types";
13
+ export type { BattleScriptApi, BattleConfig, BattleInitUnit, BuffConfig, ElementType, ISkillScript, SkillDefinition, SkillExecMode, SkillTemplate, SkillType, TargetRule, UnitModel, UnitStats } from "./battle/types";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hrbattle",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "一个基于回合制战斗引擎,支持技能脚本、buff系统和效果解析。",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -780,6 +780,8 @@ export class BattleCore {
780
780
  } else if (rep === -1) {
781
781
  stagger = Math.floor(stagger * 7000 / 10000);
782
782
  }
783
+ const takenRate = 10000 + this.effectSystem.getImbalanceTakenRate(target.id);
784
+ stagger = Math.max(0, Math.floor(stagger * takenRate / 10000));
783
785
  const max = this.computeImbalanceMax(target);
784
786
  const from = target.runtime.Imbalance;
785
787
  target.runtime.Imbalance = Math.min(max, from + stagger);
@@ -39,6 +39,7 @@
39
39
  "durationPerStack": 1,
40
40
  "onRoundEndDelta": -1,
41
41
  "expireRounds": 1,
42
+ "speedRateDelta": -1000,
42
43
  "applyOnElementBreakElements": ["water"]
43
44
  },
44
45
  {
@@ -89,7 +90,7 @@
89
90
  "durationPerStack": 1,
90
91
  "onRoundEndDelta": -1,
91
92
  "expireRounds": 1,
92
- "defDelta": -1000,
93
+ "allElementResistDelta": -1000,
93
94
  "applyOnElementBreakElements": ["dark"]
94
95
  },
95
96
  {
@@ -99,7 +100,7 @@
99
100
  "durationPerStack": 1,
100
101
  "onRoundEndDelta": -1,
101
102
  "expireRounds": 1,
102
- "defDelta": -1000
103
+ "defenseRateDelta": -1000
103
104
  },
104
105
  {
105
106
  "id": "def-break",
@@ -112,11 +113,12 @@
112
113
  },
113
114
  {
114
115
  "id": "pierce",
115
- "name": "穿透",
116
+ "name": "穿孔",
116
117
  "maxStacks": 1,
117
118
  "durationPerStack": 2,
118
119
  "onRoundEndDelta": -1,
119
- "expireRounds": 2
120
+ "expireRounds": 2,
121
+ "imbalanceTakenRateDelta": 2000
120
122
  },
121
123
  {
122
124
  "id": "counter",
@@ -138,12 +140,12 @@
138
140
  },
139
141
  {
140
142
  "id": "flash",
141
- "name": "闪光",
143
+ "name": "闪击",
142
144
  "maxStacks": 3,
143
145
  "durationPerStack": 1,
144
146
  "onRoundEndDelta": -1,
145
147
  "expireRounds": 1,
146
- "imbalanceRateDelta": 800,
148
+ "assistRateDelta": 1500,
147
149
  "critRateDelta": 1500
148
150
  },
149
151
  {
@@ -157,11 +159,13 @@
157
159
  },
158
160
  {
159
161
  "id": "will",
160
- "name": "意志",
162
+ "name": "惩戒",
161
163
  "maxStacks": 999,
162
164
  "durationPerStack": 999999999,
163
165
  "onRoundEndDelta": 0,
164
- "expireRounds": 999999999
166
+ "expireRounds": 999999999,
167
+ "defenseRateDelta": 300,
168
+ "effectHitDelta": 300
165
169
  },
166
170
  {
167
171
  "id": "rage",
@@ -170,7 +174,7 @@
170
174
  "durationPerStack": 999999999,
171
175
  "onRoundEndDelta": 0,
172
176
  "expireRounds": 999999999,
173
- "speedDelta": 1000
177
+ "speedRateDelta": 1000
174
178
  },
175
179
  {
176
180
  "id": "cook-restraint",
@@ -282,7 +286,6 @@
282
286
  "durationPerStack": 9999999,
283
287
  "onRoundEndDelta": 0,
284
288
  "expireRounds": 9999999,
285
- "speedDelta": 1000,
286
289
  "speedRateDelta": 1000
287
290
  },
288
291
  {
@@ -382,7 +385,7 @@
382
385
  "durationPerStack": 2,
383
386
  "onRoundEndDelta": -1,
384
387
  "expireRounds": 2,
385
- "defDelta": 2000
388
+ "defenseRateDelta": 2000
386
389
  },
387
390
  {
388
391
  "id": "pela-crit-up",
@@ -6,7 +6,7 @@
6
6
  "role": "歼灭",
7
7
  "skills": [
8
8
  {"id":"11011","type":"basic","mode":"hybrid","energyCost":0,"energyGain":20,"cooldown":0,"targetRule":"nearest","element":"rock","configTemplateId":"common.basic.single.50","scriptId":"cook.basic.script","level":1},
9
- {"id":"11012","type":"core","mode":"script","energyCost":0,"energyGain":30,"cooldown":2,"targetRule":"nearest","element":"rock","scriptId":"cook.core.script","level":1},
9
+ {"id":"11012","type":"core","mode":"hybrid","energyCost":0,"energyGain":30,"cooldown":2,"targetRule":"nearest","element":"rock","configTemplateId":"cook.core.single","scriptId":"cook.core.script","level":1},
10
10
  {"id":"11014","type":"ultimate","mode":"hybrid","energyCost":70,"energyGain":0,"cooldown":4,"targetRule":"nearest","element":"rock","configTemplateId":"cook.ultimate.slash","scriptId":"cook.ultimate.script","level":1},
11
11
  {"id":"11013","type":"passive","mode":"script","energyCost":0,"energyGain":0,"cooldown":0,"targetRule":"self","element":"rock","scriptId":"cook.passive.script","level":1,"activateOnBattleStart":true}
12
12
  ]
@@ -17,9 +17,9 @@
17
17
  "element": "thunder",
18
18
  "role": "歼灭",
19
19
  "skills": [
20
- {"id":"11021","type":"basic","mode":"script","energyCost":0,"energyGain":20,"cooldown":0,"targetRule":"lowestHpEnemy","element":"thunder","scriptId":"miaoluo.basic.script","level":1},
21
- {"id":"11022","type":"core","mode":"script","energyCost":0,"energyGain":30,"cooldown":2,"targetRule":"lowestHpEnemy","element":"thunder","scriptId":"miaoluo.core.script","level":1},
22
- {"id":"11024","type":"ultimate","mode":"script","energyCost":60,"energyGain":0,"cooldown":4,"targetRule":"lowestHpEnemy","element":"thunder","scriptId":"miaoluo.ultimate.script","level":1},
20
+ {"id":"11021","type":"basic","mode":"config","energyCost":0,"energyGain":20,"cooldown":0,"targetRule":"lowestHpEnemy","element":"thunder","configTemplateId":"miaoluo.basic.flash","level":1},
21
+ {"id":"11022","type":"core","mode":"hybrid","energyCost":0,"energyGain":30,"cooldown":2,"targetRule":"lowestHpEnemy","element":"thunder","configTemplateId":"miaoluo.core.lowhp","scriptId":"miaoluo.core.script","level":1},
22
+ {"id":"11024","type":"ultimate","mode":"hybrid","energyCost":60,"energyGain":0,"cooldown":4,"targetRule":"lowestHpEnemy","element":"thunder","configTemplateId":"miaoluo.ultimate.triple","scriptId":"miaoluo.ultimate.script","level":1},
23
23
  {"id":"11023","type":"passive","mode":"script","energyCost":0,"energyGain":0,"cooldown":0,"targetRule":"self","element":"thunder","scriptId":"miaoluo.passive.script","level":1,"activateOnBattleStart":true}
24
24
  ]
25
25
  },
@@ -37,7 +37,7 @@
37
37
  },
38
38
  {
39
39
  "heroId": "blade",
40
- "heroName": "布莱德",
40
+ "heroName": "",
41
41
  "element": "water",
42
42
  "role": "歼灭",
43
43
  "skills": [
@@ -1,41 +1,43 @@
1
1
  [
2
2
  {"id":"common.basic.single.50","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
3
- {"id":"cook.ultimate.slash","steps":[{"kind":"damage","ratio":4,"scaleStat":"Att"}]},
4
- {"id":"miaoluo.basic.flash","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
5
- {"id":"miaoluo.core.lowhp","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"}]},
3
+ {"id":"cook.ultimate.slash","steps":[{"kind":"damage","ratio":4,"ratioByLevel":[4,4.6,5.2,5.8,6.4],"scaleStat":"Att"}]},
4
+ {"id":"cook.core.single","steps":[{"kind":"damage","ratio":1,"ratioByLevel":[1,1.15,1.3,1.45,1.6],"scaleStat":"Att"}]},
5
+ {"id":"miaoluo.basic.flash","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
6
+ {"id":"miaoluo.core.lowhp","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"}]},
7
+ {"id":"miaoluo.ultimate.triple","steps":[{"kind":"damage","ratio":0.6,"ratioByLevel":[0.6,0.69,0.78,0.87,0.96],"scaleStat":"Att","repeat":3}]},
6
8
  {"id":"blade.basic.slow","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
7
- {"id":"blade.core.aoe","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
8
- {"id":"blade.ultimate.strike","steps":[{"kind":"damage","ratio":3,"scaleStat":"Att"}]},
9
- {"id":"luoluo.basic.will","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"dazzle","fixedProb":5000}]},
10
- {"id":"luoluo.core.taunt","steps":[{"kind":"shield","ratio":0.1,"scaleStat":"Mhp"}]},
11
- {"id":"luoluo.ultimate.def-aoe","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"taunt","fixedProb":5000}]},
12
- {"id":"rudy.basic.single","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
13
- {"id":"rudy.core.stun","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"stun","fixedProb":6500}]},
9
+ {"id":"blade.core.aoe","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
10
+ {"id":"blade.ultimate.strike","steps":[{"kind":"damage","ratio":3,"ratioByLevel":[3,3.45,3.9,4.35,4.8],"scaleStat":"Att"}]},
11
+ {"id":"luoluo.basic.will","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"dazzle","fixedProb":5000,"fixedProbByLevel":[5000,5500,6000,6500,7000]}]},
12
+ {"id":"luoluo.core.taunt","steps":[{"kind":"shield","ratio":0.1,"ratioByLevel":[0.1,0.12,0.14,0.16,0.18],"scaleStat":"Mhp"}]},
13
+ {"id":"luoluo.ultimate.def-aoe","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"taunt","fixedProb":5000,"fixedProbByLevel":[5000,5500,6000,6500,7000]}]},
14
+ {"id":"rudy.basic.single","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
15
+ {"id":"rudy.core.stun","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"stun","fixedProb":6500,"fixedProbByLevel":[6500,7000,7500,8000,8500]}]},
14
16
  {"id":"rudy.core.defense-buff","steps":[{"kind":"buff","ratio":0,"buffId":"def-up","fixedProb":10000}]},
15
17
  {"id":"rudy.ultimate.team-shield","steps":[{"kind":"shield","ratio":0.2,"ratioByLevel":[0.2,0.26,0.32,0.38,0.44],"scaleStat":"Mhp"}]},
16
- {"id":"es.basic.single","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
17
- {"id":"es.core.damage","steps":[{"kind":"damage","ratio":0.35,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"dazzle","fixedProb":5000}]},
18
+ {"id":"es.basic.single","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
19
+ {"id":"es.core.damage","steps":[{"kind":"damage","ratio":0.35,"ratioByLevel":[0.35,0.4,0.46,0.51,0.56],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"dazzle","fixedProb":5000,"fixedProbByLevel":[5000,5500,6000,6500,7000]}]},
18
20
  {"id":"es.core.heal","steps":[{"kind":"heal","ratio":0.4,"ratioByLevel":[0.4,0.48,0.56,0.64,0.72],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"bless","fixedProb":10000}]},
19
- {"id":"es.ultimate.light-aoe","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"}]},
20
- {"id":"kesi.basic.double-near","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
21
- {"id":"kesi.core.random","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
22
- {"id":"kesi.ultimate.dot-burst","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"}]},
21
+ {"id":"es.ultimate.light-aoe","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"}]},
22
+ {"id":"kesi.basic.double-near","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
23
+ {"id":"kesi.core.random","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
24
+ {"id":"kesi.ultimate.dot-burst","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"}]},
23
25
  {"id":"kleiwu.basic.single","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
24
- {"id":"kleiwu.basic.dual","steps":[{"kind":"damage","ratio":0.3,"scaleStat":"Att"}]},
25
- {"id":"kleiwu.core.backlash","steps":[{"kind":"damage","ratio":1.2,"scaleStat":"Att"}]},
26
- {"id":"kleiwu.core.split","steps":[{"kind":"damage","ratio":1.2,"scaleStat":"Att"},{"kind":"damage","ratio":0.4,"scaleStat":"Att"}]},
27
- {"id":"kleiwu.ultimate.aoe","steps":[{"kind":"damage","ratio":0.8,"scaleStat":"Att"},{"kind":"damage","ratio":0.8,"scaleStat":"Att"},{"kind":"damage","ratio":0.5,"scaleStat":"Att"},{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
28
- {"id":"ailisha.basic.fire","steps":[{"kind":"damage","ratio":0.7,"scaleStat":"Att"}]},
26
+ {"id":"kleiwu.basic.dual","steps":[{"kind":"damage","ratio":0.3,"ratioByLevel":[0.3,0.35,0.39,0.44,0.48],"scaleStat":"Att"}]},
27
+ {"id":"kleiwu.core.backlash","steps":[{"kind":"damage","ratio":1.2,"ratioByLevel":[1.2,1.38,1.56,1.74,1.92],"scaleStat":"Att"}]},
28
+ {"id":"kleiwu.core.split","steps":[{"kind":"damage","ratio":1.2,"ratioByLevel":[1.2,1.38,1.56,1.74,1.92],"scaleStat":"Att"},{"kind":"damage","ratio":0.4,"ratioByLevel":[0.4,0.46,0.52,0.58,0.64],"scaleStat":"Att"}]},
29
+ {"id":"kleiwu.ultimate.aoe","steps":[{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"},{"kind":"damage","ratio":0.8,"ratioByLevel":[0.8,0.92,1.04,1.16,1.28],"scaleStat":"Att"},{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"},{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
30
+ {"id":"ailisha.basic.fire","steps":[{"kind":"damage","ratio":0.7,"ratioByLevel":[0.7,0.81,0.91,1.02,1.12],"scaleStat":"Att"}]},
29
31
  {"id":"ailisha.core.share","steps":[{"kind":"buff","ratio":0,"buffId":"share-damage","fixedProb":10000}]},
30
- {"id":"ailisha.ultimate.hp-aoe","steps":[{"kind":"damage","ratio":1.2,"scaleStat":"Att"}]},
31
- {"id":"luolai.basic.random","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"}]},
32
- {"id":"luolai.core.hot","steps":[{"kind":"heal","ratio":0.1,"scaleStat":"Mhp"},{"kind":"buff","ratio":0,"buffId":"condense","fixedProb":10000}]},
33
- {"id":"luolai.ultimate.heal","steps":[{"kind":"heal","ratio":0.2,"scaleStat":"Mhp"},{"kind":"buff","ratio":0,"buffId":"condense","fixedProb":10000}]},
34
- {"id":"tier.basic.weathering","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":3000}]},
35
- {"id":"tier.core.double","steps":[{"kind":"damage","ratio":0.6,"scaleStat":"Att","repeat":2},{"kind":"buff","ratio":0,"buffId":"pierce","fixedProb":3000},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":3000}]},
36
- {"id":"tier.ultimate.single","steps":[{"kind":"damage","ratio":2.5,"scaleStat":"Att"}]},
37
- {"id":"tier.ultimate.aoe","steps":[{"kind":"damage","ratio":0.7,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"def-break","fixedProb":8000},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":10000}]},
38
- {"id":"pela.basic.speed","steps":[{"kind":"damage","ratio":0.5,"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"speed-up","fixedProb":10000}]},
32
+ {"id":"ailisha.ultimate.hp-aoe","steps":[{"kind":"damage","ratio":1.2,"ratioByLevel":[1.2,1.38,1.56,1.74,1.92],"scaleStat":"Att"}]},
33
+ {"id":"luolai.basic.random","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"}]},
34
+ {"id":"luolai.core.hot","steps":[{"kind":"heal","ratio":0.1,"ratioByLevel":[0.1,0.12,0.14,0.16,0.18],"scaleStat":"Mhp"},{"kind":"buff","ratio":0,"buffId":"condense","fixedProb":10000}]},
35
+ {"id":"luolai.ultimate.heal","steps":[{"kind":"heal","ratio":0.2,"ratioByLevel":[0.2,0.24,0.28,0.32,0.36],"scaleStat":"Mhp"},{"kind":"buff","ratio":0,"buffId":"condense","fixedProb":10000}]},
36
+ {"id":"tier.basic.weathering","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":3000,"fixedProbByLevel":[3000,3500,4000,4500,5000]}]},
37
+ {"id":"tier.core.double","steps":[{"kind":"damage","ratio":0.6,"ratioByLevel":[0.6,0.69,0.78,0.87,0.96],"scaleStat":"Att","repeat":2},{"kind":"buff","ratio":0,"buffId":"pierce","fixedProb":3000,"fixedProbByLevel":[3000,3500,4000,4500,5000]},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":3000,"fixedProbByLevel":[3000,3500,4000,4500,5000]}]},
38
+ {"id":"tier.ultimate.single","steps":[{"kind":"damage","ratio":2.5,"ratioByLevel":[2.5,2.88,3.25,3.63,4],"scaleStat":"Att"}]},
39
+ {"id":"tier.ultimate.aoe","steps":[{"kind":"damage","ratio":0.7,"ratioByLevel":[0.7,0.81,0.91,1.02,1.12],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"def-break","fixedProb":8000,"fixedProbByLevel":[8000,8500,9000,9500,10000]},{"kind":"buff","ratio":0,"buffId":"weathering","fixedProb":10000}]},
40
+ {"id":"pela.basic.speed","steps":[{"kind":"damage","ratio":0.5,"ratioByLevel":[0.5,0.58,0.66,0.74,0.82],"scaleStat":"Att"},{"kind":"buff","ratio":0,"buffId":"speed-up","fixedProb":10000}]},
39
41
  {"id":"pela.core.support","steps":[{"kind":"buff","ratio":0,"buffId":"damage-up","fixedProb":10000}]},
40
42
  {"id":"pela.ultimate.team-buff","steps":[{"kind":"buff","ratio":0,"buffId":"attack-up","fixedProb":10000}]},
41
43
 
@@ -27,6 +27,13 @@ export class EffectSystem {
27
27
  hasBuff(unitId: UnitId, buffId: string): boolean {
28
28
  return this.getBuffs(unitId).some((b) => b.id === buffId && b.stacks > 0);
29
29
  }
30
+
31
+ getImbalanceTakenRate(unitId: UnitId): number {
32
+ return this.getBuffs(unitId).reduce((total, buff) => {
33
+ const stacks = Math.max(1, buff.stacks);
34
+ return total + (buff.config.imbalanceTakenRateDelta ?? 0) * stacks;
35
+ }, 0);
36
+ }
30
37
 
31
38
  getEffectiveStats(unit: UnitModel): UnitStats {
32
39
  const buffs = this.getBuffs(unit.id);
@@ -61,11 +68,23 @@ export class EffectSystem {
61
68
  if (cfg.effectHitDelta) {
62
69
  stat.pEHR += cfg.effectHitDelta * stacks;
63
70
  }
71
+ if (cfg.assistRateDelta) {
72
+ stat.pAR += cfg.assistRateDelta * stacks;
73
+ }
64
74
  if (cfg.damageRateDelta) {
65
75
  stat.pBSDI += cfg.damageRateDelta * stacks;
66
76
  stat.pESDI += cfg.damageRateDelta * stacks;
67
77
  stat.pFSDI += cfg.damageRateDelta * stacks;
68
78
  }
79
+ if (cfg.allElementResistDelta) {
80
+ stat.pFDI_Def += cfg.allElementResistDelta * stacks;
81
+ stat.pTDI_Def += cfg.allElementResistDelta * stacks;
82
+ stat.pWDI_Def += cfg.allElementResistDelta * stacks;
83
+ stat.pRDI_Def += cfg.allElementResistDelta * stacks;
84
+ stat.pADI_Def += cfg.allElementResistDelta * stacks;
85
+ stat.pLDI_Def += cfg.allElementResistDelta * stacks;
86
+ stat.pDDI_Def += cfg.allElementResistDelta * stacks;
87
+ }
69
88
  if (cfg.vulnerabilityDelta) {
70
89
  stat.pVulnerability += cfg.vulnerabilityDelta * stacks;
71
90
  }
@@ -23,7 +23,7 @@ function buildDamageHit(ctx: ScriptRuntimeContext, targetId: string, finalValue:
23
23
  targetId,
24
24
  effectType: "damage",
25
25
  element: ctx.api.getUnit(ctx.caster)?.element ?? "fire",
26
- skillType: ctx.skillType,
26
+ skillType: ctx.skillType,
27
27
  isCritical: false,
28
28
  baseValue: finalValue,
29
29
  criticalValue: finalValue,
@@ -45,7 +45,7 @@ function buildBuffHit(ctx: ScriptRuntimeContext, targetId: string, buffId: strin
45
45
  targetId,
46
46
  effectType: "buff",
47
47
  element: ctx.api.getUnit(ctx.caster)?.element ?? "fire",
48
- skillType: ctx.skillType,
48
+ skillType: ctx.skillType,
49
49
  isCritical: false,
50
50
  baseValue: 0,
51
51
  criticalValue: 0,
@@ -61,7 +61,7 @@ function buildShieldHit(ctx: ScriptRuntimeContext, targetId: string, finalValue:
61
61
  targetId,
62
62
  effectType: "shield",
63
63
  element: ctx.api.getUnit(ctx.caster)?.element ?? "fire",
64
- skillType: ctx.skillType,
64
+ skillType: ctx.skillType,
65
65
  isCritical: false,
66
66
  baseValue: finalValue,
67
67
  criticalValue: finalValue,
@@ -75,7 +75,7 @@ function buildHealHit(ctx: ScriptRuntimeContext, targetId: string, finalValue: n
75
75
  targetId,
76
76
  effectType: "heal",
77
77
  element: ctx.api.getUnit(ctx.caster)?.element ?? "fire",
78
- skillType: ctx.skillType,
78
+ skillType: ctx.skillType,
79
79
  isCritical: false,
80
80
  baseValue: finalValue,
81
81
  criticalValue: finalValue,
@@ -166,49 +166,46 @@ const bladeCoreScript: ISkillScript = {
166
166
 
167
167
  const luoluoBasicScript: ISkillScript = {
168
168
  onCast(ctx) {
169
- ctx.api.addBuff(ctx.caster, ctx.caster, "will");
170
- return {
171
- skillId: ctx.skillId,
172
- casterId: ctx.caster,
173
- targets: ctx.targets,
174
- totalDamage: 0,
175
- totalHeal: 0,
176
- totalShield: 0,
177
- triggeredBy: ctx.trigger
178
- };
169
+ return buildEmptyResult(ctx, ctx.targets);
179
170
  }
180
171
  };
181
172
 
182
173
  // 洛洛核心技:获得10%生命值的护盾,每层【惩戒/意志】使护盾强度增加10%
183
174
  const luoluoCoreScript: ISkillScript = {
184
175
  onCast(ctx) {
185
- // 护盾交由config模板结算,script层不再重复加盾
186
- return buildEmptyResult(ctx, ctx.targets);
176
+ const self = ctx.api.getUnit(ctx.caster);
177
+ if (!self) {
178
+ return buildEmptyResult(ctx, ctx.targets);
179
+ }
180
+ const willStacks = ctx.api
181
+ .getBuffs(ctx.caster)
182
+ .filter((buff) => buff.id === "will")
183
+ .reduce((total, buff) => total + buff.stacks, 0);
184
+ if (willStacks <= 0) {
185
+ return buildEmptyResult(ctx, ctx.targets);
186
+ }
187
+
188
+ // 基础护盾由 config 模板提供;这里补上每层惩戒额外 +10% 基础护盾强度。
189
+ const extraShield = Math.floor(self.stats.Mhp * 0.01 * willStacks);
190
+ const totalShield = ctx.api.shield(ctx.caster, extraShield);
191
+ return {
192
+ ...buildEmptyResult(ctx, ctx.targets),
193
+ totalShield,
194
+ hits: [buildShieldHit(ctx, ctx.caster, totalShield)]
195
+ };
187
196
  }
188
197
  };
189
198
 
190
199
  const miaoluoUltimateScript: ISkillScript = {
191
200
  onCast(ctx) {
192
201
  const self = ctx.api.getUnit(ctx.caster);
193
- const target = ctx.api
194
- .getAliveUnits()
195
- .filter((unit) => self && unit.teamId !== self.teamId)
196
- .sort((a, b) => {
197
- if (a.runtime.Hp !== b.runtime.Hp) {
198
- return a.runtime.Hp - b.runtime.Hp;
199
- }
200
- return a.position - b.position;
201
- })[0];
202
+ const targetId = ctx.targets[0];
203
+ const target = targetId ? ctx.api.getUnit(targetId) : undefined;
202
204
  let totalDamage = 0;
203
205
  const hits: SkillHitDetail[] = [];
204
206
  if (self && target) {
205
207
  ctx.api.addBuff(ctx.caster, ctx.caster, "miaoluo-ultimate-focus");
206
208
  hits.push(buildBuffHit(ctx, ctx.caster, "miaoluo-ultimate-focus"));
207
- for (let i = 0; i < 3; i += 1) {
208
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.6));
209
- totalDamage += r.damage;
210
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
211
- }
212
209
  if (ctx.api.hasBuff(target.id, "imbalance-vulnerability")) {
213
210
  const r2 = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.3));
214
211
  totalDamage += r2.damage;
@@ -225,57 +222,22 @@ const miaoluoUltimateScript: ISkillScript = {
225
222
 
226
223
  const miaoluoBasicScript: ISkillScript = {
227
224
  onCast(ctx) {
228
- const self = ctx.api.getUnit(ctx.caster);
229
- const target = ctx.api
230
- .getAliveUnits()
231
- .filter((unit) => self && unit.teamId !== self.teamId)
232
- .sort((a, b) => {
233
- if (a.runtime.Hp !== b.runtime.Hp) {
234
- return a.runtime.Hp - b.runtime.Hp;
235
- }
236
- return a.position - b.position;
237
- })[0];
238
- let totalDamage = 0;
239
- const hits: SkillHitDetail[] = [];
240
- if (self && target) {
241
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.5));
242
- totalDamage += r.damage;
243
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
244
- }
245
- return {
246
- ...buildEmptyResult(ctx, target ? [target.id] : []),
247
- totalDamage,
248
- hits
249
- };
225
+ return buildEmptyResult(ctx, ctx.targets);
250
226
  }
251
227
  };
252
228
 
253
229
  const miaoluoCoreScript: ISkillScript = {
254
230
  onCast(ctx) {
255
- const self = ctx.api.getUnit(ctx.caster);
256
- const target = ctx.api
257
- .getAliveUnits()
258
- .filter((unit) => self && unit.teamId !== self.teamId)
259
- .sort((a, b) => {
260
- if (a.runtime.Hp !== b.runtime.Hp) {
261
- return a.runtime.Hp - b.runtime.Hp;
262
- }
263
- return a.position - b.position;
264
- })[0];
265
- let totalDamage = 0;
231
+ const targetId = ctx.targets[0];
266
232
  const hits: SkillHitDetail[] = [];
267
- if (self && target) {
268
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * 0.8));
269
- totalDamage += r.damage;
270
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
271
- ctx.api.addBuff(ctx.caster, target.id, "static");
272
- hits.push(buildBuffHit(ctx, target.id, "static"));
233
+ if (targetId) {
234
+ ctx.api.addBuff(ctx.caster, targetId, "static");
235
+ hits.push(buildBuffHit(ctx, targetId, "static"));
273
236
  ctx.api.addBuff(ctx.caster, ctx.caster, "flash");
274
237
  hits.push(buildBuffHit(ctx, ctx.caster, "flash"));
275
238
  }
276
239
  return {
277
- ...buildEmptyResult(ctx, target ? [target.id] : []),
278
- totalDamage,
240
+ ...buildEmptyResult(ctx, targetId ? [targetId] : []),
279
241
  hits
280
242
  };
281
243
  }
@@ -311,25 +273,19 @@ const cookBasicScript: ISkillScript = {
311
273
  const cookCoreScript: ISkillScript = {
312
274
  onCast(ctx) {
313
275
  const self = ctx.api.getUnit(ctx.caster);
314
- const enemies = ctx.api
315
- .getAliveUnits()
316
- .filter((unit) => self && unit.teamId !== self.teamId)
317
- .sort((a, b) => {
318
- if (b.runtime.Hp !== a.runtime.Hp) {
319
- return b.runtime.Hp - a.runtime.Hp;
320
- }
321
- return a.position - b.position;
322
- });
323
- const target = enemies[0];
276
+ const targetId = ctx.targets[0];
277
+ const target = targetId ? ctx.api.getUnit(targetId) : undefined;
324
278
  let totalDamage = 0;
325
279
  const hits: SkillHitDetail[] = [];
326
280
  if (self && target) {
327
281
  const lostHp = Math.max(0, self.stats.Mhp - self.runtime.Hp);
328
282
  const lostStepCount = Math.floor((lostHp * 10) / Math.max(1, self.stats.Mhp));
329
- const multiplier = 1 + lostStepCount * 0.05;
330
- const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * multiplier));
331
- totalDamage += r.damage;
332
- hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
283
+ const extraRatio = lostStepCount * 0.05;
284
+ if (extraRatio > 0) {
285
+ const r = ctx.api.damage(ctx.caster, target.id, Math.floor(self.stats.Att * extraRatio));
286
+ totalDamage += r.damage;
287
+ hits.push(buildDamageHit(ctx, target.id, r.damage, r.imbalanceDelta));
288
+ }
333
289
  }
334
290
  return {
335
291
  ...buildEmptyResult(ctx, target ? [target.id] : []),
@@ -82,9 +82,12 @@ const m19052Script: ISkillScript = {
82
82
  // 驱散1个负面效果(简化:移除第一个debuff)
83
83
  const debuffs = ctx.api.getBuffs(ally.id).filter(b => {
84
84
  const c = b.config;
85
- return (c.defDelta && c.defDelta < 0) || (c.speedRateDelta && c.speedRateDelta < 0) ||
85
+ return (c.defDelta && c.defDelta < 0) || (c.defenseRateDelta && c.defenseRateDelta < 0) ||
86
+ (c.speedRateDelta && c.speedRateDelta < 0) ||
86
87
  (c.vulnerabilityDelta && c.vulnerabilityDelta > 0) || c.stun || c.dotRatio ||
87
- (c.effectResDelta && c.effectResDelta < 0);
88
+ (c.effectResDelta && c.effectResDelta < 0) ||
89
+ (c.allElementResistDelta && c.allElementResistDelta < 0) ||
90
+ (c.imbalanceTakenRateDelta && c.imbalanceTakenRateDelta > 0);
88
91
  });
89
92
  if (debuffs.length > 0) {
90
93
  ctx.api.removeBuff(ally.id, debuffs[0].id);
@@ -322,9 +325,12 @@ const m19074Script: ISkillScript = {
322
325
  const newBuff = buffs.find(b => b.id === data.buffId);
323
326
  if (newBuff) {
324
327
  const c = newBuff.config;
325
- const isDebuff = (c.defDelta && c.defDelta < 0) || (c.speedRateDelta && c.speedRateDelta < 0) ||
328
+ const isDebuff = (c.defDelta && c.defDelta < 0) || (c.defenseRateDelta && c.defenseRateDelta < 0) ||
329
+ (c.speedRateDelta && c.speedRateDelta < 0) ||
326
330
  (c.vulnerabilityDelta && c.vulnerabilityDelta > 0) || c.stun || c.dotRatio ||
327
- (c.effectResDelta && c.effectResDelta < 0);
331
+ (c.effectResDelta && c.effectResDelta < 0) ||
332
+ (c.allElementResistDelta && c.allElementResistDelta < 0) ||
333
+ (c.imbalanceTakenRateDelta && c.imbalanceTakenRateDelta > 0);
328
334
  if (isDebuff) {
329
335
  ctx.api.removeBuff(ctx.caster, data.buffId);
330
336
  }
@@ -355,7 +361,8 @@ const m19075Script: ISkillScript = {
355
361
  (c.defenseRateDelta && c.defenseRateDelta > 0) ||
356
362
  (c.speedRateDelta && c.speedRateDelta > 0) ||
357
363
  (c.damageRateDelta && c.damageRateDelta > 0) ||
358
- (c.critRateDelta && c.critRateDelta > 0);
364
+ (c.critRateDelta && c.critRateDelta > 0) ||
365
+ (c.assistRateDelta && c.assistRateDelta > 0);
359
366
  if (isBeneficial) {
360
367
  ctx.api.removeBuff(ctx.caster, b.id);
361
368
  }
@@ -106,11 +106,14 @@ export interface BuffConfig {
106
106
  critDamageDelta?: number;
107
107
  healEffectDelta?: number;
108
108
  effectHitDelta?: number;
109
+ assistRateDelta?: number;
109
110
  damageRateDelta?: number;
110
111
  effectResDelta?: number;
112
+ allElementResistDelta?: number;
111
113
  energyRecoveryRateDelta?: number;
112
114
  vulnerabilityDelta?: number;
113
115
  imbalanceRateDelta?: number;
116
+ imbalanceTakenRateDelta?: number;
114
117
  damageShareToSourceRatio?: number;
115
118
  reactiveCounter?: boolean;
116
119
  reactiveCounterPriority?: number;
package/src/index.ts CHANGED
@@ -33,10 +33,13 @@ export type {
33
33
  BattleConfig,
34
34
  BattleInitUnit,
35
35
  BuffConfig,
36
+ ElementType,
36
37
  ISkillScript,
37
38
  SkillDefinition,
38
39
  SkillExecMode,
39
40
  SkillTemplate,
41
+ SkillType,
42
+ TargetRule,
40
43
  UnitModel,
41
44
  UnitStats
42
45
  } from "./battle/types";