Fraser commited on
Commit
190d7a5
·
1 Parent(s): 01069ac
src/lib/components/Battle/ActionButtons.svelte CHANGED
@@ -1,148 +1,105 @@
1
  <script lang="ts">
 
 
 
2
  export let isWildBattle: boolean;
 
 
 
 
3
  export let onAction: (action: string) => void;
4
- </script>
5
-
6
- <div class="action-grid">
7
- <button class="action-button fight" on:click={() => onAction('fight')}>
8
- <span class="action-icon">⚔️</span>
9
- <span class="action-label">Fight</span>
10
- </button>
11
-
12
- <button class="action-button piclet" on:click={() => onAction('piclet')}>
13
- <span class="action-icon">🔄</span>
14
- <span class="action-label">Piclet</span>
15
- </button>
16
-
17
- {#if isWildBattle}
18
- <button class="action-button catch" on:click={() => onAction('catch')}>
19
- <span class="action-icon">🎯</span>
20
- <span class="action-label">Catch</span>
21
- </button>
22
- {:else}
23
- <button class="action-button items" disabled>
24
- <span class="action-icon">🎒</span>
25
- <span class="action-label">Items</span>
26
- </button>
27
- {/if}
28
-
29
- <button class="action-button run" on:click={() => onAction('run')}>
30
- <span class="action-icon">🏃</span>
31
- <span class="action-label">Run</span>
32
- </button>
33
- </div>
34
-
35
- <style>
36
- .action-grid {
37
- display: grid;
38
- grid-template-columns: repeat(2, 1fr);
39
- gap: 1rem;
40
- max-width: 400px;
41
- margin: 0 auto;
42
- width: 100%;
43
- }
44
-
45
- .action-button {
46
- padding: 2rem 1rem;
47
- background: #f8f9fa;
48
- border: 2px solid #e0e0e0;
49
- border-radius: 12px;
50
- cursor: pointer;
51
- display: flex;
52
- flex-direction: column;
53
- align-items: center;
54
- gap: 0.5rem;
55
- transition: all 0.2s ease;
56
- position: relative;
57
- overflow: hidden;
58
- }
59
-
60
- .action-button:hover:not(:disabled) {
61
- transform: translateY(-2px);
62
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
63
- }
64
-
65
- .action-button:active:not(:disabled) {
66
- transform: translateY(0);
67
- }
68
 
69
- .action-button:disabled {
70
- opacity: 0.5;
71
- cursor: not-allowed;
72
- }
73
-
74
- .action-icon {
75
- font-size: 2rem;
76
- }
77
-
78
- .action-label {
79
- font-weight: 600;
80
- font-size: 1rem;
81
- color: #333;
82
- }
83
-
84
- /* Action specific colors */
85
- .fight {
86
- background: #ffebee;
87
- border-color: #ef5350;
88
- }
89
 
90
- .fight:hover:not(:disabled) {
91
- background: #ffcdd2;
92
- border-color: #e53935;
93
  }
94
 
95
- .piclet {
96
- background: #e3f2fd;
97
- border-color: #42a5f5;
98
  }
99
 
100
- .piclet:hover:not(:disabled) {
101
- background: #bbdefb;
102
- border-color: #2196f3;
103
  }
104
 
105
- .catch {
106
- background: #e8f5e9;
107
- border-color: #66bb6a;
108
  }
109
 
110
- .catch:hover:not(:disabled) {
111
- background: #c8e6c9;
112
- border-color: #4caf50;
113
  }
114
-
115
- .items {
116
- background: #fff3e0;
117
- border-color: #ffa726;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
- .items:hover:not(:disabled) {
121
- background: #ffe0b2;
122
- border-color: #ff9800;
 
 
 
 
 
 
 
 
 
 
 
123
  }
124
 
125
- .run {
126
- background: #f3e5f5;
127
- border-color: #ab47bc;
128
  }
129
 
130
- .run:hover:not(:disabled) {
131
- background: #e1bee7;
132
- border-color: #9c27b0;
133
  }
134
 
135
- @media (max-width: 480px) {
136
- .action-button {
137
- padding: 1.5rem 0.75rem;
138
- }
139
-
140
- .action-icon {
141
- font-size: 1.5rem;
142
- }
143
-
144
- .action-label {
145
- font-size: 0.875rem;
146
- }
147
  }
148
  </style>
 
1
  <script lang="ts">
2
+ import ActionViewSelector, { type ActionView } from './ActionViewSelector.svelte';
3
+ import type { PicletInstance, BattleMove } from '$lib/db/schema';
4
+
5
  export let isWildBattle: boolean;
6
+ export let playerPiclet: PicletInstance;
7
+ export let enemyPiclet: PicletInstance | null = null;
8
+ export let availablePiclets: PicletInstance[] = [];
9
+ export let processingTurn: boolean = false;
10
  export let onAction: (action: string) => void;
11
+ export let onMoveSelect: (move: BattleMove) => void = () => {};
12
+ export let onPicletSelect: (piclet: PicletInstance) => void = () => {};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ let currentView: ActionView = 'main';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ function handleViewChange(view: ActionView) {
17
+ currentView = view;
 
18
  }
19
 
20
+ function handleMoveSelected(move: BattleMove) {
21
+ currentView = 'main';
22
+ onMoveSelect(move);
23
  }
24
 
25
+ function handlePicletSelected(piclet: PicletInstance) {
26
+ currentView = 'main';
27
+ onPicletSelect(piclet);
28
  }
29
 
30
+ function handleCaptureAttempt() {
31
+ currentView = 'main';
32
+ onAction('catch');
33
  }
34
 
35
+ // Add Run button outside of the action selector
36
+ function handleRun() {
37
+ onAction('run');
38
  }
39
+ </script>
40
+
41
+ <div class="battle-actions">
42
+ <ActionViewSelector
43
+ {currentView}
44
+ onViewChange={handleViewChange}
45
+ moves={playerPiclet.moves}
46
+ {availablePiclets}
47
+ {playerPiclet}
48
+ {enemyPiclet}
49
+ {isWildBattle}
50
+ onMoveSelected={handleMoveSelected}
51
+ onPicletSelected={handlePicletSelected}
52
+ onCaptureAttempt={handleCaptureAttempt}
53
+ currentPicletId={playerPiclet.id}
54
+ {processingTurn}
55
+ />
56
+
57
+ <!-- Run button (always visible) -->
58
+ <button
59
+ class="run-button"
60
+ on:click={handleRun}
61
+ disabled={processingTurn}
62
+ >
63
+ <span class="run-icon">🏃</span>
64
+ <span>Run</span>
65
+ </button>
66
+ </div>
67
+
68
+ <style>
69
+ .battle-actions {
70
+ display: flex;
71
+ flex-direction: column;
72
+ gap: 12px;
73
+ height: 100%;
74
  }
75
 
76
+ .run-button {
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ gap: 8px;
81
+ padding: 12px 24px;
82
+ background: #ff3b30;
83
+ color: white;
84
+ border: none;
85
+ border-radius: 12px;
86
+ font-size: 17px;
87
+ font-weight: 500;
88
+ cursor: pointer;
89
+ transition: all 0.2s;
90
  }
91
 
92
+ .run-button:active:not(:disabled) {
93
+ transform: scale(0.95);
94
+ background: #d70015;
95
  }
96
 
97
+ .run-button:disabled {
98
+ opacity: 0.5;
99
+ cursor: not-allowed;
100
  }
101
 
102
+ .run-icon {
103
+ font-size: 20px;
 
 
 
 
 
 
 
 
 
 
104
  }
105
  </style>
src/lib/components/Battle/ActionViewSelector.svelte ADDED
@@ -0,0 +1,466 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import type { PicletInstance, BattleMove } from '$lib/db/schema';
3
+
4
+ export type ActionView = 'main' | 'moves' | 'piclets' | 'items' | 'stats' | 'forcedSwap';
5
+
6
+ export let currentView: ActionView = 'main';
7
+ export let onViewChange: (view: ActionView) => void;
8
+ export let moves: BattleMove[] = [];
9
+ export let availablePiclets: PicletInstance[] = [];
10
+ export let playerPiclet: PicletInstance;
11
+ export let enemyPiclet: PicletInstance | null = null;
12
+ export let isWildBattle: boolean = false;
13
+ export let onMoveSelected: (move: BattleMove) => void = () => {};
14
+ export let onPicletSelected: (piclet: PicletInstance) => void = () => {};
15
+ export let onCaptureAttempt: () => void = () => {};
16
+ export let currentPicletId: number | null = null;
17
+ export let processingTurn: boolean = false;
18
+
19
+ // Main action items
20
+ const actions = [
21
+ { title: 'Act', icon: '⚔️', view: 'moves' as ActionView },
22
+ { title: 'Piclets', icon: '🔄', view: 'piclets' as ActionView },
23
+ { title: 'Items', icon: '🎒', view: 'items' as ActionView },
24
+ // { title: 'Stats', icon: '📊', view: 'stats' as ActionView }, // Debug only
25
+ ];
26
+
27
+ function handleActionClick(targetView: ActionView) {
28
+ if (currentView === targetView) {
29
+ onViewChange('main');
30
+ } else {
31
+ onViewChange(targetView);
32
+ }
33
+ }
34
+ </script>
35
+
36
+ <div class="action-view-container">
37
+ <!-- Main action list -->
38
+ {#if currentView !== 'forcedSwap'}
39
+ <div class="action-list main-actions">
40
+ {#each actions as action}
41
+ <button
42
+ class="action-item"
43
+ class:active={currentView === action.view}
44
+ on:click={() => handleActionClick(action.view)}
45
+ disabled={processingTurn}
46
+ >
47
+ <span class="action-icon" class:active={currentView === action.view}>
48
+ {action.icon}
49
+ </span>
50
+ <span class="action-title">{action.title}</span>
51
+ <span class="chevron">›</span>
52
+ </button>
53
+ {/each}
54
+ </div>
55
+ {/if}
56
+
57
+ <!-- Overlay sub-views -->
58
+ {#if currentView !== 'main'}
59
+ <div class="sub-view-overlay" class:forced={currentView === 'forcedSwap'}>
60
+ <div class="sub-view-content">
61
+ {#if currentView === 'moves'}
62
+ <div class="sub-view-list">
63
+ {#each moves as move}
64
+ {@const isDisabled = move.currentPp <= 0}
65
+ <button
66
+ class="sub-item move-item"
67
+ on:click={() => !isDisabled && onMoveSelected(move)}
68
+ disabled={isDisabled || processingTurn}
69
+ >
70
+ <span class="type-emoji" class:disabled={isDisabled}>
71
+ {move.type === 'normal' ? '⚪' :
72
+ move.type === 'status' ? '🔮' :
73
+ move.type === 'special' ? '✨' : '❓'}
74
+ </span>
75
+ <div class="move-info">
76
+ <div class="move-name" class:disabled={isDisabled}>{move.name}</div>
77
+ <div class="move-desc" class:disabled={isDisabled}>{move.description}</div>
78
+ </div>
79
+ <div class="move-pp" class:disabled={isDisabled}>
80
+ PP: {move.currentPp}/{move.pp}
81
+ </div>
82
+ </button>
83
+ {/each}
84
+ </div>
85
+ {:else if currentView === 'piclets'}
86
+ <div class="sub-view-list">
87
+ {@const availableHealthyPiclets = availablePiclets.filter(p =>
88
+ p.currentHp > 0 && p.id !== currentPicletId
89
+ )}
90
+ {#if availableHealthyPiclets.length === 0}
91
+ <div class="empty-message">
92
+ No other healthy piclets available
93
+ </div>
94
+ {:else}
95
+ {#each availableHealthyPiclets as piclet}
96
+ <button
97
+ class="sub-item piclet-item"
98
+ on:click={() => onPicletSelected(piclet)}
99
+ disabled={processingTurn}
100
+ >
101
+ <img
102
+ src={piclet.imageData || piclet.imageUrl}
103
+ alt={piclet.nickname}
104
+ class="piclet-thumb"
105
+ />
106
+ <div class="piclet-info">
107
+ <div class="piclet-header">
108
+ <span class="piclet-name">{piclet.nickname}</span>
109
+ <span class="type-emoji">🔥</span>
110
+ <span class="level-badge">Lv.{piclet.level}</span>
111
+ </div>
112
+ <div class="hp-row">
113
+ <div class="hp-bar-small">
114
+ <div
115
+ class="hp-fill-small"
116
+ style="width: {(piclet.currentHp / piclet.maxHp) * 100}%"
117
+ ></div>
118
+ </div>
119
+ <span class="hp-text-small">{piclet.currentHp}/{piclet.maxHp}</span>
120
+ </div>
121
+ </div>
122
+ </button>
123
+ {/each}
124
+ {/if}
125
+ </div>
126
+ {:else if currentView === 'items'}
127
+ <div class="sub-view-list">
128
+ {#if isWildBattle && enemyPiclet}
129
+ <button
130
+ class="sub-item item-item"
131
+ on:click={onCaptureAttempt}
132
+ disabled={processingTurn}
133
+ >
134
+ <span class="item-icon">📸</span>
135
+ <div class="item-info">
136
+ <div class="item-name">Capture</div>
137
+ <div class="item-desc">Snap to capture {enemyPiclet.nickname}</div>
138
+ </div>
139
+ </button>
140
+ {:else}
141
+ <div class="empty-message">
142
+ <span class="empty-icon">🎒</span>
143
+ <div>Items coming soon!</div>
144
+ <div class="empty-subtitle">This feature is currently under development.</div>
145
+ </div>
146
+ {/if}
147
+ </div>
148
+ {/if}
149
+ </div>
150
+ </div>
151
+ {/if}
152
+
153
+ <!-- Processing overlay -->
154
+ {#if processingTurn}
155
+ <div class="processing-overlay"></div>
156
+ {/if}
157
+ </div>
158
+
159
+ <style>
160
+ .action-view-container {
161
+ position: relative;
162
+ height: 100%;
163
+ }
164
+
165
+ /* Main action list */
166
+ .action-list {
167
+ background: white;
168
+ border-radius: 12px;
169
+ border: 0.5px solid #c6c6c8;
170
+ overflow: hidden;
171
+ }
172
+
173
+ .action-item {
174
+ display: flex;
175
+ align-items: center;
176
+ width: 100%;
177
+ padding: 12px 16px;
178
+ background: none;
179
+ border: none;
180
+ cursor: pointer;
181
+ text-align: left;
182
+ transition: background-color 0.2s;
183
+ position: relative;
184
+ }
185
+
186
+ .action-item:not(:last-child)::after {
187
+ content: '';
188
+ position: absolute;
189
+ bottom: 0;
190
+ left: 16px;
191
+ right: 0;
192
+ height: 0.5px;
193
+ background: #c6c6c8;
194
+ }
195
+
196
+ .action-item:active:not(:disabled) {
197
+ background: #f2f2f7;
198
+ }
199
+
200
+ .action-item:disabled {
201
+ opacity: 0.5;
202
+ cursor: not-allowed;
203
+ }
204
+
205
+ .action-icon {
206
+ width: 32px;
207
+ height: 32px;
208
+ display: flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ font-size: 20px;
212
+ border-radius: 8px;
213
+ margin-right: 12px;
214
+ }
215
+
216
+ .action-icon.active {
217
+ background: #e5f3ff;
218
+ }
219
+
220
+ .action-title {
221
+ flex: 1;
222
+ font-size: 17px;
223
+ font-weight: 400;
224
+ color: #000;
225
+ }
226
+
227
+ .chevron {
228
+ color: #8e8e93;
229
+ font-size: 16px;
230
+ }
231
+
232
+ /* Sub-view overlay */
233
+ .sub-view-overlay {
234
+ position: absolute;
235
+ top: 0;
236
+ left: 64px; /* Icon width + padding */
237
+ right: 0;
238
+ bottom: 0;
239
+ background: white;
240
+ border-radius: 12px;
241
+ border: 0.5px solid #c6c6c8;
242
+ box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
243
+ animation: slideIn 0.2s ease-out;
244
+ }
245
+
246
+ .sub-view-overlay.forced {
247
+ left: 0;
248
+ }
249
+
250
+ @keyframes slideIn {
251
+ from {
252
+ transform: translateX(20px);
253
+ opacity: 0;
254
+ }
255
+ to {
256
+ transform: translateX(0);
257
+ opacity: 1;
258
+ }
259
+ }
260
+
261
+ .sub-view-content {
262
+ height: 100%;
263
+ overflow-y: auto;
264
+ }
265
+
266
+ .sub-view-list {
267
+ padding: 0;
268
+ }
269
+
270
+ /* Sub-items */
271
+ .sub-item {
272
+ display: flex;
273
+ align-items: center;
274
+ width: 100%;
275
+ padding: 12px 16px;
276
+ background: none;
277
+ border: none;
278
+ cursor: pointer;
279
+ text-align: left;
280
+ transition: background-color 0.2s;
281
+ position: relative;
282
+ }
283
+
284
+ .sub-item:not(:last-child)::after {
285
+ content: '';
286
+ position: absolute;
287
+ bottom: 0;
288
+ left: 16px;
289
+ right: 0;
290
+ height: 0.5px;
291
+ background: #c6c6c8;
292
+ }
293
+
294
+ .sub-item:active:not(:disabled) {
295
+ background: #f2f2f7;
296
+ }
297
+
298
+ .sub-item:disabled {
299
+ opacity: 0.5;
300
+ cursor: not-allowed;
301
+ }
302
+
303
+ /* Move items */
304
+ .type-emoji {
305
+ font-size: 20px;
306
+ margin-right: 12px;
307
+ width: 32px;
308
+ text-align: center;
309
+ }
310
+
311
+ .type-emoji.disabled {
312
+ opacity: 0.3;
313
+ }
314
+
315
+ .move-info {
316
+ flex: 1;
317
+ }
318
+
319
+ .move-name {
320
+ font-size: 16px;
321
+ font-weight: 500;
322
+ color: #000;
323
+ margin-bottom: 2px;
324
+ }
325
+
326
+ .move-name.disabled {
327
+ color: #8e8e93;
328
+ }
329
+
330
+ .move-desc {
331
+ font-size: 13px;
332
+ color: #8e8e93;
333
+ }
334
+
335
+ .move-desc.disabled {
336
+ color: #c7c7cc;
337
+ }
338
+
339
+ .move-pp {
340
+ font-size: 12px;
341
+ padding: 4px 8px;
342
+ background: #f2f2f7;
343
+ border-radius: 12px;
344
+ color: #000;
345
+ white-space: nowrap;
346
+ }
347
+
348
+ .move-pp.disabled {
349
+ background: #f2f2f7;
350
+ color: #8e8e93;
351
+ }
352
+
353
+ /* Piclet items */
354
+ .piclet-thumb {
355
+ width: 48px;
356
+ height: 48px;
357
+ object-fit: contain;
358
+ border-radius: 8px;
359
+ margin-right: 12px;
360
+ }
361
+
362
+ .piclet-info {
363
+ flex: 1;
364
+ }
365
+
366
+ .piclet-header {
367
+ display: flex;
368
+ align-items: center;
369
+ gap: 4px;
370
+ margin-bottom: 4px;
371
+ }
372
+
373
+ .piclet-name {
374
+ font-size: 16px;
375
+ font-weight: 500;
376
+ color: #000;
377
+ }
378
+
379
+ .level-badge {
380
+ font-size: 11px;
381
+ font-weight: 700;
382
+ padding: 2px 6px;
383
+ background: #e5e5ea;
384
+ border-radius: 12px;
385
+ margin-left: auto;
386
+ }
387
+
388
+ .hp-row {
389
+ display: flex;
390
+ align-items: center;
391
+ gap: 8px;
392
+ }
393
+
394
+ .hp-bar-small {
395
+ flex: 1;
396
+ height: 6px;
397
+ background: #e5e5ea;
398
+ border-radius: 3px;
399
+ overflow: hidden;
400
+ }
401
+
402
+ .hp-fill-small {
403
+ height: 100%;
404
+ background: #4cd964;
405
+ transition: width 0.3s ease;
406
+ }
407
+
408
+ .hp-text-small {
409
+ font-size: 11px;
410
+ color: #8e8e93;
411
+ white-space: nowrap;
412
+ }
413
+
414
+ /* Item items */
415
+ .item-icon {
416
+ font-size: 24px;
417
+ margin-right: 12px;
418
+ width: 32px;
419
+ text-align: center;
420
+ }
421
+
422
+ .item-info {
423
+ flex: 1;
424
+ }
425
+
426
+ .item-name {
427
+ font-size: 16px;
428
+ font-weight: 500;
429
+ color: #000;
430
+ margin-bottom: 2px;
431
+ }
432
+
433
+ .item-desc {
434
+ font-size: 13px;
435
+ color: #8e8e93;
436
+ }
437
+
438
+ /* Empty states */
439
+ .empty-message {
440
+ padding: 24px;
441
+ text-align: center;
442
+ color: #8e8e93;
443
+ font-size: 16px;
444
+ }
445
+
446
+ .empty-icon {
447
+ font-size: 32px;
448
+ display: block;
449
+ margin-bottom: 8px;
450
+ opacity: 0.5;
451
+ }
452
+
453
+ .empty-subtitle {
454
+ font-size: 14px;
455
+ color: #c7c7cc;
456
+ margin-top: 4px;
457
+ }
458
+
459
+ /* Processing overlay */
460
+ .processing-overlay {
461
+ position: absolute;
462
+ inset: 0;
463
+ background: rgba(255, 255, 255, 0.8);
464
+ border-radius: 12px;
465
+ }
466
+ </style>
src/lib/components/Battle/BattleControls.svelte CHANGED
@@ -10,6 +10,7 @@
10
  export let battleEnded: boolean;
11
  export let isWildBattle: boolean;
12
  export let playerPiclet: PicletInstance;
 
13
  export let onAction: (action: string) => void;
14
  export let onMoveSelect: (move: any) => void;
15
  export let onPicletSelect: (piclet: PicletInstance) => void;
@@ -42,65 +43,14 @@
42
  {#if battlePhase === 'main' && !processingTurn && !battleEnded}
43
  <ActionButtons
44
  {isWildBattle}
 
 
 
 
45
  {onAction}
 
 
46
  />
47
- {:else if battlePhase === 'moveSelect'}
48
- <div class="move-select">
49
- <div class="section-header">
50
- <h3>Select a move</h3>
51
- <button class="back-btn" on:click={onBack}>← Back</button>
52
- </div>
53
- <div class="moves-grid">
54
- {#each playerPiclet.moves as move}
55
- <button
56
- class="move-button"
57
- on:click={() => onMoveSelect(move)}
58
- disabled={move.currentPp <= 0}
59
- >
60
- <span class="move-name">{move.name}</span>
61
- <span class="move-type">{move.type}</span>
62
- <span class="move-pp">PP: {move.currentPp}/{move.pp}</span>
63
- </button>
64
- {/each}
65
- </div>
66
- </div>
67
- {:else if battlePhase === 'picletSelect'}
68
- <div class="piclet-select">
69
- <div class="section-header">
70
- <h3>Select a Piclet</h3>
71
- <button class="back-btn" on:click={onBack}>← Back</button>
72
- </div>
73
- <div class="piclets-list">
74
- {#if availablePiclets.length === 0}
75
- <p class="no-piclets">No other healthy Piclets available!</p>
76
- {:else}
77
- {#each availablePiclets as piclet}
78
- <button
79
- class="piclet-option"
80
- on:click={() => onPicletSelect(piclet)}
81
- >
82
- <img
83
- src={piclet.imageUrl}
84
- alt={piclet.nickname}
85
- on:error={(e) => e.currentTarget.src = 'https://via.placeholder.com/50x50?text=P'}
86
- />
87
- <div class="piclet-details">
88
- <span class="piclet-name">{piclet.nickname}</span>
89
- <span class="piclet-stats">Lv.{piclet.level} - HP: {piclet.currentHp}/{piclet.maxHp}</span>
90
- </div>
91
- <div class="hp-preview">
92
- <div class="hp-preview-bar">
93
- <div
94
- class="hp-preview-fill"
95
- style="width: {(piclet.currentHp / piclet.maxHp) * 100}%"
96
- ></div>
97
- </div>
98
- </div>
99
- </button>
100
- {/each}
101
- {/if}
102
- </div>
103
- </div>
104
  {:else if battleEnded}
105
  <div class="battle-end">
106
  <button class="continue-btn" on:click={() => window.history.back()}>
 
10
  export let battleEnded: boolean;
11
  export let isWildBattle: boolean;
12
  export let playerPiclet: PicletInstance;
13
+ export let enemyPiclet: PicletInstance;
14
  export let onAction: (action: string) => void;
15
  export let onMoveSelect: (move: any) => void;
16
  export let onPicletSelect: (piclet: PicletInstance) => void;
 
43
  {#if battlePhase === 'main' && !processingTurn && !battleEnded}
44
  <ActionButtons
45
  {isWildBattle}
46
+ {playerPiclet}
47
+ {enemyPiclet}
48
+ {availablePiclets}
49
+ {processingTurn}
50
  {onAction}
51
+ {onMoveSelect}
52
+ {onPicletSelect}
53
  />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  {:else if battleEnded}
55
  <div class="battle-end">
56
  <button class="continue-btn" on:click={() => window.history.back()}>
src/lib/components/Battle/BattleField.svelte CHANGED
@@ -179,11 +179,12 @@
179
 
180
  .enemy-platform {
181
  width: 140px;
182
- height: 80px;
183
  position: absolute;
184
- bottom: -20px;
185
  left: -20px;
186
  z-index: 0;
 
187
  }
188
 
189
  /* Player Row */
@@ -213,11 +214,12 @@
213
 
214
  .player-platform {
215
  width: 160px;
216
- height: 80px;
217
  position: absolute;
218
- bottom: -40px;
219
  left: -20px;
220
  z-index: 0;
 
221
  }
222
 
223
  /* Platform fallbacks */
@@ -229,15 +231,15 @@
229
 
230
  .enemy-platform-fallback {
231
  width: 140px;
232
- height: 80px;
233
- bottom: -20px;
234
  left: -20px;
235
  }
236
 
237
  .player-platform-fallback {
238
  width: 160px;
239
- height: 80px;
240
- bottom: -40px;
241
  left: -20px;
242
  }
243
 
 
179
 
180
  .enemy-platform {
181
  width: 140px;
182
+ height: 140px;
183
  position: absolute;
184
+ bottom: -60px;
185
  left: -20px;
186
  z-index: 0;
187
+ object-fit: cover;
188
  }
189
 
190
  /* Player Row */
 
214
 
215
  .player-platform {
216
  width: 160px;
217
+ height: 160px;
218
  position: absolute;
219
+ bottom: -80px;
220
  left: -20px;
221
  z-index: 0;
222
+ object-fit: cover;
223
  }
224
 
225
  /* Platform fallbacks */
 
231
 
232
  .enemy-platform-fallback {
233
  width: 140px;
234
+ height: 140px;
235
+ bottom: -60px;
236
  left: -20px;
237
  }
238
 
239
  .player-platform-fallback {
240
  width: 160px;
241
+ height: 160px;
242
+ bottom: -80px;
243
  left: -20px;
244
  }
245
 
src/lib/components/Pages/Battle.svelte CHANGED
@@ -37,12 +37,6 @@
37
  if (processingTurn || battleEnded) return;
38
 
39
  switch (action) {
40
- case 'fight':
41
- battlePhase = 'moveSelect';
42
- break;
43
- case 'piclet':
44
- battlePhase = 'picletSelect';
45
- break;
46
  case 'catch':
47
  if (isWildBattle) {
48
  processingTurn = true;
 
37
  if (processingTurn || battleEnded) return;
38
 
39
  switch (action) {
 
 
 
 
 
 
40
  case 'catch':
41
  if (isWildBattle) {
42
  processingTurn = true;