genshin-world 3.9.0 → 4.1.0

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.
Files changed (141) hide show
  1. package/README.md +7 -4
  2. package/dist/ReactionType-BBSdxyO3.js +47 -0
  3. package/dist/addKitEffect-DBqTfm_3.js +17 -0
  4. package/dist/ainoKit-Dy3vTp3B.js +28 -0
  5. package/dist/albedoKit-CU5N1Hnm.js +43 -0
  6. package/dist/alhaithamKit-Bhs-coX9.js +212 -0
  7. package/dist/aloyKit-C7x_Jf16.js +32 -0
  8. package/dist/amberKit-BO7ZAQgU.js +38 -0
  9. package/dist/arlecchinoKit-DJawwVVl.js +4 -0
  10. package/dist/ayakaKit-Bu_QuYsR.js +26 -0
  11. package/dist/ayatoKit-BXZNajk7.js +108 -0
  12. package/dist/baizhuKit-8_4IzZ3A.js +33 -0
  13. package/dist/barbaraKit-B5DpLyHJ.js +58 -0
  14. package/dist/beidouKit-sQUahtIk.js +59 -0
  15. package/dist/bennettKit-Cr-zZ_25.js +66 -0
  16. package/dist/candaceKit-BUs_wwFU.js +84 -0
  17. package/dist/characterPack-YAEqbhAX.d.ts +116 -0
  18. package/dist/characterPack-zycIUHje.js +641 -0
  19. package/dist/characterPack.d.ts +2 -0
  20. package/dist/characterPack.js +1 -0
  21. package/dist/charlotteKit-BOZiCPEb.js +90 -0
  22. package/dist/chascaKit-C1Csj0Yf.js +4 -0
  23. package/dist/chevreuseKit-DDHga8Tj.js +20 -0
  24. package/dist/chioriKit-CxRUSHNw.js +28 -0
  25. package/dist/chongyunKit-jrWQKRkG.js +104 -0
  26. package/dist/citlaliKit-sv7XrzVx.js +4 -0
  27. package/dist/clorindeKit-DxtRn_To.js +4 -0
  28. package/dist/colleiKit-CO_n9qra.js +28 -0
  29. package/dist/columbinaKit-DrW0EvqN.js +31 -0
  30. package/dist/constants--ARZpp1u.js +49 -0
  31. package/dist/constants-BqrUOf2M.js +48 -0
  32. package/dist/constants-CSFiwyHy.js +46 -0
  33. package/dist/createWindriseGroundPaint-BmZkGq-r.js +295 -0
  34. package/dist/cynoKit-DpfT5dmS.js +179 -0
  35. package/dist/dahliaKit-B8fOPvvi.js +16 -0
  36. package/dist/dehyaKit-42tyEI0Z.js +4 -0
  37. package/dist/dilucKit-EwLUSPgs.js +63 -0
  38. package/dist/dionaKit-89B1hwYL.js +48 -0
  39. package/dist/doriKit-G9XTwwCP.js +24 -0
  40. package/dist/durinKit-BIYdUkbh.js +49 -0
  41. package/dist/emilieKit-0b2vhNtl.js +21 -0
  42. package/dist/escoffierKit-Da5UAvAF.js +48 -0
  43. package/dist/eulaKit-DAENHIEx.js +129 -0
  44. package/dist/faruzanKit-BcW6D-N3.js +71 -0
  45. package/dist/fischlKit-Bm8vNmuV.js +98 -0
  46. package/dist/flinsKit-GUnFJdUg.js +9 -0
  47. package/dist/freminetKit-CpwsVmTT.js +4 -0
  48. package/dist/furinaKit-BREisAdJ.js +279 -0
  49. package/dist/gamingKit-D9ekWGMJ.js +4 -0
  50. package/dist/ganyuKit-DLJa1t-Z.js +74 -0
  51. package/dist/gorouKit-DkpaGNA8.js +94 -0
  52. package/dist/heizouKit-B6kRXVCP.js +35 -0
  53. package/dist/huTaoKit-drjrzLjf.js +58 -0
  54. package/dist/iansanKit-RNjD9nSq.js +4 -0
  55. package/dist/ifaKit-CXWxCOPI.js +4 -0
  56. package/dist/illugaKit-BFtXIf3P.js +4 -0
  57. package/dist/index-CjGcgRTS.d.ts +19820 -0
  58. package/dist/index.d.ts +4 -997
  59. package/dist/index.js +28867 -28063
  60. package/dist/ineffaKit-3J0FJo2E.js +51 -0
  61. package/dist/ittoKit-CfwXkR0g.js +112 -0
  62. package/dist/jahodaKit-C1sdSDfr.js +97 -0
  63. package/dist/jeanKit-Do8vx5Kp.js +56 -0
  64. package/dist/kachinaKit-DWLNDpgO.js +4 -0
  65. package/dist/kaeyaKit-DU8Df4RE.js +14 -0
  66. package/dist/kavehKit-BWoAaKs4.js +9 -0
  67. package/dist/kazuhaKit-C5gn8iGg.js +55 -0
  68. package/dist/keqingKit-uGsb_p7t.js +12 -0
  69. package/dist/kinichKit-Dp3lNUJt.js +22 -0
  70. package/dist/kiraraKit-CCAGXouk.js +43 -0
  71. package/dist/kleeKit-BzcJLC2i.js +48 -0
  72. package/dist/kokomiKit-DBdTlTDr.js +42 -0
  73. package/dist/kujouSaraKit-DDE-24jd.js +56 -0
  74. package/dist/kukiKit-DcARldP9.js +59 -0
  75. package/dist/lanYanKit-B3lwZ7OW.js +18 -0
  76. package/dist/laumaKit-DkG-i0rL.js +59 -0
  77. package/dist/laylaKit-DYtz0tSZ.js +41 -0
  78. package/dist/linneaKit-DlVhnbGM.js +4 -0
  79. package/dist/lisaKit-CWUiiam1.js +22 -0
  80. package/dist/lohenKit-D-uagI_g.js +4 -0
  81. package/dist/lynetteKit-BnNW81Pm.js +20 -0
  82. package/dist/lyneyKit-D6yTnfFv.js +19 -0
  83. package/dist/mavuikaKit-CUC1kHRJ.js +4 -0
  84. package/dist/mikaKit-C9xDhjJg.js +17 -0
  85. package/dist/mizukiKit-DY-gHM8N.js +4 -0
  86. package/dist/monaKit-B748iTEy.js +26 -0
  87. package/dist/mualaniKit-B-Km_dcQ.js +4 -0
  88. package/dist/nahidaKit-BGRc-swN.js +4 -0
  89. package/dist/naviaKit-CHh2VdX3.js +64 -0
  90. package/dist/neferKit-BTALTTiV.js +4 -0
  91. package/dist/neuvilletteKit-DAfX_2tC.js +4 -0
  92. package/dist/nicoleKit-BVjL7LI0.js +4 -0
  93. package/dist/nilouKit-BgM4u-hg.js +52 -0
  94. package/dist/ningguangKit-N88BhNb_.js +105 -0
  95. package/dist/noelleKit-DDewnuJ9.js +48 -0
  96. package/dist/ororonKit-DiAd2dlh.js +86 -0
  97. package/dist/pruneKit-CHkC_OSB.js +4 -0
  98. package/dist/qiqiKit-DCtsriE7.js +88 -0
  99. package/dist/raidenKit-BBWMmPFn.js +144 -0
  100. package/dist/razorKit-CBgdHYic.js +90 -0
  101. package/dist/readCharacterAvatar-C7FufK7J.js +292 -0
  102. package/dist/rosariaKit-D_RDXpLp.js +29 -0
  103. package/dist/save-CEbj1mOx.js +854 -0
  104. package/dist/save.d.ts +2 -0
  105. package/dist/save.js +1 -0
  106. package/dist/sayuKit-Hnv4iA3_.js +35 -0
  107. package/dist/sceneExport-BZaF05K-.d.ts +70 -0
  108. package/dist/sceneExport-DiiIi0PM.js +27 -0
  109. package/dist/sceneExport.d.ts +2 -0
  110. package/dist/sceneExport.js +1 -0
  111. package/dist/sethosKit-8EK04AA4.js +4 -0
  112. package/dist/shenheKit-DqrG2I4S.js +50 -0
  113. package/dist/sigewinneKit-CYJyadTr.js +10 -0
  114. package/dist/skirkKit-BDjoFGAq.js +10 -0
  115. package/dist/style.css +3324 -120
  116. package/dist/sucroseKit-DF0jcI2y.js +101 -0
  117. package/dist/tartagliaKit-Bbtww18S.js +136 -0
  118. package/dist/terrainTileWorker.js +71 -8
  119. package/dist/thomaKit-Zm5AJ9Fm.js +64 -0
  120. package/dist/tighnariKit-CSa_Yqpp.js +4 -0
  121. package/dist/varesaKit-CMXLbBv9.js +4 -0
  122. package/dist/varkaKit-C8_HlTVH.js +4 -0
  123. package/dist/ventiKit-BcQkbI-z.js +52 -0
  124. package/dist/wandererKit-CQM691sn.js +9 -0
  125. package/dist/wriothesleyKit-CBTnYlOy.js +4 -0
  126. package/dist/xianglingKit-BPQN7cxU.js +108 -0
  127. package/dist/xianyunKit-CVhuYBde.js +4 -0
  128. package/dist/xiaoKit-BDI_SODG.js +90 -0
  129. package/dist/xilonenKit-YAVOPRwm.js +4 -0
  130. package/dist/xingqiuKit-Cv8JYeYO.js +106 -0
  131. package/dist/xinyanKit-CffF-Er0.js +120 -0
  132. package/dist/yaeMikoKit-xAKYm2K6.js +44 -0
  133. package/dist/yanfeiKit-C6elnkmn.js +86 -0
  134. package/dist/yaoyaoKit-CaPIIp-i.js +4 -0
  135. package/dist/yelanKit-Da0oQ6yu.js +33 -0
  136. package/dist/yoimiyaKit-DTENWB4y.js +49 -0
  137. package/dist/yunjinKit-PP4yeyn1.js +22 -0
  138. package/dist/zhongliKit-uMdKUTP-.js +100 -0
  139. package/dist/zibaiKit-Dq6mFWSx.js +4 -0
  140. package/package.json +35 -20
  141. package/dist/writeWindriseColor-COtmALzZ.js +0 -249
