Add support for default colors and color restrictions based on particle type in particle management.

This commit is contained in:
akastijn 2026-02-08 00:11:21 +01:00
parent 0e4ce21c58
commit 138c01cf25
4 changed files with 248 additions and 13 deletions

View File

@ -8,7 +8,7 @@
<div class="property-row">
<mat-form-field appearance="outline">
<mat-label>Current color: {{ selectedColor }}</mat-label>
<input type="color" class="color-input" matInput [(ngModel)]="selectedColor">
<input type="color" class="color-input" matInput [(ngModel)]="selectedColor" [disabled]="supportsColor">
</mat-form-field>
<mat-form-field appearance="outline" class="type-field">
<mat-label>Select Particle Type</mat-label>

View File

@ -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
*/

View File

@ -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<Record<Particle, string>> = {
[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'
};

View File

@ -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 {