From a308bc544f0776cae1694ae18ea5b2e35001090b Mon Sep 17 00:00:00 2001 From: fgnm Date: Sun, 24 Jan 2021 20:56:58 +0100 Subject: [PATCH] Support Talos VFX particles --- CHANGES | 1 + assets/shaders/ui/default.vert | 16 ++ build.gradle | 1 + gradle.properties | 3 +- hyperlap2d-common-api | 2 +- hyperlap2d-runtime-libgdx | 2 +- .../editor/controller/BootstrapCommand.java | 1 + .../commands/PasteItemsCommand.java | 5 + .../commands/resource/DeleteTalosVFX.java | 77 +++++++++ .../resource/ExportLibraryItemCommand.java | 26 +++ .../rednblack/editor/factory/ItemFactory.java | 23 +++ .../editor/proxy/ProjectManager.java | 153 +++++++++++++++++- .../editor/proxy/ResourceManager.java | 49 +++++- .../rednblack/editor/utils/AssetImporter.java | 3 + .../rednblack/editor/utils/EntityBounds.java | 4 +- .../rednblack/editor/utils/ImportUtils.java | 15 +- .../editor/utils/runtime/EntityUtils.java | 14 ++ .../editor/utils/runtime/TalosResources.java | 24 +++ .../editor/view/ui/UIDropDownMenu.java | 1 + .../view/ui/UIDropDownMenuMediator.java | 8 + .../view/ui/box/UIResourcesBoxMediator.java | 17 +- .../UIAnimationsTabMediator.java | 1 - .../UIParticleEffectsTabMediator.java | 44 +++-- .../list/ParticleEffectResource.java | 2 - .../draggable/list/TalosResource.java | 41 +++++ .../view/ui/followers/FollowerFactory.java | 1 + .../view/ui/followers/ParticleFollower.java | 1 + .../editor/view/ui/panel/ImportPanel.java | 1 + 28 files changed, 500 insertions(+), 36 deletions(-) create mode 100644 assets/shaders/ui/default.vert create mode 100644 src/main/java/games/rednblack/editor/controller/commands/resource/DeleteTalosVFX.java create mode 100644 src/main/java/games/rednblack/editor/utils/runtime/TalosResources.java create mode 100644 src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/TalosResource.java diff --git a/CHANGES b/CHANGES index 39393fab..4847c480 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,5 @@ [0.0.4] +- Add support to Talos Particles VFX - Add Sticky Notes feature - Add GL Profiler in Performance plugin - Add smooth camera pan diff --git a/assets/shaders/ui/default.vert b/assets/shaders/ui/default.vert new file mode 100644 index 00000000..14ea510f --- /dev/null +++ b/assets/shaders/ui/default.vert @@ -0,0 +1,16 @@ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; + +uniform mat4 u_projTrans; + +varying vec4 v_color; +varying vec2 v_texCoords; + +void main() +{ + v_color = a_color; + v_color.a = v_color.a * (256.0/255.0); + v_texCoords = a_texCoord0; + gl_Position = u_projTrans * a_position; +} diff --git a/build.gradle b/build.gradle index 1a338417..31cc2b03 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,7 @@ dependencies { implementation project(":hyperlap2d-runtime-libgdx") implementation project(":h2d-libgdx-spine-extension") + implementation "com.talosvfx:talos-libgdx:$talosVersion" implementation "space.earlygrey:shapedrawer:$shapedrawerVersion" implementation "com.rafaskoberg.gdx:typing-label:$typingLabelVersion" implementation "com.kotcrab.vis:vis-ui:$visuiVersion" diff --git a/gradle.properties b/gradle.properties index 590ace2f..0ec3a5c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,5 @@ ashleyVersion = 1.7.3 spineVersion = 3.8.55.1 visuiVersion = 1.4.9-SNAPSHOT typingLabelVersion = 1.2.0 -shapedrawerVersion = 2.4.0 \ No newline at end of file +shapedrawerVersion = 2.4.0 +talosVersion = 1.3.1 \ No newline at end of file diff --git a/hyperlap2d-common-api b/hyperlap2d-common-api index 025fcfa4..2ae1c87b 160000 --- a/hyperlap2d-common-api +++ b/hyperlap2d-common-api @@ -1 +1 @@ -Subproject commit 025fcfa4fa982cabd2c3dc40ac1d6189b160bd09 +Subproject commit 2ae1c87b515ff9b010fedb43641b745b200a7dae diff --git a/hyperlap2d-runtime-libgdx b/hyperlap2d-runtime-libgdx index 8a3f2071..fb7c0da4 160000 --- a/hyperlap2d-runtime-libgdx +++ b/hyperlap2d-runtime-libgdx @@ -1 +1 @@ -Subproject commit 8a3f20715047efa2942ec7ab369033093464edb7 +Subproject commit fb7c0da4be5932ff651d2554231b6ece388953bc diff --git a/src/main/java/games/rednblack/editor/controller/BootstrapCommand.java b/src/main/java/games/rednblack/editor/controller/BootstrapCommand.java index f6287f51..0035d5f5 100644 --- a/src/main/java/games/rednblack/editor/controller/BootstrapCommand.java +++ b/src/main/java/games/rednblack/editor/controller/BootstrapCommand.java @@ -104,6 +104,7 @@ public class BootstrapCommand extends SimpleCommand { facade.registerCommand(MsgAPI.ACTION_DELETE_LIBRARY_ACTION, DeleteLibraryAction::new); facade.registerCommand(MsgAPI.ACTION_EXPORT_LIBRARY_ITEM, ExportLibraryItemCommand::new); facade.registerCommand(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT, DeleteParticleEffect::new); + facade.registerCommand(MsgAPI.ACTION_DELETE_TALOS_VFX, DeleteTalosVFX::new); facade.registerCommand(MsgAPI.ACTION_DELETE_SPINE_ANIMATION_RESOURCE, DeleteSpineAnimation::new); facade.registerCommand(MsgAPI.ACTION_DELETE_SPRITE_ANIMATION_RESOURCE, DeleteSpriteAnimation::new); diff --git a/src/main/java/games/rednblack/editor/controller/commands/PasteItemsCommand.java b/src/main/java/games/rednblack/editor/controller/commands/PasteItemsCommand.java index 9c8506ea..b7577b77 100644 --- a/src/main/java/games/rednblack/editor/controller/commands/PasteItemsCommand.java +++ b/src/main/java/games/rednblack/editor/controller/commands/PasteItemsCommand.java @@ -124,6 +124,11 @@ public class PasteItemsCommand extends EntityModifyRevertibleCommand { Sandbox.getInstance().getEngine().addEntity(child); entities.add(child); } + for (int i = 0; i < compositeVO.sTalosVFX.size(); i++) { + Entity child = factory.createEntity(parentEntity, compositeVO.sTalosVFX.get(i)); + Sandbox.getInstance().getEngine().addEntity(child); + entities.add(child); + } for (int i = 0; i < compositeVO.sLights.size(); i++) { Entity child = factory.createEntity(parentEntity, compositeVO.sLights.get(i)); Sandbox.getInstance().getEngine().addEntity(child); diff --git a/src/main/java/games/rednblack/editor/controller/commands/resource/DeleteTalosVFX.java b/src/main/java/games/rednblack/editor/controller/commands/resource/DeleteTalosVFX.java new file mode 100644 index 00000000..338c7ea4 --- /dev/null +++ b/src/main/java/games/rednblack/editor/controller/commands/resource/DeleteTalosVFX.java @@ -0,0 +1,77 @@ +package games.rednblack.editor.controller.commands.resource; + +import com.badlogic.ashley.core.Entity; +import games.rednblack.editor.renderer.components.additional.TalosComponent; +import games.rednblack.editor.renderer.data.CompositeItemVO; +import games.rednblack.editor.renderer.data.SceneVO; +import games.rednblack.editor.renderer.data.TalosVO; +import games.rednblack.editor.renderer.utils.ComponentRetriever; +import games.rednblack.editor.utils.runtime.EntityUtils; + +import java.util.ArrayList; +import java.util.function.Consumer; + +public class DeleteTalosVFX extends DeleteResourceCommand { + + private static final String CLASS_NAME = "games.rednblack.editor.controller.commands.resource.DeleteTalosVFX"; + public static final String DONE = CLASS_NAME + "DONE"; + + private final ArrayList entityList = new ArrayList<>(); + private final ArrayList tmpParticleEffectList = new ArrayList<>(); + + @Override + protected String confirmDialogTitle() { + return "Delete Talos VFX"; + } + + @Override + public void doAction() { + String particleName = notification.getBody(); + if (projectManager.deleteTalosVFX(particleName)) { + deleteEntitiesWithParticleEffects(sandbox.getRootEntity(), particleName); // delete entities from scene + deleteAllItemsWithParticleName(particleName); + projectManager.loadProjectData(projectManager.getCurrentProjectPath()); + sendNotification(DONE, particleName); + SceneVO vo = sandbox.sceneVoFromItems(); + projectManager.saveCurrentProject(vo); + } else { + cancel(); + } + } + + private void deleteAllItemsWithParticleName(String name) { + for (CompositeItemVO compositeItemVO : libraryItems.values()) { + deleteAllParticles(compositeItemVO, name); + } + } + + private void deleteAllParticles(CompositeItemVO compositeItemVO, String name) { + Consumer action = (rootItemVo) -> getParticles(rootItemVo, name); + EntityUtils.applyActionRecursivelyOnLibraryItems(compositeItemVO, action); + } + + private void getParticles(CompositeItemVO compositeItemVO, String name) { + if (compositeItemVO.composite != null && compositeItemVO.composite.sTalosVFX.size() != 0) { + ArrayList particleEffectList = compositeItemVO.composite.sTalosVFX; + for (TalosVO particleEffectVO : particleEffectList) { + if (particleEffectVO.particleName.equals(name)) { + tmpParticleEffectList.add(particleEffectVO); + } + } + particleEffectList.removeAll(tmpParticleEffectList); + tmpParticleEffectList.clear(); + } + } + + private void deleteEntitiesWithParticleEffects(Entity rootEntity, String particleName) { + entityList.clear(); + Consumer action = (root) -> { + TalosComponent particleComponent = ComponentRetriever.get(root, TalosComponent.class); + if (particleComponent != null && particleComponent.particleName.equals(particleName)) { + entityList.add(root); + } + }; + EntityUtils.applyActionRecursivelyOnEntities(rootEntity, action); + EntityUtils.removeEntities(entityList); + } +} diff --git a/src/main/java/games/rednblack/editor/controller/commands/resource/ExportLibraryItemCommand.java b/src/main/java/games/rednblack/editor/controller/commands/resource/ExportLibraryItemCommand.java index f7a2a3e9..d584cdbc 100644 --- a/src/main/java/games/rednblack/editor/controller/commands/resource/ExportLibraryItemCommand.java +++ b/src/main/java/games/rednblack/editor/controller/commands/resource/ExportLibraryItemCommand.java @@ -4,8 +4,14 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.ParticleEffect; import com.badlogic.gdx.graphics.g2d.ParticleEmitter; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.JsonWriter; +import com.talosvfx.talos.runtime.ParticleEffectDescriptor; +import com.talosvfx.talos.runtime.ParticleEmitterDescriptor; +import com.talosvfx.talos.runtime.modules.AbstractModule; +import com.talosvfx.talos.runtime.modules.ShadedSpriteModule; +import com.talosvfx.talos.runtime.modules.TextureModule; import games.rednblack.editor.controller.commands.NonRevertibleCommand; import games.rednblack.editor.proxy.ProjectManager; import games.rednblack.editor.proxy.ResourceManager; @@ -150,6 +156,26 @@ public class ExportLibraryItemCommand extends NonRevertibleCommand { } } + for (TalosVO imageVO : compositeVO.sTalosVFX) { + File fileSrc = new File(currentProjectPath + ProjectManager.TALOS_VFX_DIR_PATH + File.separator + imageVO.particleName); + FileUtils.copyFileToDirectory(fileSrc, tmpDir); + exportMapperVO.mapper.add(new ExportedAsset(ImportUtils.TYPE_TALOS_VFX, fileSrc.getName())); + ParticleEffectDescriptor particleEffect = resourceManager.getProjectTalosList().get(imageVO.particleName); + for (ParticleEmitterDescriptor emitter : new Array.ArrayIterator<>(particleEffect.emitterModuleGraphs)) { + for (AbstractModule module : new Array.ArrayIterator<>(emitter.getModules())) { + if (module instanceof TextureModule) { + String path = ((TextureModule) module).regionName + ".png"; + File f = new File(currentProjectPath + ProjectManager.IMAGE_DIR_PATH + File.separator + path); + FileUtils.copyFileToDirectory(f, tmpDir); + } else if (module instanceof ShadedSpriteModule) { + String path = ((ShadedSpriteModule) module).shdrFileName; + File f = new File(currentProjectPath + ProjectManager.TALOS_VFX_DIR_PATH + File.separator + path); + FileUtils.copyFileToDirectory(f, tmpDir); + } + } + } + } + for (CompositeItemVO compositeItemVO : compositeVO.sComposites) { exportAllAssets(compositeItemVO.composite, tmpDir); } diff --git a/src/main/java/games/rednblack/editor/factory/ItemFactory.java b/src/main/java/games/rednblack/editor/factory/ItemFactory.java index 1a0b4d2c..4f385332 100644 --- a/src/main/java/games/rednblack/editor/factory/ItemFactory.java +++ b/src/main/java/games/rednblack/editor/factory/ItemFactory.java @@ -222,6 +222,29 @@ public class ItemFactory { return entity; } + public boolean tryCreateTalosItem(String particleName, Vector2 position) { + Entity entity = createTalosItem(particleName, position); + + /* DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class); + float boundBoxSize = 10f; + dimensionsComponent.boundBox = new Rectangle(-boundBoxSize / 2f, -boundBoxSize / 2f, boundBoxSize, boundBoxSize);*/ + + if(entity == null) return false; + + return true; + } + + public Entity createTalosItem(String particleName, Vector2 position) { + TalosVO vo = new TalosVO(); + vo.particleName = particleName; + + if(!setEssentialData(vo, position)) return null; + Entity entity = entityFactory.createEntity(sandbox.getCurrentViewingEntity(), vo); + HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ACTION_CREATE_ITEM, entity); + + return entity; + } + public Entity createLabel(TextTool textSettings, Vector2 position) { LabelVO vo = new LabelVO(); if(!setEssentialData(vo, position)) return null; diff --git a/src/main/java/games/rednblack/editor/proxy/ProjectManager.java b/src/main/java/games/rednblack/editor/proxy/ProjectManager.java index b1e8300b..ba85075e 100755 --- a/src/main/java/games/rednblack/editor/proxy/ProjectManager.java +++ b/src/main/java/games/rednblack/editor/proxy/ProjectManager.java @@ -20,15 +20,16 @@ package games.rednblack.editor.proxy; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.tools.texturepacker.TexturePacker; import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Json; -import com.esotericsoftware.spine.SkeletonData; -import com.esotericsoftware.spine.SkeletonJson; -import com.esotericsoftware.spine.utils.SpineUtils; +import com.badlogic.gdx.utils.ObjectSet; import com.kotcrab.vis.ui.util.dialog.Dialogs; +import com.talosvfx.talos.runtime.ParticleEmitterDescriptor; +import com.talosvfx.talos.runtime.modules.AbstractModule; +import com.talosvfx.talos.runtime.modules.ShadedSpriteModule; +import com.talosvfx.talos.runtime.serialization.ExportData; import games.rednblack.editor.HyperLap2DFacade; import games.rednblack.editor.data.manager.PreferencesManager; import games.rednblack.editor.data.migrations.ProjectVersionMigrator; @@ -38,6 +39,7 @@ import games.rednblack.editor.renderer.utils.Version; import games.rednblack.editor.utils.AssetImporter; import games.rednblack.editor.utils.HyperLap2DUtils; import games.rednblack.editor.utils.ZipUtils; +import games.rednblack.editor.utils.runtime.TalosResources; import games.rednblack.editor.view.menu.HyperLap2DMenuBar; import games.rednblack.editor.view.stage.Sandbox; import games.rednblack.editor.view.ui.dialog.SettingsDialog; @@ -84,6 +86,7 @@ public class ProjectManager extends Proxy { public static final String SPINE_DIR_PATH = "assets/orig/spine-animations"; public static final String SPRITE_DIR_PATH = "assets/orig/sprite-animations"; public static final String PARTICLE_DIR_PATH = "assets/orig/particles"; + public static final String TALOS_VFX_DIR_PATH = "assets/orig/talos-vfx"; public static final String SHADER_DIR_PATH = "assets/shaders"; public ProjectVO currentProjectVO; @@ -648,6 +651,7 @@ public class ProjectManager extends Proxy { if (file.exists()) { imgs.add(new FileHandle(file)); } else { + imgs.clear(); return false; } } @@ -656,6 +660,7 @@ public class ProjectManager extends Proxy { if (file.exists()) { imgs.add(new FileHandle(file)); } else { + imgs.clear(); return false; } } @@ -721,6 +726,124 @@ public class ProjectManager extends Proxy { executor.shutdown(); } + private boolean addTalosImages(TalosResources talosResources, FileHandle fileHandle, Array imgs) { + try { + Array resources = talosResources.metadata.resources; + for (String res : resources) { + res += ".png"; + File file = new File(FilenameUtils.getFullPath(fileHandle.path()) + res); + if (file.exists()) { + imgs.add(new FileHandle(file)); + } else { + Dialogs.showErrorDialog(Sandbox.getInstance().getUIStage(), + "\nCould not find " + file.getName() + ".\nCheck if the file exists in the same directory.").padBottom(20).pack(); + imgs.clear(); + return false; + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + private boolean addTalosRes(TalosResources talosResources, FileHandle fileHandle, Array imgs) { + try { + for (TalosResources.Emitter emitter : talosResources.emitters) { + for (TalosResources.Module module : emitter.modules) { + if (module.get("shdrAssetName") != null) { + String assetName = module.get("shdrAssetName").toString(); + File file = new File(FilenameUtils.getFullPath(fileHandle.path()) + assetName); + if (file.exists()) { + imgs.add(new FileHandle(file)); + } else { + Dialogs.showErrorDialog(Sandbox.getInstance().getUIStage(), + "\nCould not find " + file.getName() + ".\nCheck if the file exists in the same directory.").padBottom(20).pack(); + imgs.clear(); + return false; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + public void importTalosIntoProject(final Array fileHandles, ProgressHandler progressHandler, boolean skipRepack) { + if (fileHandles == null) { + return; + } + Json json = new Json(); + json.setIgnoreUnknownFields(true); + ParticleEmitterDescriptor.registerModules(); + for (Class clazz: ParticleEmitterDescriptor.registeredModules) { + json.addClassTag(clazz.getSimpleName(), TalosResources.Module.class); + } + final String targetPath = currentProjectPath + "/assets/orig/talos-vfx"; + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + Array images = new Array<>(); + Array assetsRes = new Array<>(); + for (FileHandle fileHandle : new Array.ArrayIterator<>(fileHandles)) { + if (!fileHandle.isDirectory() && fileHandle.exists()) { + try { + TalosResources talosResources = json.fromJson(TalosResources.class, fileHandle); + //copy images + boolean allImagesFound = addTalosImages(talosResources, fileHandle, images); + if (allImagesFound) { + boolean allAssetFound = addTalosRes(talosResources, fileHandle, assetsRes); + if (allAssetFound) { + // copy the fileHandle + String newName = fileHandle.name(); + File target = new File(targetPath + "/" + newName); + FileUtils.copyFile(fileHandle.file(), target); + } + } + } catch (IllegalArgumentException e) { + System.out.println("Error importing particles."); + throw e; + } catch (IOException e) { + System.out.println("Error importing particles."); + e.printStackTrace(); + } + } + } + if (images.size > 0) { + copyImageFilesForAllResolutionsIntoProject(images, false, progressHandler); + } + if (assetsRes.size > 0) { + for (FileHandle fileHandle : assetsRes) { + try { + String newName = fileHandle.name(); + File target = new File(targetPath + "/" + newName); + FileUtils.copyFile(fileHandle.file(), target); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + if (!skipRepack) { + ResolutionManager resolutionManager = facade.retrieveProxy(ResolutionManager.NAME); + resolutionManager.rePackProjectImagesForAllResolutionsSync(); + } + }); + executor.execute(() -> { + progressHandler.progressChanged(100); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + progressHandler.progressComplete(); + }); + executor.shutdown(); + } + public void importAtlasesIntoProject(final Array files, ProgressHandler progressHandler) { ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(() -> { @@ -955,6 +1078,10 @@ public class ProjectManager extends Proxy { if (!currentProjectVO.projectMainExportPath.isEmpty()) { exportParticles(currentProjectVO.projectMainExportPath); } + exportTalosVFX(defaultBuildPath); + if (!currentProjectVO.projectMainExportPath.isEmpty()) { + exportTalosVFX(currentProjectVO.projectMainExportPath); + } exportShaders(defaultBuildPath); if (!currentProjectVO.projectMainExportPath.isEmpty()) { exportShaders(currentProjectVO.projectMainExportPath); @@ -1007,6 +1134,18 @@ public class ProjectManager extends Proxy { } } + private void exportTalosVFX(String targetPath) { + String srcPath = currentProjectPath + "/assets/orig"; + FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath); + FileHandle particlesDirectory = origDirectoryHandle.child("talos-vfx"); + File fileTarget = new File(targetPath + "/" + particlesDirectory.name()); + try { + FileUtils.copyDirectory(particlesDirectory.file(), fileTarget); + } catch (IOException e) { + e.printStackTrace(); + } + } + private void exportFonts(String targetPath) { String srcPath = currentProjectPath + "/assets/orig"; FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath); @@ -1370,6 +1509,12 @@ public class ProjectManager extends Proxy { return (new File(filePath)).delete(); } + public boolean deleteTalosVFX(String particleName) { + String particlePath = currentProjectPath + File.separator + TALOS_VFX_DIR_PATH + File.separator; + String filePath = particlePath + particleName; + return (new File(filePath)).delete(); + } + private boolean deleteSpineAnimation(String resolutionName, String spineName) { String spinePath = currentProjectPath + "/assets/" + resolutionName + "/spine-animations" + File.separator; String filePath = spinePath + spineName; diff --git a/src/main/java/games/rednblack/editor/proxy/ResourceManager.java b/src/main/java/games/rednblack/editor/proxy/ResourceManager.java index e4ab7ee6..f06acce6 100644 --- a/src/main/java/games/rednblack/editor/proxy/ResourceManager.java +++ b/src/main/java/games/rednblack/editor/proxy/ResourceManager.java @@ -14,6 +14,11 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.*; +import com.badlogic.gdx.utils.ObjectMap; +import com.talosvfx.talos.runtime.ParticleEffectDescriptor; +import com.talosvfx.talos.runtime.ParticleEffectInstance; +import com.talosvfx.talos.runtime.assets.AtlasAssetProvider; +import com.talosvfx.talos.runtime.utils.ShaderDescriptor; import games.rednblack.editor.renderer.data.*; import org.apache.commons.io.FileUtils; @@ -43,6 +48,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever { public static final String NAME = TAG; private final HashMap particleEffects = new HashMap<>(1); + private final HashMap talosVFXs = new HashMap<>(1); private TextureAtlas currentProjectAtlas; private final HashMap spineAnimAtlases = new HashMap<>(); @@ -96,6 +102,10 @@ public class ResourceManager extends Proxy implements IResourceRetriever { return new ParticleEffect(particleEffects.get(name)); } + @Override + public ParticleEffectDescriptor getTalosVFX(String name) { + return talosVFXs.get(name); + } @Override public TextureAtlas getSkeletonAtlas(String animationName) { @@ -163,6 +173,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever { loadCurrentProjectAssets(projectPath + "/assets/" + curResolution + "/pack/pack.atlas"); loadCurrentProjectSkin(projectPath + "/assets/orig/styles"); loadCurrentProjectParticles(projectPath + "/assets/orig/particles"); + loadCurrentProjectTalosVFXs(projectPath + "/assets/orig/talos-vfx"); loadCurrentProjectSpineAnimations(projectPath + "/assets/", curResolution); loadCurrentProjectSpriteAnimations(projectPath + "/assets/", curResolution); loadCurrentProjectBitmapFonts(projectPath, curResolution); @@ -181,9 +192,41 @@ public class ResourceManager extends Proxy implements IResourceRetriever { particleEffect.load(Gdx.files.internal(file.getAbsolutePath()), currentProjectAtlas, ""); particleEffects.put(filename, particleEffect); } - } + private void loadCurrentProjectTalosVFXs(String path) { + talosVFXs.clear(); + talosShaderPath = path; + FileHandle sourceDir = new FileHandle(path); + for (FileHandle entry : sourceDir.list()) { + File file = entry.file(); + String filename = file.getName(); + if (file.isDirectory() || filename.endsWith(".DS_Store") || filename.endsWith("shdr")) continue; + + AtlasAssetProvider assetProvider = new AtlasAssetProvider(currentProjectAtlas); + assetProvider.setAssetHandler(ShaderDescriptor.class, this::findShaderDescriptorOnLoad); + ParticleEffectDescriptor effectDescriptor = new ParticleEffectDescriptor(); + effectDescriptor.setAssetProvider(assetProvider); + effectDescriptor.load(Gdx.files.internal(file.getAbsolutePath())); + talosVFXs.put(filename, effectDescriptor); + } + } + + private ObjectMap shaderDescriptorObjectMap = new ObjectMap<>(); + private String talosShaderPath; + private ShaderDescriptor findShaderDescriptorOnLoad (String assetName) { + ShaderDescriptor asset = shaderDescriptorObjectMap.get(assetName); + if (asset == null) { + //Look in all paths, and hopefully load the requested asset, or fail (crash) + final FileHandle file = new FileHandle(talosShaderPath + File.separator + assetName); + + asset = new ShaderDescriptor(); + if (file.exists()) { + asset.setData(file.readString()); + } + } + return asset; + } private void loadCurrentProjectSpineAnimations(String path, String curResolution) { spineAnimAtlases.clear(); @@ -408,6 +451,10 @@ public class ResourceManager extends Proxy implements IResourceRetriever { return particleEffects; } + public HashMap getProjectTalosList() { + return talosVFXs; + } + @Override public ResolutionEntryVO getLoadedResolution() { if(packResolutionName.equals("orig")) { diff --git a/src/main/java/games/rednblack/editor/utils/AssetImporter.java b/src/main/java/games/rednblack/editor/utils/AssetImporter.java index 7032f1e8..37d87d89 100644 --- a/src/main/java/games/rednblack/editor/utils/AssetImporter.java +++ b/src/main/java/games/rednblack/editor/utils/AssetImporter.java @@ -90,6 +90,9 @@ public class AssetImporter { case ImportUtils.TYPE_PARTICLE_EFFECT: projectManager.importParticlesIntoProject(files, progressHandler, skipRepack); break; + case ImportUtils.TYPE_TALOS_VFX: + projectManager.importTalosIntoProject(files, progressHandler, skipRepack); + break; case ImportUtils.TYPE_SPINE_ANIMATION: projectManager.importSpineAnimationsIntoProject(files, progressHandler); break; diff --git a/src/main/java/games/rednblack/editor/utils/EntityBounds.java b/src/main/java/games/rednblack/editor/utils/EntityBounds.java index e464069c..63ec2177 100644 --- a/src/main/java/games/rednblack/editor/utils/EntityBounds.java +++ b/src/main/java/games/rednblack/editor/utils/EntityBounds.java @@ -25,6 +25,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import games.rednblack.editor.renderer.components.DimensionsComponent; import games.rednblack.editor.renderer.components.TransformComponent; +import games.rednblack.editor.renderer.components.additional.TalosComponent; import games.rednblack.editor.renderer.components.light.LightObjectComponent; import games.rednblack.editor.renderer.components.particle.ParticleComponent; import games.rednblack.editor.renderer.utils.ComponentRetriever; @@ -80,7 +81,8 @@ public class EntityBounds extends Rectangle { height = dimensionsComponent.boundBox.height; } - if (ComponentRetriever.get(entity, ParticleComponent.class) != null) { + if (ComponentRetriever.get(entity, ParticleComponent.class) != null + || ComponentRetriever.get(entity, TalosComponent.class) != null) { width = dimensionsComponent.boundBox.width; height = dimensionsComponent.boundBox.height; dimensionsComponent.width = width; diff --git a/src/main/java/games/rednblack/editor/utils/ImportUtils.java b/src/main/java/games/rednblack/editor/utils/ImportUtils.java index e2eeada8..56c8ec0d 100644 --- a/src/main/java/games/rednblack/editor/utils/ImportUtils.java +++ b/src/main/java/games/rednblack/editor/utils/ImportUtils.java @@ -51,6 +51,7 @@ public class ImportUtils { public static final int TYPE_SHADER = 10; public static final int TYPE_HYPERLAP2D_LIBRARY = 11; public static final int TYPE_HYPERLAP2D_INTERNAL_LIBRARY = 12; + public static final int TYPE_TALOS_VFX = 13; private final ArrayList supportedTypes = new ArrayList<>(); private final FileTypeFilter fileTypeFilter; @@ -61,6 +62,7 @@ public class ImportUtils { supportedTypes.add(TYPE_SPRITE_ANIMATION_ATLAS); supportedTypes.add(TYPE_SPINE_ANIMATION); supportedTypes.add(TYPE_PARTICLE_EFFECT); + supportedTypes.add(TYPE_TALOS_VFX); supportedTypes.add(TYPE_SHADER); supportedTypes.add(TYPE_HYPERLAP2D_LIBRARY); // TODO: not supported yet @@ -71,7 +73,7 @@ public class ImportUtils { fileTypeFilter.addRule("All Supported (*.png, *.atlas, *.p, *.json, *.vert, *.frag, *.h2dlib)", "png", "atlas", "p", "json", "vert", "frag", "h2dlib"); fileTypeFilter.addRule("PNG File (*.png)", "png"); fileTypeFilter.addRule("Sprite Animation Atlas File (*.atlas)", "atlas"); - fileTypeFilter.addRule("Particle Effect (*.p)", "p"); + fileTypeFilter.addRule("libGDX/Talos Particle Effect (*.p)", "p"); fileTypeFilter.addRule("Spine Animation (*.json)", "json"); fileTypeFilter.addRule("Shader (*.vert, *.frag)", "vert", "frag"); fileTypeFilter.addRule("HyperLap2D Library (*.h2dlib)", "h2dlib"); @@ -180,12 +182,10 @@ public class ImportUtils { return type; } - System.out.println("is spine?"); // checking for spine animation if (contents.contains("\"skeleton\":{") || contents.contains("\"skeleton\": {") || contents.contains("{\"bones\":[")) { type = TYPE_SPINE_ANIMATION; - System.out.println("is spine"); return type; } @@ -195,6 +195,11 @@ public class ImportUtils { return type; } + // checking for particle effect + if (contents.contains("emitters")) { + type = TYPE_TALOS_VFX; + return type; + } } catch (IOException ignore) { } @@ -266,6 +271,10 @@ public class ImportUtils { dir = ProjectManager.PARTICLE_DIR_PATH; ext = "p"; break; + case ImportUtils.TYPE_TALOS_VFX: + dir = ProjectManager.TALOS_VFX_DIR_PATH; + ext = "p"; + break; case ImportUtils.TYPE_SPINE_ANIMATION: dir = ProjectManager.SPINE_DIR_PATH; ext = "json"; diff --git a/src/main/java/games/rednblack/editor/utils/runtime/EntityUtils.java b/src/main/java/games/rednblack/editor/utils/runtime/EntityUtils.java index c6481f9e..1c9ffcc9 100644 --- a/src/main/java/games/rednblack/editor/utils/runtime/EntityUtils.java +++ b/src/main/java/games/rednblack/editor/utils/runtime/EntityUtils.java @@ -338,6 +338,10 @@ public class EntityUtils { ParticleEffectVO vo = json.fromJson(ParticleEffectVO.class, jsonString); return factory.createEntity(parent, vo); } + if(entityType == EntityFactory.TALOS_TYPE) { + TalosVO vo = json.fromJson(TalosVO.class, jsonString); + return factory.createEntity(parent, vo); + } if(entityType == EntityFactory.SPRITE_TYPE) { SpriteAnimationVO vo = json.fromJson(SpriteAnimationVO.class, jsonString); return factory.createEntity(parent, vo); @@ -385,6 +389,11 @@ public class EntityUtils { vo.loadFromEntity(entity); return json.toJson(vo); } + if(entityType == EntityFactory.TALOS_TYPE) { + TalosVO vo = new TalosVO(); + vo.loadFromEntity(entity); + return json.toJson(vo); + } if(entityType == EntityFactory.SPRITE_TYPE) { SpriteAnimationVO vo = new SpriteAnimationVO(); vo.loadFromEntity(entity); @@ -437,6 +446,11 @@ public class EntityUtils { vo.loadFromEntity(entity); holderComposite.sParticleEffects.add(vo); } + if(entityType == EntityFactory.TALOS_TYPE) { + TalosVO vo = new TalosVO(); + vo.loadFromEntity(entity); + holderComposite.sTalosVFX.add(vo); + } if(entityType == EntityFactory.SPRITE_TYPE) { SpriteAnimationVO vo = new SpriteAnimationVO(); vo.loadFromEntity(entity); diff --git a/src/main/java/games/rednblack/editor/utils/runtime/TalosResources.java b/src/main/java/games/rednblack/editor/utils/runtime/TalosResources.java new file mode 100644 index 00000000..2a1f1111 --- /dev/null +++ b/src/main/java/games/rednblack/editor/utils/runtime/TalosResources.java @@ -0,0 +1,24 @@ +package games.rednblack.editor.utils.runtime; + +import com.badlogic.gdx.utils.Array; + +import java.util.HashMap; + +public class TalosResources { + + public Metadata metadata = new Metadata(); + + public Array emitters = new Array<>(); + + public static class Metadata { + public Array resources = new Array<>(); + } + + public static class Emitter { + public Array modules = new Array<>(); + } + + public static class Module extends HashMap { + + } +} diff --git a/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenu.java b/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenu.java index 1483ace6..0b044c03 100644 --- a/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenu.java +++ b/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenu.java @@ -54,6 +54,7 @@ public class UIDropDownMenu extends H2DPopupMenu { actionNames.put(MsgAPI.ACTION_DELETE_IMAGE_RESOURCE, "Delete"); actionNames.put(MsgAPI.ACTION_DELETE_LIBRARY_ITEM, "Delete"); actionNames.put(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT, "Delete"); + actionNames.put(MsgAPI.ACTION_DELETE_TALOS_VFX, "Delete"); actionNames.put(MsgAPI.ACTION_DELETE_LIBRARY_ACTION, "Delete"); actionNames.put(MsgAPI.ACTION_DELETE_SPRITE_ANIMATION_RESOURCE, "Delete"); actionNames.put(MsgAPI.ACTION_DELETE_SPINE_ANIMATION_RESOURCE, "Delete"); diff --git a/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenuMediator.java b/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenuMediator.java index c62eeb64..0d801c52 100644 --- a/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenuMediator.java +++ b/src/main/java/games/rednblack/editor/view/ui/UIDropDownMenuMediator.java @@ -51,6 +51,7 @@ public class UIDropDownMenuMediator extends Mediator { public static final Integer POLYGON_VERTEX_ACTION_SET = 10; public static final Integer ORIGIN_POINT_ACTION_SET = 11; public static final Integer LIBRARY_ACTION_ACTION_SET = 12; + public static final Integer TALOS_ACTION_SET = 13; private Sandbox sandbox; @@ -92,6 +93,9 @@ public class UIDropDownMenuMediator extends Mediator { actionSets.put(PARTICLE_ACTION_SET, new Array<>()); actionSets.get(PARTICLE_ACTION_SET).add(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT); + actionSets.put(TALOS_ACTION_SET, new Array<>()); + actionSets.get(TALOS_ACTION_SET).add(MsgAPI.ACTION_DELETE_TALOS_VFX); + actionSets.put(ITEMS_ACTIONS_SET, new Array<>()); actionSets.get(ITEMS_ACTIONS_SET).add(MsgAPI.ACTION_CUT); actionSets.get(ITEMS_ACTIONS_SET).add(MsgAPI.ACTION_COPY); @@ -124,6 +128,7 @@ public class UIDropDownMenuMediator extends Mediator { UIResourcesBoxMediator.SPRITE_ANIMATION_RIGHT_CLICK, UIResourcesBoxMediator.LIBRARY_ITEM_RIGHT_CLICK, UIResourcesBoxMediator.PARTICLE_EFFECT_RIGHT_CLICK, + UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK, UIResourcesBoxMediator.LIBRARY_ACTION_RIGHT_CLICK, RulersUI.RIGHT_CLICK_RULER, PolygonTool.MANUAL_VERTEX_POSITION, @@ -181,6 +186,9 @@ public class UIDropDownMenuMediator extends Mediator { case UIResourcesBoxMediator.PARTICLE_EFFECT_RIGHT_CLICK: showPopup(PARTICLE_ACTION_SET, notification.getBody()); break; + case UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK: + showPopup(TALOS_ACTION_SET, notification.getBody()); + break; case RulersUI.RIGHT_CLICK_RULER: showPopup(RULER_RESOURCE_ACTION_SET, notification.getBody()); break; diff --git a/src/main/java/games/rednblack/editor/view/ui/box/UIResourcesBoxMediator.java b/src/main/java/games/rednblack/editor/view/ui/box/UIResourcesBoxMediator.java index deef1190..fa1bf215 100644 --- a/src/main/java/games/rednblack/editor/view/ui/box/UIResourcesBoxMediator.java +++ b/src/main/java/games/rednblack/editor/view/ui/box/UIResourcesBoxMediator.java @@ -37,16 +37,17 @@ public class UIResourcesBoxMediator extends PanelMediator { private static final String TAG = UIResourcesBoxMediator.class.getCanonicalName(); public static final String NAME = TAG; - private static final String PREFIX = "games.rednblack.editor.view.ui.box"; + private static final String PREFIX = "games.rednblack.editor.view.ui.box.UIResourcesBoxMediator"; - public static final String IMAGE_RIGHT_CLICK = "IMAGE_RIGHT_CLICK"; - public static final String SPINE_ANIMATION_RIGHT_CLICK = "SPINE_ANIMATION_RIGHT_CLICK"; - public static final String SPRITE_ANIMATION_RIGHT_CLICK = "SPRITE_ANIMATION_RIGHT_CLICK"; - public static final String LIBRARY_ITEM_RIGHT_CLICK = "LIBRARY_ITEM_RIGHT_CLICK"; - public static final String PARTICLE_EFFECT_RIGHT_CLICK = "PARTICLE_EFFECT_RIGHT_CLICK"; - public static final String LIBRARY_ACTION_RIGHT_CLICK = "LIBRARY_ACTION_RIGHT_CLICK"; + public static final String IMAGE_RIGHT_CLICK = PREFIX + ".IMAGE_RIGHT_CLICK"; + public static final String SPINE_ANIMATION_RIGHT_CLICK = PREFIX + ".SPINE_ANIMATION_RIGHT_CLICK"; + public static final String SPRITE_ANIMATION_RIGHT_CLICK = PREFIX + ".SPRITE_ANIMATION_RIGHT_CLICK"; + public static final String LIBRARY_ITEM_RIGHT_CLICK = PREFIX + ".LIBRARY_ITEM_RIGHT_CLICK"; + public static final String PARTICLE_EFFECT_RIGHT_CLICK = PREFIX + ".PARTICLE_EFFECT_RIGHT_CLICK"; + public static final String TALOS_VFX_RIGHT_CLICK = PREFIX + ".TALOS_VFX_RIGHT_CLICK"; + public static final String LIBRARY_ACTION_RIGHT_CLICK = PREFIX + ".LIBRARY_ACTION_RIGHT_CLICK"; - public Array customTargets = new Array(); + public Array customTargets = new Array<>(); @Override public void onRegister() { diff --git a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIAnimationsTabMediator.java b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIAnimationsTabMediator.java index cffa4d37..9533aab6 100644 --- a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIAnimationsTabMediator.java +++ b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/UIAnimationsTabMediator.java @@ -77,7 +77,6 @@ public class UIAnimationsTabMediator extends UIResourcesTabMediator particlesList; + public UIParticleEffectsTabMediator() { super(NAME, new UIParticleEffectsTab()); + particlesList = new Array<>(); } @Override public String[] listNotificationInterests() { String[] listNotification = super.listNotificationInterests(); listNotification = ArrayUtils.add(listNotification, DeleteParticleEffect.DONE); + listNotification = ArrayUtils.add(listNotification, DeleteTalosVFX.DONE); return listNotification; } @@ -54,6 +63,7 @@ public class UIParticleEffectsTabMediator extends UIResourcesTabMediator particles = resourceManager.getProjectParticleList(); - Array itemArray = new Array<>(); - for (String name : particles.keySet()) { - if(!name.contains(searchText))continue; - DraggableResource draggableResource = new DraggableResource(new ParticleEffectResource(name)); - draggableResource.setFactoryFunction(ItemFactory.get()::tryCreateParticleItem); - itemArray.add(draggableResource); + createAnimationResources(resourceManager.getProjectTalosList().keySet(), TalosResource.class, ItemFactory.get()::tryCreateTalosItem, searchText); + createAnimationResources(resourceManager.getProjectParticleList().keySet(), ParticleEffectResource.class, ItemFactory.get()::tryCreateParticleItem, searchText); + viewComponent.setItems(particlesList); + } + + + private void createAnimationResources(Set strings, Class resourceClass, BiFunction factoryFunction, String searchText) { + for (String animationName : strings) { + if (!animationName.contains(searchText)) continue; + try { + Constructor constructor = resourceClass.getConstructor(String.class); + DraggableResource draggableResource = new DraggableResource((DraggableResourceView) constructor.newInstance(animationName)); + draggableResource.setFactoryFunction(factoryFunction); + particlesList.add(draggableResource); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } } - viewComponent.setItems(itemArray); } } diff --git a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/ParticleEffectResource.java b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/ParticleEffectResource.java index 77f41fd9..c44c80f3 100644 --- a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/ParticleEffectResource.java +++ b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/ParticleEffectResource.java @@ -32,7 +32,6 @@ public class ParticleEffectResource extends ListItemResource { private final Image payloadImg; private final ResourcePayloadObject payload; - public ParticleEffectResource(String particleName) { super(particleName, "particle"); facade = HyperLap2DFacade.getInstance(); @@ -59,5 +58,4 @@ public class ParticleEffectResource extends ListItemResource { public ResourcePayloadObject getPayloadData() { return payload; } - } diff --git a/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/TalosResource.java b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/TalosResource.java new file mode 100644 index 00000000..f067d0fe --- /dev/null +++ b/src/main/java/games/rednblack/editor/view/ui/box/resourcespanel/draggable/list/TalosResource.java @@ -0,0 +1,41 @@ +package games.rednblack.editor.view.ui.box.resourcespanel.draggable.list; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import games.rednblack.editor.HyperLap2DFacade; +import games.rednblack.editor.view.ui.box.UIResourcesBoxMediator; +import games.rednblack.h2d.common.ResourcePayloadObject; + +public class TalosResource extends ListItemResource { + private final HyperLap2DFacade facade; + private final Image payloadImg; + private final ResourcePayloadObject payload; + + + public TalosResource(String particleName) { + super(particleName, "particle"); + facade = HyperLap2DFacade.getInstance(); + payloadImg = new Image(getStyle().resourceOver) { + @Override + public void setScale(float scaleXY) { + //Do not scale + } + }; + payloadImg.setScale(2); + payloadImg.getColor().a = .85f; + payload = new ResourcePayloadObject(); + payload.name = particleName; + setRightClickEvent(UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK, payload.name); + payload.className = getClass().getName(); + } + + @Override + public Actor getDragActor() { + return payloadImg; + } + + @Override + public ResourcePayloadObject getPayloadData() { + return payload; + } +} diff --git a/src/main/java/games/rednblack/editor/view/ui/followers/FollowerFactory.java b/src/main/java/games/rednblack/editor/view/ui/followers/FollowerFactory.java index a3942d93..3c402daf 100644 --- a/src/main/java/games/rednblack/editor/view/ui/followers/FollowerFactory.java +++ b/src/main/java/games/rednblack/editor/view/ui/followers/FollowerFactory.java @@ -33,6 +33,7 @@ public class FollowerFactory { return new ImageFollower(entity); case EntityFactory.LIGHT_TYPE: return new LightFollower(entity); + case EntityFactory.TALOS_TYPE: case EntityFactory.PARTICLE_TYPE: return new ParticleFollower(entity); case EntityFactory.SPINE_TYPE: diff --git a/src/main/java/games/rednblack/editor/view/ui/followers/ParticleFollower.java b/src/main/java/games/rednblack/editor/view/ui/followers/ParticleFollower.java index 0bbfbe14..88a75045 100644 --- a/src/main/java/games/rednblack/editor/view/ui/followers/ParticleFollower.java +++ b/src/main/java/games/rednblack/editor/view/ui/followers/ParticleFollower.java @@ -36,6 +36,7 @@ public class ParticleFollower extends BasicFollower { public ParticleFollower(Entity entity) { super(entity); + setTransform(false); } @Override diff --git a/src/main/java/games/rednblack/editor/view/ui/panel/ImportPanel.java b/src/main/java/games/rednblack/editor/view/ui/panel/ImportPanel.java index 6a3cd164..fc3de663 100644 --- a/src/main/java/games/rednblack/editor/view/ui/panel/ImportPanel.java +++ b/src/main/java/games/rednblack/editor/view/ui/panel/ImportPanel.java @@ -103,6 +103,7 @@ public class ImportPanel extends UIDraggablePanel { typeNames.put(ImportUtils.TYPE_TTF_FONT, "TTF Font"); typeNames.put(ImportUtils.TYPE_HYPERLAP2D_LIBRARY, "HyperLap2D Library"); typeNames.put(ImportUtils.TYPE_SHADER, "Shader"); + typeNames.put(ImportUtils.TYPE_TALOS_VFX, "Talos VFX"); } public static class DropBundle {