@v12-engine/create 0.1.0 → 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.
- package/README.md +4 -1
- package/base/_gitignore +5 -0
- package/base/package.json +3 -3
- package/base/src/main.ts +36 -10
- package/base/src/navigation.worker.ts +7 -0
- package/base/vite.config.ts +24 -2
- package/cli.mjs +21 -6
- package/index.mjs +27 -7
- package/layers/desktop/electron/app.mjs +237 -0
- package/layers/desktop/electron/config.mjs +16 -0
- package/layers/desktop/electron/dev.mjs +63 -0
- package/layers/desktop/electron/files.mjs +86 -0
- package/layers/desktop/electron/icons/icon.icns +0 -0
- package/layers/desktop/electron/icons/icon.png +0 -0
- package/layers/desktop/electron/main.mjs +12 -0
- package/layers/desktop/electron/package.mjs +75 -0
- package/layers/desktop/electron/preload.cjs +41 -0
- package/layers/desktop/electron/presentation.m +87 -0
- package/layers/desktop/electron/serve.mjs +76 -0
- package/layers/desktop/electron/tools.mjs +63 -0
- package/layers/desktop/electron/updates.mjs +71 -0
- package/layers/desktop/package.json +13 -0
- package/layers/desktop/src/desktop.ts +175 -0
- package/layers/desktop/src/shell.ts +279 -0
- package/layers/desktop/tests/main.test.ts +189 -0
- package/layers/desktop/tests/shell.test.ts +152 -0
- package/layers/rooms/server.ts +13 -10
- package/layers/server/server.ts +4 -5
- package/layers/source/vite.config.ts +21 -1
- package/package.json +2 -1
- package/starters/campaign/README.md +9 -2
- package/starters/campaign/layers/rooms/server.ts +3 -3
- package/starters/campaign/layers/server/server.ts +3 -5
- package/starters/campaign/layers/tests/tests/rules.test.ts +40 -21
- package/starters/campaign/src/campaign/game.ts +26 -5
- package/starters/campaign/src/campaign/index.ts +104 -68
- package/starters/campaign/src/campaign/kills.ts +1 -1
- package/starters/campaign/src/campaign/missions/homecoming.ts +7 -7
- package/starters/campaign/src/campaign/missions/siege.ts +6 -6
- package/starters/campaign/src/campaign/missions/warlord.ts +13 -14
- package/starters/campaign/src/campaign/scenes.ts +8 -7
- package/starters/campaign/src/campaign/units.ts +59 -20
- package/starters/campaign/src/campaign/view/attacks.ts +19 -0
- package/starters/campaign/src/campaign/view/fire.ts +2 -2
- package/starters/campaign/src/campaign/view/index.ts +54 -43
- package/starters/campaign/src/campaign/waves.ts +18 -17
- package/starters/campaign/src/game.ts +8 -1
- package/starters/campaign/src/main.ts +38 -19
- package/starters/campaign/src/maps/fort.names.ts +2 -2
- package/starters/campaign/src/maps/fort.vgmap.json +102 -2
- package/starters/campaign/src/maps/homestead.names.ts +2 -2
- package/starters/campaign/src/maps/homestead.vgmap.json +85 -1
- package/starters/campaign/src/maps/pass.names.ts +2 -2
- package/starters/campaign/src/maps/pass.vgmap.json +69 -1
- package/starters/campaign/src/waves-panel.ts +2 -1
- package/starters/empty/README.md +18 -10
- package/starters/empty/layers/tests/tests/rules.test.ts +16 -17
- package/starters/empty/src/game.ts +11 -75
- package/starters/empty/src/generate.worker.ts +5 -5
- package/starters/empty/src/rules.ts +83 -25
- package/starters/empty/src/view.ts +82 -0
- package/starters/examples/README.md +83 -0
- package/starters/examples/layers/tests/tests/examples.test.ts +30 -0
- package/starters/examples/package.json +5 -0
- package/starters/examples/src/examples/abilities/areas.ts +165 -0
- package/starters/examples/src/examples/abilities/areasLooks.ts +30 -0
- package/starters/examples/src/examples/abilities/buffs.ts +287 -0
- package/starters/examples/src/examples/abilities/buffsLooks.ts +46 -0
- package/starters/examples/src/examples/abilities/changing.ts +228 -0
- package/starters/examples/src/examples/abilities/changingLooks.ts +61 -0
- package/starters/examples/src/examples/abilities/control.ts +158 -0
- package/starters/examples/src/examples/abilities/controlLooks.ts +78 -0
- package/starters/examples/src/examples/abilities/damage.ts +156 -0
- package/starters/examples/src/examples/abilities/damageLooks.ts +37 -0
- package/starters/examples/src/examples/abilities/family.ts +29 -0
- package/starters/examples/src/examples/abilities/index.ts +32 -0
- package/starters/examples/src/examples/abilities/kit.ts +179 -0
- package/starters/examples/src/examples/abilities/lookKit.ts +71 -0
- package/starters/examples/src/examples/abilities/looks.ts +47 -0
- package/starters/examples/src/examples/abilities/missiles.ts +203 -0
- package/starters/examples/src/examples/abilities/missilesLooks.ts +38 -0
- package/starters/examples/src/examples/abilities/moves.ts +206 -0
- package/starters/examples/src/examples/abilities/movesLooks.ts +52 -0
- package/starters/examples/src/examples/abilities/recasts.ts +181 -0
- package/starters/examples/src/examples/abilities/recastsLooks.ts +41 -0
- package/starters/examples/src/examples/abilities/resources.ts +166 -0
- package/starters/examples/src/examples/abilities/resourcesLooks.ts +42 -0
- package/starters/examples/src/examples/abilities/summons.ts +296 -0
- package/starters/examples/src/examples/abilities/summonsLooks.ts +115 -0
- package/starters/examples/src/examples/abilities/triggers.ts +204 -0
- package/starters/examples/src/examples/abilities/triggersLooks.ts +53 -0
- package/starters/examples/src/examples/abilities/vision.ts +137 -0
- package/starters/examples/src/examples/abilities/visionLooks.ts +50 -0
- package/starters/examples/src/examples/animation/index.ts +235 -0
- package/starters/examples/src/examples/animation/looks.ts +444 -0
- package/starters/examples/src/examples/catalog.ts +52 -0
- package/starters/examples/src/examples/cinematics/index.ts +217 -0
- package/starters/examples/src/examples/cinematics/looks.ts +476 -0
- package/starters/examples/src/examples/cinematics/tour.json +43 -0
- package/starters/examples/src/examples/cinematics/village.ts +88 -0
- package/starters/examples/src/examples/common/looks.ts +65 -0
- package/starters/examples/src/examples/common/units.ts +70 -0
- package/starters/examples/src/examples/construction/index.ts +329 -0
- package/starters/examples/src/examples/construction/looks.ts +275 -0
- package/starters/examples/src/examples/custom-animation/bones.ts +92 -0
- package/starters/examples/src/examples/custom-animation/index.ts +190 -0
- package/starters/examples/src/examples/custom-animation/looks.ts +523 -0
- package/starters/examples/src/examples/custom-animation/runes.ts +82 -0
- package/starters/examples/src/examples/custom-fx/glaive.look.ts +110 -0
- package/starters/examples/src/examples/custom-fx/glaive.ts +40 -0
- package/starters/examples/src/examples/custom-fx/gpu.look.ts +145 -0
- package/starters/examples/src/examples/custom-fx/gpu.ts +22 -0
- package/starters/examples/src/examples/custom-fx/index.ts +25 -0
- package/starters/examples/src/examples/custom-fx/lights.look.ts +144 -0
- package/starters/examples/src/examples/custom-fx/lights.ts +25 -0
- package/starters/examples/src/examples/custom-fx/looks.ts +36 -0
- package/starters/examples/src/examples/custom-fx/meteor.look.ts +133 -0
- package/starters/examples/src/examples/custom-fx/meteor.ts +26 -0
- package/starters/examples/src/examples/custom-fx/parts.look.ts +193 -0
- package/starters/examples/src/examples/custom-fx/parts.ts +21 -0
- package/starters/examples/src/examples/custom-fx/portal.look.ts +193 -0
- package/starters/examples/src/examples/custom-fx/portal.ts +48 -0
- package/starters/examples/src/examples/custom-fx/renderer.look.ts +139 -0
- package/starters/examples/src/examples/custom-fx/renderer.ts +18 -0
- package/starters/examples/src/examples/custom-fx/ribbons.look.ts +151 -0
- package/starters/examples/src/examples/custom-fx/ribbons.ts +22 -0
- package/starters/examples/src/examples/custom-fx/shader.ts +42 -0
- package/starters/examples/src/examples/custom-fx/shield.look.ts +226 -0
- package/starters/examples/src/examples/custom-fx/shield.ts +43 -0
- package/starters/examples/src/examples/define.ts +86 -0
- package/starters/examples/src/examples/destruction/index.ts +570 -0
- package/starters/examples/src/examples/destruction/looks.ts +447 -0
- package/starters/examples/src/examples/dialogs/index.ts +383 -0
- package/starters/examples/src/examples/dialogs/looks.ts +546 -0
- package/starters/examples/src/examples/dynamic-map/index.ts +603 -0
- package/starters/examples/src/examples/dynamic-map/looks.ts +301 -0
- package/starters/examples/src/examples/fx/blood.look.ts +62 -0
- package/starters/examples/src/examples/fx/blood.ts +59 -0
- package/starters/examples/src/examples/fx/feel.look.ts +86 -0
- package/starters/examples/src/examples/fx/feel.ts +57 -0
- package/starters/examples/src/examples/fx/fight.ts +28 -0
- package/starters/examples/src/examples/fx/floats.look.ts +108 -0
- package/starters/examples/src/examples/fx/floats.ts +24 -0
- package/starters/examples/src/examples/fx/gallery.look.ts +168 -0
- package/starters/examples/src/examples/fx/gallery.ts +23 -0
- package/starters/examples/src/examples/fx/index.ts +30 -0
- package/starters/examples/src/examples/fx/links.look.ts +83 -0
- package/starters/examples/src/examples/fx/links.ts +49 -0
- package/starters/examples/src/examples/fx/looks.ts +55 -0
- package/starters/examples/src/examples/fx/map.look.ts +93 -0
- package/starters/examples/src/examples/fx/map.ts +33 -0
- package/starters/examples/src/examples/fx/marks.look.ts +100 -0
- package/starters/examples/src/examples/fx/marks.ts +36 -0
- package/starters/examples/src/examples/fx/shots.look.ts +92 -0
- package/starters/examples/src/examples/fx/shots.ts +71 -0
- package/starters/examples/src/examples/fx/spells.look.ts +87 -0
- package/starters/examples/src/examples/fx/spells.ts +122 -0
- package/starters/examples/src/examples/fx/stage.ts +31 -0
- package/starters/examples/src/examples/gui/babylonScreen.ts +167 -0
- package/starters/examples/src/examples/gui/babylonWorld.ts +191 -0
- package/starters/examples/src/examples/gui/htmlPart.ts +95 -0
- package/starters/examples/src/examples/gui/index.ts +143 -0
- package/starters/examples/src/examples/gui/keys.ts +91 -0
- package/starters/examples/src/examples/gui/layout.ts +42 -0
- package/starters/examples/src/examples/gui/looks.ts +270 -0
- package/starters/examples/src/examples/gui/minimap.ts +127 -0
- package/starters/examples/src/examples/gui/ownInterface.ts +129 -0
- package/starters/examples/src/examples/gui/plates.ts +87 -0
- package/starters/examples/src/examples/gui/radial.ts +104 -0
- package/starters/examples/src/examples/gui/solidPart.ts +107 -0
- package/starters/examples/src/examples/looks.ts +45 -0
- package/starters/examples/src/examples/mechanics/battle.ts +51 -0
- package/starters/examples/src/examples/mechanics/damage.ts +80 -0
- package/starters/examples/src/examples/mechanics/flying.ts +93 -0
- package/starters/examples/src/examples/mechanics/formations.ts +58 -0
- package/starters/examples/src/examples/mechanics/highGround.ts +82 -0
- package/starters/examples/src/examples/mechanics/index.ts +44 -0
- package/starters/examples/src/examples/mechanics/looks.ts +289 -0
- package/starters/examples/src/examples/mechanics/maze.ts +119 -0
- package/starters/examples/src/examples/mechanics/orders.ts +68 -0
- package/starters/examples/src/examples/mechanics/selection.ts +30 -0
- package/starters/examples/src/examples/moba/index.ts +377 -0
- package/starters/examples/src/examples/moba/looks.ts +349 -0
- package/starters/examples/src/examples/moba/maps.ts +69 -0
- package/starters/examples/src/examples/moba/spells.ts +34 -0
- package/starters/examples/src/examples/moba/units.ts +196 -0
- package/starters/examples/src/examples/nature/camera.ts +15 -0
- package/starters/examples/src/examples/nature/grass.ts +64 -0
- package/starters/examples/src/examples/nature/index.ts +327 -0
- package/starters/examples/src/examples/nature/land.ts +173 -0
- package/starters/examples/src/examples/nature/looks.ts +577 -0
- package/starters/examples/src/examples/nature/maps.ts +370 -0
- package/starters/examples/src/examples/nature/skies.ts +324 -0
- package/starters/examples/src/examples/nature/weather.ts +80 -0
- package/starters/examples/src/examples/performance/index.ts +263 -0
- package/starters/examples/src/examples/performance/looks.ts +372 -0
- package/starters/examples/src/examples/performance/meter.ts +158 -0
- package/starters/examples/src/examples/post/grades.ts +86 -0
- package/starters/examples/src/examples/post/index.ts +202 -0
- package/starters/examples/src/examples/post/looks.ts +884 -0
- package/starters/examples/src/examples/post/passes.ts +213 -0
- package/starters/examples/src/examples/rts/ai.ts +49 -0
- package/starters/examples/src/examples/rts/airlift.ts +43 -0
- package/starters/examples/src/examples/rts/base.ts +129 -0
- package/starters/examples/src/examples/rts/build.ts +65 -0
- package/starters/examples/src/examples/rts/camps.ts +36 -0
- package/starters/examples/src/examples/rts/carry.ts +103 -0
- package/starters/examples/src/examples/rts/creeps.ts +61 -0
- package/starters/examples/src/examples/rts/data.ts +406 -0
- package/starters/examples/src/examples/rts/ferry.ts +41 -0
- package/starters/examples/src/examples/rts/garrison.ts +50 -0
- package/starters/examples/src/examples/rts/harvest.ts +29 -0
- package/starters/examples/src/examples/rts/hero.ts +67 -0
- package/starters/examples/src/examples/rts/index.ts +77 -0
- package/starters/examples/src/examples/rts/looks.ts +721 -0
- package/starters/examples/src/examples/rts/shop.ts +46 -0
- package/starters/examples/src/examples/rts/tech.ts +39 -0
- package/starters/examples/src/examples/rts/train.ts +48 -0
- package/starters/examples/src/examples/rts/waterside.ts +185 -0
- package/starters/examples/src/examples/showcase/index.ts +714 -0
- package/starters/examples/src/examples/showcase/looks.ts +238 -0
- package/starters/examples/src/game.ts +17 -0
- package/starters/examples/src/main.ts +82 -0
- package/starters/examples/src/rules.ts +31 -0
- package/starters/examples/src/shell/look.ts +79 -0
- package/starters/examples/src/shell/registry.ts +7 -0
- package/starters/examples/src/shell/scenes.ts +178 -0
- package/starters/examples/src/shell/shell.ts +290 -0
- package/starters/examples/src/shell/style.ts +202 -0
- package/starters/examples/src/view.ts +50 -0
- package/starters/melee/README.md +12 -3
- package/starters/melee/layers/tests/tests/heroes.test.ts +402 -0
- package/starters/melee/layers/tests/tests/rules.test.ts +10 -8
- package/starters/melee/src/game.ts +32 -2
- package/starters/melee/src/maps/bay.names.ts +2 -2
- package/starters/melee/src/maps/bay.vgmap.json +198 -1
- package/starters/melee/src/maps.ts +11 -9
- package/starters/melee/src/melee/abilities.ts +1 -194
- package/starters/melee/src/melee/blight.ts +7 -7
- package/starters/melee/src/melee/cellLayers.json +3 -3
- package/starters/melee/src/melee/data.json +1 -18
- package/starters/melee/src/melee/game.ts +6 -4
- package/starters/melee/src/melee/heroes.ts +1025 -0
- package/starters/melee/src/melee/index.ts +64 -61
- package/starters/melee/src/melee/items.ts +15 -362
- package/starters/melee/src/melee/languages/he.json +14 -2
- package/starters/melee/src/melee/pings.ts +5 -6
- package/starters/melee/src/melee/saves.ts +1 -1
- package/starters/melee/src/melee/undead.ts +15 -230
- package/starters/melee/src/melee/units.ts +37 -171
- package/starters/melee/src/melee/view/attacks.ts +19 -0
- package/starters/melee/src/melee/view/heroSpellLooks.ts +39 -8
- package/starters/melee/src/melee/view/index.ts +56 -52
- package/starters/melee/src/melee/view/looks.ts +86 -63
- package/starters/melee/src/melee/view/undeadLooks.ts +70 -31
- package/starters/melee/src/melee/view/walls.ts +1 -1
- package/starters.mjs +6 -0
- package/v12.mjs +14 -15
- package/starters/campaign/src/rules.ts +0 -20
- package/starters/empty/src/maps.ts +0 -44
- package/starters/empty/src/tiles.ts +0 -12
- package/starters/melee/src/melee/heroSpells.ts +0 -38
- package/starters/melee/src/rules.ts +0 -24
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the abilities examples share on the client's side (the MOBA ones too): a look laid into the game's (units and
|
|
3
|
+
* abilities by id), a button that casts an ability, and the camera and selection an example starts with
|
|
4
|
+
*/
|
|
5
|
+
import type { AbilityDef } from '@v12-engine/engine'
|
|
6
|
+
import type { AbilityLook, GameClientApi, GameView, UnitLook } from '@v12-engine/client'
|
|
7
|
+
import { button, type ExampleControl } from '../../shell/look'
|
|
8
|
+
import { cast, release, reset } from './kit'
|
|
9
|
+
|
|
10
|
+
type Color = [number, number, number]
|
|
11
|
+
|
|
12
|
+
/** An ability's or a buff's look: a colour, a style of the client's (`ring` when not said) and anything else */
|
|
13
|
+
export const look = (color: Color, style?: string, more: Partial<AbilityLook> = {}): AbilityLook => ({ color, ...(style && { style }), ...more })
|
|
14
|
+
|
|
15
|
+
/** The game's look with these units' and abilities' (and buffs') looks laid over its own */
|
|
16
|
+
export function withLooks(view: GameView<any>, units: Record<string, UnitLook>, abilities: Record<string, AbilityLook>): GameView<any> {
|
|
17
|
+
const fx = view.fx ?? {}
|
|
18
|
+
return {
|
|
19
|
+
...view,
|
|
20
|
+
units: { ...view.units, looks: { ...view.units?.looks, ...units } },
|
|
21
|
+
fx: { ...fx, abilities: { ...fx.abilities, looks: { ...fx.abilities?.looks, ...abilities } } }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A button casting an ability, named as it is, its description the hint (or what it is, where it has none): aimed for
|
|
27
|
+
* the player (`castFor`)
|
|
28
|
+
*/
|
|
29
|
+
export const castButton = (
|
|
30
|
+
ability: AbilityDef,
|
|
31
|
+
options: { by?: string; at?: string; point?: { x: number; z: number }; label?: string } = {}
|
|
32
|
+
): ExampleControl =>
|
|
33
|
+
button(
|
|
34
|
+
options.label ?? ability.name,
|
|
35
|
+
(client) =>
|
|
36
|
+
client.session.send(
|
|
37
|
+
cast.make({
|
|
38
|
+
ability: ability.id,
|
|
39
|
+
...(options.by && { by: options.by }),
|
|
40
|
+
...(options.at && { at: options.at }),
|
|
41
|
+
...(options.point && { point: options.point })
|
|
42
|
+
})
|
|
43
|
+
),
|
|
44
|
+
ability.description ?? `Casts ${ability.name}`
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
/** A button letting go of what the caster holds (hold to charge, release to fire) */
|
|
48
|
+
export const releaseButton = (label = 'Release', by?: string): ExampleControl =>
|
|
49
|
+
button(
|
|
50
|
+
label,
|
|
51
|
+
(client) => client.session.send(release.make({ ...(by && { by }) })),
|
|
52
|
+
'Lets go of what is held: it fires as far and as hard as it charged'
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
/** A button laying the example out again as it started */
|
|
56
|
+
export const resetButton = (example: string): ExampleControl =>
|
|
57
|
+
button('Start again', (client) => client.session.send(reset.make({ example })), 'Takes everything away and lays the example out again')
|
|
58
|
+
|
|
59
|
+
/** A box of the ground, in cells */
|
|
60
|
+
export type Box = { minX: number; minZ: number; maxX: number; maxZ: number }
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Makes the example ready: the camera framing `box` (the caster and its targets as `lineUp` lays them, when not said),
|
|
64
|
+
* and the player's unit of `type` selected, so its card shows its abilities
|
|
65
|
+
*/
|
|
66
|
+
export function readyOn(client: GameClientApi, type: string | undefined, box: Box = { minX: 18, minZ: 15, maxX: 30, maxZ: 29 }): void {
|
|
67
|
+
client.camera.frame(box)
|
|
68
|
+
if (!type) return
|
|
69
|
+
const unit = client.session.snapshot().entities.find((each) => each.type === type && each.owner === client.session.playerId)
|
|
70
|
+
if (unit) client.controller.select([unit.id])
|
|
71
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The abilities examples on the client's side: how their casters, targets and abilities look, and each example's card
|
|
3
|
+
* (a button casting each of its family's abilities). Each family's looks are its own file (`./damageLooks.ts`…)
|
|
4
|
+
*/
|
|
5
|
+
import type { CategoryLooks, ExampleLook } from '../../shell/look'
|
|
6
|
+
import type { AbilityLook, GameView, UnitLook } from '@v12-engine/client'
|
|
7
|
+
import { areasLooks } from './areasLooks'
|
|
8
|
+
import { buffsLooks } from './buffsLooks'
|
|
9
|
+
import { changingLooks } from './changingLooks'
|
|
10
|
+
import { controlLooks } from './controlLooks'
|
|
11
|
+
import { damageLooks } from './damageLooks'
|
|
12
|
+
import { withLooks } from './lookKit'
|
|
13
|
+
import { missilesLooks } from './missilesLooks'
|
|
14
|
+
import { movesLooks } from './movesLooks'
|
|
15
|
+
import { recastsLooks } from './recastsLooks'
|
|
16
|
+
import { resourcesLooks } from './resourcesLooks'
|
|
17
|
+
import { summonsLooks } from './summonsLooks'
|
|
18
|
+
import { triggersLooks } from './triggersLooks'
|
|
19
|
+
import { visionLooks } from './visionLooks'
|
|
20
|
+
|
|
21
|
+
/** A family's looks: its units' and abilities', and its example's card */
|
|
22
|
+
export interface FamilyLooks {
|
|
23
|
+
units: Record<string, UnitLook>
|
|
24
|
+
abilities: Record<string, AbilityLook>
|
|
25
|
+
examples: Record<string, ExampleLook>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const all: FamilyLooks[] = [
|
|
29
|
+
damageLooks,
|
|
30
|
+
missilesLooks,
|
|
31
|
+
areasLooks,
|
|
32
|
+
controlLooks,
|
|
33
|
+
buffsLooks,
|
|
34
|
+
movesLooks,
|
|
35
|
+
summonsLooks,
|
|
36
|
+
triggersLooks,
|
|
37
|
+
recastsLooks,
|
|
38
|
+
resourcesLooks,
|
|
39
|
+
visionLooks,
|
|
40
|
+
changingLooks
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
export const category: CategoryLooks = {
|
|
44
|
+
looks: Object.assign({}, ...all.map((each) => each.examples)),
|
|
45
|
+
view: (view: GameView<any>) =>
|
|
46
|
+
withLooks(view, Object.assign({}, ...all.map((each) => each.units)), Object.assign({}, ...all.map((each) => each.abilities)))
|
|
47
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Missiles: the `missile` effect in every shape it takes. A bolt that chases, a wave through a line, one that stops at
|
|
3
|
+
* the first, a rocket to a spot, a grenade over everything, lightning that bounces, a fan, an orb that comes back,
|
|
4
|
+
* wisps that seek, a bolt that splits and a hook that drags its catch in
|
|
5
|
+
*/
|
|
6
|
+
import type { AbilityDef, BuffDef } from '@v12-engine/engine'
|
|
7
|
+
import { exampleField } from '../define'
|
|
8
|
+
import type { Family } from './family'
|
|
9
|
+
import { caster, put, sparring } from './kit'
|
|
10
|
+
import { ENEMY, PLAYER } from '../common/units'
|
|
11
|
+
|
|
12
|
+
const buffs: BuffDef[] = [
|
|
13
|
+
{ id: 'abilitiesBoltStun', name: 'Stunned', harmful: true, duration: 1.5, stun: true },
|
|
14
|
+
{ id: 'abilitiesBound', name: 'Bound', harmful: true, duration: 2, root: true },
|
|
15
|
+
{ id: 'abilitiesHooked', name: 'Hooked', harmful: true, duration: 0.6, stun: true }
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
const abilities: AbilityDef[] = [
|
|
19
|
+
{
|
|
20
|
+
// follows the unit it was cast on, wherever it goes: Storm Bolt
|
|
21
|
+
id: 'abilitiesStormBolt',
|
|
22
|
+
name: 'Storm Bolt',
|
|
23
|
+
description: 'A hammer that chases an enemy: {damage} and a stun',
|
|
24
|
+
hotkey: 'Q',
|
|
25
|
+
target: 'unit',
|
|
26
|
+
targets: { enemies: true },
|
|
27
|
+
range: 10,
|
|
28
|
+
cooldown: 1,
|
|
29
|
+
effects: [
|
|
30
|
+
{
|
|
31
|
+
type: 'missile',
|
|
32
|
+
homing: true,
|
|
33
|
+
speed: 14,
|
|
34
|
+
effects: [
|
|
35
|
+
{ type: 'damage', amount: 100 },
|
|
36
|
+
{ type: 'buff', buff: 'abilitiesBoltStun' }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
// toward a spot, through everything on its way (`pierce` is true unless said)
|
|
43
|
+
id: 'abilitiesShockwave',
|
|
44
|
+
name: 'Shockwave',
|
|
45
|
+
description: 'A wave along a line, through every enemy on it',
|
|
46
|
+
hotkey: 'W',
|
|
47
|
+
target: 'direction',
|
|
48
|
+
range: 12,
|
|
49
|
+
cooldown: 1,
|
|
50
|
+
effects: [{ type: 'missile', speed: 16, distance: 12, radius: 1, effects: [{ type: 'damage', amount: 80 }] }]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
// stops at the first enemy it meets: a skillshot
|
|
54
|
+
id: 'abilitiesLightBinding',
|
|
55
|
+
name: 'Light Binding',
|
|
56
|
+
description: 'A bolt that stops at the first enemy it meets and roots it',
|
|
57
|
+
hotkey: 'E',
|
|
58
|
+
target: 'direction',
|
|
59
|
+
range: 12,
|
|
60
|
+
cooldown: 1,
|
|
61
|
+
effects: [{ type: 'missile', speed: 14, distance: 12, radius: 0.6, pierce: false, effects: [{ type: 'buff', buff: 'abilitiesBound' }] }]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
// to the spot clicked, blowing up there
|
|
65
|
+
id: 'abilitiesRocket',
|
|
66
|
+
name: 'Rocket',
|
|
67
|
+
description: 'Flies to the spot and blows up there',
|
|
68
|
+
hotkey: 'R',
|
|
69
|
+
target: 'point',
|
|
70
|
+
range: 12,
|
|
71
|
+
cooldown: 1,
|
|
72
|
+
effects: [{ type: 'missile', speed: 20, distance: 12, toPoint: true, onEnd: [{ type: 'damage', amount: 120, radius: 2.5 }] }]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
// thrown in an arc, over whatever is between: hits around where it lands
|
|
76
|
+
id: 'abilitiesGrenade',
|
|
77
|
+
name: 'Grenade',
|
|
78
|
+
description: 'Thrown high over everything, it hits around where it lands',
|
|
79
|
+
hotkey: 'T',
|
|
80
|
+
target: 'point',
|
|
81
|
+
range: 12,
|
|
82
|
+
cooldown: 1,
|
|
83
|
+
effects: [{ type: 'missile', toPoint: true, distance: 12, radius: 2, arc: { height: 4, time: 1 }, effects: [{ type: 'damage', amount: 110 }] }]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
// springs on to the nearest it has not hit, a third weaker each time
|
|
87
|
+
id: 'abilitiesChainLightning',
|
|
88
|
+
name: 'Chain Lightning',
|
|
89
|
+
description: 'Lightning that springs from enemy to enemy, weaker each time',
|
|
90
|
+
hotkey: 'D',
|
|
91
|
+
target: 'unit',
|
|
92
|
+
targets: { enemies: true },
|
|
93
|
+
range: 10,
|
|
94
|
+
cooldown: 1,
|
|
95
|
+
effects: [{ type: 'missile', homing: true, speed: 30, bounce: { count: 4, range: 6, falloff: 0.25 }, effects: [{ type: 'damage', amount: 120 }] }]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
// several in a fan: none hits what another already hit
|
|
99
|
+
id: 'abilitiesVolley',
|
|
100
|
+
name: 'Volley',
|
|
101
|
+
description: 'Seven arrows in a fan, each stopping at the first it meets',
|
|
102
|
+
hotkey: 'F',
|
|
103
|
+
target: 'direction',
|
|
104
|
+
range: 10,
|
|
105
|
+
cooldown: 1,
|
|
106
|
+
effects: [{ type: 'missile', count: 7, spread: Math.PI / 2.5, speed: 18, distance: 10, pierce: false, effects: [{ type: 'damage', amount: 45 }] }]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
// out and back, hitting on the way back too
|
|
110
|
+
id: 'abilitiesOrb',
|
|
111
|
+
name: 'Orb of Deception',
|
|
112
|
+
description: 'An orb out and back again, hurting on both ways',
|
|
113
|
+
hotkey: 'G',
|
|
114
|
+
target: 'direction',
|
|
115
|
+
range: 10,
|
|
116
|
+
cooldown: 1,
|
|
117
|
+
effects: [{ type: 'missile', speed: 15, distance: 10, radius: 0.9, returns: true, hitsOnReturn: true, effects: [{ type: 'damage', amount: 50 }] }]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
// each finds its own: they fly round and after the nearest enemy within 7
|
|
121
|
+
id: 'abilitiesFoxFire',
|
|
122
|
+
name: 'Fox-Fire',
|
|
123
|
+
description: 'Three wisps that find the nearest enemies by themselves',
|
|
124
|
+
hotkey: 'Z',
|
|
125
|
+
target: 'none',
|
|
126
|
+
cooldown: 1,
|
|
127
|
+
effects: [{ type: 'missile', count: 3, spread: 2 * Math.PI, speed: 14, distance: 9, seek: 7, effects: [{ type: 'damage', amount: 50 }] }]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
// where it ends it splits in two, each going on aside
|
|
131
|
+
id: 'abilitiesFission',
|
|
132
|
+
name: 'Plasma Fission',
|
|
133
|
+
description: 'A bolt that splits in two where it stops, each half flying on aside',
|
|
134
|
+
hotkey: 'X',
|
|
135
|
+
target: 'direction',
|
|
136
|
+
range: 8,
|
|
137
|
+
cooldown: 1,
|
|
138
|
+
effects: [
|
|
139
|
+
{
|
|
140
|
+
type: 'missile',
|
|
141
|
+
speed: 14,
|
|
142
|
+
distance: 7,
|
|
143
|
+
pierce: false,
|
|
144
|
+
effects: [{ type: 'damage', amount: 60 }],
|
|
145
|
+
split: [
|
|
146
|
+
{ type: 'missile', count: 2, spread: Math.PI / 1.2, speed: 14, distance: 7, look: 'halves', effects: [{ type: 'damage', amount: 60 }] }
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
// a chain written flat: the missile, then a pull on what it hits, then damage as it arrives
|
|
153
|
+
id: 'abilitiesHook',
|
|
154
|
+
name: 'Rocket Grab',
|
|
155
|
+
description: 'A hook to the first enemy it meets, dragged back and hurt as it arrives',
|
|
156
|
+
hotkey: 'C',
|
|
157
|
+
target: 'direction',
|
|
158
|
+
range: 12,
|
|
159
|
+
cooldown: 1,
|
|
160
|
+
effects: [
|
|
161
|
+
{ type: 'missile', speed: 28, distance: 12, radius: 0.7, pierce: false, returns: true },
|
|
162
|
+
{ type: 'pull', seconds: 0.6, when: 'hit' },
|
|
163
|
+
{ type: 'damage', amount: 90, when: 'arrived' },
|
|
164
|
+
{ type: 'buff', buff: 'abilitiesHooked', when: 'hit' }
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
export const missiles: Family = {
|
|
170
|
+
abilities,
|
|
171
|
+
buffs,
|
|
172
|
+
units: [
|
|
173
|
+
caster(
|
|
174
|
+
'abilitiesArcher',
|
|
175
|
+
'Missile mage',
|
|
176
|
+
abilities.map((each) => each.id)
|
|
177
|
+
),
|
|
178
|
+
sparring('abilitiesStrafer', 'Sparring footman')
|
|
179
|
+
],
|
|
180
|
+
example: {
|
|
181
|
+
id: 'abilities-missiles',
|
|
182
|
+
category: 'abilities',
|
|
183
|
+
title: 'Missiles',
|
|
184
|
+
summary:
|
|
185
|
+
'Every kind of missile: homing, through a line, stopped by the first, to a spot, thrown, bouncing, in a fan, out and back, seeking, splitting and a hook. Press a button to fire it at the footmen across the field.',
|
|
186
|
+
tags: ['missile', 'projectile', 'skillshot', 'homing', 'bounce', 'chain', 'hook', 'arc', 'boomerang', 'split', 'seek'],
|
|
187
|
+
source: ['examples/abilities/missiles.ts', 'examples/abilities/kit.ts'],
|
|
188
|
+
map: () => exampleField({ name: 'Missiles', players: 2 }),
|
|
189
|
+
start: (world) => {
|
|
190
|
+
put(world, 'abilitiesArcher', PLAYER, { x: 24, z: 15 }, 'caster')
|
|
191
|
+
// a loose crowd across the field: one in front, others behind and aside, for lines, fans and bounces to find
|
|
192
|
+
const spots = [
|
|
193
|
+
[24, 23],
|
|
194
|
+
[22, 25.5],
|
|
195
|
+
[26.5, 25],
|
|
196
|
+
[24, 27.5],
|
|
197
|
+
[20, 28],
|
|
198
|
+
[28.5, 28.5]
|
|
199
|
+
]
|
|
200
|
+
spots.forEach(([x, z], i) => put(world, 'abilitiesStrafer', ENEMY, { x, z }, `enemy${i + 1}`, Math.PI))
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** How the missiles example looks, and its card: a button for each missile (`./missiles.ts`) */
|
|
2
|
+
import { sharedLooks } from '../common/looks'
|
|
3
|
+
import type { FamilyLooks } from './looks'
|
|
4
|
+
import { castButton, look, readyOn, resetButton } from './lookKit'
|
|
5
|
+
import { missiles } from './missiles'
|
|
6
|
+
|
|
7
|
+
/** A missile's look: the missile style, flying as `shape` (an arrow, a rock, a bird of light or a ball of fire) */
|
|
8
|
+
const flying = (color: [number, number, number], shape: 'arrow' | 'rock' | 'hawk' | 'ball', more = {}) =>
|
|
9
|
+
look(color, 'missile', { options: { shape }, ...more })
|
|
10
|
+
|
|
11
|
+
export const missilesLooks: FamilyLooks = {
|
|
12
|
+
units: {
|
|
13
|
+
abilitiesArcher: sharedLooks.mage,
|
|
14
|
+
abilitiesStrafer: sharedLooks.footman
|
|
15
|
+
},
|
|
16
|
+
abilities: {
|
|
17
|
+
abilitiesStormBolt: flying([0.6, 0.8, 1], 'rock'),
|
|
18
|
+
abilitiesShockwave: flying([1, 0.75, 0.35], 'hawk'),
|
|
19
|
+
abilitiesLightBinding: flying([1, 0.95, 0.6], 'hawk'),
|
|
20
|
+
abilitiesRocket: flying([1, 0.45, 0.15], 'ball'),
|
|
21
|
+
abilitiesGrenade: flying([0.7, 0.6, 0.5], 'rock'),
|
|
22
|
+
abilitiesChainLightning: flying([0.55, 0.75, 1], 'hawk', { link: 'chain' }),
|
|
23
|
+
abilitiesVolley: flying([0.85, 0.75, 0.55], 'arrow'),
|
|
24
|
+
abilitiesOrb: flying([0.9, 0.45, 1], 'ball'),
|
|
25
|
+
abilitiesFoxFire: flying([0.4, 0.7, 1], 'hawk'),
|
|
26
|
+
// the halves a colour of their own (`look: 'halves'` on the split's missile)
|
|
27
|
+
abilitiesFission: flying([0.6, 0.35, 1], 'ball', { effects: { halves: { color: [1, 0.6, 0.15] } } }),
|
|
28
|
+
abilitiesHook: flying([0.75, 0.75, 0.8], 'rock'),
|
|
29
|
+
abilitiesBoltStun: look([1, 1, 0.6], undefined, { aura: 'glow', options: { shape: 'ring', at: 'head' } }),
|
|
30
|
+
abilitiesBound: look([1, 0.95, 0.6], undefined, { aura: 'glow', options: { shape: 'column' } })
|
|
31
|
+
},
|
|
32
|
+
examples: {
|
|
33
|
+
'abilities-missiles': {
|
|
34
|
+
ready: (client) => readyOn(client, 'abilitiesArcher', { minX: 16, minZ: 13, maxX: 32, maxZ: 30 }),
|
|
35
|
+
controls: [...missiles.abilities.map((ability) => castButton(ability)), resetButton('abilities-missiles')]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moves: abilities that move units. The caster leaping, blinking, rushing to an enemy and through it, teleporting;
|
|
3
|
+
* enemies thrown back (into a wall, to be stunned), thrown into each other, thrown over, dragged in; two units trading
|
|
4
|
+
* places; the caster riding an ally. Most need the moves pack (`movesPack`, added in `./kit.ts`)
|
|
5
|
+
*/
|
|
6
|
+
import type { AbilityDef, BuffDef } from '@v12-engine/engine'
|
|
7
|
+
import { exampleField } from '../define'
|
|
8
|
+
import { ENEMY, PLAYER } from '../common/units'
|
|
9
|
+
import type { Family } from './family'
|
|
10
|
+
import { caster, put } from './kit'
|
|
11
|
+
|
|
12
|
+
const buffs: BuffDef[] = [{ id: 'abilitiesWallStun', name: 'Slammed', harmful: true, duration: 1.5, stun: true }]
|
|
13
|
+
|
|
14
|
+
const abilities: AbilityDef[] = [
|
|
15
|
+
{
|
|
16
|
+
// a dash with a leap flies over what is between, and hurts round where it lands
|
|
17
|
+
id: 'abilitiesLeap',
|
|
18
|
+
name: 'Leap',
|
|
19
|
+
description: 'Jumps toward the spot and strikes where it lands',
|
|
20
|
+
hotkey: 'Q',
|
|
21
|
+
target: 'point',
|
|
22
|
+
range: 7,
|
|
23
|
+
cooldown: 0.5,
|
|
24
|
+
effects: [{ type: 'dash', distance: 7, speed: 16, leap: 2, effects: [{ type: 'damage', amount: 80, radius: 2 }] }]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
// at once, up to its distance
|
|
28
|
+
id: 'abilitiesBlink',
|
|
29
|
+
name: 'Blink',
|
|
30
|
+
description: 'At once to the spot, up to 8 cells',
|
|
31
|
+
hotkey: 'W',
|
|
32
|
+
target: 'point',
|
|
33
|
+
range: 8,
|
|
34
|
+
cooldown: 0.5,
|
|
35
|
+
effects: [{ type: 'blink', distance: 8 }]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
// home: where the side's home is (here its start)
|
|
39
|
+
id: 'abilitiesRecall',
|
|
40
|
+
name: 'Teleport home',
|
|
41
|
+
description: 'Back to where it started, however far',
|
|
42
|
+
hotkey: 'E',
|
|
43
|
+
target: 'none',
|
|
44
|
+
cooldown: 0.5,
|
|
45
|
+
castTime: 0.6,
|
|
46
|
+
effects: [{ type: 'teleport', to: 'home' }]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
// rushes to the unit, to its edge, following it
|
|
50
|
+
id: 'abilitiesCharge',
|
|
51
|
+
name: 'Heroic Charge',
|
|
52
|
+
description: 'Rushes to an enemy and strikes it',
|
|
53
|
+
hotkey: 'R',
|
|
54
|
+
target: 'unit',
|
|
55
|
+
targets: { enemies: true },
|
|
56
|
+
range: 10,
|
|
57
|
+
cooldown: 0.5,
|
|
58
|
+
effects: [{ type: 'dash', to: 'target', speed: 22, effects: [{ type: 'damage', amount: 60 }] }]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
// through the unit, 3 cells past its middle
|
|
62
|
+
id: 'abilitiesSweep',
|
|
63
|
+
name: 'Sweeping Blade',
|
|
64
|
+
description: 'Dashes through an enemy, cutting it',
|
|
65
|
+
hotkey: 'T',
|
|
66
|
+
target: 'unit',
|
|
67
|
+
targets: { enemies: true },
|
|
68
|
+
range: 8,
|
|
69
|
+
cooldown: 0.5,
|
|
70
|
+
effects: [{ type: 'dash', to: 'target', through: 3, speed: 20, effects: [{ type: 'damage', amount: 50 }] }]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
// thrown back from the caster; a wall on the way stuns it
|
|
74
|
+
id: 'abilitiesCondemn',
|
|
75
|
+
name: 'Condemn',
|
|
76
|
+
description: 'Throws an enemy back: into the pillar behind it, it is stunned',
|
|
77
|
+
hotkey: 'D',
|
|
78
|
+
target: 'unit',
|
|
79
|
+
targets: { enemies: true },
|
|
80
|
+
range: 10,
|
|
81
|
+
cooldown: 0.5,
|
|
82
|
+
effects: [{ type: 'knockback', distance: 5, speed: 20, onWall: [{ type: 'buff', buff: 'abilitiesWallStun' }] }]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
// what it is thrown into is hit and thrown aside too
|
|
86
|
+
id: 'abilitiesDragonsRage',
|
|
87
|
+
name: 'Dragon’s Rage',
|
|
88
|
+
description: 'Kicks an enemy into the others: each it meets is hurt and knocked up',
|
|
89
|
+
hotkey: 'F',
|
|
90
|
+
target: 'unit',
|
|
91
|
+
targets: { enemies: true },
|
|
92
|
+
range: 10,
|
|
93
|
+
cooldown: 0.5,
|
|
94
|
+
effects: [
|
|
95
|
+
{
|
|
96
|
+
type: 'knockback',
|
|
97
|
+
distance: 8,
|
|
98
|
+
speed: 16,
|
|
99
|
+
collide: [
|
|
100
|
+
{ type: 'damage', amount: 70 },
|
|
101
|
+
{ type: 'knockback', distance: 1.5, leap: 2, speed: 4 }
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
// every enemy round the caster, back 4 cells
|
|
108
|
+
id: 'abilitiesShove',
|
|
109
|
+
name: 'Shove',
|
|
110
|
+
description: 'Throws every enemy within 4 back, through the air',
|
|
111
|
+
hotkey: 'G',
|
|
112
|
+
target: 'none',
|
|
113
|
+
cooldown: 0.5,
|
|
114
|
+
effects: [{ type: 'knockback', distance: 4, speed: 12, radius: 4, leap: 1 }]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
// over the caster, to land on its far side
|
|
118
|
+
id: 'abilitiesFlay',
|
|
119
|
+
name: 'Flay',
|
|
120
|
+
description: 'Throws the enemies near over the caster, to land behind it',
|
|
121
|
+
hotkey: 'Z',
|
|
122
|
+
target: 'none',
|
|
123
|
+
cooldown: 0.5,
|
|
124
|
+
effects: [{ type: 'knockback', direction: 'over', distance: 2.5, leap: 2, speed: 10, radius: 4 }]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
// dragged in to where it landed: a vacuum
|
|
128
|
+
id: 'abilitiesVacuum',
|
|
129
|
+
name: 'Vacuum',
|
|
130
|
+
description: 'Drags every enemy within 4 of the spot into its middle',
|
|
131
|
+
hotkey: 'X',
|
|
132
|
+
target: 'point',
|
|
133
|
+
range: 10,
|
|
134
|
+
cooldown: 0.5,
|
|
135
|
+
effects: [{ type: 'pull', seconds: 0.5, radius: 4, toPoint: true, effects: [{ type: 'damage', amount: 40 }] }]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
// the caster and the target trade places
|
|
139
|
+
id: 'abilitiesSwap',
|
|
140
|
+
name: 'Nether Swap',
|
|
141
|
+
description: 'The caster and an enemy trade places',
|
|
142
|
+
hotkey: 'C',
|
|
143
|
+
target: 'unit',
|
|
144
|
+
targets: { allies: true, enemies: true },
|
|
145
|
+
range: 12,
|
|
146
|
+
cooldown: 0.5,
|
|
147
|
+
effects: [{ type: 'swap' }]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
// out of the world, riding the ally until it ends; healing round as it lets go
|
|
151
|
+
id: 'abilitiesAttach',
|
|
152
|
+
name: 'Ride an ally',
|
|
153
|
+
description: 'Rides the ally for 6 seconds, then heals round it as it lets go',
|
|
154
|
+
hotkey: 'V',
|
|
155
|
+
target: 'unit',
|
|
156
|
+
targets: { allies: true },
|
|
157
|
+
range: 10,
|
|
158
|
+
cooldown: 0.5,
|
|
159
|
+
effects: [{ type: 'attach', duration: 6, onEnd: [{ type: 'heal', amount: 100, radius: 3 }] }]
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
export const moves: Family = {
|
|
164
|
+
abilities,
|
|
165
|
+
buffs,
|
|
166
|
+
units: [
|
|
167
|
+
caster(
|
|
168
|
+
'abilitiesMover',
|
|
169
|
+
'Duelist',
|
|
170
|
+
abilities.map((each) => each.id)
|
|
171
|
+
),
|
|
172
|
+
// a wall to throw things into: a pillar that blocks the ground
|
|
173
|
+
{
|
|
174
|
+
id: 'abilitiesPillar',
|
|
175
|
+
name: 'Pillar',
|
|
176
|
+
kind: 'building',
|
|
177
|
+
radius: 1,
|
|
178
|
+
footprint: { w: 2, d: 2 },
|
|
179
|
+
stats: { health: 5000, armor: 50 },
|
|
180
|
+
invulnerable: true,
|
|
181
|
+
sight: 2
|
|
182
|
+
}
|
|
183
|
+
],
|
|
184
|
+
example: {
|
|
185
|
+
id: 'abilities-moves',
|
|
186
|
+
category: 'abilities',
|
|
187
|
+
title: 'Dash, blink, knockback, pull',
|
|
188
|
+
summary:
|
|
189
|
+
'Leap, blink, teleport home, rush to an enemy and through it; throw enemies back into a pillar, into each other, over you; drag them in; trade places; ride an ally. Press a button to see each.',
|
|
190
|
+
tags: ['dash', 'blink', 'leap', 'teleport', 'knockback', 'pull', 'swap', 'attach', 'collide', 'wall stun', 'movement'],
|
|
191
|
+
source: ['examples/abilities/moves.ts', 'examples/abilities/kit.ts'],
|
|
192
|
+
map: () => exampleField({ name: 'Moves', players: 2 }),
|
|
193
|
+
start: (world) => {
|
|
194
|
+
put(world, 'abilitiesMover', PLAYER, { x: 24, z: 16 }, 'caster')
|
|
195
|
+
put(world, 'abilitiesWounded', PLAYER, { x: 20, z: 16 }, 'ally')
|
|
196
|
+
put(world, 'abilitiesTarget', ENEMY, { x: 24, z: 22 }, 'enemy1', Math.PI)
|
|
197
|
+
put(world, 'abilitiesTarget', ENEMY, { x: 22.5, z: 25 }, 'enemy2', Math.PI)
|
|
198
|
+
put(world, 'abilitiesTarget', ENEMY, { x: 25.5, z: 25.5 }, 'enemy3', Math.PI)
|
|
199
|
+
put(world, 'abilitiesTarget', ENEMY, { x: 24, z: 28 }, 'enemy4', Math.PI)
|
|
200
|
+
// pillars behind them, to be thrown into
|
|
201
|
+
put(world, 'abilitiesPillar', world.neutral, { x: 24, z: 31 })
|
|
202
|
+
put(world, 'abilitiesPillar', world.neutral, { x: 20, z: 30 })
|
|
203
|
+
put(world, 'abilitiesPillar', world.neutral, { x: 28, z: 30 })
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** How the moves example looks, and its card: a button for each move (`./moves.ts`) */
|
|
2
|
+
import { character, hold, person } from '../common/looks'
|
|
3
|
+
import type { FamilyLooks } from './looks'
|
|
4
|
+
import { castButton, look, readyOn, resetButton } from './lookKit'
|
|
5
|
+
import { moves } from './moves'
|
|
6
|
+
|
|
7
|
+
/** Where each is aimed, where the nearest enemy is not it */
|
|
8
|
+
const aims: Record<string, { at?: string; point?: { x: number; z: number } }> = {
|
|
9
|
+
abilitiesLeap: { point: { x: 21, z: 22 } },
|
|
10
|
+
abilitiesBlink: { point: { x: 28, z: 20 } },
|
|
11
|
+
abilitiesSweep: { at: 'enemy2' },
|
|
12
|
+
abilitiesCondemn: { at: 'enemy4' },
|
|
13
|
+
abilitiesVacuum: { point: { x: 24, z: 25 } },
|
|
14
|
+
abilitiesSwap: { at: 'enemy4' },
|
|
15
|
+
abilitiesAttach: { at: 'ally' }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const movesLooks: FamilyLooks = {
|
|
19
|
+
units: {
|
|
20
|
+
abilitiesMover: { height: 1.8, model: character('rogue', 0.72, { hold: [hold('dagger'), hold('dagger', 'l')] }), shapes: person(1.8) },
|
|
21
|
+
// the dungeon kit's pillar; its parts show while it loads
|
|
22
|
+
abilitiesPillar: {
|
|
23
|
+
height: 3.6,
|
|
24
|
+
model: { src: 'dungeon-kit/pillar.glb', scale: 0.9 },
|
|
25
|
+
shapes: [
|
|
26
|
+
{ shape: 'cylinder', size: [1.6, 3, 1.6], offset: [0, 1.5, 0], color: [0.55, 0.52, 0.48] },
|
|
27
|
+
{ shape: 'box', size: [2, 0.4, 2], offset: [0, 3.1, 0], color: [0.45, 0.42, 0.4] }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
abilities: {
|
|
32
|
+
abilitiesLeap: look([1, 0.7, 0.3], 'slam'),
|
|
33
|
+
abilitiesBlink: look([0.6, 0.4, 1], 'burst'),
|
|
34
|
+
abilitiesRecall: look([0.5, 0.8, 1], 'tornado'),
|
|
35
|
+
abilitiesCharge: look([1, 0.6, 0.2], 'slam'),
|
|
36
|
+
abilitiesSweep: look([0.8, 0.9, 1], 'burst'),
|
|
37
|
+
abilitiesCondemn: look([0.85, 0.75, 1], 'burst'),
|
|
38
|
+
abilitiesDragonsRage: look([1, 0.5, 0.1], 'smash'),
|
|
39
|
+
abilitiesShove: look([0.9, 0.85, 0.6], 'slam'),
|
|
40
|
+
abilitiesFlay: look([0.4, 1, 0.6], 'slam'),
|
|
41
|
+
abilitiesVacuum: look([0.6, 0.4, 1], 'tornado'),
|
|
42
|
+
abilitiesSwap: look([0.7, 0.3, 1], 'tether'),
|
|
43
|
+
abilitiesAttach: look([0.5, 1, 0.8], 'tether'),
|
|
44
|
+
abilitiesWallStun: look([1, 1, 0.6], undefined, { aura: 'glow', options: { shape: 'ring', at: 'head' } })
|
|
45
|
+
},
|
|
46
|
+
examples: {
|
|
47
|
+
'abilities-moves': {
|
|
48
|
+
ready: (client) => readyOn(client, 'abilitiesMover', { minX: 16, minZ: 13, maxX: 32, maxZ: 32 }),
|
|
49
|
+
controls: [...moves.abilities.map((ability) => castButton(ability, aims[ability.id])), resetButton('abilities-moves')]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|