mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 13:30:43 +00:00
2b44b68362
If this PR fixes an issue, link it below. If not, delete these two lines. Resolves #2447 ## Description: This PR updates the logic used to generate structure fill and border colors. Currently, (v0.26.16 and earlier), some light territory colors have structures that are difficult to see and identify. This PR ensures that all territory colors have structures that are easily visible. Instead of using `Colord.lighten()` and `Colord.darken()` to generate structure colors, the logic now: - queries the territory color and border color of the structure owner - Converts these colors to the [LAB color space](https://en.wikipedia.org/wiki/CIELAB_color_space) (which is a human-perception-uniform color space). - Darkens the border color (by decreasing LAB luminance) and sometimes lightens the territory color (by increasing LAB luminance) until a specific `Color Delta` is achieved (currently `delta > 0.5`) - This ensures contrast between the structure and the territory background. Additionally, this PR re-organizes colors in the `Colors.ts` file for better visibility and removes redundant colors from the `nationColors` list. This PR is an implementation of the proposed mock-up posted on imgur in issue #2447. Screenshots of the original, final, and side-by-side comparison of structure colors (for all available player colors) are in the [imgur album](https://imgur.com/a/openfront-color-playground-4cxSbbj). I'd recommend inclusion as a feature/fix for v27. ## 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
214 lines
6.2 KiB
TypeScript
214 lines
6.2 KiB
TypeScript
import { Colord } from "colord";
|
|
import { JWK } from "jose";
|
|
import {
|
|
Difficulty,
|
|
Game,
|
|
GameMapType,
|
|
GameMode,
|
|
Gold,
|
|
Player,
|
|
PlayerInfo,
|
|
Team,
|
|
TerraNullius,
|
|
Tick,
|
|
UnitInfo,
|
|
UnitType,
|
|
} from "../game/Game";
|
|
import { GameMap, TileRef } from "../game/GameMap";
|
|
import { PlayerView } from "../game/GameView";
|
|
import { UserSettings } from "../game/UserSettings";
|
|
import { GameConfig, GameID, TeamCountConfig } from "../Schemas";
|
|
import { NukeType } from "../StatsSchemas";
|
|
|
|
export enum GameEnv {
|
|
Dev,
|
|
Preprod,
|
|
Prod,
|
|
}
|
|
|
|
export interface ServerConfig {
|
|
turnIntervalMs(): number;
|
|
gameCreationRate(): number;
|
|
lobbyMaxPlayers(
|
|
map: GameMapType,
|
|
mode: GameMode,
|
|
numPlayerTeams: TeamCountConfig | undefined,
|
|
): number;
|
|
numWorkers(): number;
|
|
workerIndex(gameID: GameID): number;
|
|
workerPath(gameID: GameID): string;
|
|
workerPort(gameID: GameID): number;
|
|
workerPortByIndex(workerID: number): number;
|
|
env(): GameEnv;
|
|
adminToken(): string;
|
|
adminHeader(): string;
|
|
// Only available on the server
|
|
gitCommit(): string;
|
|
r2Bucket(): string;
|
|
r2Endpoint(): string;
|
|
r2AccessKey(): string;
|
|
r2SecretKey(): string;
|
|
apiKey(): string;
|
|
otelEndpoint(): string;
|
|
otelAuthHeader(): string;
|
|
otelEnabled(): boolean;
|
|
jwtAudience(): string;
|
|
jwtIssuer(): string;
|
|
jwkPublicKey(): Promise<JWK>;
|
|
domain(): string;
|
|
subdomain(): string;
|
|
cloudflareAccountId(): string;
|
|
cloudflareApiToken(): string;
|
|
cloudflareConfigPath(): string;
|
|
cloudflareCredsPath(): string;
|
|
stripePublishableKey(): string;
|
|
allowedFlares(): string[] | undefined;
|
|
enableMatchmaking(): boolean;
|
|
}
|
|
|
|
export interface NukeMagnitude {
|
|
inner: number;
|
|
outer: number;
|
|
}
|
|
|
|
export interface Config {
|
|
samHittingChance(): number;
|
|
samWarheadHittingChance(): number;
|
|
spawnImmunityDuration(): Tick;
|
|
serverConfig(): ServerConfig;
|
|
gameConfig(): GameConfig;
|
|
theme(): Theme;
|
|
percentageTilesOwnedToWin(): number;
|
|
numBots(): number;
|
|
spawnNPCs(): boolean;
|
|
isUnitDisabled(unitType: UnitType): boolean;
|
|
bots(): number;
|
|
infiniteGold(): boolean;
|
|
donateGold(): boolean;
|
|
infiniteTroops(): boolean;
|
|
donateTroops(): boolean;
|
|
instantBuild(): boolean;
|
|
isRandomSpawn(): boolean;
|
|
numSpawnPhaseTurns(): number;
|
|
userSettings(): UserSettings;
|
|
playerTeams(): TeamCountConfig;
|
|
|
|
startManpower(playerInfo: PlayerInfo): number;
|
|
troopIncreaseRate(player: Player | PlayerView): number;
|
|
goldAdditionRate(player: Player | PlayerView): Gold;
|
|
attackTilesPerTick(
|
|
attckTroops: number,
|
|
attacker: Player,
|
|
defender: Player | TerraNullius,
|
|
numAdjacentTilesWithEnemy: number,
|
|
): number;
|
|
attackLogic(
|
|
gm: Game,
|
|
attackTroops: number,
|
|
attacker: Player,
|
|
defender: Player | TerraNullius,
|
|
tileToConquer: TileRef,
|
|
): {
|
|
attackerTroopLoss: number;
|
|
defenderTroopLoss: number;
|
|
tilesPerTickUsed: number;
|
|
};
|
|
attackAmount(attacker: Player, defender: Player | TerraNullius): number;
|
|
radiusPortSpawn(): number;
|
|
// When computing likelihood of trading for any given port, the X closest port
|
|
// are twice more likely to be selected. X is determined below.
|
|
proximityBonusPortsNb(totalPorts: number): number;
|
|
maxTroops(player: Player | PlayerView): number;
|
|
cityTroopIncrease(): number;
|
|
boatAttackAmount(attacker: Player, defender: Player | TerraNullius): number;
|
|
shellLifetime(): number;
|
|
boatMaxNumber(): number;
|
|
allianceDuration(): Tick;
|
|
allianceRequestDuration(): Tick;
|
|
allianceRequestCooldown(): Tick;
|
|
temporaryEmbargoDuration(): Tick;
|
|
targetDuration(): Tick;
|
|
targetCooldown(): Tick;
|
|
emojiMessageCooldown(): Tick;
|
|
emojiMessageDuration(): Tick;
|
|
donateCooldown(): Tick;
|
|
embargoAllCooldown(): Tick;
|
|
deletionMarkDuration(): Tick;
|
|
deleteUnitCooldown(): Tick;
|
|
defaultDonationAmount(sender: Player): number;
|
|
unitInfo(type: UnitType): UnitInfo;
|
|
tradeShipShortRangeDebuff(): number;
|
|
tradeShipGold(dist: number, numPorts: number): Gold;
|
|
tradeShipSpawnRate(
|
|
numTradeShips: number,
|
|
numPlayerPorts: number,
|
|
numPlayerTradeShips: number,
|
|
): number;
|
|
trainGold(rel: "self" | "team" | "ally" | "other"): Gold;
|
|
trainSpawnRate(numPlayerFactories: number): number;
|
|
trainStationMinRange(): number;
|
|
trainStationMaxRange(): number;
|
|
railroadMaxSize(): number;
|
|
safeFromPiratesCooldownMax(): number;
|
|
defensePostRange(): number;
|
|
SAMCooldown(): number;
|
|
SiloCooldown(): number;
|
|
defensePostDefenseBonus(): number;
|
|
defensePostSpeedBonus(): number;
|
|
falloutDefenseModifier(percentOfFallout: number): number;
|
|
difficultyModifier(difficulty: Difficulty): number;
|
|
warshipPatrolRange(): number;
|
|
warshipShellAttackRate(): number;
|
|
warshipTargettingRange(): number;
|
|
defensePostShellAttackRate(): number;
|
|
defensePostTargettingRange(): number;
|
|
// 0-1
|
|
traitorDefenseDebuff(): number;
|
|
traitorDuration(): number;
|
|
nukeMagnitudes(unitType: UnitType): NukeMagnitude;
|
|
// Number of tiles destroyed to break an alliance
|
|
nukeAllianceBreakThreshold(): number;
|
|
defaultNukeSpeed(): number;
|
|
defaultNukeTargetableRange(): number;
|
|
defaultSamMissileSpeed(): number;
|
|
defaultSamRange(): number;
|
|
samRange(level: number): number;
|
|
maxSamRange(): number;
|
|
nukeDeathFactor(
|
|
nukeType: NukeType,
|
|
humans: number,
|
|
tilesOwned: number,
|
|
maxTroops: number,
|
|
): number;
|
|
structureMinDist(): number;
|
|
isReplay(): boolean;
|
|
allianceExtensionPromptOffset(): number;
|
|
}
|
|
|
|
export interface Theme {
|
|
teamColor(team: Team): Colord;
|
|
// Don't call directly, use PlayerView
|
|
territoryColor(playerInfo: PlayerView): Colord;
|
|
// Don't call directly, use PlayerView
|
|
structureColors(territoryColor: Colord): { light: Colord; dark: Colord };
|
|
// Don't call directly, use PlayerView
|
|
borderColor(territoryColor: Colord): Colord;
|
|
// Don't call directly, use PlayerView
|
|
defendedBorderColors(territoryColor: Colord): { light: Colord; dark: Colord };
|
|
focusedBorderColor(): Colord;
|
|
terrainColor(gm: GameMap, tile: TileRef): Colord;
|
|
backgroundColor(): Colord;
|
|
falloutColor(): Colord;
|
|
font(): string;
|
|
textColor(playerInfo: PlayerView): string;
|
|
// unit color for alternate view
|
|
selfColor(): Colord;
|
|
allyColor(): Colord;
|
|
neutralColor(): Colord;
|
|
enemyColor(): Colord;
|
|
spawnHighlightColor(): Colord;
|
|
spawnHighlightSelfColor(): Colord;
|
|
spawnHighlightTeamColor(): Colord;
|
|
spawnHighlightEnemyColor(): Colord;
|
|
}
|