Visaras commited on
Commit
7499073
·
verified ·
1 Parent(s): a8eb12f

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +881 -19
  3. prompts.txt +1 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Visaras Official
3
- emoji: 🏃
4
- colorFrom: gray
5
  colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: visaras-official
3
+ emoji: 🐳
4
+ colorFrom: red
5
  colorTo: purple
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,881 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>2v2 Battle Arena</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @keyframes pulse {
11
+ 0% { transform: scale(1); }
12
+ 50% { transform: scale(1.05); }
13
+ 100% { transform: scale(1); }
14
+ }
15
+
16
+ .pulse {
17
+ animation: pulse 1.5s infinite;
18
+ }
19
+
20
+ .map-cell {
21
+ transition: all 0.2s ease;
22
+ }
23
+
24
+ .map-cell:hover {
25
+ transform: scale(1.05);
26
+ box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
27
+ }
28
+
29
+ .character {
30
+ transition: all 0.3s ease;
31
+ z-index: 10;
32
+ }
33
+
34
+ .character.selected {
35
+ transform: scale(1.1);
36
+ filter: drop-shadow(0 0 8px rgba(255, 215, 0, 0.8));
37
+ }
38
+
39
+ .movable {
40
+ background-color: rgba(100, 200, 255, 0.3);
41
+ }
42
+
43
+ .attackable {
44
+ background-color: rgba(255, 100, 100, 0.3);
45
+ }
46
+
47
+ .health-bar {
48
+ height: 4px;
49
+ transition: width 0.3s ease;
50
+ }
51
+
52
+ .damage-popup {
53
+ position: absolute;
54
+ color: red;
55
+ font-weight: bold;
56
+ animation: float-up 1s forwards;
57
+ z-index: 20;
58
+ }
59
+
60
+ @keyframes float-up {
61
+ 0% { transform: translateY(0); opacity: 1; }
62
+ 100% { transform: translateY(-30px); opacity: 0; }
63
+ }
64
+
65
+ .ability-icon {
66
+ transition: all 0.2s ease;
67
+ }
68
+
69
+ .ability-icon:hover {
70
+ transform: scale(1.1);
71
+ filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.7));
72
+ }
73
+
74
+ .game-container {
75
+ perspective: 1000px;
76
+ }
77
+
78
+ .map-container {
79
+ transform-style: preserve-3d;
80
+ transform: rotateX(10deg);
81
+ }
82
+ </style>
83
+ </head>
84
+ <body class="bg-gray-900 text-white min-h-screen">
85
+ <div class="container mx-auto px-4 py-8">
86
+ <h1 class="text-4xl font-bold text-center mb-2 text-transparent bg-clip-text bg-gradient-to-r from-blue-400 to-purple-600">
87
+ 2v2 Battle Arena
88
+ </h1>
89
+ <p class="text-center text-gray-300 mb-8">A strategic turn-based battle game for you and your friends</p>
90
+
91
+ <div class="flex flex-col lg:flex-row gap-8">
92
+ <!-- Game setup panel -->
93
+ <div class="bg-gray-800 rounded-lg p-6 lg:w-1/4">
94
+ <h2 class="text-2xl font-bold mb-4 text-blue-400">Game Setup</h2>
95
+
96
+ <div class="mb-6">
97
+ <h3 class="text-lg font-semibold mb-2">Select Team</h3>
98
+ <div class="flex gap-4 mb-4">
99
+ <button id="team1-btn" class="flex-1 py-2 px-4 bg-blue-600 hover:bg-blue-700 rounded-lg font-medium transition">
100
+ Team 1 (Blue)
101
+ </button>
102
+ <button id="team2-btn" class="flex-1 py-2 px-4 bg-red-600 hover:bg-red-700 rounded-lg font-medium transition">
103
+ Team 2 (Red)
104
+ </button>
105
+ </div>
106
+
107
+ <div id="team1-players" class="mb-4">
108
+ <h4 class="text-sm font-semibold mb-2 text-blue-300">Team 1 Players</h4>
109
+ <div class="flex items-center gap-2 mb-2">
110
+ <input type="text" placeholder="Player 1" class="bg-gray-700 px-3 py-1 rounded w-full">
111
+ </div>
112
+ <div class="flex items-center gap-2">
113
+ <input type="text" placeholder="Player 2" class="bg-gray-700 px-3 py-1 rounded w-full">
114
+ </div>
115
+ </div>
116
+
117
+ <div id="team2-players" class="mb-4">
118
+ <h4 class="text-sm font-semibold mb-2 text-red-300">Team 2 Players</h4>
119
+ <div class="flex items-center gap-2 mb-2">
120
+ <input type="text" placeholder="Player 3" class="bg-gray-700 px-3 py-1 rounded w-full">
121
+ </div>
122
+ <div class="flex items-center gap-2">
123
+ <input type="text" placeholder="Player 4" class="bg-gray-700 px-3 py-1 rounded w-full">
124
+ </div>
125
+ </div>
126
+ </div>
127
+
128
+ <div class="mb-6">
129
+ <h3 class="text-lg font-semibold mb-2">Select Character</h3>
130
+ <div class="grid grid-cols-2 gap-3">
131
+ <div class="character-option bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-gray-600 transition" data-character="warrior">
132
+ <div class="flex items-center gap-2">
133
+ <i class="fas fa-sword text-yellow-500"></i>
134
+ <span>Warrior</span>
135
+ </div>
136
+ <p class="text-xs text-gray-400 mt-1">High damage, medium health</p>
137
+ </div>
138
+ <div class="character-option bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-gray-600 transition" data-character="archer">
139
+ <div class="flex items-center gap-2">
140
+ <i class="fas fa-bow-arrow text-green-500"></i>
141
+ <span>Archer</span>
142
+ </div>
143
+ <p class="text-xs text-gray-400 mt-1">Ranged attacks, low health</p>
144
+ </div>
145
+ <div class="character-option bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-gray-600 transition" data-character="mage">
146
+ <div class="flex items-center gap-2">
147
+ <i class="fas fa-hat-wizard text-purple-500"></i>
148
+ <span>Mage</span>
149
+ </div>
150
+ <p class="text-xs text-gray-400 mt-1">Area damage, low health</p>
151
+ </div>
152
+ <div class="character-option bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-gray-600 transition" data-character="tank">
153
+ <div class="flex items-center gap-2">
154
+ <i class="fas fa-shield-alt text-blue-500"></i>
155
+ <span>Tank</span>
156
+ </div>
157
+ <p class="text-xs text-gray-400 mt-1">High health, low damage</p>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ <div class="mb-6">
163
+ <h3 class="text-lg font-semibold mb-2">Game Status</h3>
164
+ <div id="game-status" class="bg-gray-700 p-3 rounded-lg">
165
+ <p class="text-center text-gray-400">Setup in progress...</p>
166
+ </div>
167
+ </div>
168
+
169
+ <button id="start-game-btn" class="w-full py-3 bg-green-600 hover:bg-green-700 rounded-lg font-bold transition flex items-center justify-center gap-2">
170
+ <i class="fas fa-play"></i>
171
+ Start Game
172
+ </button>
173
+ </div>
174
+
175
+ <!-- Main game area -->
176
+ <div class="flex-1">
177
+ <div class="game-container">
178
+ <div class="map-container bg-gray-800 rounded-lg p-4 mb-4">
179
+ <div id="game-map" class="grid grid-cols-8 gap-1 mx-auto" style="width: fit-content;"></div>
180
+ </div>
181
+
182
+ <div class="bg-gray-800 rounded-lg p-4">
183
+ <div class="flex justify-between items-center mb-4">
184
+ <h2 class="text-xl font-bold text-blue-400">Team 1</h2>
185
+ <h2 class="text-xl font-bold text-red-400">Team 2</h2>
186
+ </div>
187
+
188
+ <div class="grid grid-cols-2 gap-4 mb-4">
189
+ <div id="team1-info" class="bg-blue-900 bg-opacity-30 p-3 rounded-lg">
190
+ <h3 class="font-semibold mb-2">Players:</h3>
191
+ <ul class="text-sm">
192
+ <li>Player 1 (Warrior)</li>
193
+ <li>Player 2 (Archer)</li>
194
+ </ul>
195
+ </div>
196
+ <div id="team2-info" class="bg-red-900 bg-opacity-30 p-3 rounded-lg">
197
+ <h3 class="font-semibold mb-2">Players:</h3>
198
+ <ul class="text-sm">
199
+ <li>Player 3 (Mage)</li>
200
+ <li>Player 4 (Tank)</li>
201
+ </ul>
202
+ </div>
203
+ </div>
204
+
205
+ <div id="turn-indicator" class="bg-gray-700 p-3 rounded-lg mb-4 text-center font-bold text-yellow-400">
206
+ Team 1's Turn
207
+ </div>
208
+
209
+ <div id="action-panel" class="bg-gray-700 p-3 rounded-lg">
210
+ <h3 class="font-semibold mb-2">Actions</h3>
211
+ <div class="flex gap-2 mb-3">
212
+ <button id="move-btn" class="px-3 py-1 bg-blue-600 rounded hover:bg-blue-700 transition">
213
+ <i class="fas fa-walking mr-1"></i> Move
214
+ </button>
215
+ <button id="attack-btn" class="px-3 py-1 bg-red-600 rounded hover:bg-red-700 transition">
216
+ <i class="fas fa-bolt mr-1"></i> Attack
217
+ </button>
218
+ <button id="end-turn-btn" class="px-3 py-1 bg-gray-600 rounded hover:bg-gray-700 transition">
219
+ <i class="fas fa-flag mr-1"></i> End Turn
220
+ </button>
221
+ </div>
222
+
223
+ <div id="abilities" class="grid grid-cols-2 gap-2">
224
+ <!-- Abilities will be shown here -->
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ </div>
232
+
233
+ <script>
234
+ // Game state
235
+ const gameState = {
236
+ currentTeam: 1, // 1 or 2
237
+ selectedCharacter: null,
238
+ gameStarted: false,
239
+ characters: [],
240
+ mapSize: 8,
241
+ currentAction: null, // 'move', 'attack', or ability name
242
+ turnCount: 1
243
+ };
244
+
245
+ // Character classes
246
+ const characterClasses = {
247
+ warrior: {
248
+ name: "Warrior",
249
+ icon: "fa-sword",
250
+ color: "yellow",
251
+ health: 120,
252
+ attack: 30,
253
+ range: 1,
254
+ move: 3,
255
+ abilities: [
256
+ {
257
+ name: "Power Strike",
258
+ description: "Deals 50% more damage",
259
+ icon: "fa-bolt",
260
+ cooldown: 3,
261
+ currentCooldown: 0,
262
+ action: (character) => {
263
+ character.tempAttackBonus = character.attack * 0.5;
264
+ return `${character.name} prepares a powerful strike!`;
265
+ }
266
+ },
267
+ {
268
+ name: "Taunt",
269
+ description: "Forces enemies to attack you next turn",
270
+ icon: "fa-bullhorn",
271
+ cooldown: 4,
272
+ currentCooldown: 0,
273
+ action: (character) => {
274
+ // This would be implemented in the game logic
275
+ return `${character.name} taunts the enemies!`;
276
+ }
277
+ }
278
+ ]
279
+ },
280
+ archer: {
281
+ name: "Archer",
282
+ icon: "fa-bow-arrow",
283
+ color: "green",
284
+ health: 80,
285
+ attack: 25,
286
+ range: 4,
287
+ move: 2,
288
+ abilities: [
289
+ {
290
+ name: "Precision Shot",
291
+ description: "Guaranteed critical hit",
292
+ icon: "fa-crosshairs",
293
+ cooldown: 3,
294
+ currentCooldown: 0,
295
+ action: (character) => {
296
+ character.tempAttackBonus = character.attack;
297
+ return `${character.name} lines up a perfect shot!`;
298
+ }
299
+ },
300
+ {
301
+ name: "Multishot",
302
+ description: "Attack all enemies in range",
303
+ icon: "fa-arrows-to-dot",
304
+ cooldown: 4,
305
+ currentCooldown: 0,
306
+ action: (character) => {
307
+ // Would be implemented in attack logic
308
+ return `${character.name} fires arrows in all directions!`;
309
+ }
310
+ }
311
+ ]
312
+ },
313
+ mage: {
314
+ name: "Mage",
315
+ icon: "fa-hat-wizard",
316
+ color: "purple",
317
+ health: 70,
318
+ attack: 35,
319
+ range: 3,
320
+ move: 2,
321
+ abilities: [
322
+ {
323
+ name: "Fireball",
324
+ description: "Hits all adjacent enemies",
325
+ icon: "fa-fire",
326
+ cooldown: 3,
327
+ currentCooldown: 0,
328
+ action: (character) => {
329
+ // Would be implemented in attack logic
330
+ return `${character.name} conjures a massive fireball!`;
331
+ }
332
+ },
333
+ {
334
+ name: "Teleport",
335
+ description: "Move to any empty space",
336
+ icon: "fa-person-running",
337
+ cooldown: 4,
338
+ currentCooldown: 0,
339
+ action: (character) => {
340
+ // Would be implemented in move logic
341
+ return `${character.name} prepares to teleport!`;
342
+ }
343
+ }
344
+ ]
345
+ },
346
+ tank: {
347
+ name: "Tank",
348
+ icon: "fa-shield-alt",
349
+ color: "blue",
350
+ health: 150,
351
+ attack: 15,
352
+ range: 1,
353
+ move: 2,
354
+ abilities: [
355
+ {
356
+ name: "Shield Bash",
357
+ description: "Stuns enemy for 1 turn",
358
+ icon: "fa-shield",
359
+ cooldown: 3,
360
+ currentCooldown: 0,
361
+ action: (character) => {
362
+ // Would be implemented in attack logic
363
+ return `${character.name} prepares to bash with their shield!`;
364
+ }
365
+ },
366
+ {
367
+ name: "Fortify",
368
+ description: "Reduce damage taken by 50%",
369
+ icon: "fa-fort",
370
+ cooldown: 4,
371
+ currentCooldown: 0,
372
+ action: (character) => {
373
+ character.tempDefenseBonus = 0.5;
374
+ return `${character.name} fortifies their position!`;
375
+ }
376
+ }
377
+ ]
378
+ }
379
+ };
380
+
381
+ // Initialize the game
382
+ document.addEventListener('DOMContentLoaded', function() {
383
+ initializeMap();
384
+ setupEventListeners();
385
+
386
+ // For demo purposes, we'll auto-setup the game
387
+ setTimeout(() => {
388
+ setupDemoGame();
389
+ }, 500);
390
+ });
391
+
392
+ function initializeMap() {
393
+ const map = document.getElementById('game-map');
394
+ map.innerHTML = '';
395
+
396
+ for (let y = 0; y < gameState.mapSize; y++) {
397
+ for (let x = 0; x < gameState.mapSize; x++) {
398
+ const cell = document.createElement('div');
399
+ cell.className = 'map-cell w-12 h-12 bg-gray-700 rounded-sm flex items-center justify-center relative';
400
+ cell.dataset.x = x;
401
+ cell.dataset.y = y;
402
+
403
+ // Add some terrain variety for demo
404
+ if (Math.random() < 0.1) {
405
+ cell.classList.add('bg-gray-600'); // Rock
406
+ } else if (Math.random() < 0.15) {
407
+ cell.classList.add('bg-green-800'); // Bush
408
+ }
409
+
410
+ cell.addEventListener('click', () => handleMapClick(x, y));
411
+ map.appendChild(cell);
412
+ }
413
+ }
414
+ }
415
+
416
+ function setupEventListeners() {
417
+ // Team selection
418
+ document.getElementById('team1-btn').addEventListener('click', () => selectTeam(1));
419
+ document.getElementById('team2-btn').addEventListener('click', () => selectTeam(2));
420
+
421
+ // Character selection
422
+ document.querySelectorAll('.character-option').forEach(option => {
423
+ option.addEventListener('click', function() {
424
+ selectCharacter(this.dataset.character);
425
+ });
426
+ });
427
+
428
+ // Action buttons
429
+ document.getElementById('move-btn').addEventListener('click', () => setAction('move'));
430
+ document.getElementById('attack-btn').addEventListener('click', () => setAction('attack'));
431
+ document.getElementById('end-turn-btn').addEventListener('click', endTurn);
432
+
433
+ // Start game
434
+ document.getElementById('start-game-btn').addEventListener('click', startGame);
435
+ }
436
+
437
+ function selectTeam(team) {
438
+ document.getElementById('team1-btn').classList.remove('bg-blue-700', 'ring-2', 'ring-blue-400');
439
+ document.getElementById('team2-btn').classList.remove('bg-red-700', 'ring-2', 'ring-red-400');
440
+
441
+ if (team === 1) {
442
+ document.getElementById('team1-btn').classList.add('bg-blue-700', 'ring-2', 'ring-blue-400');
443
+ } else {
444
+ document.getElementById('team2-btn').classList.add('bg-red-700', 'ring-2', 'ring-red-400');
445
+ }
446
+
447
+ updateGameStatus(`Selected Team ${team}. Now choose a character.`);
448
+ }
449
+
450
+ function selectCharacter(characterClass) {
451
+ document.querySelectorAll('.character-option').forEach(option => {
452
+ option.classList.remove('ring-2', 'ring-yellow-400');
453
+ });
454
+
455
+ const selectedOption = document.querySelector(`.character-option[data-character="${characterClass}"]`);
456
+ selectedOption.classList.add('ring-2', 'ring-yellow-400');
457
+
458
+ updateGameStatus(`Selected ${characterClasses[characterClass].name}. Ready to start game!`);
459
+ }
460
+
461
+ function startGame() {
462
+ if (gameState.gameStarted) return;
463
+
464
+ gameState.gameStarted = true;
465
+ updateGameStatus("Game started! Team 1's turn.");
466
+
467
+ document.getElementById('start-game-btn').classList.add('hidden');
468
+
469
+ // For demo purposes, we'll use the demo setup
470
+ // In a real game, you would place characters based on player selections
471
+ }
472
+
473
+ function setupDemoGame() {
474
+ // Clear any existing characters
475
+ gameState.characters = [];
476
+
477
+ // Create demo characters
478
+ const characters = [
479
+ { team: 1, class: 'warrior', x: 1, y: 1, name: "Player 1" },
480
+ { team: 1, class: 'archer', x: 2, y: 1, name: "Player 2" },
481
+ { team: 2, class: 'mage', x: 5, y: 6, name: "Player 3" },
482
+ { team: 2, class: 'tank', x: 6, y: 6, name: "Player 4" }
483
+ ];
484
+
485
+ characters.forEach(charData => {
486
+ const charClass = characterClasses[charData.class];
487
+ const character = {
488
+ id: Math.random().toString(36).substr(2, 9),
489
+ name: charData.name,
490
+ team: charData.team,
491
+ class: charData.class,
492
+ x: charData.x,
493
+ y: charData.y,
494
+ maxHealth: charClass.health,
495
+ health: charClass.health,
496
+ attack: charClass.attack,
497
+ range: charClass.range,
498
+ move: charClass.move,
499
+ abilities: JSON.parse(JSON.stringify(charClass.abilities)), // Deep copy
500
+ tempAttackBonus: 0,
501
+ tempDefenseBonus: 0,
502
+ moved: false,
503
+ attacked: false
504
+ };
505
+
506
+ gameState.characters.push(character);
507
+ });
508
+
509
+ renderCharacters();
510
+ updateTeamInfo();
511
+ }
512
+
513
+ function renderCharacters() {
514
+ // Clear existing character elements
515
+ document.querySelectorAll('.character').forEach(el => el.remove());
516
+
517
+ gameState.characters.forEach(character => {
518
+ const cell = document.querySelector(`.map-cell[data-x="${character.x}"][data-y="${character.y}"]`);
519
+ if (!cell) return;
520
+
521
+ const charElement = document.createElement('div');
522
+ charElement.className = `character absolute w-10 h-10 rounded-full flex items-center justify-center text-xl cursor-pointer ${
523
+ character.team === 1 ? 'bg-blue-600' : 'bg-red-600'
524
+ }`;
525
+ charElement.dataset.id = character.id;
526
+ charElement.innerHTML = `<i class="fas ${characterClasses[character.class].icon}"></i>`;
527
+
528
+ // Health bar
529
+ const healthBar = document.createElement('div');
530
+ healthBar.className = 'absolute bottom-0 left-0 right-0 bg-gray-800 rounded-b-full overflow-hidden';
531
+
532
+ const healthFill = document.createElement('div');
533
+ healthFill.className = `health-bar ${character.team === 1 ? 'bg-blue-400' : 'bg-red-400'}`;
534
+ healthFill.style.width = `${(character.health / character.maxHealth) * 100}%`;
535
+ healthBar.appendChild(healthFill);
536
+
537
+ charElement.appendChild(healthBar);
538
+
539
+ charElement.addEventListener('click', () => selectCharacterOnMap(character.id));
540
+ cell.appendChild(charElement);
541
+ });
542
+ }
543
+
544
+ function selectCharacterOnMap(characterId) {
545
+ // Deselect all characters
546
+ document.querySelectorAll('.character').forEach(el => el.classList.remove('selected'));
547
+
548
+ const character = gameState.characters.find(c => c.id === characterId);
549
+ if (!character) return;
550
+
551
+ // Can only select characters from current team
552
+ if (character.team !== gameState.currentTeam) {
553
+ showMessage(`It's Team ${gameState.currentTeam}'s turn!`);
554
+ return;
555
+ }
556
+
557
+ // Select the character
558
+ gameState.selectedCharacter = character;
559
+ document.querySelector(`.character[data-id="${characterId}"]`).classList.add('selected');
560
+
561
+ // Highlight movable and attackable cells
562
+ highlightActionCells(character);
563
+
564
+ showMessage(`Selected ${character.name} the ${characterClasses[character.class].name}`);
565
+ }
566
+
567
+ function highlightActionCells(character) {
568
+ // Clear previous highlights
569
+ document.querySelectorAll('.map-cell').forEach(cell => {
570
+ cell.classList.remove('movable', 'attackable');
571
+ });
572
+
573
+ if (!character) return;
574
+
575
+ // Highlight movable cells
576
+ if (!character.moved) {
577
+ const movableCells = getMovableCells(character.x, character.y, character.move);
578
+ movableCells.forEach(([x, y]) => {
579
+ const cell = document.querySelector(`.map-cell[data-x="${x}"][data-y="${y}"]`);
580
+ if (cell && !isCellOccupied(x, y)) {
581
+ cell.classList.add('movable');
582
+ }
583
+ });
584
+ }
585
+
586
+ // Highlight attackable cells
587
+ if (!character.attacked) {
588
+ const attackableCells = getAttackableCells(character.x, character.y, character.range);
589
+ attackableCells.forEach(([x, y]) => {
590
+ const cell = document.querySelector(`.map-cell[data-x="${x}"][data-y="${y}"]`);
591
+ const target = getCharacterAtPosition(x, y);
592
+ if (cell && target && target.team !== character.team) {
593
+ cell.classList.add('attackable');
594
+ }
595
+ });
596
+ }
597
+ }
598
+
599
+ function getMovableCells(x, y, range) {
600
+ const cells = [];
601
+ for (let dx = -range; dx <= range; dx++) {
602
+ for (let dy = -range; dy <= range; dy++) {
603
+ const newX = x + dx;
604
+ const newY = y + dy;
605
+
606
+ // Check if within bounds
607
+ if (newX >= 0 && newX < gameState.mapSize && newY >= 0 && newY < gameState.mapSize) {
608
+ // Simple movement - can move in any direction within range
609
+ // For more complex movement, you'd implement pathfinding
610
+ if (Math.abs(dx) + Math.abs(dy) <= range) {
611
+ cells.push([newX, newY]);
612
+ }
613
+ }
614
+ }
615
+ }
616
+ return cells;
617
+ }
618
+
619
+ function getAttackableCells(x, y, range) {
620
+ const cells = [];
621
+ for (let dx = -range; dx <= range; dx++) {
622
+ for (let dy = -range; dy <= range; dy++) {
623
+ const newX = x + dx;
624
+ const newY = y + dy;
625
+
626
+ // Check if within bounds
627
+ if (newX >= 0 && newX < gameState.mapSize && newY >= 0 && newY < gameState.mapSize) {
628
+ // Different attack patterns could be implemented here
629
+ // This is simple radial attack
630
+ if (Math.abs(dx) + Math.abs(dy) <= range) {
631
+ cells.push([newX, newY]);
632
+ }
633
+ }
634
+ }
635
+ }
636
+ return cells;
637
+ }
638
+
639
+ function isCellOccupied(x, y) {
640
+ return gameState.characters.some(c => c.x === x && c.y === y);
641
+ }
642
+
643
+ function getCharacterAtPosition(x, y) {
644
+ return gameState.characters.find(c => c.x === x && c.y === y);
645
+ }
646
+
647
+ function handleMapClick(x, y) {
648
+ if (!gameState.gameStarted || !gameState.selectedCharacter) return;
649
+
650
+ const cell = document.querySelector(`.map-cell[data-x="${x}"][data-y="${y}"]`);
651
+ const character = gameState.selectedCharacter;
652
+
653
+ if (cell.classList.contains('movable') && gameState.currentAction === 'move') {
654
+ // Move character
655
+ character.x = x;
656
+ character.y = y;
657
+ character.moved = true;
658
+
659
+ showMessage(`${character.name} moved to (${x}, ${y})`);
660
+ renderCharacters();
661
+ highlightActionCells(character);
662
+
663
+ // Update abilities that might be affected by position
664
+ updateAbilitiesPanel();
665
+ }
666
+ else if (cell.classList.contains('attackable') && (gameState.currentAction === 'attack' || gameState.currentAction?.startsWith('ability-'))) {
667
+ // Attack or use ability
668
+ const target = getCharacterAtPosition(x, y);
669
+ if (target && target.team !== character.team) {
670
+ let damage = character.attack;
671
+ let message = `${character.name} attacks ${target.name}!`;
672
+
673
+ // Check if using an ability
674
+ if (gameState.currentAction?.startsWith('ability-')) {
675
+ const abilityIndex = parseInt(gameState.currentAction.split('-')[1]);
676
+ const ability = character.abilities[abilityIndex];
677
+
678
+ if (ability.currentCooldown === 0) {
679
+ message = ability.action(character);
680
+ damage += character.tempAttackBonus || 0;
681
+ ability.currentCooldown = ability.cooldown;
682
+
683
+ // Reset temp bonuses after use
684
+ character.tempAttackBonus = 0;
685
+ }
686
+ }
687
+
688
+ // Apply damage
689
+ const finalDamage = Math.max(1, Math.floor(damage * (1 - (target.tempDefenseBonus || 0))));
690
+ target.health -= finalDamage;
691
+ target.health = Math.max(0, target.health);
692
+
693
+ showMessage(`${message} Dealt ${finalDamage} damage!`);
694
+
695
+ // Show damage popup
696
+ showDamagePopup(x, y, finalDamage);
697
+
698
+ // Check if target died
699
+ if (target.health <= 0) {
700
+ showMessage(`${target.name} has been defeated!`);
701
+ // In a full game, you'd remove the character or mark as dead
702
+ }
703
+
704
+ character.attacked = true;
705
+ renderCharacters();
706
+ highlightActionCells(character);
707
+ updateAbilitiesPanel();
708
+ }
709
+ }
710
+
711
+ // Reset action after performing it
712
+ gameState.currentAction = null;
713
+ }
714
+
715
+ function showDamagePopup(x, y, amount) {
716
+ const cell = document.querySelector(`.map-cell[data-x="${x}"][data-y="${y}"]`);
717
+ if (!cell) return;
718
+
719
+ const popup = document.createElement('div');
720
+ popup.className = 'damage-popup';
721
+ popup.textContent = `-${amount}`;
722
+ cell.appendChild(popup);
723
+
724
+ // Remove after animation
725
+ setTimeout(() => {
726
+ popup.remove();
727
+ }, 1000);
728
+ }
729
+
730
+ function setAction(action) {
731
+ if (!gameState.selectedCharacter) {
732
+ showMessage("Select a character first!");
733
+ return;
734
+ }
735
+
736
+ gameState.currentAction = action;
737
+ showMessage(`Ready to ${action}! Select a target.`);
738
+ }
739
+
740
+ function updateAbilitiesPanel() {
741
+ const panel = document.getElementById('abilities');
742
+ panel.innerHTML = '';
743
+
744
+ if (!gameState.selectedCharacter) return;
745
+
746
+ const character = gameState.selectedCharacter;
747
+
748
+ character.abilities.forEach((ability, index) => {
749
+ const abilityEl = document.createElement('div');
750
+ abilityEl.className = `ability-icon bg-gray-600 p-2 rounded cursor-pointer flex flex-col items-center ${
751
+ ability.currentCooldown > 0 ? 'opacity-50' : 'hover:bg-gray-500'
752
+ }`;
753
+ abilityEl.title = `${ability.name}: ${ability.description}\nCooldown: ${ability.cooldown} turns`;
754
+
755
+ abilityEl.innerHTML = `
756
+ <i class="fas ${ability.icon} mb-1"></i>
757
+ <span class="text-xs">${ability.name}</span>
758
+ ${ability.currentCooldown > 0 ?
759
+ `<span class="text-xs text-yellow-400">CD: ${ability.currentCooldown}</span>` : ''}
760
+ `;
761
+
762
+ if (ability.currentCooldown === 0 && !character.attacked) {
763
+ abilityEl.addEventListener('click', () => {
764
+ gameState.currentAction = `ability-${index}`;
765
+ showMessage(`Using ${ability.name}! Select a target.`);
766
+ });
767
+ }
768
+
769
+ panel.appendChild(abilityEl);
770
+ });
771
+ }
772
+
773
+ function endTurn() {
774
+ // Reset all characters' moved/attacked status for the current team
775
+ gameState.characters
776
+ .filter(c => c.team === gameState.currentTeam)
777
+ .forEach(c => {
778
+ c.moved = false;
779
+ c.attacked = false;
780
+ c.tempAttackBonus = 0;
781
+ c.tempDefenseBonus = 0;
782
+
783
+ // Update ability cooldowns
784
+ c.abilities.forEach(ability => {
785
+ if (ability.currentCooldown > 0) {
786
+ ability.currentCooldown--;
787
+ }
788
+ });
789
+ });
790
+
791
+ // Switch teams
792
+ gameState.currentTeam = gameState.currentTeam === 1 ? 2 : 1;
793
+ gameState.turnCount++;
794
+
795
+ // Deselect any character
796
+ gameState.selectedCharacter = null;
797
+ document.querySelectorAll('.character').forEach(el => el.classList.remove('selected'));
798
+
799
+ // Clear action highlights
800
+ document.querySelectorAll('.map-cell').forEach(cell => {
801
+ cell.classList.remove('movable', 'attackable');
802
+ });
803
+
804
+ // Update UI
805
+ updateTurnIndicator();
806
+ showMessage(`Team ${gameState.currentTeam}'s turn!`);
807
+
808
+ // Check for win condition
809
+ checkWinCondition();
810
+ }
811
+
812
+ function checkWinCondition() {
813
+ const team1Alive = gameState.characters.some(c => c.team === 1 && c.health > 0);
814
+ const team2Alive = gameState.characters.some(c => c.team === 2 && c.health > 0);
815
+
816
+ if (!team1Alive) {
817
+ endGame(2);
818
+ } else if (!team2Alive) {
819
+ endGame(1);
820
+ }
821
+ }
822
+
823
+ function endGame(winningTeam) {
824
+ gameState.gameStarted = false;
825
+
826
+ const message = `Team ${winningTeam} wins the game!`;
827
+ showMessage(message, true);
828
+ updateGameStatus(message);
829
+
830
+ document.getElementById('start-game-btn').classList.remove('hidden');
831
+ document.getElementById('start-game-btn').textContent = 'Play Again';
832
+ }
833
+
834
+ function updateTurnIndicator() {
835
+ const indicator = document.getElementById('turn-indicator');
836
+ indicator.textContent = `Team ${gameState.currentTeam}'s Turn (Round ${gameState.turnCount})`;
837
+ indicator.className = `bg-gray-700 p-3 rounded-lg mb-4 text-center font-bold ${
838
+ gameState.currentTeam === 1 ? 'text-blue-400' : 'text-red-400'
839
+ }`;
840
+ }
841
+
842
+ function updateTeamInfo() {
843
+ const team1Chars = gameState.characters.filter(c => c.team === 1);
844
+ const team2Chars = gameState.characters.filter(c => c.team === 2);
845
+
846
+ document.getElementById('team1-info').innerHTML = `
847
+ <h3 class="font-semibold mb-2">Players:</h3>
848
+ <ul class="text-sm">
849
+ ${team1Chars.map(c => `<li>${c.name} (${characterClasses[c.class].name}) - HP: ${c.health}/${c.maxHealth}</li>`).join('')}
850
+ </ul>
851
+ `;
852
+
853
+ document.getElementById('team2-info').innerHTML = `
854
+ <h3 class="font-semibold mb-2">Players:</h3>
855
+ <ul class="text-sm">
856
+ ${team2Chars.map(c => `<li>${c.name} (${characterClasses[c.class].name}) - HP: ${c.health}/${c.maxHealth}</li>`).join('')}
857
+ </ul>
858
+ `;
859
+ }
860
+
861
+ function updateGameStatus(message) {
862
+ document.getElementById('game-status').innerHTML = `
863
+ <p class="text-center">${message}</p>
864
+ `;
865
+ }
866
+
867
+ function showMessage(message, isImportant = false) {
868
+ const messageEl = document.createElement('div');
869
+ messageEl.className = `fixed bottom-4 right-4 bg-gray-800 px-4 py-2 rounded-lg shadow-lg ${
870
+ isImportant ? 'border-2 border-yellow-400 pulse' : ''
871
+ }`;
872
+ messageEl.textContent = message;
873
+ document.body.appendChild(messageEl);
874
+
875
+ setTimeout(() => {
876
+ messageEl.remove();
877
+ }, 3000);
878
+ }
879
+ </script>
880
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Visaras/visaras-official" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
881
+ </html>
prompts.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Create a 2v2 game with characters and a map that I can play with my friends