feat(lootboxes): add lootbox opening feature and images

This commit is contained in:
Jan-Marlon Leibl 2025-04-23 13:17:44 +02:00
commit 8e27c9c7c3
Signed by: jleibl
GPG key ID: 300B2F906DC6F1D5
15 changed files with 536 additions and 327 deletions

View file

@ -1,71 +1,134 @@
import { Component } from '@angular/core';
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
interface Lootbox {
id: string;
name: string;
category: 'common' | 'rare' | 'legendary';
price: number;
image: string;
chance: number;
maxPrize: number;
}
import { NavbarComponent } from '@shared/components/navbar/navbar.component';
import { LootboxService } from '../services/lootbox.service';
import { LootBox } from 'app/model/LootBox';
import { Router } from '@angular/router';
import { timeout } from 'rxjs';
@Component({
selector: 'app-lootbox-selection',
standalone: true,
imports: [CommonModule, RouterModule],
imports: [CommonModule, NavbarComponent],
templateUrl: './lootbox-selection.component.html',
styleUrl: './lootbox-selection.component.scss'
styleUrls: ['./lootbox-selection.component.css']
})
export default class LootboxSelectionComponent {
lootboxes: Lootbox[] = [
export default class LootboxSelectionComponent implements OnInit {
lootboxes: LootBox[] = [];
isLoading = true;
error = '';
// Fallback data in case the API call fails
fallbackLootboxes: LootBox[] = [
{
id: 'common-box',
name: 'Gewöhnliche Box',
category: 'common',
price: 5,
image: '/assets/images/lootboxes/common-box.png',
chance: 7,
maxPrize: 50
id: 1,
name: "Basic LootBox",
price: 2.00,
rewards: [
{
id: 1,
value: 0.50,
probability: 0.70
},
{
id: 5,
value: 5.00,
probability: 0.30
}
]
},
{
id: 'rare-box',
name: 'Seltene Box',
category: 'rare',
price: 20,
image: '/assets/images/lootboxes/rare-box.png',
chance: 3.5,
maxPrize: 200
id: 2,
name: "Premium LootBox",
price: 5.00,
rewards: [
{
id: 4,
value: 2.00,
probability: 0.60
},
{
id: 5,
value: 5.00,
probability: 0.30
},
{
id: 6,
value: 15.00,
probability: 0.10
}
]
},
{
id: 'legendary-box',
name: 'Legendäre Box',
category: 'legendary',
price: 50,
image: '/assets/images/lootboxes/legendary-box.png',
chance: 1,
maxPrize: 1000
id: 3,
name: "Legendäre LootBox",
price: 15.00,
rewards: [
{
id: 4,
value: 2.00,
probability: 0.60
},
{
id: 5,
value: 5.00,
probability: 0.30
},
{
id: 6,
value: 15.00,
probability: 0.10
}
]
}
];
categories = [
{ id: 'common', name: 'Gewöhnlich' },
{ id: 'rare', name: 'Selten' },
{ id: 'legendary', name: 'Legendär' }
];
constructor(private lootboxService: LootboxService, private router: Router, private cdr: ChangeDetectorRef) {}
selectedCategory: string | null = null;
filterByCategory(category: string | null): void {
this.selectedCategory = category;
ngOnInit(): void {
this.loadLootboxes();
}
get filteredLootboxes(): Lootbox[] {
if (!this.selectedCategory) {
return this.lootboxes;
loadLootboxes(): void {
this.isLoading = true;
this.lootboxService.getAllLootBoxes().pipe(
timeout(5000)
).subscribe({
next: (data) => {
console.log('Received lootboxes:', data);
this.lootboxes = data;
this.isLoading = false;
this.cdr.detectChanges();
},
error: (err) => {
this.error = 'Konnte keine Verbindung zum Backend herstellen. Zeige Demo-Daten.';
this.lootboxes = this.fallbackLootboxes;
this.isLoading = false;
this.cdr.detectChanges();
console.error('Failed to load lootboxes:', err);
}
});
}
getBoxImage(id: number): string {
return `/images/${id}-box.png`;
}
openLootbox(lootboxId: number): void {
this.router.navigate(['/game/lootboxes/open', lootboxId]);
}
getRarityClass(probability: number): string {
if (probability <= 0.1) {
return 'text-yellow-400'; // Legendary
} else if (probability <= 0.3) {
return 'text-purple-400'; // Rare
} else {
return 'text-blue-400'; // Common
}
return this.lootboxes.filter(box => box.category === this.selectedCategory);
}
formatProbability(probability: number): string {
return (probability * 100).toFixed(0) + '%';
}
}