mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 13:04:36 +00:00
test
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"patterns": {
|
||||
"stripes": {
|
||||
"tileWidth": 2,
|
||||
"tileHeight": 2,
|
||||
"scale": 2,
|
||||
"pattern": [
|
||||
[1, 0],
|
||||
[1, 0]
|
||||
]
|
||||
},
|
||||
"checkerboard": {
|
||||
"tileWidth": 2,
|
||||
"tileHeight": 2,
|
||||
"scale": 2,
|
||||
"pattern": [
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
]
|
||||
},
|
||||
"diagonal": {
|
||||
"tileWidth": 16,
|
||||
"tileHeight": 16,
|
||||
"scale": 1,
|
||||
"pattern": [
|
||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import { createRenderer, GameRenderer } from "./graphics/GameRenderer";
|
||||
|
||||
export interface LobbyConfig {
|
||||
serverConfig: ServerConfig;
|
||||
pattern: string;
|
||||
flag: string;
|
||||
playerName: string;
|
||||
clientID: ClientID;
|
||||
|
||||
@@ -208,6 +208,7 @@ class Client {
|
||||
{
|
||||
gameID: lobby.gameID,
|
||||
serverConfig: config,
|
||||
pattern: localStorage.getItem("territoryPattern"),
|
||||
flag:
|
||||
this.flagInput.getCurrentFlag() == "xx"
|
||||
? ""
|
||||
|
||||
@@ -404,6 +404,7 @@ export class SinglePlayerModal extends LitElement {
|
||||
flagInput.getCurrentFlag() == "xx"
|
||||
? ""
|
||||
: flagInput.getCurrentFlag(),
|
||||
pattern: localStorage.getItem("territoryPattern"),
|
||||
},
|
||||
],
|
||||
config: {
|
||||
|
||||
@@ -339,6 +339,7 @@ export class Transport {
|
||||
persistentID: this.lobbyConfig.persistentID,
|
||||
username: this.lobbyConfig.playerName,
|
||||
flag: this.lobbyConfig.flag,
|
||||
pattern: localStorage.getItem("territoryPattern"),
|
||||
}),
|
||||
),
|
||||
);
|
||||
@@ -393,6 +394,7 @@ export class Transport {
|
||||
type: "spawn",
|
||||
clientID: this.lobbyConfig.clientID,
|
||||
flag: this.lobbyConfig.flag,
|
||||
pattern: this.lobbyConfig.pattern,
|
||||
name: this.lobbyConfig.playerName,
|
||||
playerType: PlayerType.Human,
|
||||
x: event.cell.x,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { PriorityQueue } from "@datastructures-js/priority-queue";
|
||||
import { Colord } from "colord";
|
||||
import territory_patterns from "../../../../resources/territory_patterns.json";
|
||||
import { Theme } from "../../../core/configuration/Config";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { Cell, PlayerType, UnitType } from "../../../core/game/Game";
|
||||
@@ -280,12 +281,31 @@ export class TerritoryLayer implements Layer {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.paintCell(
|
||||
this.game.x(tile),
|
||||
this.game.y(tile),
|
||||
this.theme.territoryColor(owner),
|
||||
150,
|
||||
);
|
||||
const patternName = owner.pattern();
|
||||
if (!patternName) {
|
||||
this.paintCell(
|
||||
this.game.x(tile),
|
||||
this.game.y(tile),
|
||||
this.theme.territoryColor(owner),
|
||||
150,
|
||||
);
|
||||
} else {
|
||||
const x = this.game.x(tile);
|
||||
const y = this.game.y(tile);
|
||||
const baseColor = this.theme.territoryColor(owner);
|
||||
const patternConfig = territory_patterns.patterns[patternName];
|
||||
|
||||
const { tileWidth, tileHeight, scale, pattern } = patternConfig;
|
||||
|
||||
const px = Math.floor(x / scale) % tileWidth;
|
||||
const py = Math.floor(y / scale) % tileHeight;
|
||||
|
||||
const patternValue = pattern[py][px];
|
||||
|
||||
const colorToUse =
|
||||
patternValue === 1 ? baseColor.darken(0.2) : baseColor;
|
||||
this.paintCell(x, y, colorToUse, 150);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ export async function createGameRunner(
|
||||
gameStart.players.map(
|
||||
(p) =>
|
||||
new PlayerInfo(
|
||||
p.pattern,
|
||||
p.flag,
|
||||
p.clientID == clientID
|
||||
? sanitize(p.username)
|
||||
|
||||
@@ -185,6 +185,7 @@ export const AttackIntentSchema = BaseIntentSchema.extend({
|
||||
|
||||
export const SpawnIntentSchema = BaseIntentSchema.extend({
|
||||
flag: z.string().nullable(),
|
||||
pattern: z.string().nullable(),
|
||||
type: z.literal("spawn"),
|
||||
name: SafeString,
|
||||
playerType: PlayerTypeSchema,
|
||||
@@ -321,6 +322,7 @@ export const PlayerSchema = z.object({
|
||||
clientID: ID,
|
||||
username: SafeString,
|
||||
flag: SafeString.optional(),
|
||||
pattern: SafeString.optional(),
|
||||
});
|
||||
|
||||
export const GameStartInfoSchema = z.object({
|
||||
@@ -397,6 +399,7 @@ export const ClientJoinMessageSchema = ClientBaseMessageSchema.extend({
|
||||
lastTurn: z.number(), // The last turn the client saw.
|
||||
username: SafeString,
|
||||
flag: SafeString.nullable().optional(),
|
||||
pattern: SafeString.nullable().optional(),
|
||||
});
|
||||
|
||||
export const ClientMessageSchema = z.union([
|
||||
|
||||
@@ -47,7 +47,14 @@ export class BotSpawner {
|
||||
}
|
||||
}
|
||||
return new SpawnExecution(
|
||||
new PlayerInfo("", botName, PlayerType.Bot, null, this.random.nextID()),
|
||||
new PlayerInfo(
|
||||
null,
|
||||
"",
|
||||
botName,
|
||||
PlayerType.Bot,
|
||||
null,
|
||||
this.random.nextID(),
|
||||
),
|
||||
tile,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ export class Executor {
|
||||
new FakeHumanExecution(
|
||||
this.gameID,
|
||||
new PlayerInfo(
|
||||
null,
|
||||
nation.flag || "",
|
||||
nation.name,
|
||||
PlayerType.FakeHuman,
|
||||
|
||||
@@ -242,6 +242,7 @@ export class PlayerInfo {
|
||||
public readonly clan: string | null;
|
||||
|
||||
constructor(
|
||||
public readonly pattern: string,
|
||||
public readonly flag: string,
|
||||
public readonly name: string,
|
||||
public readonly playerType: PlayerType,
|
||||
|
||||
@@ -88,6 +88,7 @@ export interface PlayerUpdate {
|
||||
type: GameUpdateType.Player;
|
||||
nameViewData?: NameViewData;
|
||||
clientID: ClientID;
|
||||
pattern: string;
|
||||
flag: string;
|
||||
name: string;
|
||||
displayName: string;
|
||||
|
||||
@@ -177,6 +177,11 @@ export class PlayerView {
|
||||
flag(): string {
|
||||
return this.data.flag;
|
||||
}
|
||||
|
||||
pattern(): string {
|
||||
return this.data.pattern;
|
||||
}
|
||||
|
||||
name(): string {
|
||||
return userSettings.anonymousNames() && this.anonymousName !== null
|
||||
? this.anonymousName
|
||||
@@ -275,6 +280,7 @@ export class PlayerView {
|
||||
}
|
||||
info(): PlayerInfo {
|
||||
return new PlayerInfo(
|
||||
this.pattern(),
|
||||
this.flag(),
|
||||
this.name(),
|
||||
this.type(),
|
||||
|
||||
@@ -80,6 +80,7 @@ export class PlayerImpl implements Player {
|
||||
public _units: UnitImpl[] = [];
|
||||
public _tiles: Set<TileRef> = new Set();
|
||||
|
||||
private _pattern: string;
|
||||
private _flag: string;
|
||||
private _name: string;
|
||||
private _displayName: string;
|
||||
@@ -107,6 +108,7 @@ export class PlayerImpl implements Player {
|
||||
startTroops: number,
|
||||
private readonly _team: Team | null,
|
||||
) {
|
||||
this._pattern = playerInfo.pattern;
|
||||
this._flag = playerInfo.flag;
|
||||
this._name = sanitizeUsername(playerInfo.name);
|
||||
this._targetTroopRatio = 95n;
|
||||
@@ -127,6 +129,7 @@ export class PlayerImpl implements Player {
|
||||
return {
|
||||
type: GameUpdateType.Player,
|
||||
clientID: this.clientID(),
|
||||
pattern: this.pattern(),
|
||||
flag: this.flag(),
|
||||
name: this.name(),
|
||||
displayName: this.displayName(),
|
||||
@@ -176,6 +179,10 @@ export class PlayerImpl implements Player {
|
||||
return this._smallID;
|
||||
}
|
||||
|
||||
pattern(): string {
|
||||
return this._pattern;
|
||||
}
|
||||
|
||||
flag(): string {
|
||||
return this._flag;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ describe("Attack", () => {
|
||||
infiniteTroops: true,
|
||||
});
|
||||
const attackerInfo = new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"attacker dude",
|
||||
PlayerType.Human,
|
||||
@@ -41,6 +42,7 @@ describe("Attack", () => {
|
||||
);
|
||||
game.addPlayer(attackerInfo);
|
||||
const defenderInfo = new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"defender dude",
|
||||
PlayerType.Human,
|
||||
|
||||
@@ -32,6 +32,7 @@ describe("MissileSilo", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup("Plains", { infiniteGold: true, instantBuild: true });
|
||||
const attacker_info = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"attacker_id",
|
||||
PlayerType.Human,
|
||||
|
||||
@@ -4,6 +4,7 @@ describe("PlayerInfo", () => {
|
||||
describe("clan", () => {
|
||||
test("should extract clan from name when format is [XX]Name", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[CL]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -15,6 +16,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should extract clan from name when format is [XXX]Name", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[ABC]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -26,6 +28,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should extract clan from name when format is [XXXX]Name", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[ABCD]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -37,6 +40,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should extract clan from name when format is [XXXXX]Name", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[ABCDE]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -48,6 +52,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should return null when name doesn't start with [", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -59,6 +64,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should return null when name doesn't contain ]", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[ABCPlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -70,6 +76,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should return null when clan tag is not 2-5 uppercase letters", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[A]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -81,6 +88,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should return null when clan tag contains non-uppercase letters", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[Abc]PlayerName",
|
||||
PlayerType.Human,
|
||||
@@ -92,6 +100,7 @@ describe("PlayerInfo", () => {
|
||||
|
||||
test("should return null when clan tag is too long", () => {
|
||||
const playerInfo = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"[ABCDEF]PlayerName",
|
||||
PlayerType.Human,
|
||||
|
||||
@@ -18,6 +18,7 @@ describe("SAM", () => {
|
||||
beforeEach(async () => {
|
||||
game = await setup("Plains", { infiniteGold: true, instantBuild: true });
|
||||
const defender_info = new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"defender_id",
|
||||
PlayerType.Human,
|
||||
@@ -25,6 +26,7 @@ describe("SAM", () => {
|
||||
"defender_id",
|
||||
);
|
||||
const attacker_info = new PlayerInfo(
|
||||
null,
|
||||
"fr",
|
||||
"attacker_id",
|
||||
PlayerType.Human,
|
||||
|
||||
@@ -6,7 +6,14 @@ describe("Territory management", () => {
|
||||
test("player owns the tile it spawns on", async () => {
|
||||
const game = await setup("Plains");
|
||||
game.addPlayer(
|
||||
new PlayerInfo("us", "test_player", PlayerType.Human, null, "test_id"),
|
||||
new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"test_player",
|
||||
PlayerType.Human,
|
||||
null,
|
||||
"test_id",
|
||||
),
|
||||
);
|
||||
const spawnTile = game.map().ref(50, 50);
|
||||
game.addExecution(
|
||||
|
||||
@@ -21,6 +21,7 @@ describe("Warship", () => {
|
||||
instantBuild: true,
|
||||
});
|
||||
const player_1_info = new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"boat dude",
|
||||
PlayerType.Human,
|
||||
@@ -29,6 +30,7 @@ describe("Warship", () => {
|
||||
);
|
||||
game.addPlayer(player_1_info);
|
||||
const player_2_info = new PlayerInfo(
|
||||
null,
|
||||
"us",
|
||||
"boat dude",
|
||||
PlayerType.Human,
|
||||
|
||||
Reference in New Issue
Block a user