mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-13 07:15:10 +00:00
feat: structures cosmetic effect (hover-shown gradient/transition recolor) (#4492)
## Description: Adds a new `structures` cosmetic effect type: an equippable effect that recolors the owner's structure icons (City, Port, Factory, Defense Post, SAM Launcher, Missile Silo) with gradient or transition color styles. The effect is **shown while the owner's territory is hovered** — structures otherwise keep their normal player colors, so the map stays readable. **Cosmetics / selection** - `StructuresEffectAttributesSchema` (`CosmeticSchemas.ts`): its own discriminated union (`gradient` / `transition`) — structurally identical to the trail attributes today, but structures aren't trails, so it's a separate schema free to diverge. - Slot = the effectType itself: `effectTypeForSlot` is generalized to map any non-nukeExplosion effect type to itself, so server privilege checks (`Privilege.ts`), client selection, and persistence all work with no per-type code. - Effects tab, Default tile, and the store preview (shared color swatch) come from `EFFECT_TYPES`; the only UI addition is the `effects.type.structures` label in `en.json`. **Rendering** - The shared per-player effect palette grows from 2 to 3 blocks (`EFFECT_PALETTE_BLOCKS`; structures = block 2, pinned by a build-breaking guard). `syncPlayerEffects` resolves the `structures` selection through the same `writeEffectEntry` used by trails. - `StructurePass` binds the effect texture plus `uTime` and `uHoverOwner` (fed from the existing `HoverHighlightController` → `setHighlightOwner` path, now forwarded to the pass). - `structure.frag.glsl` recolors the **fill only** — the border keeps the player color for ownership legibility; alt view and construction gray bypass the effect entirely. - Style semantics: - `gradient` — the palette spans each icon's diagonal once (a visible gradient across the shape), sliding one full cycle every `colorSize · 4 · count / movementSpeed` seconds (the trail-equivalent pace; world-space banding like the trail's would put a whole icon inside one band and read as a flat color) - `transition` — the whole icon is one color at a time, cross-fading at `frequency` colors/s - Glyph contrast: the inner icon's black/white decision is now a smooth luminance fade (`smoothstep(0.25, 0.45)`) instead of a hard flip at 0.25, so animated fills cross-fade the glyph instead of snapping it between black and white. ## Please complete the following: - [ ] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -188,8 +188,9 @@ export class CosmeticButton extends LitElement {
|
||||
</div>`;
|
||||
}
|
||||
// Nuke explosions preview per visual type (expanding ring or sparkle
|
||||
// burst); every trail effectType (transportShipTrail, nukeTrail) shares
|
||||
// the same attributes shape and previews as a color swatch.
|
||||
// burst); every trail effectType (transportShipTrail, nukeTrail) and the
|
||||
// structures effect share the same attribute shapes and preview as a
|
||||
// color swatch.
|
||||
if (isNukeExplosionEffect(c)) {
|
||||
if (c.attributes.type === "sparkles") {
|
||||
return html`<sparkles-swatch
|
||||
|
||||
@@ -2,6 +2,7 @@ import { html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import {
|
||||
NukeExplosionAttributes,
|
||||
StructuresEffectAttributes,
|
||||
TrailEffectAttributes,
|
||||
} from "../../core/CosmeticSchemas";
|
||||
|
||||
@@ -9,7 +10,8 @@ import {
|
||||
const EMPTY_BG = "#444";
|
||||
|
||||
/**
|
||||
* Swatch preview of a transport-ship-trail effect, filling its container.
|
||||
* Swatch preview of a trail-styled effect (trails and the structures effect
|
||||
* share the same gradient/transition attribute shapes), filling its container.
|
||||
*
|
||||
* - gradient / single color: a static swatch (flat color or left-to-right
|
||||
* gradient — a multi-color list reads as a rainbow).
|
||||
@@ -20,7 +22,7 @@ const EMPTY_BG = "#444";
|
||||
export class TrailSwatch extends LitElement {
|
||||
// Named `trail` (not `attributes`) to avoid clashing with Element.attributes.
|
||||
@property({ attribute: false })
|
||||
trail: TrailEffectAttributes | null = null;
|
||||
trail: TrailEffectAttributes | StructuresEffectAttributes | null = null;
|
||||
|
||||
private animation: Animation | null = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user