From 138c01cf253c6af6b75cc8919d965d884f164417 Mon Sep 17 00:00:00 2001 From: akastijn Date: Sun, 8 Feb 2026 00:11:21 +0100 Subject: [PATCH] Add support for default colors and color restrictions based on particle type in particle management. --- .../particle/particle.component.html | 2 +- .../components/particle/particle.component.ts | 8 +- .../pages/particles/models/particle.model.ts | 228 +++++++++++++++++- .../services/particle-manager.service.ts | 23 +- 4 files changed, 248 insertions(+), 13 deletions(-) diff --git a/frontend/src/app/pages/particles/components/particle/particle.component.html b/frontend/src/app/pages/particles/components/particle/particle.component.html index 32ca199..c029ec1 100644 --- a/frontend/src/app/pages/particles/components/particle/particle.component.html +++ b/frontend/src/app/pages/particles/components/particle/particle.component.html @@ -8,7 +8,7 @@
Current color: {{ selectedColor }} - + Select Particle Type diff --git a/frontend/src/app/pages/particles/components/particle/particle.component.ts b/frontend/src/app/pages/particles/components/particle/particle.component.ts index 6d71575..a412159 100644 --- a/frontend/src/app/pages/particles/components/particle/particle.component.ts +++ b/frontend/src/app/pages/particles/components/particle/particle.component.ts @@ -10,7 +10,7 @@ import {MatInputModule} from '@angular/material/input'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {Observable} from 'rxjs'; import {map, startWith} from 'rxjs/operators'; -import { AsyncPipe } from '@angular/common'; +import {AsyncPipe} from '@angular/common'; @Component({ selector: 'app-particle', @@ -27,7 +27,7 @@ import { AsyncPipe } from '@angular/common'; MatInputModule, MatAutocompleteModule, AsyncPipe -], + ], templateUrl: './particle.component.html', styleUrl: './particle.component.scss' }) @@ -70,6 +70,10 @@ export class ParticleComponent implements OnInit { return particle ? particle : ''; } + public get supportsColor(): boolean { + return this.particleManagerService.supportsColor; + } + /** * Get the selected color */ diff --git a/frontend/src/app/pages/particles/models/particle.model.ts b/frontend/src/app/pages/particles/models/particle.model.ts index 90a3548..a3d3aa6 100644 --- a/frontend/src/app/pages/particles/models/particle.model.ts +++ b/frontend/src/app/pages/particles/models/particle.model.ts @@ -1,11 +1,12 @@ -/** - * Defines the types of particles available in the system - */ -export enum Particle { - DUST = 'DUST', - DUST_COLOR_TRANSITION = 'DUST_COLOR_TRANSITION', - TINTED_LEAVES = 'TINTED_LEAVES' - // Other particle types can be added later +export function supportsColors(particle: Particle): boolean { + switch (particle) { + case Particle.DUST: + case Particle.DUST_COLOR_TRANSITION: + case Particle.TINTED_LEAVES: + return true; + default: + return false + } } export enum ParticleType { @@ -52,3 +53,214 @@ export interface ParticleData { [frameId: string]: ParticleInfo[]; }; } + +/** + * Defines the types of particles available in the system + */ +export enum Particle { + DUST = 'DUST', + DUST_COLOR_TRANSITION = 'DUST_COLOR_TRANSITION', + TINTED_LEAVES = 'TINTED_LEAVES', + POOF = 'POOF', + EXPLOSION = 'EXPLOSION', + EXPLOSION_EMITTER = 'EXPLOSION_EMITTER', + FIREWORK = 'FIREWORK', + BUBBLE = 'BUBBLE', + SPLASH = 'SPLASH', + FISHING = 'FISHING', + UNDERWATER = 'UNDERWATER', + CRIT = 'CRIT', + ENCHANTED_HIT = 'ENCHANTED_HIT', + SMOKE = 'SMOKE', + LARGE_SMOKE = 'LARGE_SMOKE', + WITCH = 'WITCH', + DRIPPING_WATER = 'DRIPPING_WATER', + DRIPPING_LAVA = 'DRIPPING_LAVA', + ANGRY_VILLAGER = 'ANGRY_VILLAGER', + HAPPY_VILLAGER = 'HAPPY_VILLAGER', + MYCELIUM = 'MYCELIUM', + NOTE = 'NOTE', + PORTAL = 'PORTAL', + ENCHANT = 'ENCHANT', + FLAME = 'FLAME', + LAVA = 'LAVA', + CLOUD = 'CLOUD', + ITEM_SNOWBALL = 'ITEM_SNOWBALL', + ITEM_SLIME = 'ITEM_SLIME', + HEART = 'HEART', + RAIN = 'RAIN', + ELDER_GUARDIAN = 'ELDER_GUARDIAN', + END_ROD = 'END_ROD', + DAMAGE_INDICATOR = 'DAMAGE_INDICATOR', + SWEEP_ATTACK = 'SWEEP_ATTACK', + TOTEM_OF_UNDYING = 'TOTEM_OF_UNDYING', + SPIT = 'SPIT', + SQUID_INK = 'SQUID_INK', + BUBBLE_POP = 'BUBBLE_POP', + CURRENT_DOWN = 'CURRENT_DOWN', + BUBBLE_COLUMN_UP = 'BUBBLE_COLUMN_UP', + NAUTILUS = 'NAUTILUS', + DOLPHIN = 'DOLPHIN', + SNEEZE = 'SNEEZE', + CAMPFIRE_COSY_SMOKE = 'CAMPFIRE_COSY_SMOKE', + CAMPFIRE_SIGNAL_SMOKE = 'CAMPFIRE_SIGNAL_SMOKE', + COMPOSTER = 'COMPOSTER', + FALLING_LAVA = 'FALLING_LAVA', + LANDING_LAVA = 'LANDING_LAVA', + FALLING_WATER = 'FALLING_WATER', + DRIPPING_HONEY = 'DRIPPING_HONEY', + FALLING_HONEY = 'FALLING_HONEY', + LANDING_HONEY = 'LANDING_HONEY', + FALLING_NECTAR = 'FALLING_NECTAR', + SOUL_FIRE_FLAME = 'SOUL_FIRE_FLAME', + ASH = 'ASH', + CRIMSON_SPORE = 'CRIMSON_SPORE', + WARPED_SPORE = 'WARPED_SPORE', + SOUL = 'SOUL', + DRIPPING_OBSIDIAN_TEAR = 'DRIPPING_OBSIDIAN_TEAR', + FALLING_OBSIDIAN_TEAR = 'FALLING_OBSIDIAN_TEAR', + LANDING_OBSIDIAN_TEAR = 'LANDING_OBSIDIAN_TEAR', + REVERSE_PORTAL = 'REVERSE_PORTAL', + WHITE_ASH = 'WHITE_ASH', + FALLING_SPORE_BLOSSOM = 'FALLING_SPORE_BLOSSOM', + SPORE_BLOSSOM_AIR = 'SPORE_BLOSSOM_AIR', + SMALL_FLAME = 'SMALL_FLAME', + SNOWFLAKE = 'SNOWFLAKE', + DRIPPING_DRIPSTONE_LAVA = 'DRIPPING_DRIPSTONE_LAVA', + FALLING_DRIPSTONE_LAVA = 'FALLING_DRIPSTONE_LAVA', + DRIPPING_DRIPSTONE_WATER = 'DRIPPING_DRIPSTONE_WATER', + FALLING_DRIPSTONE_WATER = 'FALLING_DRIPSTONE_WATER', + GLOW_SQUID_INK = 'GLOW_SQUID_INK', + GLOW = 'GLOW', + WAX_ON = 'WAX_ON', + WAX_OFF = 'WAX_OFF', + ELECTRIC_SPARK = 'ELECTRIC_SPARK', + SCRAPE = 'SCRAPE', + SONIC_BOOM = 'SONIC_BOOM', + SCULK_SOUL = 'SCULK_SOUL', + SCULK_CHARGE_POP = 'SCULK_CHARGE_POP', + CHERRY_LEAVES = 'CHERRY_LEAVES', + PALE_OAK_LEAVES = 'PALE_OAK_LEAVES', + EGG_CRACK = 'EGG_CRACK', + DUST_PLUME = 'DUST_PLUME', + WHITE_SMOKE = 'WHITE_SMOKE', + GUST = 'GUST', + SMALL_GUST = 'SMALL_GUST', + GUST_EMITTER_LARGE = 'GUST_EMITTER_LARGE', + GUST_EMITTER_SMALL = 'GUST_EMITTER_SMALL', + TRIAL_SPAWNER_DETECTION = 'TRIAL_SPAWNER_DETECTION', + TRIAL_SPAWNER_DETECTION_OMINOUS = 'TRIAL_SPAWNER_DETECTION_OMINOUS', + VAULT_CONNECTION = 'VAULT_CONNECTION', + INFESTED = 'INFESTED', + ITEM_COBWEB = 'ITEM_COBWEB', + FIREFLY = 'FIREFLY', + OMINOUS_SPAWNING = 'OMINOUS_SPAWNING', + RAID_OMEN = 'RAID_OMEN', + TRIAL_OMEN = 'TRIAL_OMEN', + COPPER_FIRE_FLAME = 'COPPER_FIRE_FLAME' +} + +export function getDefaultParticleColor(particle: Particle): string | undefined { + return ParticleColorDefaults[particle]; +} + +export const ParticleColorDefaults: Partial> = { + [Particle.POOF]: '#E0E0E0', + [Particle.EXPLOSION]: '#FFB300', + [Particle.EXPLOSION_EMITTER]: '#FF9800', + [Particle.FIREWORK]: '#FF4081', + [Particle.BUBBLE]: '#80DEEA', + [Particle.SPLASH]: '#4FC3F7', + [Particle.FISHING]: '#81D4FA', + [Particle.UNDERWATER]: '#0288D1', + [Particle.CRIT]: '#B0BEC5', + [Particle.ENCHANTED_HIT]: '#7E57C2', + [Particle.SMOKE]: '#9E9E9E', + [Particle.LARGE_SMOKE]: '#757575', + [Particle.WITCH]: '#9C27B0', + [Particle.DRIPPING_WATER]: '#4FC3F7', + [Particle.DRIPPING_LAVA]: '#FF5722', + [Particle.ANGRY_VILLAGER]: '#FF1744', + [Particle.HAPPY_VILLAGER]: '#8BC34A', + [Particle.MYCELIUM]: '#6D4C41', + [Particle.NOTE]: '#FFEB3B', + [Particle.PORTAL]: '#7B1FA2', + [Particle.ENCHANT]: '#64B5F6', + [Particle.FLAME]: '#FF6F00', + [Particle.LAVA]: '#FF3D00', + [Particle.CLOUD]: '#ECEFF1', + [Particle.ITEM_SNOWBALL]: '#FFFFFF', + [Particle.ITEM_SLIME]: '#66BB6A', + [Particle.HEART]: '#E53935', + [Particle.RAIN]: '#90CAF9', + [Particle.ELDER_GUARDIAN]: '#80CBC4', + [Particle.END_ROD]: '#F5F5F5', + [Particle.DAMAGE_INDICATOR]: '#D32F2F', + [Particle.SWEEP_ATTACK]: '#CFD8DC', + [Particle.TOTEM_OF_UNDYING]: '#FFD54F', + [Particle.SPIT]: '#A1887F', + [Particle.SQUID_INK]: '#263238', + [Particle.BUBBLE_POP]: '#B3E5FC', + [Particle.CURRENT_DOWN]: '#0277BD', + [Particle.BUBBLE_COLUMN_UP]: '#4DD0E1', + [Particle.NAUTILUS]: '#B39DDB', + [Particle.DOLPHIN]: '#4FC3F7', + [Particle.SNEEZE]: '#C5E1A5', + [Particle.CAMPFIRE_COSY_SMOKE]: '#BDBDBD', + [Particle.CAMPFIRE_SIGNAL_SMOKE]: '#757575', + [Particle.COMPOSTER]: '#8D6E63', + [Particle.FALLING_LAVA]: '#FF7043', + [Particle.LANDING_LAVA]: '#E64A19', + [Particle.FALLING_WATER]: '#81D4FA', + [Particle.DRIPPING_HONEY]: '#FFB300', + [Particle.FALLING_HONEY]: '#FFA000', + [Particle.LANDING_HONEY]: '#FF8F00', + [Particle.FALLING_NECTAR]: '#FFD54F', + [Particle.SOUL_FIRE_FLAME]: '#29B6F6', + [Particle.ASH]: '#B0BEC5', + [Particle.CRIMSON_SPORE]: '#C62828', + [Particle.WARPED_SPORE]: '#26A69A', + [Particle.SOUL]: '#64FFDA', + [Particle.DRIPPING_OBSIDIAN_TEAR]: '#5E35B1', + [Particle.FALLING_OBSIDIAN_TEAR]: '#512DA8', + [Particle.LANDING_OBSIDIAN_TEAR]: '#4527A0', + [Particle.REVERSE_PORTAL]: '#9575CD', + [Particle.WHITE_ASH]: '#ECEFF1', + [Particle.FALLING_SPORE_BLOSSOM]: '#F8BBD0', + [Particle.SPORE_BLOSSOM_AIR]: '#F48FB1', + [Particle.SMALL_FLAME]: '#FF8F00', + [Particle.SNOWFLAKE]: '#E1F5FE', + [Particle.DRIPPING_DRIPSTONE_LAVA]: '#FF5722', + [Particle.FALLING_DRIPSTONE_LAVA]: '#F4511E', + [Particle.DRIPPING_DRIPSTONE_WATER]: '#4FC3F7', + [Particle.FALLING_DRIPSTONE_WATER]: '#29B6F6', + [Particle.GLOW_SQUID_INK]: '#00E5FF', + [Particle.GLOW]: '#FFFF8D', + [Particle.WAX_ON]: '#FFD54F', + [Particle.WAX_OFF]: '#BDBDBD', + [Particle.ELECTRIC_SPARK]: '#76FF03', + [Particle.SCRAPE]: '#BCAAA4', + [Particle.SONIC_BOOM]: '#00B0FF', + [Particle.SCULK_SOUL]: '#00E676', + [Particle.SCULK_CHARGE_POP]: '#1DE9B6', + [Particle.CHERRY_LEAVES]: '#F48FB1', + [Particle.PALE_OAK_LEAVES]: '#A5D6A7', + [Particle.EGG_CRACK]: '#FFFDE7', + [Particle.DUST_PLUME]: '#D7CCC8', + [Particle.WHITE_SMOKE]: '#F5F5F5', + [Particle.GUST]: '#CFD8DC', + [Particle.SMALL_GUST]: '#ECEFF1', + [Particle.GUST_EMITTER_LARGE]: '#B0BEC5', + [Particle.GUST_EMITTER_SMALL]: '#CFD8DC', + [Particle.TRIAL_SPAWNER_DETECTION]: '#42A5F5', + [Particle.TRIAL_SPAWNER_DETECTION_OMINOUS]: '#D50000', + [Particle.VAULT_CONNECTION]: '#64B5F6', + [Particle.INFESTED]: '#7E7E7E', + [Particle.ITEM_COBWEB]: '#EEEEEE', + [Particle.FIREFLY]: '#FFF176', + [Particle.OMINOUS_SPAWNING]: '#B71C1C', + [Particle.RAID_OMEN]: '#C62828', + [Particle.TRIAL_OMEN]: '#AD1457', + [Particle.COPPER_FIRE_FLAME]: '#4DD0E1' +}; + diff --git a/frontend/src/app/pages/particles/services/particle-manager.service.ts b/frontend/src/app/pages/particles/services/particle-manager.service.ts index 1aca2a4..927b8a7 100644 --- a/frontend/src/app/pages/particles/services/particle-manager.service.ts +++ b/frontend/src/app/pages/particles/services/particle-manager.service.ts @@ -1,7 +1,14 @@ import {inject, Injectable} from '@angular/core'; import * as THREE from 'three'; import {RendererService} from './renderer.service'; -import {Particle, ParticleData, ParticleInfo, ParticleType} from '../models/particle.model'; +import { + getDefaultParticleColor, + Particle, + ParticleData, + ParticleInfo, + ParticleType, + supportsColors +} from '../models/particle.model'; import {IntersectionPlaneService, PlaneOrientation} from './intersection-plane.service'; import {deepCopy} from '../../../util/deep-copy.util'; @@ -34,9 +41,10 @@ export class ParticleManagerService { private frames: string[] = ['frame-0']; private selectedColor: string = '#ff0000'; private selectedParticle: Particle = Particle.DUST; + private supports_color: boolean = true; private selectedSize: number = 1; - private onlyIntersecting: boolean = false; + private onlyIntersecting: boolean = false; private readonly rendererService = inject(RendererService); private readonly intersectionPlaneService = inject(IntersectionPlaneService); @@ -223,6 +231,10 @@ export class ParticleManagerService { this.selectedColor = color; } + public get supportsColor(): boolean { + return this.supports_color; + } + /** * Gets the selected color */ @@ -236,6 +248,13 @@ export class ParticleManagerService { public set particle(selectedParticle: Particle) { this.selectedParticle = selectedParticle; + this.supports_color = supportsColors(selectedParticle); + if (!this.supports_color) { + const defaultParticleColor = getDefaultParticleColor(selectedParticle); + if (defaultParticleColor) { + this.selectedColor = defaultParticleColor; + } + } } public get size(): number {