Skip to content

Commit 49fd153

Browse files
committed
Implement Playercams and Name Overrides
1 parent fdd74c0 commit 49fd153

19 files changed

+274
-17
lines changed

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"angular-schematics.schematicsDefaultOptions": {
3+
"angular-*": {
4+
"externalTemplate": true
5+
}
6+
}
7+
}

src/app/agent-select/agent-select.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<app-select-player-info
55
*ngFor="let player of teamLeft.players; trackBy: trackByPlayerId"
66
[player]="player"
7+
[overrideNames]="match?.tools?.nameOverrides?.overrides"
78
[color]="teamLeft.isAttacking ? 'attacker' : 'defender'"
89
/>
910
</div>
@@ -27,6 +28,7 @@
2728
<app-select-player-info
2829
*ngFor="let player of teamRight.players; trackBy: trackByPlayerId"
2930
[player]="player"
31+
[overrideNames]="match?.tools?.nameOverrides?.overrides"
3032
[color]="teamRight.isAttacking ? 'attacker' : 'defender'"
3133
/>
3234
</div>

src/app/agent-select/agent-select.component.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,29 @@ export class AgentSelectComponent implements OnInit, AfterViewInit {
104104

105105
this.teamLeft = this.match.teams[0];
106106
this.teamRight = this.match.teams[1];
107+
108+
// Construct map for name overrides if it's a string (from JSON). The server might keep it as JSON to avoid issues.
109+
const tempOverrides = this.match?.tools?.nameOverrides?.overrides || null;
110+
if (typeof tempOverrides === "string") {
111+
this.match.tools.nameOverrides.overrides = this.jsonToMap(tempOverrides);
112+
}
107113
}
108114

109115
trackByPlayerId(index: number, player: any) {
110116
return player.playerId;
111117
}
118+
119+
private jsonToMap(json: string): Map<string, string> {
120+
try {
121+
const obj = JSON.parse(json);
122+
if (Array.isArray(obj)) {
123+
return new Map(obj);
124+
} else {
125+
throw new Error("Invalid JSON format for Map");
126+
}
127+
} catch (error) {
128+
console.error("Failed to parse JSON to Map:", error);
129+
return new Map();
130+
}
131+
}
112132
}

src/app/agent-select/select-player-info/select-player-info.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
/>
1818
</div>
1919
<div class="player-name">
20-
{{ player.name }}
20+
{{ player.fullName | nameOverride: player.name : getOverrideNames() }}
2121
</div>
2222
<div class="player-gradient" [ngClass]="color"></div>
2323
</div>

src/app/agent-select/select-player-info/select-player-info.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Component, Input } from "@angular/core";
22
import { AgentRoleService } from "../../services/agentRole.service";
33
import { trigger, transition, style, animate } from "@angular/animations";
44
import { NgClass } from "@angular/common";
5+
import { NameoverridePipe } from "../../pipes/nameoverride.pipe";
56

67
@Component({
78
selector: "app-select-player-info",
@@ -18,13 +19,22 @@ import { NgClass } from "@angular/common";
1819
transition("* <=> *", [style({ opacity: "0" }), animate("100ms", style({ opacity: "1" }))]),
1920
]),
2021
],
21-
imports: [NgClass],
22+
imports: [NgClass, NameoverridePipe],
2223
})
2324
export class SelectPlayerInfoComponent {
2425
@Input() player: any;
2526
@Input() color: "attacker" | "defender" = "attacker";
27+
@Input() overrideNames = new Map<string, string>();
2628

2729
getAgentRole(agent: string) {
2830
return AgentRoleService.getAgentRole(agent);
2931
}
32+
33+
getOverrideNames(): Map<string, string> {
34+
let toReturn = this.overrideNames;
35+
if (!toReturn) {
36+
toReturn = new Map<string, string>();
37+
}
38+
return toReturn;
39+
}
3040
}

src/app/combat/playercard/playercard-minimal.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
</div>
3333
</div>
3434
<div class="username-container">
35-
<div class="username-title minimal" [class]="side">{{ player.name }}</div>
35+
<div class="username-title minimal" [class]="side">
36+
{{ player.fullName | nameOverride: player.name : getOverrideNames() }}
37+
</div>
3638
<img
3739
class="captain-icon"
3840
*ngIf="player.isCaptain"

src/app/combat/playercard/playercard.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@
106106
</div>
107107
</div>
108108
<div class="username-container">
109-
<div class="username-title" [class]="side">{{ player.name }}</div>
109+
<div class="username-title" [class]="side">
110+
{{ player.fullName | nameOverride: player.name : getOverrideNames() }}
111+
</div>
110112
<img
111113
class="captain-icon"
112114
*ngIf="player.isCaptain"

src/app/combat/playercard/playercard.component.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { NgIf, NgFor } from "@angular/common";
66
import { AbilitiesComponent } from "../../abilities/abilities.component";
77
import { ShieldIconComponent } from "./shield-icon/shield-icon.component";
88
import { TranslateModule } from "@ngx-translate/core";
9+
import { NameoverridePipe } from "../../pipes/nameoverride.pipe";
910

