Skip to content

Commit d8829fd

Browse files
committed
Add Dash & Change trail particle system
Added camera preset to set player position as audio listener, this improves the volume and clarity of all sounds. Changed light trails to use same persistent particles as light spin trail, in doing so removed redundant light_trail particle and renamed light_spin_trail particle to light_trail particle Removed unused volumes in sound_definitions Made the last particle positions reset when starting flying and made a new system to store those values per player reflecting the removal of old light trail system Made new light trail particles shrink so the light trails "fades away", this was possible thanks to new light trails system Added dash: - Added dash particles - Added dash sound
1 parent b2a9404 commit d8829fd

File tree

7 files changed

+116
-111
lines changed

7 files changed

+116
-111
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"format_version": "1.21.0",
3+
"minecraft:camera_preset": {
4+
"identifier": "whynot:follow_orbit",
5+
"inherit_from": "minecraft:follow_orbit",
6+
"view_offset": [0.0, 0.0],
7+
"listener": "player",
8+
"radius": 12
9+
}
10+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"format_version": "1.10.0",
3+
"particle_effect": {
4+
"description": {
5+
"identifier": "whynot:dash",
6+
"basic_render_parameters": {
7+
"material": "particles_opaque",
8+
"texture": "textures/white"
9+
}
10+
},
11+
"components": {
12+
"minecraft:emitter_initialization": {
13+
"creation_expression": "variable.direction;"
14+
},
15+
"minecraft:emitter_rate_instant": {
16+
"num_particles": 15
17+
},
18+
"minecraft:emitter_lifetime_once": {
19+
"active_time": 0.08
20+
},
21+
"minecraft:emitter_shape_box": {
22+
"half_dimensions": [0.6, 1.8, 0.6],
23+
"direction": ["variable.direction.x", "variable.direction.y", "variable.direction.z"]
24+
},
25+
"minecraft:particle_lifetime_expression": {
26+
"max_lifetime": 0.2
27+
},
28+
"minecraft:particle_initial_speed": "math.random(20, 25)",
29+
"minecraft:particle_motion_dynamic": {},
30+
"minecraft:particle_appearance_billboard": {
31+
"size": ["math.random(0.5,0.75) / 1.5", "0.025 * (1 - variable.particle_age / variable.particle_lifetime)"],
32+
"facing_camera_mode": "lookat_direction",
33+
"direction": {
34+
"mode": "custom",
35+
"custom_direction": ["variable.direction.x", "variable.direction.y", "variable.direction.z"]
36+
},
37+
"uv": {
38+
"texture_width": 1,
39+
"texture_height": 1,
40+
"uv": [0, 0],
41+
"uv_size": [1, 1]
42+
}
43+
}
44+
}
45+
}
46+
}

resource_packs/whynot/particles/light_spin_trail.particle.json

Lines changed: 0 additions & 43 deletions
This file was deleted.

resource_packs/whynot/particles/light_trail.particle.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@
1616
"num_particles": 1
1717
},
1818
"minecraft:emitter_lifetime_once": {
19-
"active_time": 0.08
19+
"active_time": 0.5
2020
},
2121
"minecraft:emitter_shape_point": {},
2222
"minecraft:particle_lifetime_expression": {
23-
"max_lifetime": 0.05
23+
"max_lifetime": 0.5
2424
},
2525
"minecraft:particle_initial_speed": 0,
2626
"minecraft:particle_motion_dynamic": {},
2727
"minecraft:particle_appearance_billboard": {
28-
"size": ["variable.length", "variable.thickness"],
28+
"size": ["variable.length", "variable.thickness * (1.0 - variable.particle_age / variable.particle_lifetime)"],
2929
"facing_camera_mode": "lookat_direction",
3030
"direction": {
3131
"mode": "custom",
22.7 KB
Binary file not shown.

resource_packs/whynot/sounds/sound_definitions.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@
1111
},
1212
"light_beam_start": {
1313
"category": "player",
14-
"sounds": ["sounds/light/light_beam_start"],
15-
"volume": 0.01
14+
"sounds": ["sounds/light/light_beam_start"]
1615
},
1716
"light_beam_loop": {
1817
"category": "player",
19-
"volume": 0.01,
2018
"sounds": ["sounds/light/light_beam_loop"]
2119
},
2220
"moon_jump": {
2321
"category": "player",
24-
"volume": 0.01,
2522
"sounds": ["sounds/light/moon_jump"]
23+
},
24+
"dash": {
25+
"category": "player",
26+
"sounds": ["sounds/light/dash"]
2627
}
2728
}
2829
}

scripts/addons/lightFruit/lightFruit.ts

Lines changed: 52 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { MinecraftEffectTypes } from "@minecraft/vanilla-data";
33
import { directionVector, drawLine, entityCenter, entityGetSlot, entityHasSlotTag, spawnLine } from "../../utility";
44
import { V3 } from "../../math/vectorUtils";
55
import { deg2Rad, PI, remap, TAU } from "../../math/general";
6+
import { VECTOR2_ZERO, VECTOR3_BACK, VECTOR3_ZERO } from "@minecraft/math";
67