package/README.md CHANGED
@@ -28,21 +28,22 @@ It ships no image, model or sound from the game: every mesh, texture and shader
28
28
  pnpm i genshin-world genshin-engine genshin-interface @esposter/shared @tresjs/cientos @tresjs/core @vueuse/core three vue zod
29
29
  ```
30
30
 
31
- Mount `GenshinWorld` inside your own `TresCanvas` and pass in only what your bundler and server decide, and load the screens' styles once:
31
+ Mount `WorldScreen`, which brings its own canvas, and pass in only what your bundler and server decide, and load the screens' styles once:
32
32
 
33
33
  ```vue
34
34
  <script setup lang="ts">
35
- import { GenshinWorld } from "genshin-world";
35
+ import { WorldScreen } from "genshin-world";
36
36
  import TerrainTileWorker from "genshin-world/terrainTileWorker?worker";
37
37
  import "genshin-interface/style.css";
38
38
  import "genshin-world/style.css";
39
39
  </script>
40
40
 
41
41
  <template>
42
- <GenshinWorld
42
+ <WorldScreen
43
43
  :create-terrain-worker="() => new TerrainTileWorker()"
44
- :is-tuning="isDevelopment"
44
+ :is-tuning="isDevelopment || undefined"
45
45
  :quality-tier
46
+ game-data-base-url="https://your-host.example/game-data"
46
47
  region-data-base-url="genshin"
47
48
  />
48
49
  </template>
@@ -50,6 +51,8 @@ import "genshin-world/style.css";
50
51
 
51
52
  Region data lives in `src/data/regions/<region>.json`, and your server serves it at the base URL, so a region is fetched as the camera comes within reach and released as it leaves.
52
53
 
54
+ The game's data is not bundled. Every record the world reads — the opening's title logo and login screen, the world's ground, catalogue and animals, the game's tables and words, the character profiles and the book bodies — is fetched from `game-data-base-url`, which `GameOpening` takes as `WorldScreen` does, and every reader the package exports (`readGameData`, `readStatTables` and the rest) takes the same base as its first argument. Your host must serve every object and index entry that the package's `gameDataLock.json` names, each as `<base>/<sha256>.json`, with CORS for your page's origin. Esposter's own accounts admit only Esposter's origins, so another host must publish its own copy.
55
+
53
56
  ## <a name="documentation">📖 Documentation</a>
54
57
 