1011
const componentAnimations = [
1112
trigger("deathAnimation", [
@@ -51,7 +52,7 @@ const componentAnimations = [
5152
templateUrl: "./playercard.component.html",
5253
styleUrls: ["./playercard.component.scss"],
5354
animations: componentAnimations,
54-
imports: [NgIf, AbilitiesComponent, ShieldIconComponent, NgFor],
55+
imports: [NgIf, AbilitiesComponent, ShieldIconComponent, NgFor, NameoverridePipe],
5556
})
5657
export class InhouseTrackerPlayercardComponent {
5758
private config = inject(Config);
@@ -99,13 +100,21 @@ export class InhouseTrackerPlayercardComponent {
99100
clamp(value: number, min: number, max: number): number {
100101
return Math.max(min, Math.min(max, value));
101102
}
103+
104+
getOverrideNames(): Map<string, string> {
105+
let toReturn = this.match?.tools?.nameOverrides?.overrides;
106+
if (!toReturn) {
107+
toReturn = new Map<string, string>();
108+
}
109+
return toReturn;
110+
}
102111
}
103112

104113
@Component({
105114
selector: "app-playercard-minimal",
106115
templateUrl: "./playercard-minimal.component.html",
107116
styleUrls: ["./playercard.component.scss"],
108117
animations: componentAnimations,
109-
imports: [TranslateModule, NgIf],
118+
imports: [TranslateModule, NgIf, NameoverridePipe],
110119
})
111120
export class InhouseTrackerPlayercardMinimalComponent extends InhouseTrackerPlayercardComponent {}

src/app/pipes/nameoverride.pipe.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Pipe, type PipeTransform } from "@angular/core";
2+
3+
@Pipe({
4+
name: "nameOverride",
5+
})
6+
export class NameoverridePipe implements PipeTransform {
7+
transform(value: string, fallback: string, overrideMap: Map<string, string>): string {
8+
if (!overrideMap || typeof overrideMap.get !== "function") {
9+
return fallback;
10+
}
11+
return overrideMap.get(value) || fallback;
12+
}
13+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@for (player of match.teams[0].players; track $index) {
2+
@if (streams.has(player.fullName)) {
3+
<div
4+
class="border-[#0f1923] border-3 box-border rounded-sm h-48 aspect-video overflow-clip absolute bg-[#0f1923]"
5+
[class.hidden]="!player.isObserved"
6+
>
7+
<div class="h-48 w-full">
8+
<iframe
9+
allow="camera;fullscreen;autoplay;"
10+
[src]="streams.get(player.fullName)"
11+
class="w-full aspect-video"
12+
></iframe>
13+
</div>
14+
<div class="bg-black/70 h-7 w-full absolute -bottom-1 left-0 flex">
15+
<div
16+
class="absolute gradient"
17+
[class]="match.teams[0].isAttacking ? 'attacker' : 'defender'"
18+
></div>
19+
<div
20+
class="w-full max-w-85 text-left px-2 text-lg text-white text-shadow-xl font-extrabold font-[Montserrat] overflow-clip"
21+
>
22+
{{ player.fullName | nameOverride: player.name : getOverrideNames() }}
23+
</div>
24+
<div class="w-full text-right px-2 text-lg text-white font-semibold font-[Montserrat]">
25+
{{ player.kills }} / {{ player.deaths }} / {{ player.assists }}
26+
</div>
27+
</div>
28+
</div>
29+
}
30+
}
31+
32+
@for (player of match.teams[1].players; track $index) {
33+
@if (streams.has(player.fullName)) {
34+
<div
35+
class="border-[#0f1923] border-3 box-border rounded-sm h-48 aspect-video overflow-clip absolute bg-[#0f1923]"
36+
[class.hidden]="!player.isObserved"
37+
>
38+
<div class="h-48 w-full">
39+
<iframe
40+
allow="camera;fullscreen;autoplay;"
41+
[src]="streams.get(player.fullName)"
42+
class="w-full aspect-video"
43+
></iframe>
44+
</div>
45+
<div class="bg-black/70 h-7 w-full absolute -bottom-1 left-0 flex">
46+
<div
47+
class="absolute gradient"
48+
[class]="match.teams[1].isAttacking ? 'attacker' : 'defender'"
49+
></div>
50+
<div
51+
class="w-full max-w-85 text-left px-2 text-lg text-white text-shadow-xl font-extrabold font-[Montserrat] overflow-clip"
52+
>
53+
{{ player.fullName | nameOverride: player.name : getOverrideNames() }}
54+
</div>
55+
<div class="w-full text-right px-2 text-lg text-white font-semibold font-[Montserrat]">
56+
{{ player.kills }} / {{ player.deaths }} / {{ player.assists }}
57+
</div>
58+
</div>
59+
</div>
60+
}
61+
}

0 commit comments

Comments
 (0)