@rbxts/vfx-forge 2.2.2
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/LICENSE +82 -0
- package/README.md +39 -0
- package/out/effects/beam.luau +312 -0
- package/out/effects/bezier.luau +392 -0
- package/out/effects/camera_shake.luau +200 -0
- package/out/effects/lightning.luau +1183 -0
- package/out/effects/mesh.luau +466 -0
- package/out/effects/particle.luau +64 -0
- package/out/effects/randomizer.luau +110 -0
- package/out/effects/screen.luau +61 -0
- package/out/effects/shockwave_debris.luau +277 -0
- package/out/effects/shockwave_line.luau +356 -0
- package/out/effects/shockwave_ring.luau +252 -0
- package/out/effects/sound.luau +311 -0
- package/out/effects/spin.luau +88 -0
- package/out/effects/tweener.luau +122 -0
- package/out/emitters.luau +387 -0
- package/out/index.d.ts +341 -0
- package/out/init.luau +279 -0
- package/out/mod/attributes.luau +227 -0
- package/out/mod/color/Oklab.luau +93 -0
- package/out/mod/color/sRGB.luau +71 -0
- package/out/mod/common/bezier.luau +372 -0
- package/out/mod/common/flipbook.luau +102 -0
- package/out/mod/lerp.luau +210 -0
- package/out/mod/logger.luau +20 -0
- package/out/mod/shape.luau +207 -0
- package/out/mod/tween.luau +161 -0
- package/out/mod/utility.luau +707 -0
- package/out/obj/Bezier.luau +268 -0
- package/out/obj/ObjectCache.luau +289 -0
- package/out/services/caches.luau +62 -0
- package/out/services/effects.luau +234 -0
- package/out/services/enabled_effects.luau +120 -0
- package/out/services/texture_loader.luau +174 -0
- package/out/tsconfig.tsbuildinfo +1 -0
- package/out/types.luau +43 -0
- package/package.json +63 -0
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main API for Forge VFX.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import vfx from "@rbxts/forge-vfx";
|
|
8
|
+
* vfx.init();
|
|
9
|
+
*
|
|
10
|
+
* const env = vfx.emit(Workspace.Effect);
|
|
11
|
+
* env.Finished.finally(() => print("Effect finished!"));
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export interface Api {
|
|
15
|
+
/**
|
|
16
|
+
* Caches attributes for a VFX object. Client-side only. Use with
|
|
17
|
+
* `restoreAttributes` to save/restore original attribute values.
|
|
18
|
+
*
|
|
19
|
+
* @param object - Instance whose attributes to cache.
|
|
20
|
+
*/
|
|
21
|
+
cacheAttributes: (object: Instance) => void;
|
|
22
|
+
|
|
23
|
+
/** Internal caches used by the VFX system. */
|
|
24
|
+
caches: ApiCaches;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Clean up and shut down Forge VFX. Destroys all caches, cleans up scopes,
|
|
28
|
+
* deinitializes all modules, and disconnects event handlers.
|
|
29
|
+
*/
|
|
30
|
+
deinit: () => void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Disables a ParticleEmitter, Beam, or VFX object.
|
|
34
|
+
*
|
|
35
|
+
* @param object - Instance to disable.
|
|
36
|
+
*/
|
|
37
|
+
disable: (object: Instance) => void;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Emit VFX effects from the provided instances. Supports ParticleEmitters,
|
|
41
|
+
* Beams, Trails, Meshes, Beziers, Spin Models, Shockwaves, and all other
|
|
42
|
+
* Forge VFX effect types.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* // Basic emit
|
|
48
|
+
* vfx.emit(Workspace.Effect);
|
|
49
|
+
*
|
|
50
|
+
* // Emit multiple effects
|
|
51
|
+
* vfx.emit(Effects.Explosion, Effects.Wind);
|
|
52
|
+
*
|
|
53
|
+
* // Emit with 2x scale
|
|
54
|
+
* vfx.emit(2, Workspace.Effect);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
emit: {
|
|
58
|
+
/**
|
|
59
|
+
* Emit effects at default scale (1).
|
|
60
|
+
*
|
|
61
|
+
* @param instances - One or more Roblox instances to emit effects from.
|
|
62
|
+
* @returns Environment with a Finished promise that resolves when
|
|
63
|
+
* complete.
|
|
64
|
+
*/
|
|
65
|
+
(...instances: Array<Instance>): EmitEnvironment;
|
|
66
|
+
/**
|
|
67
|
+
* Emit effects at a specified scale.
|
|
68
|
+
*
|
|
69
|
+
* @param scale - Scale multiplier for the effects.
|
|
70
|
+
* @param instances - One or more Roblox instances to emit effects from.
|
|
71
|
+
* @returns Environment with a Finished promise that resolves when
|
|
72
|
+
* complete.
|
|
73
|
+
*/
|
|
74
|
+
(scale: number, ...instances: Array<Instance>): EmitEnvironment;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Emit VFX effects with specified render depth ordering.
|
|
79
|
+
*
|
|
80
|
+
* @param depth - Render priority depth for the emitted effects.
|
|
81
|
+
* @param instances - One or more Roblox instances to emit effects from.
|
|
82
|
+
* @returns Environment with a Finished promise that resolves when complete.
|
|
83
|
+
*/
|
|
84
|
+
emitWithDepth: (depth: number, ...instances: Array<Instance>) => EmitEnvironment;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Enables a ParticleEmitter, Beam, or VFX object.
|
|
88
|
+
*
|
|
89
|
+
* @param object - Instance to enable.
|
|
90
|
+
*/
|
|
91
|
+
enable: (object: Instance) => void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Initializes the VFX system. Sets up collision groups on server,
|
|
95
|
+
* initializes caches and all VFX modules.
|
|
96
|
+
*
|
|
97
|
+
* @param parameters - Optional initialization parameters.
|
|
98
|
+
*/
|
|
99
|
+
init: (parameters?: object) => void;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Restores previously cached attributes for a VFX object. Client-side only.
|
|
103
|
+
*
|
|
104
|
+
* @param object - Instance whose attributes to restore.
|
|
105
|
+
*/
|
|
106
|
+
restoreAttributes: (object: Instance) => void;
|
|
107
|
+
|
|
108
|
+
/** Current active scope stack for cleanup management. */
|
|
109
|
+
scope: Array<unknown>;
|
|
110
|
+
|
|
111
|
+
/** Whether the VFX system has been initialized. */
|
|
112
|
+
setup: boolean;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Internal cache storage for the VFX system. */
|
|
116
|
+
export interface ApiCaches {
|
|
117
|
+
/** Shared part cache for pooling reusable effect parts. */
|
|
118
|
+
shared_part: ObjectCache;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Configuration parameters for object caching. Controls pooling behavior for
|
|
123
|
+
* VFX instances.
|
|
124
|
+
*/
|
|
125
|
+
export interface CacheParameters {
|
|
126
|
+
/**
|
|
127
|
+
* Seconds before excess cached items are cleaned up.
|
|
128
|
+
*
|
|
129
|
+
* @default undefined
|
|
130
|
+
*/
|
|
131
|
+
excess_lifetime?: number;
|
|
132
|
+
/**
|
|
133
|
+
* Callback invoked when an item is returned to the cache.
|
|
134
|
+
*
|
|
135
|
+
* @param item - The cache item being freed.
|
|
136
|
+
*/
|
|
137
|
+
on_free?: (item: Item) => void;
|
|
138
|
+
/**
|
|
139
|
+
* Initial/target size of the cache pool.
|
|
140
|
+
*
|
|
141
|
+
* @default undefined
|
|
142
|
+
*/
|
|
143
|
+
size?: number;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Internal service managing effect emission and lifecycle.
|
|
148
|
+
*
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
151
|
+
export interface EffectsService {
|
|
152
|
+
/** Shuts down the effects service and cleans up resources. */
|
|
153
|
+
deinit: () => void;
|
|
154
|
+
/**
|
|
155
|
+
* Emits effects with specified depth ordering.
|
|
156
|
+
*
|
|
157
|
+
* @param depth - Render priority depth.
|
|
158
|
+
* @param instances - Instances to emit effects from.
|
|
159
|
+
*/
|
|
160
|
+
emit: (depth: number, ...instances: Array<Instance>) => EmitEnvironment;
|
|
161
|
+
/**
|
|
162
|
+
* Emits effects from a folder's children, parenting them to the target first.
|
|
163
|
+
*
|
|
164
|
+
* @param folder - Folder containing effects to emit, or undefined.
|
|
165
|
+
* @param targetParent - Instance to parent the folder's children to.
|
|
166
|
+
* @param depth - Render priority depth.
|
|
167
|
+
*/
|
|
168
|
+
emitFromFolder: (folder: Folder | undefined, targetParent: Instance, depth: number) => EmitEnvironment;
|
|
169
|
+
/**
|
|
170
|
+
* Emits nested effects from a part's children.
|
|
171
|
+
*
|
|
172
|
+
* @param part - Instance whose children to emit.
|
|
173
|
+
* @param depth - Render priority depth.
|
|
174
|
+
*/
|
|
175
|
+
emitNested: (part: Instance, depth: number) => EmitEnvironment;
|
|
176
|
+
/**
|
|
177
|
+
* Emits effects from an EmitOnFinish folder. Delegates to emitFromFolder.
|
|
178
|
+
*
|
|
179
|
+
* @param emitOnFinish - EmitOnFinish folder, or undefined.
|
|
180
|
+
* @param targetParent - Instance to parent effects to.
|
|
181
|
+
* @param depth - Render priority depth.
|
|
182
|
+
*/
|
|
183
|
+
emitOnFinish: (emitOnFinish: Folder | undefined, targetParent: Instance, depth: number) => EmitEnvironment;
|
|
184
|
+
/**
|
|
185
|
+
* Initializes the effects service.
|
|
186
|
+
*
|
|
187
|
+
* @param api - Reference to the main API.
|
|
188
|
+
*/
|
|
189
|
+
init: (api: Api) => void;
|
|
190
|
+
/**
|
|
191
|
+
* Prepares a named folder for deferred emission by unparenting it.
|
|
192
|
+
*
|
|
193
|
+
* @param obj - Instance to search for the folder.
|
|
194
|
+
* @param folderName - Name of the folder to prepare.
|
|
195
|
+
* @param scope - Scope for cleanup.
|
|
196
|
+
*/
|
|
197
|
+
prepareEmitFolder: (obj: Instance, folderName: string, scope: Scope) => Folder | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* Prepares the EmitOnFinish folder. Delegates to prepareEmitFolder.
|
|
200
|
+
*
|
|
201
|
+
* @param obj - Instance to search for EmitOnFinish.
|
|
202
|
+
* @param scope - Scope for cleanup.
|
|
203
|
+
*/
|
|
204
|
+
prepareEmitOnFinish: (obj: Instance, scope: Scope) => Folder | undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Result returned from emitting VFX effects. Contains a promise for tracking
|
|
209
|
+
* effect completion.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
*
|
|
213
|
+
* ```ts
|
|
214
|
+
* const env = vfx.emit(Workspace.Effect);
|
|
215
|
+
* env.Finished.finally(() => print("Effect finished!"));
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
export interface EmitEnvironment {
|
|
219
|
+
/**
|
|
220
|
+
* Promise that resolves when all emitted effects have finished playing. Use
|
|
221
|
+
* `:finally()` or `:andThen()` to run code after completion.
|
|
222
|
+
*/
|
|
223
|
+
Finished: Promise<void>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Object cache for pooling and reusing VFX instances. Extends the base Cache
|
|
228
|
+
* with additional tracking for part-based effects. MeshPart and Union effects
|
|
229
|
+
* cannot be reasonably pooled, so their CFrames are not updated in bulk which
|
|
230
|
+
* may impact performance with heavy emission.
|
|
231
|
+
*/
|
|
232
|
+
export interface ObjectCache extends Cache {
|
|
233
|
+
/** Current number of items in the cache. */
|
|
234
|
+
amount: number;
|
|
235
|
+
/** Map of keys to their corresponding cache items. */
|
|
236
|
+
item_map: Map<unknown, Item>;
|
|
237
|
+
/** Cache configuration parameters. */
|
|
238
|
+
params: CacheParameters;
|
|
239
|
+
/** Parent instance for cached items. */
|
|
240
|
+
parent?: Instance;
|
|
241
|
+
/** Whether this cache is in part mode for bulk CFrame updates. */
|
|
242
|
+
part_mode: boolean;
|
|
243
|
+
/** Reference instance used as template for creating new cache items. */
|
|
244
|
+
ref: Instance;
|
|
245
|
+
/** Number of items to restore to the pool. */
|
|
246
|
+
restore_amount: number;
|
|
247
|
+
/** Scope for cleanup management. */
|
|
248
|
+
scope: Array<unknown>;
|
|
249
|
+
/** Array of unused items available for reuse. */
|
|
250
|
+
unused: Array<Item>;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Scope for managing VFX cleanup and lifecycle. Scopes hold cleanup functions,
|
|
255
|
+
* connections, and tweens that need to be cleaned up when effects finish.
|
|
256
|
+
* Implements array semantics for storing cleanup handlers.
|
|
257
|
+
*/
|
|
258
|
+
export interface Scope extends Array<unknown> {
|
|
259
|
+
/**
|
|
260
|
+
* Render priority depth for this scope. Used to determine the order of
|
|
261
|
+
* render step bindings.
|
|
262
|
+
*/
|
|
263
|
+
depth: number;
|
|
264
|
+
/** Reference to the effects service for this scope. */
|
|
265
|
+
effects: EffectsService;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Internal representation of a cached item.
|
|
270
|
+
*
|
|
271
|
+
* @internal
|
|
272
|
+
*/
|
|
273
|
+
interface Item {
|
|
274
|
+
/** Unique key identifying this item in the cache. */
|
|
275
|
+
key: unknown;
|
|
276
|
+
/** Timestamp when item was added to cache. */
|
|
277
|
+
added: number;
|
|
278
|
+
/** Number of active references to this item. */
|
|
279
|
+
dependents: number;
|
|
280
|
+
/** The actual Roblox instance being cached. */
|
|
281
|
+
value: Instance;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Base cache class for pooling Roblox instances. Used internally to reduce
|
|
286
|
+
* instantiation overhead for VFX effects.
|
|
287
|
+
*/
|
|
288
|
+
declare class Cache {
|
|
289
|
+
/**
|
|
290
|
+
* Destroys the cache and all cached items. Call during cleanup to prevent
|
|
291
|
+
* memory leaks.
|
|
292
|
+
*/
|
|
293
|
+
public destroy: () => void;
|
|
294
|
+
/**
|
|
295
|
+
* Returns an item to the cache pool for reuse.
|
|
296
|
+
*
|
|
297
|
+
* @param key - Key of the item to free.
|
|
298
|
+
*/
|
|
299
|
+
public free: (key: unknown) => void;
|
|
300
|
+
/**
|
|
301
|
+
* Retrieves an item from the cache, creating one if needed.
|
|
302
|
+
*
|
|
303
|
+
* @param key - Key to retrieve or create.
|
|
304
|
+
* @returns The cached instance.
|
|
305
|
+
*/
|
|
306
|
+
public get: (key: unknown) => Instance;
|
|
307
|
+
/**
|
|
308
|
+
* Checks if an item exists in the cache.
|
|
309
|
+
*
|
|
310
|
+
* @param key - Key to check.
|
|
311
|
+
* @returns True if the key exists in the cache.
|
|
312
|
+
*/
|
|
313
|
+
public has: (key: unknown) => boolean;
|
|
314
|
+
/**
|
|
315
|
+
* Retrieves an item without creating it if missing.
|
|
316
|
+
*
|
|
317
|
+
* @param key - Key to look up.
|
|
318
|
+
* @returns The cached instance, or undefined if not found.
|
|
319
|
+
*/
|
|
320
|
+
public peek: (key: unknown) => Instance | undefined;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Creates a new cache.
|
|
324
|
+
*
|
|
325
|
+
* @param ref - Template instance to clone when creating new items.
|
|
326
|
+
* @param parent - Optional parent for cached instances.
|
|
327
|
+
* @param parameters - Optional cache configuration.
|
|
328
|
+
*/
|
|
329
|
+
constructor(ref: Instance, parent?: Instance, parameters?: CacheParameters);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Forge VFX - An advanced custom VFX system for Roblox.
|
|
334
|
+
*
|
|
335
|
+
* Supports 12+ effect types including particles, beams, trails, meshes, bezier
|
|
336
|
+
* curves, shockwaves, spin models, screen effects, and camera shake.
|
|
337
|
+
*
|
|
338
|
+
* @see https://docs.zilibobi.dev/vfx-forge/
|
|
339
|
+
*/
|
|
340
|
+
declare const VfxForge: Api;
|
|
341
|
+
export default VfxForge;
|
package/out/init.luau
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
-- The license is placed inside a string in order for it to be preserved when the code is decompiled
|
|
2
|
+
-- Even if the engine retains the entire string in memory, it's only around 3.5kB
|
|
3
|
+
local _ = [[
|
|
4
|
+
Preamble.
|
|
5
|
+
Disclaimer: nothing stated in this preamble is legal advice.
|
|
6
|
+
|
|
7
|
+
This is a simple license that allows anyone to use the emit module in their Roblox games.
|
|
8
|
+
|
|
9
|
+
1. You cannot use the module in anything that isn't a Roblox game. For example, it means
|
|
10
|
+
that you cannot create a plugin using this module.
|
|
11
|
+
|
|
12
|
+
2. You are allowed to use the module commercially in your games.
|
|
13
|
+
|
|
14
|
+
3. You are free to share the module with other developers so they can use it in their games,
|
|
15
|
+
as long as the license is retained.
|
|
16
|
+
|
|
17
|
+
4. You can modify and share the module as long as you follow the terms of the license. All
|
|
18
|
+
derivates of the module must have the same license.
|
|
19
|
+
|
|
20
|
+
5. If you break the terms and conditions of the license, you are required to stop the use and
|
|
21
|
+
distribution of the module immediately.
|
|
22
|
+
|
|
23
|
+
End of preamble.
|
|
24
|
+
|
|
25
|
+
VFX Forge Developer License (VFX-DL) Version 1.1
|
|
26
|
+
|
|
27
|
+
Copyright (c) 2025 zilibobi
|
|
28
|
+
|
|
29
|
+
1. Definitions.
|
|
30
|
+
- "Module" means the source code and any compiled form of the Emit Module.
|
|
31
|
+
- "You" means any individual or organization exercising the rights granted herein.
|
|
32
|
+
- "Derivative Work" means any work based upon or incorporating the Module.
|
|
33
|
+
- "Roblox Experience" means a user-facing game or simulation that runs on the
|
|
34
|
+
Roblox platform, created using Roblox Studio and played via the Roblox client.
|
|
35
|
+
|
|
36
|
+
2. Grant of Rights.
|
|
37
|
+
Permission is hereby granted, free of charge, to You to use, reproduce,
|
|
38
|
+
prepare Derivative Works of, publicly display, publicly perform, sublicense,
|
|
39
|
+
and distribute the Module, **solely when embedded in the runtime environment of
|
|
40
|
+
a Roblox Experience** (including playtesting in Roblox Studio), and **not** when
|
|
41
|
+
loaded by any Roblox Studio plugin or other developer tool, running in any context
|
|
42
|
+
that has access to API methods or permissions unavailable to runtime scripts within
|
|
43
|
+
Roblox Experiences (excluding the Roblox Studio command bar feature, when used for
|
|
44
|
+
the purpose of viewing finished effects). You may distribute the Module or Derivative
|
|
45
|
+
Work to other developers, provided they use it only within the permitted runtime
|
|
46
|
+
context described above.
|
|
47
|
+
|
|
48
|
+
3. Conditions.
|
|
49
|
+
a. Copyleft.
|
|
50
|
+
Any Derivative Work, including modified or extended versions of the Module, that
|
|
51
|
+
You distribute must be licensed under the exact same terms as this VFX-DL.
|
|
52
|
+
b. Redistribution.
|
|
53
|
+
You must include a copy of this license text with any distribution of the Module or Derivative Work.
|
|
54
|
+
c. No Other Contexts.
|
|
55
|
+
You may not embed, load, or distribute the Module within any Roblox Studio
|
|
56
|
+
plugin, editor extension, command-line tool, test harness, or any code running
|
|
57
|
+
under Studio outside of normal game runtime.
|
|
58
|
+
|
|
59
|
+
4. Disclaimer of Warranty.
|
|
60
|
+
The Module is provided "AS IS," without warranty of any kind, express or implied,
|
|
61
|
+
including but not limited to the warranties of merchantability, fitness for a
|
|
62
|
+
particular purpose, and noninfringement.
|
|
63
|
+
|
|
64
|
+
5. Limitation of Liability.
|
|
65
|
+
In no event shall the authors or copyright holders be liable for any claim,
|
|
66
|
+
damages, or other liability arising from, out of, or in connection with the
|
|
67
|
+
Module or the use or other dealings in the Module.
|
|
68
|
+
|
|
69
|
+
6. Termination.
|
|
70
|
+
If You violate the terms of this License, Your rights under this VFX-DL will
|
|
71
|
+
terminate automatically. Upon termination, You must cease all use and distribution
|
|
72
|
+
of the Module and any Derivative Works.
|
|
73
|
+
|
|
74
|
+
7. Versioning.
|
|
75
|
+
This license applies to Version 1.0 of the VFX-DL. Future versions may be published
|
|
76
|
+
by the copyright holder.
|
|
77
|
+
|
|
78
|
+
8. Commercial use.
|
|
79
|
+
This License permits commercial use within the scope defined in Section 2.
|
|
80
|
+
|
|
81
|
+
9. Trademarks and branding.
|
|
82
|
+
Nothing in this License grants permission to use the trade names, trademarks, service marks,
|
|
83
|
+
or product names of the Licensor.
|
|
84
|
+
]]
|
|
85
|
+
|
|
86
|
+
local RunService = game:GetService("RunService")
|
|
87
|
+
local CollectionService = game:GetService("CollectionService")
|
|
88
|
+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
89
|
+
|
|
90
|
+
local logger = require("@mod/logger")
|
|
91
|
+
local utility = require("@mod/utility")
|
|
92
|
+
local attributes = require("@mod/attributes")
|
|
93
|
+
|
|
94
|
+
local Sound = require("@vfx/sound")
|
|
95
|
+
local Bezier = require("@vfx/bezier")
|
|
96
|
+
local Lightning = require("@vfx/lightning")
|
|
97
|
+
local CameraShake = require("@vfx/camera_shake")
|
|
98
|
+
local ShockwaveRing = require("@vfx/shockwave_ring")
|
|
99
|
+
local ShockwaveLine = require("@vfx/shockwave_line")
|
|
100
|
+
local ShockwaveDebris = require("@vfx/shockwave_debris")
|
|
101
|
+
|
|
102
|
+
local caches = require("@srv/caches")
|
|
103
|
+
local effects = require("@srv/effects")
|
|
104
|
+
local texture_loader = require("@srv/texture_loader")
|
|
105
|
+
local enabled_effects = require("@srv/enabled_effects")
|
|
106
|
+
|
|
107
|
+
local PluginContext = utility.PLUGIN_CONTEXT
|
|
108
|
+
local ServerContext = utility.SERVER_CONTEXT
|
|
109
|
+
|
|
110
|
+
type params = {}
|
|
111
|
+
|
|
112
|
+
local api = {}
|
|
113
|
+
|
|
114
|
+
api.scope = {}
|
|
115
|
+
api.setup = false
|
|
116
|
+
|
|
117
|
+
function api.init(params: params?)
|
|
118
|
+
if api.setup then
|
|
119
|
+
return
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if ServerContext then
|
|
123
|
+
task.spawn(function()
|
|
124
|
+
local done = false
|
|
125
|
+
local tries = 0
|
|
126
|
+
|
|
127
|
+
local lastErr
|
|
128
|
+
|
|
129
|
+
repeat
|
|
130
|
+
tries += 1
|
|
131
|
+
|
|
132
|
+
local ok, err = pcall(utility.setCollisionGroups, utility.COLLISION_GROUPS)
|
|
133
|
+
|
|
134
|
+
done = ok
|
|
135
|
+
lastErr = err
|
|
136
|
+
|
|
137
|
+
if not done then
|
|
138
|
+
task.wait(tries)
|
|
139
|
+
end
|
|
140
|
+
until done or tries >= 5
|
|
141
|
+
|
|
142
|
+
if not done then
|
|
143
|
+
logger.warn(
|
|
144
|
+
`couldn't register necessary collision groups after {tries} tries with the last error being: {lastErr}`
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
api.setup = true
|
|
151
|
+
|
|
152
|
+
if RunService:IsServer() and not PluginContext then
|
|
153
|
+
return
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
api.caches = caches.init(api.scope)
|
|
157
|
+
|
|
158
|
+
shared.vfx = api
|
|
159
|
+
|
|
160
|
+
-- init services
|
|
161
|
+
effects.init(api)
|
|
162
|
+
|
|
163
|
+
texture_loader.init(api.scope)
|
|
164
|
+
enabled_effects.init(api.scope, api.caches.shared_part, effects)
|
|
165
|
+
|
|
166
|
+
-- init effects
|
|
167
|
+
Sound.init()
|
|
168
|
+
CameraShake.init()
|
|
169
|
+
|
|
170
|
+
Bezier.init(api.caches.shared_part)
|
|
171
|
+
Lightning.init(api.caches.shared_part)
|
|
172
|
+
ShockwaveRing.init(api.caches.shared_part)
|
|
173
|
+
ShockwaveLine.init(api.caches.shared_part)
|
|
174
|
+
ShockwaveDebris.init(api.caches.shared_part)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
function api.deinit()
|
|
178
|
+
if not api.setup then
|
|
179
|
+
return
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
api.setup = false
|
|
183
|
+
|
|
184
|
+
shared.vfx = nil
|
|
185
|
+
|
|
186
|
+
if RunService:IsServer() and not PluginContext then
|
|
187
|
+
return
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
utility.cleanupScope(api.scope)
|
|
191
|
+
|
|
192
|
+
effects.deinit()
|
|
193
|
+
|
|
194
|
+
Sound.deinit()
|
|
195
|
+
Bezier.deinit()
|
|
196
|
+
Lightning.deinit()
|
|
197
|
+
CameraShake.deinit()
|
|
198
|
+
ShockwaveRing.deinit()
|
|
199
|
+
ShockwaveLine.deinit()
|
|
200
|
+
ShockwaveDebris.deinit()
|
|
201
|
+
|
|
202
|
+
local cleanupObjects = CollectionService:GetTagged(utility.CLEANUP_TAG)
|
|
203
|
+
|
|
204
|
+
for _, obj in cleanupObjects do
|
|
205
|
+
obj:Destroy()
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
local function fullEmit(scale: number, depth: number, ...: Instance)
|
|
210
|
+
if not api.setup then
|
|
211
|
+
logger.error("not initialized")
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
return effects.emit(depth, ...)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
function api.emit(vfxOrScale: number | Instance, ...: Instance)
|
|
218
|
+
if typeof(vfxOrScale) ~= "number" then
|
|
219
|
+
return fullEmit(1, 0, vfxOrScale, ...)
|
|
220
|
+
else
|
|
221
|
+
return fullEmit(vfxOrScale, 0, ...)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
function api.emitWithDepth(depth: number, ...: Instance)
|
|
226
|
+
return fullEmit(1, depth, ...)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
function api.enable(obj: Instance)
|
|
230
|
+
if obj:IsA("ParticleEmitter") or obj:IsA("Beam") then
|
|
231
|
+
obj.Enabled = true
|
|
232
|
+
return
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
if attributes.isCached(obj) then
|
|
236
|
+
attributes.trigger(obj, "Enabled", true)
|
|
237
|
+
else
|
|
238
|
+
obj:SetAttribute("Enabled", true)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
function api.disable(obj: Instance)
|
|
243
|
+
if obj:IsA("ParticleEmitter") or obj:IsA("Beam") then
|
|
244
|
+
obj.Enabled = false
|
|
245
|
+
return
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
if attributes.isCached(obj) then
|
|
249
|
+
attributes.trigger(obj, "Enabled", false)
|
|
250
|
+
else
|
|
251
|
+
obj:SetAttribute("Enabled", false)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
function api.cacheAttributes(obj: Instance)
|
|
256
|
+
if utility.SERVER_CONTEXT then
|
|
257
|
+
logger.error("attributes can only be cached in a client-side context")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if not obj:IsDescendantOf(ReplicatedStorage) then
|
|
261
|
+
logger.error("attributes can only be cached for VFX inside ReplicatedStorage")
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
for _, v in obj:GetDescendants() do
|
|
265
|
+
attributes.cache(v)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
function api.restoreAttributes(obj: Instance)
|
|
270
|
+
if utility.SERVER_CONTEXT then
|
|
271
|
+
logger.error("attributes can only be restored in a client-side context")
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
for _, v in obj:GetDescendants() do
|
|
275
|
+
attributes.restore(v)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
return api
|