55
58
  We highly recommend you take a look at the [documentation](https://esposter.com/docs/api/modules/genshin-world.html) to level up. The world's design is in the app's [Genshin docs](https://esposter.com/docs/genshin), and how each screen is matched to the game is its [parity page](https://esposter.com/docs/genshin/parity).
@@ -0,0 +1,47 @@
1
+ import { mergeObjectsStrict } from "@esposter/shared";
2
+ //#region src/models/combat/TransformativeReactionType.ts
3
+ let TransformativeReactionType = /* @__PURE__ */ function(TransformativeReactionType) {
4
+ TransformativeReactionType["Bloom"] = "Bloom";
5
+ TransformativeReactionType["Burgeon"] = "Burgeon";
6
+ TransformativeReactionType["Burning"] = "Burning";
7
+ TransformativeReactionType["ElectroCharged"] = "ElectroCharged";
8
+ TransformativeReactionType["Hyperbloom"] = "Hyperbloom";
9
+ TransformativeReactionType["Overloaded"] = "Overloaded";
10
+ TransformativeReactionType["Shattered"] = "Shattered";
11
+ TransformativeReactionType["Superconduct"] = "Superconduct";
12
+ TransformativeReactionType["Swirl"] = "Swirl";
13
+ return TransformativeReactionType;
14
+ }({});
15
+ //#endregion
16
+ //#region src/models/combat/AmplifyingReactionType.ts
17
+ let AmplifyingReactionType = /* @__PURE__ */ function(AmplifyingReactionType) {
18
+ AmplifyingReactionType["Melt"] = "Melt";
19
+ AmplifyingReactionType["Vaporize"] = "Vaporize";
20
+ return AmplifyingReactionType;
21
+ }({});
22
+ //#endregion
23
+ //#region src/models/combat/CatalyzeReactionType.ts
24
+ let CatalyzeReactionType = /* @__PURE__ */ function(CatalyzeReactionType) {
25
+ CatalyzeReactionType["Aggravate"] = "Aggravate";
26
+ CatalyzeReactionType["Spread"] = "Spread";
27
+ return CatalyzeReactionType;
28
+ }({});
29
+ //#endregion
30
+ //#region src/models/combat/LunarReactionType.ts
31
+ let LunarReactionType = /* @__PURE__ */ function(LunarReactionType) {
32
+ LunarReactionType["LunarBloom"] = "LunarBloom";
33
+ LunarReactionType["LunarCharged"] = "LunarCharged";
34
+ LunarReactionType["LunarCrystallize"] = "LunarCrystallize";
35
+ return LunarReactionType;
36
+ }({});
37
+ //#endregion
38
+ //#region src/models/combat/ReactionType.ts
39
+ var BaseReactionType = /* @__PURE__ */ function(BaseReactionType) {
40
+ BaseReactionType["Crystallize"] = "Crystallize";
41
+ BaseReactionType["Frozen"] = "Frozen";
42
+ BaseReactionType["Quicken"] = "Quicken";
43
+ return BaseReactionType;
44
+ }(BaseReactionType || {});
45
+ const ReactionType = mergeObjectsStrict(AmplifyingReactionType, BaseReactionType, CatalyzeReactionType, LunarReactionType, TransformativeReactionType);
46
+ //#endregion
47
+ export { TransformativeReactionType as a, AmplifyingReactionType as i, LunarReactionType as n, CatalyzeReactionType as r, ReactionType as t };
@@ -0,0 +1,17 @@
1
+ //#region src/services/kit/effects/addKitEffect.ts
2
+ const checkIsRestartedBy = (earlier, effect) => {
3
+ if (earlier.kind === "buff" && effect.kind === "buff") return earlier.characterId === effect.characterId && earlier.attribute === effect.attribute && earlier.source === effect.source;
4
+ if (earlier.kind === "infusion" && effect.kind === "infusion") return earlier.characterId === effect.characterId && earlier.element === effect.element;
5
+ if (earlier.kind === "status" && effect.kind === "status") return earlier.characterId === effect.characterId && earlier.id === effect.id;
6
+ if (earlier.kind === "stance" && effect.kind === "stance") return earlier.characterId === effect.characterId;
7
+ return false;
8
+ };
9
+ const addKitEffect = (kitEffectState, effect) => {
10
+ if (effect.kind === "shield") {
11
+ for (const earlier of kitEffectState.effects) if (earlier.kind === "shield" && Boolean(earlier.isCrystallize) === Boolean(effect.isCrystallize) && (effect.isCrystallize || earlier.characterId === effect.characterId)) earlier.secondsRemaining = 0;
12
+ }
13
+ const index = kitEffectState.effects.findIndex((earlier) => checkIsRestartedBy(earlier, effect));
14
+ kitEffectState.effects = index === -1 ? [...kitEffectState.effects, effect] : kitEffectState.effects.with(index, effect);
15
+ };
16
+ //#endregion
17
+ export { addKitEffect as t };
@@ -0,0 +1,28 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { castKitField, castKitSummon } from "./index.js";
3
+ //#region src/services/kit/characters/ainoKit.ts
4
+ const ASCENSION_4 = 4;
5
+ const createAinoKitBehaviour = ({ readHit, readParameter, readSeconds }) => {
6
+ const masteryShare = readParameter("ascension4MasteryShare");
7
+ const waterBall = readHit("waterBall", { additiveBaseDamageBonus: (combatant) => combatant.ascension >= ASCENSION_4 ? combatant.attributes.attributeTotalMap["FIGHT_PROP_ELEMENT_MASTERY"] * masteryShare : 0 });
8
+ const burstFirstTickSeconds = readSeconds("burstStart");
9
+ const burstTickIntervalSeconds = readSeconds("waterBallInterval");
10
+ const burstSeconds = readSeconds("burstDuration");
11
+ const burstRadius = readParameter("burstRadius");
12
+ return { burst: { onStart: ({ activeCombatant: combatant, body: { facing, height, position }, kitEffectState }) => {
13
+ const burstField = castKitField(kitEffectState, combatant.characterId, position, {
14
+ isFollowing: true,
15
+ nextTickSeconds: burstFirstTickSeconds,
16
+ onTick: ({ kitEffectState: tickKitEffectState }) => castKitSummon(tickKitEffectState, {
17
+ facing,
18
+ height,
19
+ position: burstField.centre
20
+ }, combatant, [waterBall]),
21
+ radius: burstRadius,
22
+ secondsRemaining: burstFirstTickSeconds + burstSeconds,
23
+ tickIntervalSeconds: burstTickIntervalSeconds
24
+ });
25
+ } } };
26
+ };
27
+ //#endregion
28
+ export { createAinoKitBehaviour };
@@ -0,0 +1,43 @@
1
+ import { castKitSummon, createAheadBody, findStandingKitSummon, startKitCooldown } from "./index.js";
2
+ //#region src/services/kit/characters/albedoKit.ts
3
+ const SOLAR_ISOTOMA_ID = "albedo-solar-isotoma";
4
+ const TRANSIENT_BLOSSOM_COOLDOWN_STATUS_ID = "albedo-transient-blossom-cooldown";
5
+ const createAlbedoKitBehaviour = ({ readHit, readHits, readParameter, readSeconds }) => {
6
+ const solarIsotomaAheadMetres = readParameter("solarIsotomaAheadMetres");
7
+ const solarIsotomaRadius = readParameter("solarIsotomaRadius");
8
+ const solarIsotomaSeconds = readSeconds("solarIsotomaDuration");
9
+ const transientBlossomCooldownSeconds = readSeconds("transientBlossomCooldown");
10
+ const solarIsotomaHit = readHit("solarIsotoma");
11
+ const transientBlossom = readHit("transientBlossom");
12
+ const fatalBlossoms = readHits("fatalBlossoms");
13
+ return {
14
+ burst: { onStart: ({ activeCombatant: combatant, kitEffectState }) => {
15
+ const solarIsotoma = findStandingKitSummon(kitEffectState.effects, SOLAR_ISOTOMA_ID, combatant.characterId);
16
+ if (solarIsotoma) castKitSummon(kitEffectState, solarIsotoma.body, solarIsotoma.combatant, fatalBlossoms);
17
+ } },
18
+ onKitEvent: (event, { kitEffectState }, combatant) => {
19
+ if (event.kind !== "DamageTaken") return;
20
+ const { characterId } = combatant;
21
+ const { effects } = kitEffectState;
22
+ const solarIsotoma = findStandingKitSummon(effects, SOLAR_ISOTOMA_ID, characterId);
23
+ if (!solarIsotoma) return;
24
+ const { position } = event.enemy;
25
+ if (Math.hypot(position.x - solarIsotoma.body.position.x, position.z - solarIsotoma.body.position.z) > solarIsotomaRadius || !startKitCooldown(kitEffectState, characterId, TRANSIENT_BLOSSOM_COOLDOWN_STATUS_ID, transientBlossomCooldownSeconds)) return;
26
+ castKitSummon(kitEffectState, {
27
+ facing: 0,
28
+ height: 0,
29
+ position
30
+ }, solarIsotoma.combatant, [transientBlossom]);
31
+ },
32
+ skill: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => {
33
+ for (const effect of kitEffectState.effects) if (effect.kind === "summon" && effect.id === SOLAR_ISOTOMA_ID) effect.secondsRemaining = 0;
34
+ castKitSummon(kitEffectState, createAheadBody(body, solarIsotomaAheadMetres), combatant, [solarIsotomaHit], {
35
+ id: SOLAR_ISOTOMA_ID,
36
+ secondsRemaining: solarIsotomaSeconds,
37
+ spawnSeconds: solarIsotomaHit.hitmarkSeconds
38
+ });
39
+ } }
40
+ };
41
+ };
42
+ //#endregion
43
+ export { createAlbedoKitBehaviour };
@@ -0,0 +1,212 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { t as addKitEffect } from "./addKitEffect-DBqTfm_3.js";
3
+ import { addKitStatus, buffKitMember, castKitField, castKitSummon, findKitStatus, getDeployedCharacterIds, scheduleKitTask, startKitCooldown } from "./index.js";
4
+ import { takeOne } from "@esposter/shared";
5
+ //#region src/services/kit/characters/alhaithamKit.ts
6
+ const ASCENSION_1 = 1;
7
+ const ASCENSION_4 = 4;
8
+ const CONSTELLATION_2 = 2;
9
+ const CONSTELLATION_4 = 4;
10
+ const CONSTELLATION_6 = 6;
11
+ const HELD_UNTIL_SWAP_SECONDS = Number.POSITIVE_INFINITY;
12
+ const MIRROR_STATUS_ID = "alhaitham-mirrors";
13
+ const MIRROR_DECAY_FIELD_ID = "alhaitham-mirror-decay";
14
+ const MIRROR_REGEN_TASK_ID = "alhaitham-mirror-regen";
15
+ const PROJECTION_ICD_STATUS_ID = "alhaitham-projection-icd";
16
+ const ASCENSION_1_ICD_STATUS_ID = "alhaitham-a1-icd";
17
+ const CONSTELLATION_2_CURSOR_STATUS_ID = "alhaitham-c2-cursor";
18
+ const CONSTELLATION_2_SOURCE_PREFIX = "alhaitham-c2-";
19
+ const CONSTELLATION_4_LOSS_SOURCE = "alhaitham-c4-loss";
20
+ const CONSTELLATION_4_GAIN_SOURCE = "alhaitham-c4-gain";
21
+ const CONSTELLATION_6_SOURCE = "alhaitham-c6";
22
+ const findKitField = (effects, id) => effects.find((effect) => effect.kind === "field" && effect.id === id);
23
+ const findKitBuff = (effects, characterId, attribute, source) => effects.find((effect) => effect.kind === "buff" && effect.characterId === characterId && effect.attribute === attribute && effect.source === source);
24
+ const getMirrorCount = (effects, characterId) => findKitStatus(effects, characterId, MIRROR_STATUS_ID)?.stacks ?? 0;
25
+ const setMirrorCount = (kitEffectState, characterId, mirrors) => {
26
+ if (mirrors <= 0) {
27
+ const status = findKitStatus(kitEffectState.effects, characterId, MIRROR_STATUS_ID);
28
+ if (status) {
29
+ status.stacks = 0;
30
+ status.secondsRemaining = 0;
31
+ }
32
+ for (const effect of kitEffectState.effects) {
33
+ if (effect.kind === "infusion" && effect.characterId === characterId && effect.element === "Grass") effect.secondsRemaining = 0;
34
+ if (effect.kind === "field" && effect.id === MIRROR_DECAY_FIELD_ID) effect.secondsRemaining = 0;
35
+ }
36
+ return;
37
+ }
38
+ addKitStatus(kitEffectState, characterId, {
39
+ id: MIRROR_STATUS_ID,
40
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
41
+ stacks: mirrors
42
+ });
43
+ addKitEffect(kitEffectState, {
44
+ characterId,
45
+ element: "Grass",
46
+ kind: "infusion",
47
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS
48
+ });
49
+ };
50
+ const addConstellation2Buff = (kitEffectState, characterId, buffs) => {
51
+ const cursor = findKitStatus(kitEffectState.effects, characterId, CONSTELLATION_2_CURSOR_STATUS_ID)?.stacks ?? 0;
52
+ addKitStatus(kitEffectState, characterId, {
53
+ id: CONSTELLATION_2_CURSOR_STATUS_ID,
54
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
55
+ stacks: (cursor + 1) % buffs.constellation2StacksMax
56
+ });
57
+ buffKitMember(kitEffectState, characterId, {
58
+ amount: buffs.constellation2ElementalMastery,
59
+ attribute: "FIGHT_PROP_ELEMENT_MASTERY",
60
+ secondsRemaining: buffs.constellation2Seconds,
61
+ source: `${CONSTELLATION_2_SOURCE_PREFIX}${cursor + 1}`
62
+ });
63
+ };
64
+ const addConstellation6Buffs = (kitEffectState, characterId, overflow, buffs) => {
65
+ for (let index = 0; index < overflow; index++) {
66
+ const critical = findKitBuff(kitEffectState.effects, characterId, "FIGHT_PROP_CRITICAL", CONSTELLATION_6_SOURCE);
67
+ if (critical) {
68
+ critical.secondsRemaining += buffs.constellation6Seconds;
69
+ const criticalDamage = findKitBuff(kitEffectState.effects, characterId, "FIGHT_PROP_CRITICAL_HURT", CONSTELLATION_6_SOURCE);
70
+ if (criticalDamage) criticalDamage.secondsRemaining += buffs.constellation6Seconds;
71
+ continue;
72
+ }
73
+ buffKitMember(kitEffectState, characterId, {
74
+ amount: buffs.constellation6CriticalRate,
75
+ attribute: "FIGHT_PROP_CRITICAL",
76
+ secondsRemaining: buffs.constellation6Seconds,
77
+ source: CONSTELLATION_6_SOURCE
78
+ });
79
+ buffKitMember(kitEffectState, characterId, {
80
+ amount: buffs.constellation6CriticalDamage,
81
+ attribute: "FIGHT_PROP_CRITICAL_HURT",
82
+ secondsRemaining: buffs.constellation6Seconds,
83
+ source: CONSTELLATION_6_SOURCE
84
+ });
85
+ }
86
+ };
87
+ const elementalMasteryMultiplier = (combatant, multiplier) => combatant.attributes.attributeTotalMap["FIGHT_PROP_ELEMENT_MASTERY"] * multiplier;
88
+ const getSkillMirrorGain = (effects, characterId) => getMirrorCount(effects, characterId) === 0 ? 2 : 1;
89
+ const createAlhaithamKitBehaviour = ({ kit, readHits, readParameter, readSeconds, readSecondsList }) => {
90
+ const mirrorSecondsList = readSecondsList("universalityMirrorDelays");
91
+ const mirrorDecaySeconds = readSeconds("mirrorDecay");
92
+ const projectionCooldownSeconds = readSeconds("projectionAttackCooldown");
93
+ const burstMirrorRegenSeconds = readSeconds("particularFieldMirrorDelay");
94
+ const projectionElementalMasteryShare = readParameter("projectionAttackElementalMasteryShare");
95
+ const burstElementalMasteryShare = readParameter("particularFieldElementalMasteryShare");
96
+ const skillElementalMasteryShare = readParameter("universalityElementalMasteryShare");
97
+ const mirrorsMax = readParameter("mirrorsMax");
98
+ const burstBaseHitCount = readParameter("burstBaseHitCount");
99
+ const burstHitCountPerMirror = readParameter("burstHitCountPerMirror");
100
+ const ascension1IcdSeconds = readSeconds("ascension1IcdDuration");
101
+ const ascension4DamagePerElementalMastery = readParameter("ascension4DamagePerElementalMastery");
102
+ const ascension4DamageMax = readParameter("ascension4DamageMax");
103
+ const constellation2ElementalMastery = readParameter("constellation2ElementalMastery");
104
+ const constellation2Seconds = readSeconds("constellation2Duration");
105
+ const constellation2StacksMax = readParameter("constellation2StacksMax");
106
+ const constellation4ElementalMasteryPerMirror = readParameter("constellation4ElementalMasteryPerMirror");
107
+ const constellation4DendroDamageBonusPerMirror = readParameter("constellation4DendroDamageBonusPerMirror");
108
+ const constellation4Seconds = readSeconds("constellation4Duration");
109
+ const constellation6CriticalRate = readParameter("constellation6CriticalRate");
110
+ const constellationBuffs = {
111
+ constellation2ElementalMastery,
112
+ constellation2Seconds,
113
+ constellation2StacksMax,
114
+ constellation6CriticalDamage: readParameter("constellation6CriticalDamage"),
115
+ constellation6CriticalRate,
116
+ constellation6Seconds: readSeconds("constellation6Duration")
117
+ };
118
+ const projectionHitBehaviour = { additiveBaseDamageBonus: (striker) => elementalMasteryMultiplier(striker, projectionElementalMasteryShare) };
119
+ const projectionAttacks = [
120
+ readHits("projectionAttackOneMirror", projectionHitBehaviour),
121
+ readHits("projectionAttackTwoMirrors", projectionHitBehaviour),
122
+ readHits("projectionAttackThreeMirrors", projectionHitBehaviour)
123
+ ];
124
+ const particularFieldHits = readHits("particularFieldHits", { additiveBaseDamageBonus: (striker) => elementalMasteryMultiplier(striker, burstElementalMasteryShare) });
125
+ const startMirrorDecay = (kitEffectState, body, combatant) => {
126
+ const { characterId } = combatant;
127
+ const field = findKitField(kitEffectState.effects, MIRROR_DECAY_FIELD_ID);
128
+ if (field) {
129
+ field.nextTickSeconds = mirrorDecaySeconds;
130
+ field.secondsRemaining = HELD_UNTIL_SWAP_SECONDS;
131
+ return;
132
+ }
133
+ castKitField(kitEffectState, characterId, body.position, {
134
+ id: MIRROR_DECAY_FIELD_ID,
135
+ nextTickSeconds: mirrorDecaySeconds,
136
+ onTick: ({ kitEffectState: effectState }) => {
137
+ const count = getMirrorCount(effectState.effects, characterId);
138
+ setMirrorCount(effectState, characterId, count > 1 ? count - 1 : 0);
139
+ },
140
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
141
+ tickIntervalSeconds: mirrorDecaySeconds
142
+ });
143
+ };
144
+ const gainMirrors = (kitEffectState, body, combatant, generated) => {
145
+ if (generated <= 0) return;
146
+ const { characterId, constellationCount } = combatant;
147
+ const count = getMirrorCount(kitEffectState.effects, characterId);
148
+ const total = count + generated;
149
+ if (count === 0 || total > mirrorsMax) startMirrorDecay(kitEffectState, body, combatant);
150
+ setMirrorCount(kitEffectState, characterId, Math.min(total, mirrorsMax));
151
+ if (constellationCount >= CONSTELLATION_2) for (let made = 0; made < generated; made++) addConstellation2Buff(kitEffectState, characterId, constellationBuffs);
152
+ if (constellationCount >= CONSTELLATION_6 && total > mirrorsMax) addConstellation6Buffs(kitEffectState, characterId, total - mirrorsMax, constellationBuffs);
153
+ };
154
+ const triggerProjection = ({ kitEffectState }, { body, combatant }, isMirrorSource) => {
155
+ const { ascension, characterId } = combatant;
156
+ if (isMirrorSource && ascension >= ASCENSION_1 && startKitCooldown(kitEffectState, characterId, ASCENSION_1_ICD_STATUS_ID, ascension1IcdSeconds)) gainMirrors(kitEffectState, body, combatant, 1);
157
+ const count = getMirrorCount(kitEffectState.effects, characterId);
158
+ if (count === 0 || !startKitCooldown(kitEffectState, characterId, PROJECTION_ICD_STATUS_ID, projectionCooldownSeconds)) return;
159
+ castKitSummon(kitEffectState, body, combatant, takeOne(projectionAttacks, count - 1));
160
+ };
161
+ const strikeHitBehaviour = { onStrike: (context, strike) => triggerProjection(context, strike, false) };
162
+ const mirrorSourceHitBehaviour = { onStrike: (context, strike) => triggerProjection(context, strike, true) };
163
+ const createSkillBehaviour = (mirrorSeconds) => ({
164
+ hits: [{ additiveBaseDamageBonus: (striker) => elementalMasteryMultiplier(striker, skillElementalMasteryShare) }],
165
+ onStart: ({ activeCombatant: combatant, body, kitEffectState }) => scheduleKitTask(kitEffectState, combatant.characterId, mirrorSeconds, (tick) => gainMirrors(tick.kitEffectState, body, combatant, getSkillMirrorGain(tick.kitEffectState.effects, combatant.characterId)))
166
+ });
167
+ return {
168
+ burst: { onStart: ({ activeCombatant: combatant, body, kitEffectState, party }) => {
169
+ const { characterId, constellationCount } = combatant;
170
+ const consumed = getMirrorCount(kitEffectState.effects, characterId);
171
+ castKitSummon(kitEffectState, body, combatant, particularFieldHits.slice(0, burstBaseHitCount + burstHitCountPerMirror * consumed));
172
+ setMirrorCount(kitEffectState, characterId, 0);
173
+ if (constellationCount >= CONSTELLATION_4 && consumed > 0) for (const memberId of getDeployedCharacterIds(party)) {
174
+ if (memberId === characterId) continue;
175
+ buffKitMember(kitEffectState, memberId, {
176
+ amount: constellation4ElementalMasteryPerMirror * consumed,
177
+ attribute: "FIGHT_PROP_ELEMENT_MASTERY",
178
+ secondsRemaining: constellation4Seconds,
179
+ source: CONSTELLATION_4_LOSS_SOURCE
180
+ });
181
+ }
182
+ const generated = constellationCount >= CONSTELLATION_6 ? mirrorsMax : mirrorsMax - consumed;
183
+ if (generated <= 0) return;
184
+ scheduleKitTask(kitEffectState, characterId, burstMirrorRegenSeconds, (tick) => {
185
+ gainMirrors(tick.kitEffectState, body, combatant, generated);
186
+ if (constellationCount >= CONSTELLATION_4) buffKitMember(tick.kitEffectState, characterId, {
187
+ amount: constellation4DendroDamageBonusPerMirror * generated,
188
+ attribute: "FIGHT_PROP_GRASS_ADD_HURT",
189
+ secondsRemaining: constellation4Seconds,
190
+ source: CONSTELLATION_4_GAIN_SOURCE
191
+ });
192
+ }, { id: MIRROR_REGEN_TASK_ID });
193
+ } },
194
+ chargedAttack: { hits: kit.chargedAttack.hits.map(() => mirrorSourceHitBehaviour) },
195
+ getStrikeDamageBonus: ({ combatant, hit }) => combatant.ascension >= ASCENSION_4 && (hit.internalCooldownTag === "ElementalBurst" || hit.internalCooldownTag === "ElementalSkill") ? Math.min(combatant.attributes.attributeTotalMap["FIGHT_PROP_ELEMENT_MASTERY"] * ascension4DamagePerElementalMastery, ascension4DamageMax) : 0,
196
+ normalAttacks: kit.normalAttacks.map(({ hits }) => ({ hits: hits.map(() => strikeHitBehaviour) })),
197
+ onKitEvent: (event, { kitEffectState }, combatant) => {
198
+ if (event.kind !== "CharacterSwapped" || event.previousCharacterId !== combatant.characterId) return;
199
+ setMirrorCount(kitEffectState, combatant.characterId, 0);
200
+ for (const effect of kitEffectState.effects) if (effect.kind === "field" && effect.id === MIRROR_REGEN_TASK_ID) effect.secondsRemaining = 0;
201
+ },
202
+ plungeCollision: mirrorSourceHitBehaviour,
203
+ plunges: {
204
+ ["high"]: { hits: [mirrorSourceHitBehaviour] },
205
+ ["low"]: { hits: [mirrorSourceHitBehaviour] }
206
+ },
207
+ skill: createSkillBehaviour(takeOne(mirrorSecondsList, 0)),
208
+ skillHolds: [createSkillBehaviour(takeOne(mirrorSecondsList, 1))]
209
+ };
210
+ };
211
+ //#endregion
212
+ export { createAlhaithamKitBehaviour };
@@ -0,0 +1,32 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { t as addKitEffect } from "./addKitEffect-DBqTfm_3.js";
3
+ import { addKitStatus, checkHasKitStatus, gainKitResource, spendKitResource } from "./index.js";
4
+ //#region src/services/kit/characters/aloyKit.ts
5
+ const COIL_RUSHING_ICE_STACKS = 4;
6
+ const COIL_RESOURCE_ID = "aloy-coil";
7
+ const RUSHING_ICE_STATUS_ID = "aloy-rushing-ice";
8
+ const createAloyKitBehaviour = ({ readSeconds }) => {
9
+ const rushingIceSeconds = readSeconds("rushingIceDuration");
10
+ const addCoilStack = ({ kitEffectState }, { combatant }) => {
11
+ if (checkHasKitStatus(kitEffectState.effects, combatant.characterId, RUSHING_ICE_STATUS_ID)) return;
12
+ if (gainKitResource(kitEffectState, combatant.characterId, COIL_RESOURCE_ID, 1, COIL_RUSHING_ICE_STACKS) < COIL_RUSHING_ICE_STACKS) return;
13
+ spendKitResource(kitEffectState, combatant.characterId, COIL_RESOURCE_ID);
14
+ addKitEffect(kitEffectState, {
15
+ characterId: combatant.characterId,
16
+ element: "Ice",
17
+ kind: "infusion",
18
+ secondsRemaining: rushingIceSeconds
19
+ });
20
+ addKitStatus(kitEffectState, combatant.characterId, {
21
+ id: RUSHING_ICE_STATUS_ID,
22
+ secondsRemaining: rushingIceSeconds
23
+ });
24
+ };
25
+ return { skill: { hits: [
26
+ {},
27
+ { onStrike: addCoilStack },
28
+ { onStrike: addCoilStack }
29
+ ] } };
30
+ };
31
+ //#endregion
32
+ export { createAloyKitBehaviour };
@@ -0,0 +1,38 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { castKitSummon, castKitTaunt } from "./index.js";
3
+ //#region src/services/kit/characters/amberKit.ts
4
+ const EVERY_ARROW_FINDS_ITS_TARGET_ASCENSION = 1;
5
+ const EVERY_ARROW_FINDS_ITS_TARGET_CRITICAL_RATE = .1;
6
+ const addEveryArrowCriticalRate = (combatant) => {
7
+ const { attributeTotalMap } = combatant.attributes;
8
+ return {
9
+ ...combatant,
10
+ attributes: {
11
+ ...combatant.attributes,
12
+ attributeTotalMap: {
13
+ ...attributeTotalMap,
14
+ ["FIGHT_PROP_CRITICAL"]: attributeTotalMap["FIGHT_PROP_CRITICAL"] + EVERY_ARROW_FINDS_ITS_TARGET_CRITICAL_RATE
15
+ }
16
+ }
17
+ };
18
+ };
19
+ const createAmberKitBehaviour = ({ readHit, readHits, readParameter, readSeconds }) => {
20
+ const bunnyExplosion = readHit("baronBunnyExplosion");
21
+ const bunnyMaxHealthShare = readParameter("baronBunnyMaxHealthShare");
22
+ const bunnySeconds = readSeconds("baronBunnySeconds");
23
+ const fieryRainArrows = readHits("fieryRainArrows");
24
+ const everyArrowFindsItsTargetFieryRainArrows = readHits("everyArrowFindsItsTargetFieryRainArrows");
25
+ return {
26
+ burst: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => {
27
+ const hasEveryArrowFindsItsTarget = combatant.ascension >= EVERY_ARROW_FINDS_ITS_TARGET_ASCENSION;
28
+ castKitSummon(kitEffectState, body, hasEveryArrowFindsItsTarget ? addEveryArrowCriticalRate(combatant) : combatant, hasEveryArrowFindsItsTarget ? everyArrowFindsItsTargetFieryRainArrows : fieryRainArrows);
29
+ } },
30
+ skill: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => castKitTaunt(kitEffectState, body, combatant, {
31
+ explosion: bunnyExplosion,
32
+ health: bunnyMaxHealthShare * combatant.attributes.maxHealth,
33
+ secondsRemaining: bunnySeconds
34
+ }) }
35
+ };
36
+ };
37
+ //#endregion
38
+ export { createAmberKitBehaviour };
@@ -0,0 +1,4 @@
1
+ //#region src/services/kit/characters/arlecchinoKit.ts
2
+ const createArlecchinoKitBehaviour = () => ({});
3
+ //#endregion
4
+ export { createArlecchinoKitBehaviour };
@@ -0,0 +1,26 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { t as addKitEffect } from "./addKitEffect-DBqTfm_3.js";
3
+ import { castKitSummon } from "./index.js";
4
+ //#region src/services/kit/characters/ayakaKit.ts
5
+ const BLIZZARD_BLADE_SEKI_NO_TO_CONSTELLATION = 2;
6
+ const SENHO_INFUSION_SECONDS = 5;
7
+ const createAyakaKitBehaviour = ({ readHits }) => {
8
+ const frostflakeHits = readHits("frostflake");
9
+ const smallFrostflakeHits = readHits("smallFrostflake");
10
+ return {
11
+ burst: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => {
12
+ castKitSummon(kitEffectState, body, combatant, frostflakeHits);
13
+ if (combatant.constellationCount < BLIZZARD_BLADE_SEKI_NO_TO_CONSTELLATION) return;
14
+ castKitSummon(kitEffectState, body, combatant, smallFrostflakeHits);
15
+ castKitSummon(kitEffectState, body, combatant, smallFrostflakeHits);
16
+ } },
17
+ onSprint: ({ activeCombatant: combatant, kitEffectState }) => addKitEffect(kitEffectState, {
18
+ characterId: combatant.characterId,
19
+ element: "Ice",
20
+ kind: "infusion",
21
+ secondsRemaining: SENHO_INFUSION_SECONDS
22
+ })
23
+ };
24
+ };
25
+ //#endregion
26
+ export { createAyakaKitBehaviour };
@@ -0,0 +1,108 @@
1
+ import { addKitStatus, castKitField, castKitSummon, enterKitStance, findKitStatus, scheduleKitTask } from "./index.js";
2
+ import { takeOne } from "@esposter/shared";
3
+ //#region src/services/kit/characters/ayatoKit.ts
4
+ const SOUKAI_KANKA_SECONDS = 6;
5
+ const CONSTELLATION_6_HIT_MULTIPLIER = 4.5;
6
+ const ASCENSION_1 = 1;
7
+ const ASCENSION_1_CAST_STACKS = 2;
8
+ const NAMISEN_STACKS_MAX = 4;
9
+ const CONSTELLATION_1 = 1;
10
+ const CONSTELLATION_1_DAMAGE_BONUS = .4;
11
+ const CONSTELLATION_1_HEALTH_SHARE = .5;
12
+ const CONSTELLATION_2 = 2;
13
+ const CONSTELLATION_2_NAMISEN_STACKS_MAX = 5;
14
+ const CONSTELLATION_6 = 6;
15
+ const HELD_UNTIL_SWAP_SECONDS = Number.POSITIVE_INFINITY;
16
+ const NAMISEN_STATUS_ID = "ayato-namisen";
17
+ const CONSTELLATION_6_STATUS_ID = "ayato-constellation-6";
18
+ const countNamisenStacks = (effects, characterId) => findKitStatus(effects, characterId, NAMISEN_STATUS_ID)?.stacks ?? 0;
19
+ const getNamisenStacksMax = (combatant) => combatant.constellationCount >= CONSTELLATION_2 ? CONSTELLATION_2_NAMISEN_STACKS_MAX : NAMISEN_STACKS_MAX;
20
+ const createAyatoKitBehaviour = ({ kit, readHit, readHitFields, readParameter, readParameters, readSeconds, readSecondsList }) => {
21
+ const namisenShare = readParameter("namisenShare");
22
+ const gardenOfPuritySeconds = readParameter("gardenOfPuritySeconds");
23
+ const bloomwaterBladeFirstTickSeconds = readSeconds("bloomwaterBladeFirstTick");
24
+ const bloomwaterBladeIntervalSeconds = readSeconds("bloomwaterBladeInterval");
25
+ const bloomwaterBlade = readHit("bloomwaterBlade");
26
+ const illusionSeconds = takeOne(kit.elementalSkill.hits).hitmarkSeconds;
27
+ const shunsuikenSeconds = readSeconds("shunsuikenStrike");
28
+ const shunsuikenTargetingArea = takeOne(kit.normalAttacks).targetingArea;
29
+ const shunsuiken = readHitFields("shunsuiken", ["talentMultiplier"]);
30
+ const shunsuikenMultipliers = readParameters("shunsuikenMultipliers");
31
+ const constellation6Hits = Array.from(readSecondsList("boundlessOriginHitmarks"), (hitmarkSeconds) => ({
32
+ ...shunsuiken,
33
+ hitmarkSeconds: hitmarkSeconds - shunsuiken.hitmarkSeconds,
34
+ talentMultiplier: CONSTELLATION_6_HIT_MULTIPLIER
35
+ }));
36
+ const createShunsuikenHit = (talentMultiplier, combatant, kitEffectState) => ({
37
+ ...shunsuiken,
38
+ additiveBaseDamageBonus: (striker) => striker.attributes.maxHealth * namisenShare * countNamisenStacks(kitEffectState.effects, striker.characterId),
39
+ onStrike: ({ kitEffectState: effectState }, { body }) => {
40
+ const { characterId } = combatant;
41
+ const stacks = countNamisenStacks(effectState.effects, characterId);
42
+ if (stacks < getNamisenStacksMax(combatant)) addKitStatus(effectState, characterId, {
43
+ id: NAMISEN_STATUS_ID,
44
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
45
+ stacks: stacks + 1
46
+ });
47
+ const constellation6 = findKitStatus(effectState.effects, characterId, CONSTELLATION_6_STATUS_ID);
48
+ if (!constellation6) return;
49
+ constellation6.secondsRemaining = 0;
50
+ castKitSummon(effectState, body, combatant, constellation6Hits);
51
+ },
52
+ talentMultiplier
53
+ });
54
+ const castGardenOfPurity = (kitEffectState, { facing, height, position }, combatant) => {
55
+ const gardenOfPurity = castKitField(kitEffectState, combatant.characterId, position, {
56
+ isFollowing: true,
57
+ nextTickSeconds: bloomwaterBladeFirstTickSeconds,
58
+ onTick: ({ kitEffectState: tickKitEffectState }) => castKitSummon(tickKitEffectState, {
59
+ facing,
60
+ height,
61
+ position: gardenOfPurity.centre
62
+ }, combatant, [bloomwaterBlade]),
63
+ secondsRemaining: bloomwaterBladeFirstTickSeconds + gardenOfPuritySeconds,
64
+ tickIntervalSeconds: bloomwaterBladeIntervalSeconds
65
+ });
66
+ };
67
+ return {
68
+ burst: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => castGardenOfPurity(kitEffectState, body, combatant) },
69
+ getStrikeDamageBonus: ({ attackTag, combatant }, enemy) => combatant.constellationCount >= CONSTELLATION_1 && attackTag === "NormalAttack" && enemy.health / enemy.maxHealth <= CONSTELLATION_1_HEALTH_SHARE ? CONSTELLATION_1_DAMAGE_BONUS : 0,
70
+ onKitEvent: (event, { kitEffectState }, combatant) => {
71
+ if (event.kind !== "CharacterSwapped" || event.previousCharacterId !== combatant.characterId) return;
72
+ const namisen = findKitStatus(kitEffectState.effects, combatant.characterId, NAMISEN_STATUS_ID);
73
+ if (namisen) namisen.secondsRemaining = 0;
74
+ },
75
+ skill: { onStart: ({ activeCombatant: combatant, kitEffectState }) => {
76
+ const { characterId } = combatant;
77
+ if (combatant.ascension >= ASCENSION_1) {
78
+ addKitStatus(kitEffectState, characterId, {
79
+ id: NAMISEN_STATUS_ID,
80
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
81
+ stacks: ASCENSION_1_CAST_STACKS
82
+ });
83
+ scheduleKitTask(kitEffectState, characterId, illusionSeconds, ({ kitEffectState: effectState }) => addKitStatus(effectState, characterId, {
84
+ id: NAMISEN_STATUS_ID,
85
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS,
86
+ stacks: getNamisenStacksMax(combatant)
87
+ }));
88
+ }
89
+ if (combatant.constellationCount >= CONSTELLATION_6) addKitStatus(kitEffectState, characterId, {
90
+ id: CONSTELLATION_6_STATUS_ID,
91
+ secondsRemaining: HELD_UNTIL_SWAP_SECONDS
92
+ });
93
+ enterKitStance(kitEffectState, combatant, {
94
+ chargedAttack: kit.chargedAttack,
95
+ chargedAttackStamina: kit.chargedAttackStamina,
96
+ elementalBurst: kit.elementalBurst,
97
+ elementalSkill: kit.elementalSkill,
98
+ normalAttacks: shunsuikenMultipliers.map((talentMultiplier) => ({
99
+ hits: [createShunsuikenHit(talentMultiplier, combatant, kitEffectState)],
100
+ seconds: shunsuikenSeconds,
101
+ targetingArea: shunsuikenTargetingArea
102
+ }))
103
+ }, SOUKAI_KANKA_SECONDS, { isEndedOnSwap: true });
104
+ } }
105
+ };
106
+ };
107
+ //#endregion
108
+ export { createAyatoKitBehaviour };
@@ -0,0 +1,33 @@
1
+ import "./characterPack-zycIUHje.js";
2
+ import { castKitField, castKitShield } from "./index.js";
3
+ //#region src/services/kit/characters/baizhuKit.ts
4
+ const createBaizhuKitBehaviour = ({ readHit, readParameter, readSeconds }) => {
5
+ const shieldMaxHealthShare = readParameter("seamlessShieldMaxHealthShare");
6
+ const shieldFlatHealth = readParameter("seamlessShieldFlatHealth");
7
+ const firstShieldSeconds = readSeconds("firstSeamlessShield");
8
+ const shieldSeconds = readSeconds("seamlessShield");
9
+ const firstRefreshSeconds = readSeconds("firstSeamlessShieldRefresh");
10
+ const refreshIntervalSeconds = readSeconds("seamlessShieldRefreshInterval");
11
+ const refreshFieldSeconds = readSeconds("seamlessShieldRefreshField");
12
+ const spiritvein = readHit("spiritvein");
13
+ const castShield = (kitEffectState, combatant, secondsRemaining) => castKitShield(kitEffectState, combatant.characterId, {
14
+ element: "Grass",
15
+ explosion: {
16
+ combatant,
17
+ hit: spiritvein
18
+ },
19
+ health: shieldMaxHealthShare * combatant.attributes.maxHealth + shieldFlatHealth,
20
+ secondsRemaining
21
+ });
22
+ return { burst: { onStart: ({ activeCombatant: combatant, body, kitEffectState }) => {
23
+ castShield(kitEffectState, combatant, firstShieldSeconds);
24
+ castKitField(kitEffectState, combatant.characterId, body.position, {
25
+ nextTickSeconds: firstRefreshSeconds,
26
+ onTick: ({ kitEffectState: tickKitEffectState }) => castShield(tickKitEffectState, combatant, shieldSeconds),
27
+ secondsRemaining: refreshFieldSeconds,
28
+ tickIntervalSeconds: refreshIntervalSeconds
29
+ });
30
+ } } };
31
+ };
32
+ //#endregion
33
+ export { createBaizhuKitBehaviour };