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).

<img width="1161" height="895" alt="Screenshot 2025-10-22 211929"
src="https://github.com/user-attachments/assets/71d466b8-61e4-4e30-83e5-06efdfc706ce"
/>
<img width="1322" height="934" alt="Screenshot 2025-10-22 212003"
src="https://github.com/user-attachments/assets/4e6c18b7-7f9e-436d-afb9-85a08a11c40b"
/>
<img width="1340" height="954" alt="Screenshot 2025-10-22 212028"
src="https://github.com/user-attachments/assets/597d0ed5-5519-4cf7-bc60-9963da3f7d7f"
/>

### 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
This commit is contained in:
Mike Harris
2025-10-24 13:55:01 -05:00
committed by GitHub
parent f1b70ea26d
commit 69373e28cb
5 changed files with 363 additions and 96 deletions
+1
View File
@@ -10,3 +10,4 @@ resources/.DS_Store
.DS_Store
.clinic/
CLAUDE.md
.idea/
+59 -24
View File
@@ -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();
}
}
+277 -72
View File
@@ -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
];
+3
View File
@@ -200,4 +200,7 @@ export interface Theme {
neutralColor(): Colord;
enemyColor(): Colord;
spawnHighlightColor(): Colord;
spawnHighlightSelfColor(): Colord;
spawnHighlightTeamColor(): Colord;
spawnHighlightEnemyColor(): Colord;
}
+23
View File
@@ -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;
}
}