From 69373e28cbe0c789632a8921d97f9c4411777fde Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Fri, 24 Oct 2025 13:55:01 -0500 Subject: [PATCH] Feature: Improve Spawn Color Highlighting (#2271) **This PR improves spawn highlighting to identify self and friend/foe. Suggested Label: Feature Suggested Milestone: v26 or v27** ## Description: **This PR changes the behavior for spawn color highlighting and addresses issue #2270.** Currently, the user's spawn highlight color is the same as all other players in FFA and the same as all enemies in Team games. Although "breathing" rings were added recently for the user's spawn highlight, this can still be difficult to find on the map, especially with large player counts. This PR modifies how spawn highlights are drawn for the user and for allies and enemies in Team games. ### User Spawn Color Updates First, an additional spawn highlight color was added for the user in `src/core/configuration/PastelTheme.ts`: `_spawnHighlightSelfColor`. This is defined to be white (0xFFFFFF). Second, the breathing ring was modified to improve visibility (all in `src/client/graphics/layers/TerritoryLayer.ts`) : - A radial-gradient transparent ring in the spawn color (white) is drawn at all times - The ring is transparent for `radius = 8` pixels from the player's center point - The gradient extends from `8` to `24` pixels from the player's center point - The first 10% of the ring (~ 1 pixel) is solid - The remaining ring fades to transparent at `24` pixels - A solid, "breathing" ring is drawn on top of the transparent ring - The solid ring is also transparent for `radius = 8` pixels from the center point - The outer radius of the solid ring is a function of "time" in the same way that the current breathing ring is implemented. - The solid ring therefore grows and shrinks to cover the transparent ring ### Other Player Spawn Color Updates In FFA games, no change is made to the spawn color highlight of other players. It remains `rgb(255,213,79)`. In team games, the spawn color highlight of other players is updated to use their team colors. For example, a player on the red team will have a red spawn highlight, while a player on the purple team will have a purple spawn highlight. Both of these changes are handled with a simple update in `src/client/graphics/layers/TerritoryLayer.ts` within the `spawnHighlight()` method: ```typescript const myPlayer = this.game.myPlayer(); if (myPlayer !== null && myPlayer !== human && myPlayer.team() === null) { // In FFA games (when team === null), use default yellow spawn highlight color color = this.theme.spawnHighlightColor(); } else if (myPlayer !== null && myPlayer !== human) { // In Team games, the spawn highlight color becomes that player's team color // Optionally, this could be broken down to teammate or enemy and simplified to green and red, respectively const team = human.team(); if (team !== null) color = this.theme.teamColor(team); } ``` ### Attached Images Three images have been attached. The three images show a progression of the "breathing" user highlight. They also show the team-specific highlights of players on other teams. (Note that Nations in the private game were assigned teams but do not have spawn highlights). Screenshot 2025-10-22 211929 Screenshot 2025-10-22 212003 Screenshot 2025-10-22 212028 ### Misc. - I added `.idea/` to `.gitignore` because I use JetBrains IDEs - I expanded the `fallbackColors` list. Right now it has a lot of green colors, so I added equivalents for red, blue, cyan, magenta, and yellow. ## Please complete the following: - [x] 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 - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: GlacialDrift --- .gitignore | 1 + src/client/graphics/layers/TerritoryLayer.ts | 83 +++-- src/core/configuration/Colors.ts | 349 +++++++++++++++---- src/core/configuration/Config.ts | 3 + src/core/configuration/PastelTheme.ts | 23 ++ 5 files changed, 363 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index 8b3f0c0db..18fa251ae 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ resources/.DS_Store .DS_Store .clinic/ CLAUDE.md +.idea/ diff --git a/src/client/graphics/layers/TerritoryLayer.ts b/src/client/graphics/layers/TerritoryLayer.ts index 59670db17..945ac3524 100644 --- a/src/client/graphics/layers/TerritoryLayer.ts +++ b/src/client/graphics/layers/TerritoryLayer.ts @@ -74,6 +74,10 @@ export class TerritoryLayer implements Layer { } tick() { + if (this.game.inSpawnPhase()) { + this.spawnHighlight(); + } + this.game.recentlyUpdatedTiles().forEach((t) => this.enqueueTile(t)); const updates = this.game.updatesSinceLastTick(); const unitUpdates = updates !== null ? updates[GameUpdateType.Unit] : []; @@ -145,12 +149,6 @@ export class TerritoryLayer implements Layer { } this.lastFocusedPlayer = focusedPlayer; } - - if (!this.game.inSpawnPhase()) { - return; - } - - this.spawnHighlight(); } private spawnHighlight() { @@ -186,13 +184,16 @@ export class TerritoryLayer implements Layer { } let color = this.theme.spawnHighlightColor(); const myPlayer = this.game.myPlayer(); - if ( - myPlayer !== null && - myPlayer !== human && - myPlayer.isFriendly(human) - ) { - color = this.theme.selfColor(); + if (myPlayer !== null && myPlayer !== human && myPlayer.team() === null) { + // In FFA games (when team === null), use default yellow spawn highlight color + color = this.theme.spawnHighlightColor(); + } else if (myPlayer !== null && myPlayer !== human) { + // In Team games, the spawn highlight color becomes that player's team color + // Optionally, this could be broken down to teammate or enemy and simplified to green and red, respectively + const team = human.team(); + if (team !== null) color = this.theme.teamColor(team); } + for (const tile of this.game.bfs( centerTile, euclDistFN(centerTile, 9, true), @@ -215,20 +216,20 @@ export class TerritoryLayer implements Layer { return; } // Breathing border animation - this.borderAnimTime += 3; - const minPadding = 6; - const maxPadding = 12; + this.borderAnimTime += 0.5; + const minRad = 8; + const maxRad = 24; // Range: [minPadding..maxPadding] - const breathingPadding = - minPadding + - (maxPadding - minPadding) * - (0.5 + 0.5 * Math.sin(this.borderAnimTime * 0.3)); + const radius = + minRad + (maxRad - minRad) * (0.5 + 0.5 * Math.sin(this.borderAnimTime)); this.drawBreathingRing( center.x, center.y, - breathingPadding, - this.theme.spawnHighlightColor(), + minRad, + maxRad, + radius, + this.theme.spawnHighlightSelfColor(), // Always draw breathing ring with self spawn highlight color ); } @@ -558,18 +559,52 @@ export class TerritoryLayer implements Layer { const y = this.game.y(tile); this.highlightContext.clearRect(x, y, 1, 1); } + private drawBreathingRing( cx: number, cy: number, + minRad: number, + maxRad: number, radius: number, color: Colord, ) { const ctx = this.highlightContext; if (!ctx) return; + + // Draw a semi-transparent ring around the starting location ctx.beginPath(); + // Transparency matches the highlight color provided + const transparent = color.toHex() + "00"; + const c = color.toHex(); + const radGrad = ctx.createRadialGradient(cx, cy, minRad, cx, cy, maxRad); + + // Pixels with radius < minRad are transparent + radGrad.addColorStop(0, transparent); + // The ring then starts with solid highlight color + radGrad.addColorStop(0.01, c); + radGrad.addColorStop(0.1, c); + // The outer edge of the ring is transparent + radGrad.addColorStop(1, transparent); + + // Draw an arc at the max radius and fill with the created radial gradient + ctx.arc(cx, cy, maxRad, 0, Math.PI * 2); + ctx.fillStyle = radGrad; + ctx.closePath(); + ctx.fill(); + + // Draw a solid ring around the starting location with outer radius = the breathing radius + ctx.beginPath(); + const radGrad2 = ctx.createRadialGradient(cx, cy, minRad, cx, cy, radius); + // Pixels with radius < minRad are transparent + radGrad2.addColorStop(0, transparent); + // The ring then starts with solid highlight color + radGrad2.addColorStop(0.01, c); + // The ring is solid throughout + radGrad2.addColorStop(1, c); + + // Draw an arc at the current breathing radius and fill with the created "gradient" ctx.arc(cx, cy, radius, 0, Math.PI * 2); - ctx.strokeStyle = color.toRgbString(); - ctx.lineWidth = 4; - ctx.stroke(); + ctx.fillStyle = radGrad2; + ctx.fill(); } } diff --git a/src/core/configuration/Colors.ts b/src/core/configuration/Colors.ts index 1a0ccabd9..2e913a6b6 100644 --- a/src/core/configuration/Colors.ts +++ b/src/core/configuration/Colors.ts @@ -262,104 +262,309 @@ export const botColors: Colord[] = [ // Fallback colors for when the color palette is exhausted. Currently 100 colors. export const fallbackColors: Colord[] = [ - colord({ r: 0, g: 5, b: 0 }), // Black Mint - colord({ r: 0, g: 15, b: 0 }), // Deep Forest - colord({ r: 0, g: 25, b: 0 }), // Jungle - colord({ r: 0, g: 35, b: 0 }), // Dark Emerald - colord({ r: 0, g: 45, b: 0 }), // Green Moss - colord({ r: 0, g: 55, b: 0 }), // Moss Shadow - colord({ r: 0, g: 65, b: 0 }), // Dark Meadow - colord({ r: 0, g: 75, b: 0 }), // Forest Fern - colord({ r: 0, g: 85, b: 0 }), // Pine Leaf - colord({ r: 0, g: 95, b: 0 }), // Shadow Grass - colord({ r: 0, g: 105, b: 0 }), // Classic Green - colord({ r: 0, g: 115, b: 0 }), // Deep Lime - colord({ r: 0, g: 125, b: 0 }), // Dense Leaf - colord({ r: 0, g: 135, b: 0 }), // Basil Green - colord({ r: 0, g: 145, b: 0 }), // Organic Green - colord({ r: 0, g: 155, b: 0 }), // Bitter Herb - colord({ r: 0, g: 165, b: 0 }), // Raw Spinach - colord({ r: 0, g: 175, b: 0 }), // Woodland - colord({ r: 0, g: 185, b: 0 }), // Spring Weed - colord({ r: 0, g: 195, b: 5 }), // Apple Stem - colord({ r: 0, g: 205, b: 10 }), // Crisp Lettuce - colord({ r: 0, g: 215, b: 15 }), // Vibrant Green - colord({ r: 0, g: 225, b: 20 }), // Bright Herb - colord({ r: 0, g: 235, b: 25 }), // Green Splash - colord({ r: 0, g: 245, b: 30 }), // Mint Leaf - colord({ r: 0, g: 255, b: 35 }), // Fresh Mint - colord({ r: 10, g: 255, b: 45 }), // Neon Grass - colord({ r: 20, g: 255, b: 55 }), // Lemon Balm - colord({ r: 30, g: 255, b: 65 }), // Juicy Green - colord({ r: 40, g: 255, b: 75 }), // Pear Tint - colord({ r: 50, g: 255, b: 85 }), // Avocado Pastel - colord({ r: 60, g: 255, b: 95 }), // Lime Glow - colord({ r: 70, g: 255, b: 105 }), // Light Leaf - colord({ r: 80, g: 255, b: 115 }), // Soft Fern - colord({ r: 90, g: 255, b: 125 }), // Pastel Green - colord({ r: 100, g: 255, b: 135 }), // Green Melon - colord({ r: 110, g: 255, b: 145 }), // Herbal Mist - colord({ r: 120, g: 255, b: 155 }), // Kiwi Foam - colord({ r: 130, g: 255, b: 165 }), // Aloe Fresh - colord({ r: 140, g: 255, b: 175 }), // Light Mint + colord({ r: 35, g: 0, b: 0 }), + colord({ r: 45, g: 0, b: 0 }), + colord({ r: 55, g: 0, b: 0 }), + colord({ r: 65, g: 0, b: 0 }), + colord({ r: 75, g: 0, b: 0 }), + colord({ r: 85, g: 0, b: 0 }), + colord({ r: 95, g: 0, b: 0 }), + colord({ r: 105, g: 0, b: 0 }), + colord({ r: 115, g: 0, b: 0 }), + colord({ r: 125, g: 0, b: 0 }), + colord({ r: 135, g: 0, b: 0 }), + colord({ r: 145, g: 0, b: 0 }), + colord({ r: 155, g: 0, b: 0 }), + colord({ r: 165, g: 0, b: 0 }), + colord({ r: 175, g: 0, b: 0 }), + colord({ r: 185, g: 0, b: 0 }), + colord({ r: 195, g: 0, b: 5 }), + colord({ r: 205, g: 0, b: 10 }), + colord({ r: 215, g: 0, b: 15 }), + colord({ r: 225, g: 0, b: 20 }), + colord({ r: 235, g: 0, b: 25 }), + colord({ r: 245, g: 0, b: 30 }), + colord({ r: 255, g: 0, b: 35 }), + colord({ r: 255, g: 10, b: 45 }), + colord({ r: 255, g: 20, b: 55 }), + colord({ r: 255, g: 30, b: 65 }), + colord({ r: 255, g: 40, b: 75 }), + colord({ r: 255, g: 50, b: 85 }), + colord({ r: 255, g: 60, b: 95 }), + colord({ r: 255, g: 70, b: 105 }), + colord({ r: 255, g: 80, b: 115 }), + colord({ r: 255, g: 90, b: 125 }), + colord({ r: 255, g: 100, b: 135 }), + colord({ r: 255, g: 110, b: 145 }), + colord({ r: 255, g: 120, b: 155 }), + colord({ r: 255, g: 130, b: 165 }), + colord({ r: 255, g: 140, b: 175 }), + colord({ r: 255, g: 150, b: 185 }), + colord({ r: 255, g: 160, b: 195 }), + colord({ r: 255, g: 170, b: 205 }), + colord({ r: 255, g: 180, b: 215 }), + colord({ r: 255, g: 190, b: 225 }), + colord({ r: 255, g: 200, b: 235 }), + colord({ r: 0, g: 45, b: 0 }), + colord({ r: 0, g: 55, b: 0 }), + colord({ r: 0, g: 65, b: 0 }), + colord({ r: 0, g: 75, b: 0 }), + colord({ r: 0, g: 85, b: 0 }), + colord({ r: 0, g: 95, b: 0 }), + colord({ r: 0, g: 105, b: 0 }), + colord({ r: 0, g: 115, b: 0 }), + colord({ r: 0, g: 125, b: 0 }), + colord({ r: 0, g: 135, b: 0 }), + colord({ r: 0, g: 145, b: 0 }), + colord({ r: 0, g: 155, b: 0 }), + colord({ r: 0, g: 165, b: 0 }), + colord({ r: 0, g: 175, b: 0 }), + colord({ r: 0, g: 185, b: 0 }), + colord({ r: 0, g: 195, b: 5 }), + colord({ r: 0, g: 205, b: 10 }), + colord({ r: 0, g: 215, b: 15 }), + colord({ r: 0, g: 225, b: 20 }), + colord({ r: 0, g: 235, b: 25 }), + colord({ r: 0, g: 245, b: 30 }), + colord({ r: 0, g: 255, b: 35 }), + colord({ r: 10, g: 255, b: 45 }), + colord({ r: 20, g: 255, b: 55 }), + colord({ r: 30, g: 255, b: 65 }), + colord({ r: 40, g: 255, b: 75 }), + colord({ r: 50, g: 255, b: 85 }), + colord({ r: 60, g: 255, b: 95 }), + colord({ r: 70, g: 255, b: 105 }), + colord({ r: 80, g: 255, b: 115 }), + colord({ r: 90, g: 255, b: 125 }), + colord({ r: 100, g: 255, b: 135 }), + colord({ r: 110, g: 255, b: 145 }), + colord({ r: 120, g: 255, b: 155 }), + colord({ r: 130, g: 255, b: 165 }), + colord({ r: 140, g: 255, b: 175 }), + colord({ r: 150, g: 255, b: 185 }), + colord({ r: 160, g: 255, b: 195 }), + colord({ r: 170, g: 255, b: 205 }), + colord({ r: 180, g: 255, b: 215 }), + colord({ r: 190, g: 255, b: 225 }), + colord({ r: 200, g: 255, b: 235 }), + colord({ r: 0, g: 0, b: 35 }), + colord({ r: 0, g: 0, b: 45 }), + colord({ r: 0, g: 0, b: 55 }), + colord({ r: 0, g: 0, b: 65 }), + colord({ r: 0, g: 0, b: 75 }), + colord({ r: 0, g: 0, b: 85 }), + colord({ r: 0, g: 0, b: 95 }), + colord({ r: 0, g: 0, b: 105 }), + colord({ r: 0, g: 0, b: 115 }), + colord({ r: 0, g: 0, b: 125 }), + colord({ r: 0, g: 0, b: 135 }), + colord({ r: 0, g: 0, b: 145 }), + colord({ r: 0, g: 0, b: 155 }), + colord({ r: 0, g: 0, b: 165 }), + colord({ r: 0, g: 0, b: 175 }), + colord({ r: 0, g: 0, b: 185 }), + colord({ r: 5, g: 0, b: 195 }), + colord({ r: 10, g: 0, b: 205 }), + colord({ r: 15, g: 0, b: 215 }), + colord({ r: 20, g: 0, b: 225 }), + colord({ r: 25, g: 0, b: 235 }), + colord({ r: 30, g: 0, b: 245 }), + colord({ r: 35, g: 0, b: 255 }), + colord({ r: 45, g: 10, b: 255 }), + colord({ r: 55, g: 20, b: 255 }), + colord({ r: 65, g: 30, b: 255 }), + colord({ r: 75, g: 40, b: 255 }), + colord({ r: 85, g: 50, b: 255 }), + colord({ r: 95, g: 60, b: 255 }), + colord({ r: 105, g: 70, b: 255 }), + colord({ r: 115, g: 80, b: 255 }), + colord({ r: 125, g: 90, b: 255 }), + colord({ r: 135, g: 100, b: 255 }), + colord({ r: 145, g: 110, b: 255 }), + colord({ r: 155, g: 120, b: 255 }), + colord({ r: 165, g: 130, b: 255 }), + colord({ r: 175, g: 140, b: 255 }), + colord({ r: 185, g: 150, b: 255 }), + colord({ r: 195, g: 160, b: 255 }), + colord({ r: 205, g: 170, b: 255 }), + colord({ r: 215, g: 180, b: 255 }), + colord({ r: 225, g: 190, b: 255 }), + colord({ r: 235, g: 200, b: 255 }), + colord({ r: 35, g: 0, b: 35 }), + colord({ r: 45, g: 0, b: 45 }), + colord({ r: 55, g: 0, b: 55 }), + colord({ r: 65, g: 0, b: 65 }), + colord({ r: 75, g: 0, b: 75 }), + colord({ r: 85, g: 0, b: 85 }), + colord({ r: 95, g: 0, b: 95 }), + colord({ r: 105, g: 0, b: 105 }), + colord({ r: 115, g: 0, b: 115 }), + colord({ r: 125, g: 0, b: 125 }), + colord({ r: 135, g: 0, b: 135 }), + colord({ r: 145, g: 0, b: 145 }), + colord({ r: 155, g: 0, b: 155 }), + colord({ r: 165, g: 0, b: 165 }), + colord({ r: 175, g: 0, b: 175 }), + colord({ r: 185, g: 0, b: 185 }), + colord({ r: 195, g: 5, b: 195 }), + colord({ r: 205, g: 10, b: 205 }), + colord({ r: 215, g: 15, b: 215 }), + colord({ r: 225, g: 20, b: 225 }), + colord({ r: 235, g: 25, b: 235 }), + colord({ r: 245, g: 30, b: 245 }), + colord({ r: 255, g: 35, b: 255 }), + colord({ r: 255, g: 45, b: 255 }), + colord({ r: 255, g: 55, b: 255 }), + colord({ r: 255, g: 65, b: 255 }), + colord({ r: 255, g: 75, b: 255 }), + colord({ r: 255, g: 85, b: 255 }), + colord({ r: 255, g: 95, b: 255 }), + colord({ r: 255, g: 105, b: 255 }), + colord({ r: 255, g: 115, b: 255 }), + colord({ r: 255, g: 125, b: 255 }), + colord({ r: 255, g: 135, b: 255 }), + colord({ r: 255, g: 145, b: 255 }), + colord({ r: 255, g: 155, b: 255 }), + colord({ r: 255, g: 165, b: 255 }), + colord({ r: 255, g: 175, b: 255 }), + colord({ r: 255, g: 185, b: 255 }), + colord({ r: 255, g: 195, b: 255 }), + colord({ r: 255, g: 205, b: 255 }), + colord({ r: 255, g: 215, b: 255 }), + colord({ r: 0, g: 35, b: 35 }), + colord({ r: 0, g: 45, b: 45 }), + colord({ r: 0, g: 55, b: 55 }), + colord({ r: 0, g: 65, b: 65 }), + colord({ r: 0, g: 75, b: 75 }), + colord({ r: 0, g: 85, b: 85 }), + colord({ r: 0, g: 95, b: 95 }), + colord({ r: 0, g: 105, b: 105 }), + colord({ r: 0, g: 115, b: 115 }), + colord({ r: 0, g: 125, b: 125 }), + colord({ r: 0, g: 135, b: 135 }), + colord({ r: 0, g: 145, b: 145 }), + colord({ r: 0, g: 155, b: 155 }), + colord({ r: 0, g: 165, b: 165 }), + colord({ r: 0, g: 175, b: 175 }), + colord({ r: 0, g: 185, b: 185 }), + colord({ r: 5, g: 195, b: 195 }), + colord({ r: 10, g: 205, b: 205 }), + colord({ r: 15, g: 215, b: 215 }), + colord({ r: 20, g: 225, b: 225 }), + colord({ r: 25, g: 235, b: 235 }), + colord({ r: 30, g: 245, b: 245 }), + colord({ r: 35, g: 255, b: 255 }), + colord({ r: 45, g: 255, b: 255 }), + colord({ r: 55, g: 255, b: 255 }), + colord({ r: 65, g: 255, b: 255 }), + colord({ r: 75, g: 255, b: 255 }), + colord({ r: 85, g: 255, b: 255 }), + colord({ r: 95, g: 255, b: 255 }), + colord({ r: 105, g: 255, b: 255 }), + colord({ r: 115, g: 255, b: 255 }), + colord({ r: 125, g: 255, b: 255 }), + colord({ r: 135, g: 255, b: 255 }), + colord({ r: 145, g: 255, b: 255 }), + colord({ r: 155, g: 255, b: 255 }), + colord({ r: 165, g: 255, b: 255 }), + colord({ r: 175, g: 255, b: 255 }), + colord({ r: 185, g: 255, b: 255 }), + colord({ r: 195, g: 255, b: 255 }), + colord({ r: 205, g: 255, b: 255 }), + colord({ r: 215, g: 255, b: 255 }), + colord({ r: 35, g: 35, b: 0 }), + colord({ r: 45, g: 45, b: 0 }), + colord({ r: 55, g: 55, b: 0 }), + colord({ r: 65, g: 65, b: 0 }), + colord({ r: 75, g: 75, b: 0 }), + colord({ r: 85, g: 85, b: 0 }), + colord({ r: 95, g: 95, b: 0 }), + colord({ r: 105, g: 105, b: 0 }), + colord({ r: 115, g: 115, b: 0 }), + colord({ r: 125, g: 125, b: 0 }), + colord({ r: 135, g: 135, b: 0 }), + colord({ r: 145, g: 145, b: 0 }), + colord({ r: 155, g: 155, b: 0 }), + colord({ r: 165, g: 165, b: 0 }), + colord({ r: 175, g: 175, b: 0 }), + colord({ r: 185, g: 185, b: 0 }), + colord({ r: 195, g: 195, b: 5 }), + colord({ r: 205, g: 205, b: 10 }), + colord({ r: 215, g: 215, b: 15 }), + colord({ r: 225, g: 225, b: 20 }), + colord({ r: 235, g: 235, b: 25 }), + colord({ r: 245, g: 245, b: 30 }), + colord({ r: 255, g: 255, b: 35 }), + colord({ r: 255, g: 255, b: 45 }), + colord({ r: 255, g: 255, b: 55 }), + colord({ r: 255, g: 255, b: 65 }), + colord({ r: 255, g: 255, b: 75 }), + colord({ r: 255, g: 255, b: 85 }), + colord({ r: 255, g: 255, b: 95 }), + colord({ r: 255, g: 255, b: 105 }), + colord({ r: 255, g: 255, b: 115 }), + colord({ r: 255, g: 255, b: 125 }), + colord({ r: 255, g: 255, b: 135 }), + colord({ r: 255, g: 255, b: 145 }), + colord({ r: 255, g: 255, b: 155 }), + colord({ r: 255, g: 255, b: 165 }), + colord({ r: 255, g: 255, b: 175 }), + colord({ r: 255, g: 255, b: 185 }), + colord({ r: 255, g: 255, b: 195 }), + colord({ r: 255, g: 255, b: 205 }), + colord({ r: 255, g: 255, b: 215 }), + colord({ r: 215, g: 255, b: 200 }), // Fresh Mint + colord({ r: 225, g: 255, b: 175 }), // Soft Lime + colord({ r: 240, g: 250, b: 160 }), // Citrus Wash + colord({ r: 245, g: 245, b: 175 }), // Lemon Mist colord({ r: 150, g: 200, b: 255 }), // Cornflower Mist - colord({ r: 150, g: 255, b: 185 }), // Green Sorbet colord({ r: 160, g: 215, b: 255 }), // Powder Blue - colord({ r: 160, g: 255, b: 195 }), // Pastel Apple - colord({ r: 170, g: 190, b: 255 }), // Periwinkle Ice colord({ r: 170, g: 225, b: 255 }), // Baby Sky - colord({ r: 170, g: 255, b: 205 }), // Aloe Breeze - colord({ r: 180, g: 180, b: 255 }), // Pale Indigo colord({ r: 180, g: 235, b: 250 }), // Aqua Pastel - colord({ r: 180, g: 255, b: 215 }), // Pale Mint - colord({ r: 190, g: 140, b: 195 }), // Fuchsia Tint colord({ r: 190, g: 245, b: 240 }), // Ice Mint - colord({ r: 190, g: 255, b: 225 }), // Mint Water + colord({ r: 210, g: 255, b: 245 }), // Sea Mist + colord({ r: 220, g: 255, b: 255 }), // Pale Aqua + colord({ r: 230, g: 250, b: 255 }), // Sky Haze + colord({ r: 240, g: 240, b: 255 }), // Frosted Lilac + colord({ r: 250, g: 230, b: 255 }), // Misty Mauve + colord({ r: 170, g: 190, b: 255 }), // Periwinkle Ice + colord({ r: 180, g: 180, b: 255 }), // Pale Indigo + colord({ r: 200, g: 170, b: 255 }), // Lilac Bloom + colord({ r: 190, g: 140, b: 195 }), // Fuchsia Tint colord({ r: 195, g: 145, b: 200 }), // Dusky Rose colord({ r: 200, g: 150, b: 205 }), // Plum Frost - colord({ r: 200, g: 170, b: 255 }), // Lilac Bloom - colord({ r: 200, g: 255, b: 215 }), // Cool Aloe - colord({ r: 200, g: 255, b: 235 }), // Cool Mist colord({ r: 205, g: 155, b: 210 }), // Berry Foam colord({ r: 210, g: 160, b: 215 }), // Grape Cloud - colord({ r: 210, g: 255, b: 245 }), // Sea Mist colord({ r: 215, g: 165, b: 220 }), // Light Bloom - colord({ r: 215, g: 255, b: 200 }), // Fresh Mint - colord({ r: 220, g: 160, b: 255 }), // Violet Mist colord({ r: 220, g: 170, b: 225 }), // Cherry Blossom - colord({ r: 220, g: 255, b: 255 }), // Pale Aqua colord({ r: 225, g: 175, b: 230 }), // Faded Rose - colord({ r: 225, g: 255, b: 175 }), // Soft Lime colord({ r: 230, g: 180, b: 235 }), // Dreamy Mauve - colord({ r: 230, g: 250, b: 255 }), // Sky Haze - colord({ r: 235, g: 150, b: 255 }), // Orchid Glow colord({ r: 235, g: 185, b: 240 }), // Powder Violet colord({ r: 240, g: 190, b: 245 }), // Pastel Violet - colord({ r: 240, g: 240, b: 255 }), // Frosted Lilac - colord({ r: 240, g: 250, b: 160 }), // Citrus Wash - colord({ r: 245, g: 160, b: 240 }), // Rose Lilac colord({ r: 245, g: 195, b: 250 }), // Soft Magenta - colord({ r: 245, g: 245, b: 175 }), // Lemon Mist colord({ r: 250, g: 200, b: 255 }), // Lilac Cream - colord({ r: 250, g: 230, b: 255 }), // Misty Mauve + colord({ r: 255, g: 205, b: 255 }), // Violet Bloom + colord({ r: 255, g: 210, b: 255 }), // Orchid Mist + colord({ r: 255, g: 210, b: 250 }), // Lavender Mist + colord({ r: 255, g: 205, b: 245 }), // Pastel Orchid + colord({ r: 255, g: 215, b: 245 }), // Rose Whisper + colord({ r: 220, g: 160, b: 255 }), // Violet Mist + colord({ r: 235, g: 150, b: 255 }), // Orchid Glow + colord({ r: 245, g: 160, b: 240 }), // Rose Lilac colord({ r: 255, g: 170, b: 225 }), // Bubblegum Pink colord({ r: 255, g: 185, b: 215 }), // Blush Mist colord({ r: 255, g: 195, b: 235 }), // Faded Fuchsia colord({ r: 255, g: 200, b: 220 }), // Cotton Rose - colord({ r: 255, g: 205, b: 245 }), // Pastel Orchid - colord({ r: 255, g: 205, b: 255 }), // Violet Bloom colord({ r: 255, g: 210, b: 230 }), // Pastel Blush - colord({ r: 255, g: 210, b: 250 }), // Lavender Mist - colord({ r: 255, g: 210, b: 255 }), // Orchid Mist - colord({ r: 255, g: 215, b: 195 }), // Apricot Glow - colord({ r: 255, g: 215, b: 245 }), // Rose Whisper colord({ r: 255, g: 220, b: 235 }), // Pink Mist colord({ r: 255, g: 220, b: 250 }), // Powder Petal - colord({ r: 255, g: 225, b: 180 }), // Butter Peach colord({ r: 255, g: 225, b: 255 }), // Petal Mist colord({ r: 255, g: 230, b: 245 }), // Light Rose - colord({ r: 255, g: 235, b: 200 }), // Cream Peach colord({ r: 255, g: 235, b: 235 }), // Blushed Petal - colord({ r: 255, g: 240, b: 220 }), // Pastel Sand + colord({ r: 255, g: 215, b: 195 }), // Apricot Glow + colord({ r: 255, g: 225, b: 180 }), // Butter Peach + colord({ r: 255, g: 230, b: 190 }), + colord({ r: 255, g: 235, b: 200 }), // Cream Peach colord({ r: 255, g: 245, b: 210 }), // Soft Banana + colord({ r: 255, g: 240, b: 220 }), // Pastel Sand ]; diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index 1a55fb236..965f7c9bb 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -200,4 +200,7 @@ export interface Theme { neutralColor(): Colord; enemyColor(): Colord; spawnHighlightColor(): Colord; + spawnHighlightSelfColor(): Colord; + spawnHighlightTeamColor(): Colord; + spawnHighlightEnemyColor(): Colord; } diff --git a/src/core/configuration/PastelTheme.ts b/src/core/configuration/PastelTheme.ts index d40509e1c..627c0cb10 100644 --- a/src/core/configuration/PastelTheme.ts +++ b/src/core/configuration/PastelTheme.ts @@ -29,12 +29,23 @@ export class PastelTheme implements Theme { private water = colord({ r: 70, g: 132, b: 180 }); private shorelineWater = colord({ r: 100, g: 143, b: 255 }); + /** Alternate View colors for self, green */ private _selfColor = colord({ r: 0, g: 255, b: 0 }); + /** Alternate View colors for allies, yellow */ private _allyColor = colord({ r: 255, g: 255, b: 0 }); + /** Alternate View colors for neutral, gray */ private _neutralColor = colord({ r: 128, g: 128, b: 128 }); + /** Alternate View colors for enemies, red */ private _enemyColor = colord({ r: 255, g: 0, b: 0 }); + /** Default spawn highlight colors for other players in FFA, yellow */ private _spawnHighlightColor = colord({ r: 255, g: 213, b: 79 }); + /** Added non-default spawn highlight colors for self, full white */ + private _spawnHighlightSelfColor = colord({ r: 255, g: 255, b: 255 }); + /** Added non-default spawn highlight colors for teammates, green */ + private _spawnHighlightTeamColor = colord({ r: 0, g: 255, b: 0 }); + /** Added non-default spawn highlight colors for enemies, red */ + private _spawnHighlightEnemyColor = colord({ r: 255, g: 0, b: 0 }); teamColor(team: Team): Colord { return this.teamColorAllocator.assignTeamColor(team); @@ -144,4 +155,16 @@ export class PastelTheme implements Theme { spawnHighlightColor(): Colord { return this._spawnHighlightColor; } + /** Return spawn highlight color for self */ + spawnHighlightSelfColor(): Colord { + return this._spawnHighlightSelfColor; + } + /** Return spawn highlight color for teammates */ + spawnHighlightTeamColor(): Colord { + return this._spawnHighlightTeamColor; + } + /** Return spawn highlight color for enemies */ + spawnHighlightEnemyColor(): Colord { + return this._spawnHighlightEnemyColor; + } }