78
let light: ItemStack
89
const maxAirJumps: number = 10
@@ -14,12 +15,15 @@ const flyTurnThreshold = Math.cos(deg2Rad(60));
1415
enum States {
1516
NORMAL,
1617
FLYING,
17-
MOON_JUMP
18+
MOON_JUMP,
19+
DASH
1820
}
19-
type Line = {
20-
start: Vector3,
21-
end: Vector3,
22-
length: number
21+
22+
class LightVisual {
23+
lastSpin1: Vector3 | undefined
24+
lastSpin2: Vector3 | undefined
25+
lastTrail: Vector3 | undefined
26+
angle: number = 0.0
2327
}
2428
const flyTurnCooldownTime: number = 10
2529
const flyTurnCooldown: Map<string, number> = new Map()
@@ -28,7 +32,7 @@ const airTime: Map<string, number> = new Map()
2832
const ignoreFall: Map<string, boolean> = new Map()
2933
const airJumps: Map<string, number> = new Map()
3034
const flyingAngles: Map<string, Vector3> = new Map()
31-
const trails: Map<string, Line[]> = new Map()
35+
const visuals: Map<string, LightVisual> = new Map()
3236

3337
// Defining setters for ability cooldowns
3438
Object.defineProperties(Player.prototype, {
@@ -76,13 +80,6 @@ export function startup(ev: StartupEvent) {
7680
})
7781
}
7882

79-
function addTrail(player: Player) {
80-
if (!trails.has(player.id)) trails.set(player.id, [])
81-
const trail = trails.get(player.id) as Line[]
82-
const cent = entityCenter(player) ?? player.location
83-
trail.push({start: cent, end: cent, length: 0})
84-
}
85-
8683
function changeState(player: Player, state: States) {
8784
const oldState = player.state
8885
player.state = state
@@ -95,8 +92,7 @@ function changeState(player: Player, state: States) {
9592

9693
player.playSound("light_dash")
9794
player.playSound("light_beam_start")
98-
addTrail(player)
99-
95+
visuals.set(player.id, new LightVisual())
10096
flySoundCooldown.set(player.id, 0)
10197
flyTurnCooldown.set(player.id, 0)
10298
player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, false)
@@ -117,20 +113,33 @@ function changeState(player: Player, state: States) {
117113
changeState(player, States.NORMAL)
118114
break;
119115

116+
case States.DASH:
117+
const dir = player.getViewDirection()
118+
let vel = V3.normalize(V3.make(dir.x, 0, dir.z ))
119+
const dirMap = new MolangVariableMap();
120+
dirMap.setVector3("direction", V3.scale(vel, -1))
121+
player.spawnParticle("whynot:dash", entityCenter(player) ?? player.location, dirMap)
122+
player.addEffect(MinecraftEffectTypes.SlowFalling, 5, {showParticles: false})
123+
player.playSound("dash")
124+
125+
player.clearVelocity()
126+
player.applyImpulse(V3.add(V3.scale(vel, 1.0), V3.make(0,0.1,0)))
127+
128+
changeState(player, States.NORMAL)
129+
break;
130+
120131
}
121132

122133
switch (oldState) {
123134
case States.FLYING:
124135
player.triggerEvent("whynot:remove_static_player");
125136

126137
player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, true)
127-
trails.delete(player.id)
128138

129139
player.removeEffect(MinecraftEffectTypes.Invisibility)
130140
break;
131141
}
132142
}
133-
let angle = 0
134143
export function main() {
135144
light = new ItemStack("whynot:light", 1);
136145
light.lockMode = ItemLockMode.inventory;
@@ -148,6 +157,9 @@ export function main() {
148157
const pressed = newButtonState == ButtonState.Pressed
149158
if (!entityHasSlotTag(player, EquipmentSlot.Mainhand, "whynot:light")) return;
150159

160+
if (button == InputButton.Sneak && newButtonState == ButtonState.Pressed && player.state == States.NORMAL) {
161+
changeState(player, States.DASH)
162+
}
151163
if (button != InputButton.Jump) return
152164
if (((airTime.get(player.id) ?? 0) > 2) && pressed && player.state == States.NORMAL) {
153165
// Activate fly
@@ -172,9 +184,6 @@ export function main() {
172184
system.runInterval(mainTick)
173185
}
174186

175-
let lastAdd1: Vector3 | undefined = undefined
176-
let lastAdd2: Vector3 | undefined = undefined
177-
178187
function mainTick() {
179188
world.getAllPlayers().forEach(player => {
180189
// Set Airtime
@@ -203,28 +212,7 @@ function mainTick() {
203212
player.clearVelocity();
204213
player.applyImpulse(vel);
205214

206-
// Trail construction
207-
const trail: Line[] = trails.get(player.id) as Line[]
208-
const line = trail[trail.length - 1]
209-
line.end = entityCenter(player) ?? player.location
210-
line.length = V3.distance(line.start, line.end)
211-
212-
let length = remap(health.currentValue, health.effectiveMin, health.effectiveMax, lightTrailLengthMin, lightTrailLengthMax)
213-
let i = trail.length - 1
214-
while (length > 0 && i >= 0) {
215-
const line = trail[i]
216-
const segmentLength = Math.min(line.length, length)
217-
const dir = V3.direction(line.end, line.start)
218-
spawnLine(
219-
"whynot:light_trail",
220-
player.dimension, line.end,
221-
dir, segmentLength,
222-
lightTrailThickness
223-
)
224-
225-
length -= segmentLength
226-
i--;
227-
}
215+
// Particles
228216
const starMap = new MolangVariableMap()
229217
const center = entityCenter(player) ?? player.location
230218
starMap.setFloat("size", 2.0)
@@ -235,21 +223,28 @@ function mainTick() {
235223
starMap
236224
)
237225

238-
const matrix = V3.getBasisMatrix(addVel)
239-
angle += (1 / 20.0) * TAU * 1.5 * speed
240-
const spin1 = V3.make(Math.cos(angle) * 0.5, Math.sin(angle) * 0.5, 0)
241-
const spin2 = V3.make(Math.cos(angle + PI) * 0.5, Math.sin(angle + PI) * 0.5, 0)
242-
243-
const add1 = V3.add(V3.multiplyVectorByMatrix(spin1, matrix), center)
244-
const add2 = V3.add(V3.multiplyVectorByMatrix(spin2, matrix), center)
245-
if (lastAdd1 && lastAdd2) {
246-
drawLine("whynot:light_spin_trail", player.dimension, add1, lastAdd1, 0.075)
247-
drawLine("whynot:light_spin_trail", player.dimension, add2, lastAdd2, 0.075)
226+
// Visuals
227+
const playerVisuals = visuals.get(player.id)
228+
if (playerVisuals) {
229+
const matrix = V3.getBasisMatrix(addVel)
230+
playerVisuals.angle += (1 / 20.0) * TAU * 1.5 * speed
231+
232+
let angle = playerVisuals.angle
233+
const spin1 = V3.make(Math.cos(angle) * 0.5, Math.sin(angle) * 0.5, 0)
234+
const spin2 = V3.make(Math.cos(angle + PI) * 0.5, Math.sin(angle + PI) * 0.5, 0)
235+
236+
const add1 = V3.add(V3.multiplyVectorByMatrix(spin1, matrix), center)
237+
const add2 = V3.add(V3.multiplyVectorByMatrix(spin2, matrix), center)
238+
if (playerVisuals.lastSpin1 && playerVisuals.lastSpin2) {
239+
drawLine("whynot:light_trail", player.dimension, add1, playerVisuals.lastSpin1, 0.075)
240+
drawLine("whynot:light_trail", player.dimension, add2, playerVisuals.lastSpin2, 0.075)
241+
}
242+
if (playerVisuals.lastTrail)
243+
drawLine("whynot:light_trail", player.dimension, center, playerVisuals.lastTrail, lightTrailThickness)
244+
playerVisuals.lastSpin1 = add1
245+
playerVisuals.lastSpin2 = add2
246+
playerVisuals.lastTrail = center
248247
}
249-
lastAdd1 = add1
250-
lastAdd2 = add2
251-
252-
253248

254249
// Get block in path and bounce if needed
255250
const blockHit = player.dimension.getBlockFromRay(entityCenter(player) ?? player.location, vel, {maxDistance: 4, includeLiquidBlocks:false, includePassableBlocks: false})
@@ -258,16 +253,12 @@ function mainTick() {
258253
flyingAngles.set(player.id, bounced);
259254
flyTurnCooldown.set(player.id, flyTurnCooldownTime)
260255
player.playSound("light_dash")
261-
// Cut off and end last trail, make new trail
262-
addTrail(player)
263256
}
264257

265258
// If viewing angle change is significant change direction and did not bounce
266259
else if (V3.dot(viewDir, addVel) < flyTurnThreshold && (flyTurnCooldown.get(player.id) ?? 0) <= 0) {
267260
flyingAngles.set(player.id, viewDir);
268261
player.playSound("light_dash")
269-
// Cut off and end last trail, make new trail
270-
addTrail(player)
271262
}
272263

273264
// Reduce fly turn cooldown
@@ -294,7 +285,7 @@ function mainTick() {
294285
player.camera.clear()
295286
return
296287
}
297-
player.camera.setCamera("minecraft:follow_orbit")
288+
player.camera.setCamera("whynot:follow_orbit")
298289
player.dimension.runCommand(`/ability ${player.name} mayfly false`)
299290
player.onScreenDisplay.setActionBar(`Z: ${player.zCooldown} X: ${player.xCooldown} C: ${player.cCooldown} V: ${player.vCooldown} F: ${player.fCooldown}`)
300291
})

0 commit comments

Comments
 (0)