@v12-engine/create 0.1.1 → 0.4.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 (263) hide show
  1. package/README.md +4 -1
  2. package/base/_gitignore +5 -0
  3. package/base/package.json +3 -3
  4. package/base/src/main.ts +36 -10
  5. package/base/src/navigation.worker.ts +7 -0
  6. package/base/vite.config.ts +24 -2
  7. package/cli.mjs +21 -6
  8. package/index.mjs +27 -7
  9. package/layers/desktop/electron/app.mjs +237 -0
  10. package/layers/desktop/electron/config.mjs +16 -0
  11. package/layers/desktop/electron/dev.mjs +63 -0
  12. package/layers/desktop/electron/files.mjs +86 -0
  13. package/layers/desktop/electron/icons/icon.icns +0 -0
  14. package/layers/desktop/electron/icons/icon.png +0 -0
  15. package/layers/desktop/electron/main.mjs +12 -0
  16. package/layers/desktop/electron/package.mjs +75 -0
  17. package/layers/desktop/electron/preload.cjs +41 -0
  18. package/layers/desktop/electron/presentation.m +87 -0
  19. package/layers/desktop/electron/serve.mjs +76 -0
  20. package/layers/desktop/electron/tools.mjs +63 -0
  21. package/layers/desktop/electron/updates.mjs +71 -0
  22. package/layers/desktop/package.json +13 -0
  23. package/layers/desktop/src/desktop.ts +175 -0
  24. package/layers/desktop/src/shell.ts +279 -0
  25. package/layers/desktop/tests/main.test.ts +189 -0
  26. package/layers/desktop/tests/shell.test.ts +152 -0
  27. package/layers/rooms/server.ts +13 -10
  28. package/layers/server/server.ts +4 -5
  29. package/layers/source/vite.config.ts +21 -1
  30. package/package.json +1 -1
  31. package/starters/campaign/README.md +9 -2
  32. package/starters/campaign/layers/rooms/server.ts +3 -3
  33. package/starters/campaign/layers/server/server.ts +3 -5
  34. package/starters/campaign/layers/tests/tests/rules.test.ts +40 -21
  35. package/starters/campaign/src/campaign/game.ts +26 -5
  36. package/starters/campaign/src/campaign/index.ts +104 -68
  37. package/starters/campaign/src/campaign/kills.ts +1 -1
  38. package/starters/campaign/src/campaign/missions/homecoming.ts +7 -7
  39. package/starters/campaign/src/campaign/missions/siege.ts +6 -6
  40. package/starters/campaign/src/campaign/missions/warlord.ts +13 -14
  41. package/starters/campaign/src/campaign/scenes.ts +8 -7
  42. package/starters/campaign/src/campaign/units.ts +59 -20
  43. package/starters/campaign/src/campaign/view/attacks.ts +19 -0
  44. package/starters/campaign/src/campaign/view/fire.ts +2 -2
  45. package/starters/campaign/src/campaign/view/index.ts +54 -43
  46. package/starters/campaign/src/campaign/waves.ts +18 -17
  47. package/starters/campaign/src/game.ts +8 -1
  48. package/starters/campaign/src/main.ts +38 -19
  49. package/starters/campaign/src/maps/fort.names.ts +2 -2
  50. package/starters/campaign/src/maps/fort.vgmap.json +102 -2
  51. package/starters/campaign/src/maps/homestead.names.ts +2 -2
  52. package/starters/campaign/src/maps/homestead.vgmap.json +85 -1
  53. package/starters/campaign/src/maps/pass.names.ts +2 -2
  54. package/starters/campaign/src/maps/pass.vgmap.json +69 -1
  55. package/starters/campaign/src/waves-panel.ts +2 -1
  56. package/starters/empty/README.md +18 -10
  57. package/starters/empty/layers/tests/tests/rules.test.ts +16 -17
  58. package/starters/empty/src/game.ts +11 -75
  59. package/starters/empty/src/generate.worker.ts +5 -5
  60. package/starters/empty/src/rules.ts +83 -25
  61. package/starters/empty/src/view.ts +82 -0
  62. package/starters/examples/README.md +83 -0
  63. package/starters/examples/layers/tests/tests/examples.test.ts +30 -0
  64. package/starters/examples/package.json +5 -0
  65. package/starters/examples/src/examples/abilities/areas.ts +165 -0
  66. package/starters/examples/src/examples/abilities/areasLooks.ts +30 -0
  67. package/starters/examples/src/examples/abilities/buffs.ts +287 -0
  68. package/starters/examples/src/examples/abilities/buffsLooks.ts +46 -0
  69. package/starters/examples/src/examples/abilities/changing.ts +228 -0
  70. package/starters/examples/src/examples/abilities/changingLooks.ts +61 -0
  71. package/starters/examples/src/examples/abilities/control.ts +158 -0
  72. package/starters/examples/src/examples/abilities/controlLooks.ts +78 -0
  73. package/starters/examples/src/examples/abilities/damage.ts +156 -0
  74. package/starters/examples/src/examples/abilities/damageLooks.ts +37 -0
  75. package/starters/examples/src/examples/abilities/family.ts +29 -0
  76. package/starters/examples/src/examples/abilities/index.ts +32 -0
  77. package/starters/examples/src/examples/abilities/kit.ts +179 -0
  78. package/starters/examples/src/examples/abilities/lookKit.ts +71 -0
  79. package/starters/examples/src/examples/abilities/looks.ts +47 -0
  80. package/starters/examples/src/examples/abilities/missiles.ts +203 -0
  81. package/starters/examples/src/examples/abilities/missilesLooks.ts +38 -0
  82. package/starters/examples/src/examples/abilities/moves.ts +206 -0
  83. package/starters/examples/src/examples/abilities/movesLooks.ts +52 -0
  84. package/starters/examples/src/examples/abilities/recasts.ts +181 -0
  85. package/starters/examples/src/examples/abilities/recastsLooks.ts +41 -0
  86. package/starters/examples/src/examples/abilities/resources.ts +166 -0
  87. package/starters/examples/src/examples/abilities/resourcesLooks.ts +42 -0
  88. package/starters/examples/src/examples/abilities/summons.ts +296 -0
  89. package/starters/examples/src/examples/abilities/summonsLooks.ts +115 -0
  90. package/starters/examples/src/examples/abilities/triggers.ts +204 -0
  91. package/starters/examples/src/examples/abilities/triggersLooks.ts +53 -0
  92. package/starters/examples/src/examples/abilities/vision.ts +137 -0
  93. package/starters/examples/src/examples/abilities/visionLooks.ts +50 -0
  94. package/starters/examples/src/examples/animation/index.ts +235 -0
  95. package/starters/examples/src/examples/animation/looks.ts +444 -0
  96. package/starters/examples/src/examples/catalog.ts +52 -0
  97. package/starters/examples/src/examples/cinematics/index.ts +217 -0
  98. package/starters/examples/src/examples/cinematics/looks.ts +476 -0
  99. package/starters/examples/src/examples/cinematics/tour.json +43 -0
  100. package/starters/examples/src/examples/cinematics/village.ts +88 -0
  101. package/starters/examples/src/examples/common/looks.ts +65 -0
  102. package/starters/examples/src/examples/common/units.ts +70 -0
  103. package/starters/examples/src/examples/construction/index.ts +329 -0
  104. package/starters/examples/src/examples/construction/looks.ts +275 -0
  105. package/starters/examples/src/examples/custom-animation/bones.ts +92 -0
  106. package/starters/examples/src/examples/custom-animation/index.ts +190 -0
  107. package/starters/examples/src/examples/custom-animation/looks.ts +523 -0
  108. package/starters/examples/src/examples/custom-animation/runes.ts +82 -0
  109. package/starters/examples/src/examples/custom-fx/glaive.look.ts +110 -0
  110. package/starters/examples/src/examples/custom-fx/glaive.ts +40 -0
  111. package/starters/examples/src/examples/custom-fx/gpu.look.ts +145 -0
  112. package/starters/examples/src/examples/custom-fx/gpu.ts +22 -0
  113. package/starters/examples/src/examples/custom-fx/index.ts +25 -0
  114. package/starters/examples/src/examples/custom-fx/lights.look.ts +144 -0
  115. package/starters/examples/src/examples/custom-fx/lights.ts +25 -0
  116. package/starters/examples/src/examples/custom-fx/looks.ts +36 -0
  117. package/starters/examples/src/examples/custom-fx/meteor.look.ts +133 -0
  118. package/starters/examples/src/examples/custom-fx/meteor.ts +26 -0
  119. package/starters/examples/src/examples/custom-fx/parts.look.ts +193 -0
  120. package/starters/examples/src/examples/custom-fx/parts.ts +21 -0
  121. package/starters/examples/src/examples/custom-fx/portal.look.ts +193 -0
  122. package/starters/examples/src/examples/custom-fx/portal.ts +48 -0
  123. package/starters/examples/src/examples/custom-fx/renderer.look.ts +139 -0
  124. package/starters/examples/src/examples/custom-fx/renderer.ts +18 -0
  125. package/starters/examples/src/examples/custom-fx/ribbons.look.ts +151 -0
  126. package/starters/examples/src/examples/custom-fx/ribbons.ts +22 -0
  127. package/starters/examples/src/examples/custom-fx/shader.ts +42 -0
  128. package/starters/examples/src/examples/custom-fx/shield.look.ts +226 -0
  129. package/starters/examples/src/examples/custom-fx/shield.ts +43 -0
  130. package/starters/examples/src/examples/define.ts +86 -0
  131. package/starters/examples/src/examples/destruction/index.ts +570 -0
  132. package/starters/examples/src/examples/destruction/looks.ts +447 -0
  133. package/starters/examples/src/examples/dialogs/index.ts +383 -0
  134. package/starters/examples/src/examples/dialogs/looks.ts +546 -0
  135. package/starters/examples/src/examples/dynamic-map/index.ts +603 -0
  136. package/starters/examples/src/examples/dynamic-map/looks.ts +301 -0
  137. package/starters/examples/src/examples/fx/blood.look.ts +62 -0
  138. package/starters/examples/src/examples/fx/blood.ts +59 -0
  139. package/starters/examples/src/examples/fx/feel.look.ts +86 -0
  140. package/starters/examples/src/examples/fx/feel.ts +57 -0
  141. package/starters/examples/src/examples/fx/fight.ts +28 -0
  142. package/starters/examples/src/examples/fx/floats.look.ts +108 -0
  143. package/starters/examples/src/examples/fx/floats.ts +24 -0
  144. package/starters/examples/src/examples/fx/gallery.look.ts +168 -0
  145. package/starters/examples/src/examples/fx/gallery.ts +23 -0
  146. package/starters/examples/src/examples/fx/index.ts +30 -0
  147. package/starters/examples/src/examples/fx/links.look.ts +83 -0
  148. package/starters/examples/src/examples/fx/links.ts +49 -0
  149. package/starters/examples/src/examples/fx/looks.ts +55 -0
  150. package/starters/examples/src/examples/fx/map.look.ts +93 -0
  151. package/starters/examples/src/examples/fx/map.ts +33 -0
  152. package/starters/examples/src/examples/fx/marks.look.ts +100 -0
  153. package/starters/examples/src/examples/fx/marks.ts +36 -0
  154. package/starters/examples/src/examples/fx/shots.look.ts +92 -0
  155. package/starters/examples/src/examples/fx/shots.ts +71 -0
  156. package/starters/examples/src/examples/fx/spells.look.ts +87 -0
  157. package/starters/examples/src/examples/fx/spells.ts +122 -0
  158. package/starters/examples/src/examples/fx/stage.ts +31 -0
  159. package/starters/examples/src/examples/gui/babylonScreen.ts +167 -0
  160. package/starters/examples/src/examples/gui/babylonWorld.ts +191 -0
  161. package/starters/examples/src/examples/gui/htmlPart.ts +95 -0
  162. package/starters/examples/src/examples/gui/index.ts +143 -0
  163. package/starters/examples/src/examples/gui/keys.ts +91 -0
  164. package/starters/examples/src/examples/gui/layout.ts +42 -0
  165. package/starters/examples/src/examples/gui/looks.ts +270 -0
  166. package/starters/examples/src/examples/gui/minimap.ts +127 -0
  167. package/starters/examples/src/examples/gui/ownInterface.ts +129 -0
  168. package/starters/examples/src/examples/gui/plates.ts +87 -0
  169. package/starters/examples/src/examples/gui/radial.ts +104 -0
  170. package/starters/examples/src/examples/gui/solidPart.ts +107 -0
  171. package/starters/examples/src/examples/looks.ts +45 -0
  172. package/starters/examples/src/examples/mechanics/battle.ts +51 -0
  173. package/starters/examples/src/examples/mechanics/damage.ts +80 -0
  174. package/starters/examples/src/examples/mechanics/flying.ts +93 -0
  175. package/starters/examples/src/examples/mechanics/formations.ts +58 -0
  176. package/starters/examples/src/examples/mechanics/highGround.ts +82 -0
  177. package/starters/examples/src/examples/mechanics/index.ts +44 -0
  178. package/starters/examples/src/examples/mechanics/looks.ts +289 -0
  179. package/starters/examples/src/examples/mechanics/maze.ts +119 -0
  180. package/starters/examples/src/examples/mechanics/orders.ts +68 -0
  181. package/starters/examples/src/examples/mechanics/selection.ts +30 -0
  182. package/starters/examples/src/examples/moba/index.ts +377 -0
  183. package/starters/examples/src/examples/moba/looks.ts +349 -0
  184. package/starters/examples/src/examples/moba/maps.ts +69 -0
  185. package/starters/examples/src/examples/moba/spells.ts +34 -0
  186. package/starters/examples/src/examples/moba/units.ts +196 -0
  187. package/starters/examples/src/examples/nature/camera.ts +15 -0
  188. package/starters/examples/src/examples/nature/grass.ts +64 -0
  189. package/starters/examples/src/examples/nature/index.ts +327 -0
  190. package/starters/examples/src/examples/nature/land.ts +173 -0
  191. package/starters/examples/src/examples/nature/looks.ts +577 -0
  192. package/starters/examples/src/examples/nature/maps.ts +370 -0
  193. package/starters/examples/src/examples/nature/skies.ts +324 -0
  194. package/starters/examples/src/examples/nature/weather.ts +80 -0
  195. package/starters/examples/src/examples/performance/index.ts +263 -0
  196. package/starters/examples/src/examples/performance/looks.ts +372 -0
  197. package/starters/examples/src/examples/performance/meter.ts +158 -0
  198. package/starters/examples/src/examples/post/grades.ts +86 -0
  199. package/starters/examples/src/examples/post/index.ts +202 -0
  200. package/starters/examples/src/examples/post/looks.ts +884 -0
  201. package/starters/examples/src/examples/post/passes.ts +213 -0
  202. package/starters/examples/src/examples/rts/ai.ts +49 -0
  203. package/starters/examples/src/examples/rts/airlift.ts +43 -0
  204. package/starters/examples/src/examples/rts/base.ts +129 -0
  205. package/starters/examples/src/examples/rts/build.ts +65 -0
  206. package/starters/examples/src/examples/rts/camps.ts +36 -0
  207. package/starters/examples/src/examples/rts/carry.ts +103 -0
  208. package/starters/examples/src/examples/rts/creeps.ts +61 -0
  209. package/starters/examples/src/examples/rts/data.ts +406 -0
  210. package/starters/examples/src/examples/rts/ferry.ts +41 -0
  211. package/starters/examples/src/examples/rts/garrison.ts +50 -0
  212. package/starters/examples/src/examples/rts/harvest.ts +29 -0
  213. package/starters/examples/src/examples/rts/hero.ts +67 -0
  214. package/starters/examples/src/examples/rts/index.ts +77 -0
  215. package/starters/examples/src/examples/rts/looks.ts +721 -0
  216. package/starters/examples/src/examples/rts/shop.ts +46 -0
  217. package/starters/examples/src/examples/rts/tech.ts +39 -0
  218. package/starters/examples/src/examples/rts/train.ts +48 -0
  219. package/starters/examples/src/examples/rts/waterside.ts +185 -0
  220. package/starters/examples/src/examples/showcase/index.ts +714 -0
  221. package/starters/examples/src/examples/showcase/looks.ts +238 -0
  222. package/starters/examples/src/game.ts +17 -0
  223. package/starters/examples/src/main.ts +82 -0
  224. package/starters/examples/src/rules.ts +31 -0
  225. package/starters/examples/src/shell/look.ts +79 -0
  226. package/starters/examples/src/shell/registry.ts +7 -0
  227. package/starters/examples/src/shell/scenes.ts +178 -0
  228. package/starters/examples/src/shell/shell.ts +290 -0
  229. package/starters/examples/src/shell/style.ts +202 -0
  230. package/starters/examples/src/view.ts +50 -0
  231. package/starters/melee/README.md +12 -3
  232. package/starters/melee/layers/tests/tests/heroes.test.ts +402 -0
  233. package/starters/melee/layers/tests/tests/rules.test.ts +10 -8
  234. package/starters/melee/src/game.ts +32 -2
  235. package/starters/melee/src/maps/bay.names.ts +2 -2
  236. package/starters/melee/src/maps/bay.vgmap.json +198 -1
  237. package/starters/melee/src/maps.ts +11 -9
  238. package/starters/melee/src/melee/abilities.ts +1 -194
  239. package/starters/melee/src/melee/blight.ts +7 -7
  240. package/starters/melee/src/melee/cellLayers.json +3 -3
  241. package/starters/melee/src/melee/data.json +1 -18
  242. package/starters/melee/src/melee/game.ts +6 -4
  243. package/starters/melee/src/melee/heroes.ts +1025 -0
  244. package/starters/melee/src/melee/index.ts +64 -61
  245. package/starters/melee/src/melee/items.ts +15 -362
  246. package/starters/melee/src/melee/languages/he.json +14 -2
  247. package/starters/melee/src/melee/pings.ts +5 -6
  248. package/starters/melee/src/melee/saves.ts +1 -1
  249. package/starters/melee/src/melee/undead.ts +15 -230
  250. package/starters/melee/src/melee/units.ts +37 -171
  251. package/starters/melee/src/melee/view/attacks.ts +19 -0
  252. package/starters/melee/src/melee/view/heroSpellLooks.ts +39 -8
  253. package/starters/melee/src/melee/view/index.ts +56 -52
  254. package/starters/melee/src/melee/view/looks.ts +86 -63
  255. package/starters/melee/src/melee/view/undeadLooks.ts +70 -31
  256. package/starters/melee/src/melee/view/walls.ts +1 -1
  257. package/starters.mjs +6 -0
  258. package/v12.mjs +14 -15
  259. package/starters/campaign/src/rules.ts +0 -20
  260. package/starters/empty/src/maps.ts +0 -44
  261. package/starters/empty/src/tiles.ts +0 -12
  262. package/starters/melee/src/melee/heroSpells.ts +0 -38
  263. package/starters/melee/src/rules.ts +0 -24
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Recasts, charges, holds and channels: abilities used several times in a row, cast again for a second part, charged
3
+ * by stacks, made ready again, held down to charge (the holds pack), and kept up while aimed, while walking, or while
4
+ * the target stays near
5
+ */
6
+ import type { AbilityDef, BuffDef } from '@v12-engine/engine'
7
+ import { exampleField } from '../define'
8
+ import type { Family } from './family'
9
+ import { caster, lineUp } from './kit'
10
+
11
+ const buffs: BuffDef[] = [
12
+ { id: 'abilitiesSonicMark', name: 'Sonic Wave', description: 'Marked: the wave’s recast rushes here', harmful: true, duration: 3 },
13
+ // four stacks charge Point Blank
14
+ { id: 'abilitiesFocus', name: 'Focus', description: 'At four, Point Blank is charged', maxStacks: 4 },
15
+ { id: 'abilitiesDrawing', name: 'Drawing', description: 'Slowed while the bow is drawn', percent: { moveSpeed: -0.2 } }
16
+ ]
17
+
18
+ const abilities: AbilityDef[] = [
19
+ {
20
+ // three dashes: the cast and two recasts within 10 seconds; the cooldown after the last
21
+ id: 'abilitiesSpiritRush',
22
+ name: 'Spirit Rush',
23
+ description: 'A dash, and two more within {window}: press it three times',
24
+ hotkey: 'Q',
25
+ target: 'point',
26
+ range: 6,
27
+ cooldown: 6,
28
+ recast: { window: 10, count: 2 },
29
+ effects: [{ type: 'dash', distance: 3, speed: 30 }]
30
+ },
31
+ {
32
+ // a recast that does something else: rushes to whoever the first cast marked
33
+ id: 'abilitiesSonicWave',
34
+ name: 'Sonic Wave',
35
+ description: 'A wave that marks the first enemy it hits; cast again within 3 seconds to rush to it',
36
+ hotkey: 'W',
37
+ target: 'direction',
38
+ range: 12,
39
+ cooldown: 5,
40
+ recast: {
41
+ window: 3,
42
+ mark: 'abilitiesSonicMark',
43
+ target: 'none',
44
+ effects: [{ type: 'dash', to: 'target', speed: 30, effects: [{ type: 'damage', amount: 100 }] }]
45
+ },
46
+ effects: [
47
+ {
48
+ type: 'missile',
49
+ speed: 30,
50
+ distance: 12,
51
+ pierce: false,
52
+ effects: [
53
+ { type: 'damage', amount: 50 },
54
+ { type: 'buff', buff: 'abilitiesSonicMark' }
55
+ ]
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ // three uses held, one back every 6 seconds; the button shows how many are left
61
+ id: 'abilitiesRoll',
62
+ name: 'Roll',
63
+ description: 'A short roll: three held, one back every 6 seconds',
64
+ hotkey: 'E',
65
+ target: 'point',
66
+ range: 3,
67
+ cooldown: 0.4,
68
+ charges: { count: 3, refill: 6 },
69
+ effects: [{ type: 'dash', distance: 2.5, speed: 25 }]
70
+ },
71
+ {
72
+ // charged by stacks of Focus, one a spell (its passive part); charged, it hits much harder and spends them
73
+ id: 'abilitiesPointBlank',
74
+ name: 'Point Blank',
75
+ description: 'A cone of shot: 300 when charged by four casts of anything, 100 otherwise',
76
+ hotkey: 'R',
77
+ target: 'direction',
78
+ range: 6,
79
+ cooldown: 0.5,
80
+ charge: 'abilitiesFocus',
81
+ effects: [
82
+ {
83
+ type: 'charged',
84
+ effects: [{ type: 'damage', amount: 300, shape: 'cone', length: 7, angle: 1 }],
85
+ otherwise: [{ type: 'damage', amount: 100, shape: 'cone', length: 7, angle: 1 }]
86
+ }
87
+ ],
88
+ passive: [{ type: 'onCast', effects: [{ type: 'buff', buff: 'abilitiesFocus', stack: true, on: 'caster' }] }]
89
+ },
90
+ {
91
+ // makes abilities ready again, charges and all
92
+ id: 'abilitiesReady',
93
+ name: 'Ready again',
94
+ description: 'Spirit Rush, Sonic Wave and Roll ready at once',
95
+ hotkey: 'T',
96
+ target: 'none',
97
+ effects: [
98
+ { type: 'refresh', ability: 'abilitiesSpiritRush', on: 'caster' },
99
+ { type: 'refresh', ability: 'abilitiesSonicWave', on: 'caster' },
100
+ { type: 'refresh', ability: 'abilitiesRoll', on: 'caster' }
101
+ ]
102
+ },
103
+ {
104
+ // held: the cast starts the draw, letting go fires it, farther and harder the longer it was held
105
+ id: 'abilitiesPiercingArrow',
106
+ name: 'Piercing Arrow',
107
+ description: 'Hold to draw (then Release): farther and half again as hard at full, fired by itself after 4 seconds',
108
+ hotkey: 'D',
109
+ target: 'direction',
110
+ cooldown: 1,
111
+ hold: { max: 1.5, upTo: 4, range: { from: 5, to: 13 }, scale: 1.5, buff: 'abilitiesDrawing' },
112
+ effects: [{ type: 'missile', speed: 40, distance: 20, toPoint: true, radius: 0.7, effects: [{ type: 'damage', amount: 100 }] }]
113
+ },
114
+ {
115
+ // a channel that follows the player's aim (holds pack)
116
+ id: 'abilitiesDisintegrate',
117
+ name: 'Disintegrate',
118
+ description: 'A beam kept up for 3 seconds, following the aim',
119
+ hotkey: 'F',
120
+ target: 'direction',
121
+ range: 10,
122
+ cooldown: 1,
123
+ effects: [],
124
+ channel: { duration: 3, every: 0.25, aimed: true, effects: [{ type: 'damage', amount: 20, shape: 'line', length: 10, width: 0.5 }] }
125
+ },
126
+ {
127
+ // a channel kept up on the march (holds pack)
128
+ id: 'abilitiesWarSong',
129
+ name: 'War Song',
130
+ description: 'Heals allies round the caster every second for 6 seconds, while it walks',
131
+ hotkey: 'G',
132
+ target: 'none',
133
+ cooldown: 1,
134
+ effects: [],
135
+ channel: { duration: 6, every: 1, walks: true, effects: [{ type: 'heal', amount: 40, radius: 5 }] }
136
+ },
137
+ {
138
+ // a channel on a unit, broken as it gets 9 cells away
139
+ id: 'abilitiesLifeDrain',
140
+ name: 'Life Drain',
141
+ description: 'Drains an enemy for 4 seconds, while it stays within 9',
142
+ hotkey: 'Z',
143
+ target: 'unit',
144
+ targets: { enemies: true },
145
+ range: 7,
146
+ cooldown: 1,
147
+ effects: [],
148
+ channel: {
149
+ duration: 4,
150
+ every: 0.5,
151
+ leash: 9,
152
+ effects: [
153
+ { type: 'damage', amount: 30 },
154
+ { type: 'heal', amount: 30, on: 'caster' }
155
+ ]
156
+ }
157
+ }
158
+ ]
159
+
160
+ export const recasts: Family = {
161
+ abilities,
162
+ buffs,
163
+ units: [
164
+ caster(
165
+ 'abilitiesRanger',
166
+ 'Ranger',
167
+ abilities.map((each) => each.id)
168
+ )
169
+ ],
170
+ example: {
171
+ id: 'abilities-recasts',
172
+ category: 'abilities',
173
+ title: 'Recasts, charges, holds, channels',
174
+ summary:
175
+ 'Press Spirit Rush three times, Sonic Wave twice (the second rushes to who it marked), Roll till its charges run out; four casts charge Point Blank. Piercing Arrow draws while held: Release fires it. Three channels: aimed, walking, leashed.',
176
+ tags: ['recast', 'charges', 'cooldown', 'refresh', 'hold', 'charge up', 'channel', 'stacks', 'charged'],
177
+ source: ['examples/abilities/recasts.ts', 'examples/abilities/kit.ts'],
178
+ map: () => exampleField({ name: 'Recasts', players: 2 }),
179
+ start: (world) => lineUp(world, 'abilitiesRanger', 'abilitiesTarget', 3, 'abilitiesWounded')
180
+ }
181
+ }
@@ -0,0 +1,41 @@
1
+ /** How the recasts example looks, and its card: a button for each, and one to let go of the drawn bow */
2
+ import { character, hold, person } from '../common/looks'
3
+ import type { FamilyLooks } from './looks'
4
+ import { castButton, look, readyOn, releaseButton, resetButton } from './lookKit'
5
+ import { recasts } from './recasts'
6
+
7
+ export const recastsLooks: FamilyLooks = {
8
+ units: {
9
+ abilitiesRanger: {
10
+ height: 1.7,
11
+ model: character('ranger', 0.7, { hold: [hold('bow')], animations: { attack: 'Ranged_2H_Shoot' } }),
12
+ shot: { color: [0.85, 0.75, 0.55], size: 0.2 },
13
+ shapes: person(1.7)
14
+ }
15
+ },
16
+ abilities: {
17
+ abilitiesSpiritRush: look([0.9, 0.45, 1], 'burst'),
18
+ abilitiesSonicWave: look([1, 0.75, 0.3], 'missile', { options: { shape: 'hawk' } }),
19
+ abilitiesRoll: look([0.8, 0.8, 0.8]),
20
+ abilitiesPointBlank: look([1, 0.6, 0.2], 'burst'),
21
+ abilitiesReady: look([0.5, 1, 0.6], 'sonar'),
22
+ abilitiesPiercingArrow: look([0.4, 1, 0.5], 'missile', { options: { shape: 'arrow' } }),
23
+ abilitiesDisintegrate: look([1, 0.3, 0.9], 'ring'),
24
+ abilitiesWarSong: look([1, 0.9, 0.5], 'sonar'),
25
+ abilitiesLifeDrain: look([0.7, 0.1, 0.3], 'tether'),
26
+ abilitiesSonicMark: look([1, 0.75, 0.3], undefined, { aura: 'glow', options: { shape: 'ring', at: 'head' } }),
27
+ abilitiesFocus: look([1, 0.6, 0.2], undefined, { counter: { max: 4 } }),
28
+ abilitiesDrawing: look([0.4, 1, 0.5], undefined, { aura: 'glow', options: { shape: 'about' } })
29
+ },
30
+ examples: {
31
+ 'abilities-recasts': {
32
+ ready: (client) => readyOn(client, 'abilitiesRanger'),
33
+ controls: [
34
+ ...recasts.abilities.flatMap((ability) =>
35
+ ability.hold ? [castButton(ability, { label: `${ability.name}: hold` }), releaseButton()] : [castButton(ability)]
36
+ ),
37
+ resetButton('abilities-recasts')
38
+ ]
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Resources: what abilities cost beyond mana. With the resources pack (`resourcesPack`), pools of a unit's own: energy
3
+ * that comes back, fury built by blows, heat that overheats, ammo that reloads. And health as a cost, a cost that grows
4
+ * with each cast, a toggle that pays with health, and mana burned off an enemy (`manaBurnPack`)
5
+ */
6
+ import { type AbilityDef, type BuffDef, poolOf } from '@v12-engine/engine'
7
+ import { exampleField } from '../define'
8
+ import { ENEMY, PLAYER, UNIT } from '../common/units'
9
+ import type { Family } from './family'
10
+ import { caster, put } from './kit'
11
+
12
+ const buffs: BuffDef[] = [
13
+ // heat's thresholds: hot at 50 (stronger), and at 100 overheated: silenced, the pool held, then emptied
14
+ { id: 'abilitiesDangerZone', name: 'Danger Zone', description: 'Hot: 30% more damage', stats: { outgoingDamage: 0.3 } },
15
+ { id: 'abilitiesOverheat', name: 'Overheated', description: 'Can not cast until it cools', harmful: true, duration: 3, silence: true },
16
+ {
17
+ id: 'abilitiesRiftwalkStacks',
18
+ name: 'Riftwalk',
19
+ description: 'Each makes the next Riftwalk cost as much again',
20
+ duration: 8,
21
+ maxStacks: 4,
22
+ stacking: 'refresh'
23
+ },
24
+ // its carrier's abilities cost health, not mana
25
+ { id: 'abilitiesBloodTithe', name: 'Blood Tithe', description: 'Spells cost health, not mana', paysWithHealth: true }
26
+ ]
27
+
28
+ const abilities: AbilityDef[] = [
29
+ {
30
+ id: 'abilitiesFivePoint',
31
+ name: 'Five Point Strike',
32
+ description: 'Costs 60 energy (energy comes back 10 a second)',
33
+ hotkey: 'Q',
34
+ target: 'direction',
35
+ range: 5,
36
+ cost: { energy: 60 },
37
+ effects: [{ type: 'damage', amount: 80, shape: 'cone', length: 5, angle: 1 }]
38
+ },
39
+ {
40
+ // as much as the fury it has, then all of it spent
41
+ id: 'abilitiesBloodlust',
42
+ name: 'Bloodlust',
43
+ description: 'Heals 30, and 3 for each point of fury; spends all the fury (gathered by its blows)',
44
+ hotkey: 'W',
45
+ target: 'none',
46
+ cooldown: 0.5,
47
+ effects: [
48
+ { type: 'heal', on: 'caster', amount: (context) => 30 + 3 * (context.effect ? poolOf(context.effect.caster, 'fury') : 0) },
49
+ { type: 'gain', pool: 'fury', on: 'caster', amount: -100 }
50
+ ]
51
+ },
52
+ {
53
+ // fills heat as it goes off: at 50 it is hot, at 100 it overheats
54
+ id: 'abilitiesFlameBurst',
55
+ name: 'Flame Burst',
56
+ description: 'Burns the nearest enemies and gives 25 heat; hot at 50, overheated (silenced) at 100',
57
+ hotkey: 'E',
58
+ target: 'point',
59
+ range: 8,
60
+ cooldown: 0.3,
61
+ gain: { heat: 25 },
62
+ effects: [{ type: 'damage', amount: 50, radius: 2 }]
63
+ },
64
+ {
65
+ id: 'abilitiesBloodRite',
66
+ name: 'Blood Rite',
67
+ description: 'Costs a tenth of the caster’s health: 150 to an enemy',
68
+ hotkey: 'R',
69
+ target: 'unit',
70
+ targets: { enemies: true },
71
+ range: 8,
72
+ cooldown: 0.5,
73
+ healthCost: 0.1,
74
+ effects: [{ type: 'damage', amount: 150 }]
75
+ },
76
+ {
77
+ // each cast leaves a stack that makes the next cost more
78
+ id: 'abilitiesRiftwalk',
79
+ name: 'Riftwalk',
80
+ description: 'A blink for 50 mana, and 50 more for each Riftwalk of the last 8 seconds',
81
+ hotkey: 'T',
82
+ target: 'point',
83
+ range: 5,
84
+ manaCost: 50,
85
+ costGrowth: { buff: 'abilitiesRiftwalkStacks', per: 1 },
86
+ effects: [
87
+ { type: 'blink', distance: 3 },
88
+ { type: 'buff', buff: 'abilitiesRiftwalkStacks', stack: true, on: 'caster' }
89
+ ]
90
+ },
91
+ {
92
+ id: 'abilitiesManaBurn',
93
+ name: 'Mana Burn',
94
+ description: 'Burns 80 of an enemy’s mana, and deals as much',
95
+ hotkey: 'D',
96
+ target: 'unit',
97
+ targets: { enemies: true },
98
+ range: 8,
99
+ cooldown: 0.5,
100
+ manaCost: 20,
101
+ effects: [{ type: 'manaBurn', amount: 80 }]
102
+ },
103
+ {
104
+ id: 'abilitiesCastTithe',
105
+ name: 'Blood Tithe',
106
+ description: 'Turned on and off: while on, every spell costs health instead of mana',
107
+ hotkey: 'F',
108
+ target: 'none',
109
+ effects: [{ type: 'toggle', buff: 'abilitiesBloodTithe' }]
110
+ }
111
+ ]
112
+
113
+ /** What gathers fury: each blow that lands */
114
+ const battleFury: AbilityDef = {
115
+ id: 'abilitiesBattleFury',
116
+ name: 'Battle Fury',
117
+ description: 'Each blow that lands: 10 fury',
118
+ target: 'passive',
119
+ effects: [{ type: 'onHit', effects: [{ type: 'gain', pool: 'fury', amount: 10, on: 'caster' }] }]
120
+ }
121
+
122
+ export const resources: Family = {
123
+ abilities,
124
+ more: [battleFury],
125
+ buffs,
126
+ units: [
127
+ caster('abilitiesStriker', 'Striker', [...abilities.map((each) => each.id), battleFury.id], {
128
+ // it strikes the dummy beside it: every attack spends a shot of ammo, and gives fury
129
+ stats: { health: 1500, healthRegen: 15, mana: 400, manaRegen: 8, attackDamage: 25, attackSpeed: 1.6, attackRange: 5, moveSpeed: 4.2 },
130
+ attacks: [{ damagePoint: 0.3, acquisitionRange: 6, projectileSpeed: 30 }],
131
+ attackCost: { ammo: 1 },
132
+ pools: {
133
+ energy: { name: 'Energy', color: '#ffe14d', max: 200, regen: 10 },
134
+ fury: { name: 'Fury', color: '#e0402a', max: 100, start: 0, decay: 8, idle: 3 },
135
+ heat: {
136
+ name: 'Heat',
137
+ color: '#ff7a1a',
138
+ max: 100,
139
+ start: 0,
140
+ decay: 12,
141
+ idle: 2,
142
+ thresholds: [
143
+ { at: 50, buff: 'abilitiesDangerZone', kept: true },
144
+ { at: 100, buff: 'abilitiesOverheat', empties: true }
145
+ ]
146
+ },
147
+ ammo: { name: 'Ammo', color: '#c8c8c8', max: 6, reload: 2.5 }
148
+ }
149
+ })
150
+ ],
151
+ example: {
152
+ id: 'abilities-resources',
153
+ category: 'abilities',
154
+ title: 'Energy, fury, heat, ammo',
155
+ summary:
156
+ 'A striker with four pools besides mana: energy that comes back, fury its blows build, heat that overheats, and six shots that reload. It shoots the dummy by itself. Press the buttons to spend them, and watch the bars below.',
157
+ tags: ['resource', 'energy', 'fury', 'rage', 'heat', 'ammo', 'reload', 'health cost', 'mana burn', 'cost'],
158
+ source: ['examples/abilities/resources.ts', 'examples/abilities/kit.ts'],
159
+ map: () => exampleField({ name: 'Resources', players: 2 }),
160
+ start: (world) => {
161
+ put(world, 'abilitiesStriker', PLAYER, { x: 24, z: 18 }, 'caster')
162
+ put(world, UNIT.dummy, ENEMY, { x: 24, z: 22.5 }, 'dummy', Math.PI)
163
+ for (const [i, x] of [21.5, 26.5].entries()) put(world, 'abilitiesTarget', ENEMY, { x, z: 24 }, `enemy${i + 1}`, Math.PI)
164
+ }
165
+ }
166
+ }
@@ -0,0 +1,42 @@
1
+ /** How the resources example looks, and its card: a button for each, and the pools read out */
2
+ import { readout } from '../../shell/look'
3
+ import { character, hold, person } from '../common/looks'
4
+ import type { FamilyLooks } from './looks'
5
+ import { castButton, look, readyOn, resetButton } from './lookKit'
6
+ import { resources } from './resources'
7
+
8
+ export const resourcesLooks: FamilyLooks = {
9
+ units: {
10
+ abilitiesStriker: {
11
+ height: 1.8,
12
+ model: character('rogue', 0.72, { hold: [hold('crossbow_1handed')], animations: { attack: 'Ranged_1H_Shoot' } }),
13
+ shot: { color: [0.9, 0.85, 0.7], size: 0.18 },
14
+ shapes: person(1.8)
15
+ }
16
+ },
17
+ abilities: {
18
+ abilitiesFivePoint: look([1, 0.9, 0.3], 'burst'),
19
+ abilitiesBloodlust: look([0.9, 0.15, 0.1], 'burst'),
20
+ abilitiesFlameBurst: look([1, 0.45, 0.1], 'smash'),
21
+ abilitiesBloodRite: look([0.7, 0.05, 0.1], 'burst'),
22
+ abilitiesRiftwalk: look([0.7, 0.4, 1], 'burst'),
23
+ abilitiesManaBurn: look([0.3, 0.4, 1], 'tether'),
24
+ abilitiesDangerZone: look([1, 0.5, 0.1], undefined, { aura: 'glow', options: { shape: 'rise' } }),
25
+ abilitiesOverheat: look([1, 0.2, 0.05], undefined, { aura: 'glow', options: { shape: 'column', streaks: true } }),
26
+ abilitiesRiftwalkStacks: look([0.7, 0.4, 1], undefined, { counter: { max: 4 } }),
27
+ abilitiesBloodTithe: look([0.8, 0.05, 0.1], undefined, { aura: 'glow', options: { shape: 'fall', solid: true } })
28
+ },
29
+ examples: {
30
+ 'abilities-resources': {
31
+ ready: (client) => readyOn(client, 'abilitiesStriker', { minX: 18, minZ: 14, maxX: 30, maxZ: 27 }),
32
+ controls: [
33
+ ...resources.abilities.map((ability) => castButton(ability, ability.id === 'abilitiesManaBurn' ? { at: 'enemy1' } : {})),
34
+ resetButton('abilities-resources'),
35
+ readout('Health · mana', (client) => {
36
+ const striker = client.session.snapshot().entities.find((each) => each.type === 'abilitiesStriker')
37
+ return striker ? `${Math.round(striker.health)} · ${Math.round(striker.mana ?? 0)}` : '—'
38
+ })
39
+ ]
40
+ }
41
+ }
42
+ }