Skip to content

Commit d13dd44

Browse files
committed
Introduce configurable settings for language and squad members
1 parent 90b984b commit d13dd44

19 files changed

Lines changed: 692 additions & 604 deletions

README.md

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ You can see demonstration here (low quality to be hosted on GitHub):
3333
- Other damage events: fire, crit, severe damage
3434
- Sound effects if not possible with the game client itself
3535
- Realistic sounds like from this awesome video [Battlefield 1](https://www.youtube.com/watch?v=J2JBmYt2Z44)
36-
- Detection for events like following are possible would be possible with the webinterface:
36+
- Detection for events like the following would be possible with the webinterface:
3737
- lost crew members
3838
- marked enemies on map
3939
- and more.
@@ -109,7 +109,7 @@ settings.json
109109
// list of your squad and you and the corresponding avatar names
110110
"squad": [
111111
{
112-
// again username without squadron tag
112+
// username without squadron tag
113113
"username": "TuxCode",
114114
// Avatar name can be extracted from: https://warthunder.com/de/community/userinfo?nick=TuxCode
115115
// and opening getting the image url like opening it in a new tab
@@ -119,42 +119,6 @@ settings.json
119119
"username": "Wingman",
120120
"avatar": "cardicon_bundeswehr_infantryman"
121121
}
122-
],
123-
// what should happen for certain game events
124-
"events": [
125-
{
126-
// <kill|firstblood|nuke>
127-
"event": "kill",
128-
// Either one of those <me|squad|all>
129-
"src": "squad"
130-
},
131-
{
132-
"event": "firstblood",
133-
"src": "me",
134-
"sound": [
135-
{
136-
// sound file from src/assets/sound
137-
"file": "xyz.opus",
138-
// percentage value from 0-100%
139-
"volume": 10
140-
}
141-
]
142-
},
143-
{
144-
"event": "nuke",
145-
"src": "all",
146-
"sound": [
147-
// if multiple sounds are given, a random one will be played
148-
{
149-
"file": "xyz.opus",
150-
"volume": 10
151-
},
152-
{
153-
"file": "xyz.opus",
154-
"volume": 10
155-
}
156-
]
157-
}
158122
]
159123
}
160124
```

eslint.config.mjs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-check
22

3-
// add ts type data
3+
// ts type data
44
import eslint from "@eslint/js";
55

66
// plugins
@@ -11,19 +11,21 @@ import jsdoc from "eslint-plugin-jsdoc";
1111

1212
export default tseslint.config(
1313
{
14-
// ignored compiled and configs
14+
// ignored compiled and build configs
1515
ignores: ["jest.config.js", "src/assets/**", "eslint.config.mjs"],
1616
},
1717
{
18-
// Add warnings for missing simicolons
1918
rules: {
19+
// Add warnings for missing simicolons
2020
semi: ["warn", "always"],
21+
// allow await promises without checking return
2122
"@typescript-eslint/no-misused-promises": [
2223
"error",
2324
{ checksVoidReturn: false },
2425
],
2526

2627
// plugins
28+
// standardize qoute handling to use double and allow inner usuage
2729
"@stylistic/quotes": ["error", "double", { avoidEscape: true }],
2830
},
2931
plugins: {
@@ -48,5 +50,5 @@ export default tseslint.config(
4850
...tseslint.configs.recommendedTypeChecked,
4951
...tseslint.configs.stylisticTypeChecked,
5052
// plugins
51-
jsdoc.configs["flat/recommended-typescript"],
53+
jsdoc.configs["flat/stylistic-typescript"],
5254
);

jest.config.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ module.exports = {
66
// might switch later to happy-dom for browser test environments
77
testEnvironment: "node",
88

9-
// including only test files
9+
// Test naming convention to use ./tests/**/FILE.test.ts
1010
testMatch: ["**/tests/**/*.test.ts"],
11+
1112
// Use Typescript test runner
1213
transform: {
1314
"^.+.tsx?$": ["ts-jest", {}],
1415
},
1516

17+
// Allow TS name mapper in test files too although requires duplicate defs
1618
moduleNameMapper: pathsToModuleNameMapper(
1719
{
1820
"@App/*": ["src/*"],
19-
"@Mapping/*": ["src/mappings/*"],
21+
"@Mapping/*": ["src/lang/mappings/*"],
2022
},
2123
{ prefix: "<rootDir>/" },
2224
),

src/NotificationFeed.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
<body>
2121
<div id="notification" class="container">
22+
<!-- KILLER Destroyed/Animation KILLED -->
23+
<!-- Vehicle Vehicle -->
2224
<div class="avatar">
2325
<img id="killer-avatar" />
2426
</div>
@@ -47,7 +49,7 @@
4749
<source src="./assets/vid/smoke.webm" type="video/webm" />
4850
</video>
4951

50-
<img id="ammunition" src="./assets/img/APFSDS.svg" />
52+
<img id="ammunition" src="./assets/img/APFSDS.avif" />
5153

5254
<span id="killed-name" class="player-name"></span>
5355
</div>

src/Team.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<i class="fa-solid fa-skull-crossbones fa-xs"></i>
3636
</p>
3737
</div>
38+
3839
<div class="line">
3940
<img
4041
class="line-icon"

src/assets/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ body {
6464
font-display: swap;
6565
}
6666

67-
/* War thunder icons */
67+
/* War Thunder icons */
6868
@font-face {
6969
/* 0 = tank icon, . = fighter plane, : = bomber, 4-9 = various symbols */
7070
font-family: Icons;

src/assets.ts renamed to src/lang/assets.ts

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,8 @@ export const AVATAR_FILE_PATH = "./assets/img/avatars";
55
// File extension
66
export const LOCAL_EXT = "avif";
77

8+
import { type AssetMap } from "@App/network";
89
// mappings will be loaded into Javascript bundle by using resolveJSON from Typescript
9-
import defaultMapping from "@Mapping/english.json";
10-
11-
// mapping that is different from the wiki definition
12-
// so we don't need to modify the original files
13-
// content is sorted by values
14-
import specialMapping from "@Mapping/specials.json";
15-
import { AssetMap } from "./network";
1610

1711
/**
1812
* Types for mapping vehicle name to file name
@@ -32,23 +26,25 @@ export enum VehicleType {
3226
Ship = "ships",
3327
}
3428

35-
let assetMap: AssetMap = defaultMapping;
36-
37-
/**
38-
* Selects the correct localized asset name mapping
39-
* @param mapping localized mapping
40-
*/
41-
export function setAssetMap(mapping: AssetMap) {
42-
console.log("Overriding mapping", mapping);
43-
assetMap = mapping;
29+
// mapping that is different from the wiki definition
30+
// so we don't need to modify the original files
31+
// content is sorted by
32+
interface SpecialLocation {
33+
type: VehicleType,
34+
file: string
4435
}
4536

37+
export type SpecialMap = Record<string, SpecialLocation>
38+
import specialMapping from "@Mapping/specials.json";
39+
40+
41+
4642
/**
4743
* Get file path or null
4844
* @param vehicle localized battle log vehicle name
4945
* @returns file name with extension and path or null if not existing
5046
*/
51-
export function findVehicleFile(vehicle: LocalizedVehicle): string | null {
47+
export function findVehicleFile(assetMap: AssetMap, vehicle: LocalizedVehicle): string | null {
5248
// vehicles are translated to local languages
5349
// some vehicles (i.e. russian) use cyrillic characters.
5450
// however they should not be cleaned, because then we would have duplicates see for example T-34-85
@@ -61,7 +57,7 @@ export function findVehicleFile(vehicle: LocalizedVehicle): string | null {
6157
// clean up crlf that somehow got into game files and are therefore used
6258
.replace("\r", "");
6359

64-
const fileName = findLocalMapping(cleanVehicleName);
60+
const fileName = findLocalMapping(assetMap, cleanVehicleName);
6561
if (fileName) {
6662
// add path data if existing
6763
return `${VEHICLE_FILE_PATH}/${fileName}`;
@@ -75,8 +71,8 @@ export function findVehicleFile(vehicle: LocalizedVehicle): string | null {
7571
* @param vehicle localized vehicle name
7672
* @returns folder name and file name if existing
7773
*/
78-
function findLocalMapping(vehicle: LocalizedVehicle): string | null {
79-
const mapping = findMapping(vehicle);
74+
function findLocalMapping(assetMap: AssetMap, vehicle: LocalizedVehicle): string | null {
75+
const mapping = findMapping(assetMap, vehicle);
8076
if (mapping) {
8177
const [typeFolder, normalizedFileName] = mapping;
8278

@@ -97,8 +93,8 @@ const REMOTE_EXT = "png";
9793
* @returns full path to vehicle file
9894
*/
9995
// eslint-disable-next-line @typescript-eslint/no-unused-vars
100-
function findRemoteMapping(vehicle: LocalizedVehicle): string | null {
101-
const mapping = findMapping(vehicle);
96+
function findRemoteMapping(assetMap: AssetMap, vehicle: LocalizedVehicle): string | null {
97+
const mapping = findMapping(assetMap, vehicle);
10298
if (mapping) {
10399
// images are organized here in a flatten folder structure
104100
const [, normalizedFileName] = mapping;
@@ -110,26 +106,35 @@ function findRemoteMapping(vehicle: LocalizedVehicle): string | null {
110106

111107
/**
112108
* Find type and normalized vehicle identifier for a given localized vehicle name
113-
* @param vehicle localized vehicle name
109+
* @param searchVehicle localized vehicle name
114110
* @returns vehicle type and vehicle identifier in an array
115111
*/
116-
function findMapping(vehicle: LocalizedVehicle) {
112+
function findMapping(assetMap: AssetMap, searchVehicle: LocalizedVehicle) {
117113
// search ground vehicles first, because it is mostly played
118114
const vehicleTypes: [string, Mapping][] = [
119-
[VehicleType.Ground, assetMap.ground],
120-
[VehicleType.Air, assetMap.air],
121-
[VehicleType.Ship, assetMap.ships],
122-
["", specialMapping],
115+
[VehicleType.Ground, assetMap.vehicles.ground],
116+
[VehicleType.Air, assetMap.vehicles.air],
117+
[VehicleType.Ship, assetMap.vehicles.ships],
123118
];
124119

125120
for (const vehicleType of vehicleTypes) {
126-
const [path, map] = vehicleType;
121+
const [pathType, map] = vehicleType;
127122

128-
const name = map[vehicle];
123+
const name = map[searchVehicle];
129124
if (name) {
130125
// UNIX file systems are case-sensitive
131-
const normalizedFile = name.toLowerCase();
132-
return [path, normalizedFile];
126+
const normalizedFileName = name.toLowerCase();
127+
return [pathType, normalizedFileName];
128+
}
129+
}
130+
131+
const specialMap = specialMapping as SpecialMap;
132+
for (const specialVehicleName in specialMap) {
133+
if (specialVehicleName === searchVehicle) {
134+
const vehicleType = specialMap[specialVehicleName].type;
135+
const vehicleFileName = specialMap[specialVehicleName].file.toLowerCase();
136+
137+
return [vehicleType, vehicleFileName];
133138
}
134139
}
135140

0 commit comments

Comments
 (0)