refactor: remove unused imports and clean up code
This commit is contained in:
parent
667e4313d2
commit
d29fc10cc8
4 changed files with 312 additions and 237 deletions
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue