Fraser's picture
BIG CHANGE
c703ea3
<script lang="ts">
import { fade } from 'svelte/transition';
import type { PicletInstance } from '$lib/db/schema';
import LLMBattleEngine from '../Battle/LLMBattleEngine.svelte';
import type { GradioClient } from '$lib/types';
interface Props {
playerPiclet: PicletInstance;
enemyPiclet: PicletInstance;
isWildBattle: boolean;
rosterPiclets?: PicletInstance[];
onBattleEnd: (result: { winner: 'player' | 'enemy'; capturedPiclet?: PicletInstance }) => void;
commandClient: GradioClient;
}
let { playerPiclet, enemyPiclet, isWildBattle, rosterPiclets, onBattleEnd, commandClient }: Props = $props();
// Simple battle state
let battleEnded = $state(false);
let battleResult: { winner: 'player' | 'enemy'; capturedPiclet?: PicletInstance } | null = $state(null);
// Handle battle end
function handleBattleEnd(winner: 'player' | 'enemy') {
battleEnded = true;
// Simplified: no capture mechanics since Piclets are auto-captured when scanned
battleResult = { winner };
// Give time for final battle messages, then call parent handler
setTimeout(() => {
onBattleEnd(battleResult!);
}, 2000);
}
</script>
<div class="battle-page" transition:fade>
<!-- Header -->
<div class="battle-header">
<h2>{isWildBattle ? 'Wild Battle' : 'Trainer Battle'}</h2>
<div class="battle-participants">
<div class="participant player">
<img src={playerPiclet.imageUrl} alt={playerPiclet.typeId} />
<h3>{playerPiclet.typeId}</h3>
<span class="tier tier-{playerPiclet.tier}">{playerPiclet.tier}</span>
</div>
<div class="vs-indicator">
<span>VS</span>
</div>
<div class="participant enemy">
<img src={enemyPiclet.imageUrl} alt={enemyPiclet.typeId} />
<h3>{enemyPiclet.typeId}</h3>
<span class="tier tier-{enemyPiclet.tier}">{enemyPiclet.tier}</span>
</div>
</div>
</div>
<!-- Main Battle Area -->
<div class="battle-main">
{#if !battleEnded}
<LLMBattleEngine
{playerPiclet}
{enemyPiclet}
{rosterPiclets}
{commandClient}
onBattleEnd={handleBattleEnd}
/>
{:else}
<div class="battle-results">
<h2>{battleResult?.winner === 'player' ? 'πŸŽ‰ Victory!' : 'πŸ’€ Defeat!'}</h2>
{#if battleResult?.winner === 'player'}
<p>You defeated {enemyPiclet.typeId}!</p>
{:else}
<p>{playerPiclet.typeId} was defeated by {enemyPiclet.typeId}...</p>
<p>Better luck next time!</p>
{/if}
</div>
{/if}
</div>
</div>
<style>
.battle-page {
height: 100vh;
display: flex;
flex-direction: column;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.battle-header {
padding: 1rem;
text-align: center;
background: rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
}
.battle-participants {
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
margin-top: 1rem;
}
.participant {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
}
.participant img {
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 50%;
border: 3px solid rgba(255, 255, 255, 0.3);
}
.participant.player img {
border-color: #007bff;
}
.participant.enemy img {
border-color: #dc3545;
}
.tier {
padding: 0.25rem 0.5rem;
border-radius: 12px;
font-size: 0.8rem;
font-weight: bold;
text-transform: uppercase;
}
.tier-low { background: #6c757d; }
.tier-medium { background: #28a745; }
.tier-high { background: #fd7e14; }
.tier-legendary { background: #dc3545; }
.vs-indicator {
font-size: 2rem;
font-weight: bold;
color: #ffd700;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.battle-main {
flex: 1;
display: flex;
flex-direction: column;
background: white;
color: #333;
border-radius: 20px 20px 0 0;
overflow: hidden;
}
.battle-results {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 2rem;
gap: 1rem;
}
.battle-results h2 {
font-size: 2.5rem;
margin: 0;
}
</style>