refactor: remove unused imports and clean up code

This commit is contained in:
Jan-Marlon Leibl 2025-05-07 14:54:50 +02:00
commit d29fc10cc8
Signed by: jleibl
GPG key ID: 300B2F906DC6F1D5
4 changed files with 312 additions and 237 deletions

View file

@ -5,15 +5,6 @@ import { LootboxService } from '../services/lootbox.service';
import { LootBox, Reward } from 'app/model/LootBox';
import { NavbarComponent } from '@shared/components/navbar/navbar.component';
function shuffle<T>(array: T[]): T[] {
const arr = array.slice();
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
@Component({
selector: 'app-lootbox-opening',
standalone: true,
@ -25,12 +16,11 @@ export default class LootboxOpeningComponent {
lootbox: LootBox | null = null;
isLoading = true;
error = '';
// UI State
isOpening = false;
isOpen = false;
wonReward: Reward | null = null;
prizeList: Reward[] = [];
animationCompleted = false;
constructor(
private route: ActivatedRoute,
@ -38,12 +28,17 @@ export default class LootboxOpeningComponent {
private lootboxService: LootboxService,
private cdr: ChangeDetectorRef
) {
this.loadLootbox();
}
private loadLootbox(): void {
const idParam = this.route.snapshot.paramMap.get('id');
if (!idParam) {
this.error = 'Invalid lootbox ID';
this.isLoading = false;
return;
}
const lootboxId = parseInt(idParam, 10);
this.lootboxService.getAllLootBoxes().subscribe({
next: (lootboxes) => {
@ -59,88 +54,86 @@ export default class LootboxOpeningComponent {
});
}
openLootbox() {
openLootbox(): void {
if (!this.lootbox || this.isOpening) return;
this.isOpening = true;
this.isOpen = false;
this.wonReward = null;
this.prizeList = []; // Clear previous prizes
this.cdr.detectChanges();
// Short delay to ensure animation plays from the beginning
this.resetState(true);
setTimeout(() => {
this.lootboxService.purchaseLootBox(this.lootbox!.id).subscribe({
next: (reward) => {
this.wonReward = reward;
this.generateCasePrizes(reward);
this.isOpening = false;
this.isOpen = true;
this.cdr.detectChanges();
},
error: () => {
// Fallback if API fails
const rewards = this.lootbox!.rewards;
const fallback = rewards[Math.floor(Math.random() * rewards.length)];
this.wonReward = fallback;
this.generateCasePrizes(fallback);
this.isOpening = false;
this.isOpen = true;
this.cdr.detectChanges();
},
next: this.handleRewardSuccess.bind(this),
error: this.handleRewardError.bind(this),
});
}, 100);
}
generateCasePrizes(wonReward: Reward) {
private handleRewardSuccess(reward: Reward): void {
this.wonReward = reward;
this.generateCasePrizes(reward);
this.isOpening = false;
this.isOpen = true;
this.cdr.detectChanges();
}
private handleRewardError(): void {
if (!this.lootbox) return;
const rewards = this.lootbox.rewards;
const fallback = rewards[Math.floor(Math.random() * rewards.length)];
this.handleRewardSuccess(fallback);
}
private resetState(isOpening = false): void {
this.isOpening = isOpening;
this.isOpen = false;
this.wonReward = null;
this.prizeList = [];
this.animationCompleted = false;
this.cdr.detectChanges();
}
generateCasePrizes(wonReward: Reward): void {
if (!this.lootbox) return;
// Create a case opening display with an extremely large number of prizes for a massive scrolling animation
const prizeCount = 200; // Set to 200 for an extremely long scrolling animation
const winningPosition = Math.floor(prizeCount / 2); // Position of the winning prize (middle)
// Get possible rewards from the lootbox
const prizeCount = 120;
const winningPosition = Math.floor(prizeCount / 2);
const possibleRewards = this.lootbox.rewards;
// Generate an array of random rewards
let items: Reward[] = [];
const items: Reward[] = [];
for (let i = 0; i < prizeCount; i++) {
// Special handling for the winning position
if (i === winningPosition) {
items.push(wonReward);
items.push({...wonReward});
} else {
// For all other positions, choose a random reward
// Weight rarer items to appear less frequently
const randomReward = this.getWeightedRandomReward(possibleRewards);
items.push(randomReward);
items.push(this.getWeightedRandomReward(possibleRewards));
}
}
this.prizeList = items;
setTimeout(() => {
this.animationCompleted = true;
this.cdr.detectChanges();
}, 10000);
}
getWeightedRandomReward(rewards: Reward[]): Reward {
// Create a weighted distribution based on probabilities
const totalProbability = rewards.reduce((sum, reward) => sum + reward.probability, 0);
const randomValue = Math.random() * totalProbability;
let cumulativeProbability = 0;
for (const reward of rewards) {
cumulativeProbability += reward.probability;
if (randomValue <= cumulativeProbability) {
return { ...reward }; // Return a copy of the reward
return { ...reward };
}
}
// Fallback, should never reach here
return { ...rewards[0] };
}
openAgain() {
this.isOpening = false;
this.isOpen = false;
this.wonReward = null;
this.prizeList = [];
this.cdr.detectChanges();
openAgain(): void {
this.resetState();
this.openLootbox();
}
getBoxImage(id: number): string {
@ -152,25 +145,28 @@ export default class LootboxOpeningComponent {
}
isWonReward(reward: Reward): boolean {
if (!this.wonReward) {
return false;
}
return (
reward.id === this.wonReward.id &&
reward.value === this.wonReward.value &&
reward.probability === this.wonReward.probability
);
if (!this.wonReward || !this.prizeList.length) return false;
const middleIndex = Math.floor(this.prizeList.length / 2);
return this.prizeList.indexOf(reward) === middleIndex;
}
// Calculate the center position for better alignment
getCenterOffset(): string {
return '0px'; // No additional offset - using animation transform instead
getRewardRarityClass(reward: Reward): string {
if (!reward) return 'text-common';
const probability = reward.probability;
if (probability < 0.01) return 'text-mythic';
if (probability < 0.05) return 'text-legendary';
if (probability < 0.10) return 'text-epic';
if (probability < 0.20) return 'text-rare';
if (probability < 0.40) return 'text-uncommon';
return 'text-common';
}
// Check if item is at center position (100th item)
isCenterItem(index: number): boolean {
return index === Math.floor(200 / 2); // Center item at index 100 (0-indexed)
getRewardClass(): string {
if (!this.wonReward || !this.lootbox) return '';
return this.wonReward.value > (this.lootbox.price || 0) ? 'text-emerald' : 'text-accent-red';
}
}