lunarflu HF Staff commited on
Commit
5763680
·
verified ·
1 Parent(s): 35356ff

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +916 -754
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Epic RPG Adventure</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>
@@ -52,21 +52,29 @@
52
  transform: translateY(-5px);
53
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
54
  }
 
 
 
 
 
 
 
 
55
  </style>
56
  </head>
57
  <body class="bg-gray-900 text-white font-sans">
58
  <div class="game-container min-h-screen flex flex-col items-center justify-center p-4">
59
  <!-- Main Menu -->
60
  <div id="main-menu" class="text-center fade-in">
61
- <h1 class="text-6xl font-bold mb-8 text-yellow-400">Epic RPG Adventure</h1>
62
  <div class="space-y-4">
63
- <button onclick="startNewGame()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
64
- <i class="fas fa-play mr-2"></i> New Game
65
  </button>
66
- <button onclick="loadGame()" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
67
  <i class="fas fa-folder-open mr-2"></i> Load Game
68
  </button>
69
- <button onclick="showCredits()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
70
  <i class="fas fa-info-circle mr-2"></i> Credits
71
  </button>
72
  </div>
@@ -74,7 +82,7 @@
74
 
75
  <!-- Character Creation -->
76
  <div id="character-creation" class="hidden text-center w-full max-w-4xl">
77
- <h2 class="text-4xl font-bold mb-8 text-yellow-400">Create Your Hero</h2>
78
 
79
  <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
80
  <!-- Warrior -->
@@ -138,8 +146,8 @@
138
  </div>
139
  </div>
140
 
141
- <button onclick="finalizeCharacter()" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-8 rounded-lg text-xl transition-all hover:scale-105">
142
- <i class="fas fa-check mr-2"></i> Begin Adventure
143
  </button>
144
  </div>
145
 
@@ -162,596 +170,798 @@
162
  <span>Health</span>
163
  <span id="health-text">100/100</span>
164
  </div>
165
- <div class="w-full bg-gray-700 rounded-full h-4">
166
- <div id="health-bar" class="health-bar bg-red-500 h-4 rounded-full" style="width: 100%"></div>
167
- </div>
168
- </div>
169
-
170
- <div class="mb-4">
171
- <div class="flex justify-between mb-1">
172
- <span>Mana</span>
173
- <span id="mana-text">50/50</span>
174
- </div>
175
- <div class="w-full bg-gray-700 rounded-full h-4">
176
- <div id="mana-bar" class="health-bar bg-blue-500 h-4 rounded-full" style="width: 100%"></div>
177
- </div>
178
- </div>
179
-
180
- <div class="mb-4">
181
- <div class="flex justify-between mb-1">
182
- <span>Experience</span>
183
- <span id="exp-text">0/100</span>
184
- </div>
185
- <div class="w-full bg-gray-700 rounded-full h-4">
186
- <div id="exp-bar" class="health-bar bg-yellow-500 h-4 rounded-full" style="width: 0%"></div>
187
- </div>
188
- </div>
189
-
190
- <div class="grid grid-cols-2 gap-2 mb-4">
191
- <div class="bg-gray-700 p-2 rounded">
192
- <div class="text-sm text-gray-300">Level</div>
193
- <div class="font-bold" id="level-text">1</div>
194
- </div>
195
- <div class="bg-gray-700 p-2 rounded">
196
- <div class="text-sm text-gray-300">Gold</div>
197
- <div class="font-bold" id="gold-text">10</div>
198
- </div>
199
- <div class="bg-gray-700 p-2 rounded">
200
- <div class="text-sm text-gray-300">Attack</div>
201
- <div class="font-bold" id="attack-text">10</div>
202
- </div>
203
- <div class="bg-gray-700 p-2 rounded">
204
- <div class="text-sm text-gray-300">Defense</div>
205
- <div class="font-bold" id="defense-text">5</div>
206
- </div>
207
- </div>
208
-
209
- <button onclick="openInventory()" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded mb-2">
210
- <i class="fas fa-backpack mr-2"></i> Inventory
211
- </button>
212
- <button onclick="openQuests()" class="w-full bg-green-600 hover:bg-green-700 text-white py-2 rounded mb-2">
213
- <i class="fas fa-scroll mr-2"></i> Quests
214
- </button>
215
- <button onclick="saveGame()" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 rounded">
216
- <i class="fas fa-save mr-2"></i> Save Game
217
- </button>
218
- </div>
219
-
220
- <!-- Main Game Area -->
221
- <div class="flex-1">
222
- <!-- Game Messages -->
223
- <div id="game-messages" class="bg-gray-800 bg-opacity-90 rounded-lg p-4 mb-4 h-40 overflow-y-auto">
224
- <p class="text-yellow-300">Welcome to Epic RPG Adventure!</p>
225
- <p>Create your character and begin your journey.</p>
226
- </div>
227
-
228
- <!-- Action Buttons -->
229
- <div class="grid grid-cols-2 gap-4 mb-6">
230
- <button onclick="explore()" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
231
- <i class="fas fa-binoculars mr-2"></i> Explore
232
- </button>
233
- <button onclick="rest()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
234
- <i class="fas fa-bed mr-2"></i> Rest
235
- </button>
236
- <button onclick="visitTown()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
237
- <i class="fas fa-city mr-2"></i> Visit Town
238
- </button>
239
- <button onclick="train()" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
240
- <i class="fas fa-dumbbell mr-2"></i> Train
241
- </button>
242
- </div>
243
-
244
- <!-- Combat Area -->
245
- <div id="combat-area" class="hidden bg-gray-800 bg-opacity-90 rounded-lg p-6">
246
- <div class="flex flex-col md:flex-row justify-between items-center mb-8">
247
- <!-- Player -->
248
- <div class="text-center mb-6 md:mb-0 relative">
249
- <div class="text-6xl mb-2" id="player-combat-icon">
250
- <i class="fas fa-user"></i>
251
- </div>
252
- <h4 class="text-xl font-bold" id="player-combat-name">Hero</h4>
253
- <div class="w-full bg-gray-700 rounded-full h-3 mt-2">
254
- <div id="player-health-bar" class="health-bar bg-red-500 h-3 rounded-full" style="width: 100%"></div>
255
- </div>
256
- <div class="text-sm" id="player-health-text">100/100</div>
257
- </div>
258
-
259
- <!-- VS -->
260
- <div class="text-2xl font-bold mx-4 mb-6 md:mb-0">VS</div>
261
-
262
- <!-- Enemy -->
263
- <div class="text-center relative">
264
- <div class="text-6xl mb-2" id="enemy-icon">
265
- <i class="fas fa-spider"></i>
266
  </div>
267
- <h4 class="text-xl font-bold" id="enemy-name">Goblin</h4>
268
- <div class="w-full bg-gray-700 rounded-full h-3 mt-2">
269
- <div id="enemy-health-bar" class="health-bar bg-red-500 h-3 rounded-full" style="width: 100%"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  </div>
271
- <div class="text-sm" id="enemy-health-text">30/30</div>
272
  </div>
273
  </div>
274
-
275
- <!-- Combat Actions -->
276
- <div id="combat-actions" class="grid grid-cols-2 gap-4">
277
- <button onclick="playerAttack()" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg">
278
- <i class="fas fa-sword mr-2"></i> Attack
279
- </button>
280
- <button onclick="playerSpell()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg">
281
- <i class="fas fa-magic mr-2"></i> Cast Spell
282
- </button>
283
- <button onclick="playerDefend()" class="bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg">
284
- <i class="fas fa-shield-alt mr-2"></i> Defend
285
- </button>
286
- <button onclick="playerFlee()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg">
287
- <i class="fas fa-running mr-2"></i> Flee
288
- </button>
289
- </div>
290
- </div>
291
-
292
- <!-- Town Area -->
293
- <div id="town-area" class="hidden bg-gray-800 bg-opacity-90 rounded-lg p-6">
294
- <h3 class="text-2xl font-bold mb-4">Town Square</h3>
295
- <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
296
- <button onclick="visitShop()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg">
297
- <i class="fas fa-shopping-cart mr-2"></i> Shop
298
- </button>
299
- <button onclick="visitTavern()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg">
300
- <i class="fas fa-beer mr-2"></i> Tavern
301
- </button>
302
- <button onclick="visitGuild()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-4 rounded-lg">
303
- <i class="fas fa-scroll mr-2"></i> Adventurer's Guild
304
- </button>
305
- <button onclick="leaveTown()" class="bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg">
306
- <i class="fas fa-door-open mr-2"></i> Leave Town
307
- </button>
308
- </div>
309
- </div>
310
- </div>
311
- </div>
312
- </div>
313
 
314
- <!-- Inventory Modal -->
315
- <div id="inventory-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
316
- <div class="bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto">
317
- <div class="flex justify-between items-center mb-4">
318
- <h3 class="text-2xl font-bold">Inventory</h3>
319
- <button onclick="closeInventory()" class="text-gray-400 hover:text-white">
320
- <i class="fas fa-times"></i>
321
- </button>
322
- </div>
323
-
324
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
325
- <div class="bg-gray-700 p-4 rounded-lg text-center">
326
- <div class="text-3xl mb-2"><i class="fas fa-sword"></i></div>
327
- <div class="font-bold">Iron Sword</div>
328
- <div class="text-sm text-gray-300">Attack +5</div>
329
- <button class="mt-2 bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">
330
- Equip
331
- </button>
332
- </div>
333
- <div class="bg-gray-700 p-4 rounded-lg text-center">
334
- <div class="text-3xl mb-2"><i class="fas fa-shield-alt"></i></div>
335
- <div class="font-bold">Wooden Shield</div>
336
- <div class="text-sm text-gray-300">Defense +3</div>
337
- <button class="mt-2 bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">
338
- Equip
339
- </button>
340
- </div>
341
- <div class="bg-gray-700 p-4 rounded-lg text-center">
342
- <div class="text-3xl mb-2"><i class="fas fa-flask"></i></div>
343
- <div class="font-bold">Health Potion</div>
344
- <div class="text-sm text-gray-300">Restores 30 HP</div>
345
- <button class="mt-2 bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm">
346
- Use
347
- </button>
348
- </div>
349
- <div class="bg-gray-700 p-4 rounded-lg text-center">
350
- <div class="text-3xl mb-2"><i class="fas fa-flask"></i></div>
351
- <div class="font-bold">Mana Potion</div>
352
- <div class="text-sm text-gray-300">Restores 20 MP</div>
353
- <button class="mt-2 bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm">
354
- Use
355
- </button>
356
- </div>
357
- </div>
358
-
359
- <h4 class="text-xl font-bold mb-3">Equipped Items</h4>
360
- <div class="grid grid-cols-2 gap-4">
361
- <div class="bg-gray-700 p-3 rounded-lg">
362
- <div class="flex items-center">
363
- <div class="text-2xl mr-3"><i class="fas fa-sword"></i></div>
364
- <div>
365
  <div class="font-bold">Iron Sword</div>
366
  <div class="text-sm text-gray-300">Attack +5</div>
 
 
 
367
  </div>
368
- </div>
369
- </div>
370
- <div class="bg-gray-700 p-3 rounded-lg">
371
- <div class="flex items-center">
372
- <div class="text-2xl mr-3"><i class="fas fa-shield-alt"></i></div>
373
- <div>
374
  <div class="font-bold">Wooden Shield</div>
375
  <div class="text-sm text-gray-300">Defense +3</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  </div>
377
  </div>
378
  </div>
379
  </div>
380
- </div>
381
- </div>
382
 
383
- <!-- Credits Modal -->
384
- <div id="credits-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
385
- <div class="bg-gray-800 rounded-lg p-6 w-full max-w-md">
386
- <div class="flex justify-between items-center mb-4">
387
- <h3 class="text-2xl font-bold">Credits</h3>
388
- <button onclick="hideCredits()" class="text-gray-400 hover:text-white">
389
- <i class="fas fa-times"></i>
390
- </button>
391
- </div>
392
-
393
- <div class="space-y-4">
394
- <div>
395
- <h4 class="text-xl font-bold text-yellow-400">Epic RPG Adventure</h4>
396
- <p class="text-gray-300">Created with HTML, CSS, and JavaScript</p>
397
- </div>
398
-
399
- <div>
400
- <h4 class="font-bold">Developer</h4>
401
- <p class="text-gray-300">Your Name Here</p>
402
- </div>
403
-
404
- <div>
405
- <h4 class="font-bold">Special Thanks</h4>
406
- <ul class="list-disc list-inside text-gray-300">
407
- <li>Tailwind CSS</li>
408
- <li>Font Awesome</li>
409
- <li>Unsplash for images</li>
410
- </ul>
411
- </div>
412
-
413
- <div class="pt-4 border-t border-gray-700">
414
- <p class="text-sm text-gray-400">© 2023 All Rights Reserved</p>
 
 
415
  </div>
416
  </div>
417
  </div>
418
- </div>
419
- </div>
420
 
421
- <script>
422
- // Game State
423
- const gameState = {
424
- player: {
425
- name: '',
426
- class: '',
427
- gender: '',
428
- level: 1,
429
- exp: 0,
430
- expToNextLevel: 100,
431
- health: 100,
432
- maxHealth: 100,
433
- mana: 50,
434
- maxMana: 50,
435
- attack: 10,
436
- defense: 5,
437
- gold: 10,
438
- inventory: [
439
- { name: 'Iron Sword', type: 'weapon', attack: 5, icon: 'fa-s sword' },
440
- { name: 'Wooden Shield', type: 'shield', defense: 3, icon: 'fa-shield-alt' },
441
- { name: 'Health Potion', type: 'consumable', effect: 'heal', amount: 30, icon: 'fa-flask' },
442
- { name: 'Mana Potion', type: 'consumable', effect: 'mana', amount: 20, icon: 'fa-flask' }
443
- ],
444
- equipped: {
445
- weapon: { name: 'Iron Sword', type: 'weapon', attack: 5, icon: 'fa-sword' },
446
- shield: { name: 'Wooden Shield', type: 'shield', defense: 3, icon: 'fa-shield-alt' }
447
- }
448
- },
449
- currentEnemy: null,
450
- inCombat: false,
451
- gameMessages: []
452
- };
453
-
454
- // Cute Monstergirl Enemies
455
- const enemies = [
456
- { name: 'Goblin Girl', health: 30, maxHealth: 30, attack: 8, defense: 2, exp: 20, gold: 5, icon: 'fa-user-ninja' },
457
- { name: 'Orc Girl', health: 50, maxHealth: 50, attack: 12, defense: 5, exp: 35, gold: 10, icon: 'fa-user-injured' },
458
- { name: 'Skeleton Girl', health: 25, maxHealth: 25, attack: 10, defense: 3, exp: 25, gold: 8, icon: 'fa-skull' },
459
- { name: 'Wolf Girl', health: 20, maxHealth: 20, attack: 7, defense: 1, exp: 15, gold: 3, icon: 'fa-paw' },
460
- { name: 'Bandit Girl', health: 40, maxHealth: 40, attack: 11, defense: 4, exp: 30, gold: 15, icon: 'fa-user' },
461
- { name: 'Catgirl', health: 25, maxHealth: 25, attack: 9, defense: 2, exp: 22, gold: 7, icon: 'fa-cat' },
462
- { name: 'Bunny Girl', health: 35, maxHealth: 35, attack: 7, defense: 3, exp: 25, gold: 8, icon: 'fa-paw' },
463
- { name: 'Fox Girl', health: 28, maxHealth: 28, attack: 10, defense: 2, exp: 24, gold: 9, icon: 'fa-paw' },
464
- { name: 'Slime Girl', health: 45, maxHealth: 45, attack: 6, defense: 6, exp: 28, gold: 10, icon: 'fa-droplet' },
465
- { name: 'Dragon Girl', health: 60, maxHealth: 60, attack: 15, defense: 8, exp: 50, gold: 25, icon: 'fa-dragon' }
466
- ];
467
 
468
- // Game Functions
469
- function startNewGame() {
470
- document.getElementById('main-menu').classList.add('hidden');
471
- document.getElementById('character-creation').classList.remove('hidden');
472
- addGameMessage('Begin your adventure by creating your character.');
473
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
 
475
- function selectClass(characterClass) {
476
- const cards = document.querySelectorAll('.character-card');
477
- cards.forEach(card => card.classList.remove('ring-2', 'ring-yellow-400'));
478
-
479
- const selectedCard = document.querySelector(`.character-card:nth-child(${characterClass === 'warrior' ? 1 : characterClass === 'mage' ? 2 : 3})`);
480
- selectedCard.classList.add('ring-2', 'ring-yellow-400');
481
-
482
- gameState.player.class = characterClass;
483
-
484
- // Update stats based on class
485
- if (characterClass === 'warrior') {
486
- gameState.player.maxHealth = 120;
487
- gameState.player.health = 120;
488
- gameState.player.attack = 12;
489
- gameState.player.defense = 8;
490
- gameState.player.mana = 30;
491
- gameState.player.maxMana = 30;
492
- } else if (characterClass === 'mage') {
493
- gameState.player.maxHealth = 70;
494
- gameState.player.health = 70;
495
- gameState.player.attack = 8;
496
- gameState.player.defense = 3;
497
- gameState.player.mana = 80;
498
- gameState.player.maxMana = 80;
499
- } else if (characterClass === 'rogue') {
500
- gameState.player.maxHealth = 90;
501
- gameState.player.health = 90;
502
- gameState.player.attack = 10;
503
- gameState.player.defense = 5;
504
- gameState.player.mana = 50;
505
- gameState.player.maxMana = 50;
506
  }
507
-
508
- addGameMessage(`You selected the ${characterClass} class.`);
509
- }
510
 
511
- function finalizeCharacter() {
512
- const nameInput = document.getElementById('character-name');
513
- const genderSelect = document.getElementById('character-gender');
514
-
515
- if (!nameInput.value.trim()) {
516
- addGameMessage('Please enter a name for your character.', 'error');
517
- return;
518
- }
519
-
520
- if (!gameState.player.class) {
521
- addGameMessage('Please select a class for your character.', 'error');
522
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  }
524
-
525
- gameState.player.name = nameInput.value.trim();
526
- gameState.player.gender = genderSelect.value;
527
-
528
- // Start the game
529
- document.getElementById('character-creation').classList.add('hidden');
530
- document.getElementById('game-screen').classList.remove('hidden');
531
-
532
- // Update character display
533
- updateCharacterDisplay();
534
-
535
- addGameMessage(`Welcome, ${gameState.player.name} the ${gameState.player.class}! Your adventure begins now.`, 'success');
536
- }
537
 
538
- function updateCharacterDisplay() {
539
- // Update character panel
540
- document.getElementById('character-display-name').textContent = gameState.player.name;
541
- document.getElementById('character-display-class').textContent = `Class: ${capitalizeFirstLetter(gameState.player.class)}`;
542
-
543
- // Update stats
544
- document.getElementById('health-text').textContent = `${gameState.player.health}/${gameState.player.maxHealth}`;
545
- document.getElementById('mana-text').textContent = `${gameState.player.mana}/${gameState.player.maxMana}`;
546
- document.getElementById('exp-text').textContent = `${gameState.player.exp}/${gameState.player.expToNextLevel}`;
547
- document.getElementById('level-text').textContent = gameState.player.level;
548
- document.getElementById('gold-text').textContent = gameState.player.gold;
549
- document.getElementById('attack-text').textContent = gameState.player.attack + (gameState.player.equipped.weapon ? gameState.player.equipped.weapon.attack : 0);
550
- document.getElementById('defense-text').textContent = gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0);
551
-
552
- // Update health bar
553
- const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
554
- document.getElementById('health-bar').style.width = `${healthPercent}%`;
555
-
556
- // Update mana bar
557
- const manaPercent = (gameState.player.mana / gameState.player.maxMana) * 100;
558
- document.getElementById('mana-bar').style.width = `${manaPercent}%`;
559
-
560
- // Update exp bar
561
- const expPercent = (gameState.player.exp / gameState.player.expToNextLevel) * 100;
562
- document.getElementById('exp-bar').style.width = `${expPercent}%`;
563
-
564
- // Update character icon based on class
565
- const characterIcon = document.getElementById('character-icon');
566
- const playerCombatIcon = document.getElementById('player-combat-icon');
567
-
568
- if (gameState.player.class === 'warrior') {
569
- characterIcon.innerHTML = '<i class="fas fa-shield-alt text-red-500"></i>';
570
- playerCombatIcon.innerHTML = '<i class="fas fa-shield-alt text-red-500"></i>';
571
- } else if (gameState.player.class === 'mage') {
572
- characterIcon.innerHTML = '<i class="fas fa-hat-wizard text-blue-500"></i>';
573
- playerCombatIcon.innerHTML = '<i class="fas fa-hat-wizard text-blue-500"></i>';
574
- } else if (gameState.player.class === 'rogue') {
575
- characterIcon.innerHTML = '<i class="fas fa-user-ninja text-green-500"></i>';
576
- playerCombatIcon.innerHTML = '<i class="fas fa-user-ninja text-green-500"></i>';
577
  }
578
-
579
- // Update player combat name
580
- document.getElementById('player-combat-name').textContent = gameState.player.name;
581
- }
582
 
583
- function addGameMessage(message, type = 'info') {
584
- const messagesDiv = document.getElementById('game-messages');
585
- const messageElement = document.createElement('p');
586
-
587
- if (type === 'error') {
588
- messageElement.className = 'text-red-400';
589
- } else if (type === 'success') {
590
- messageElement.className = 'text-green-400';
591
- } else if (type === 'warning') {
592
- messageElement.className = 'text-yellow-400';
593
- } else {
594
- messageElement.className = 'text-gray-300';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  }
596
-
597
- messageElement.textContent = message;
598
- messagesDiv.appendChild(messageElement);
599
- messagesDiv.scrollTop = messagesDiv.scrollHeight;
600
-
601
- // Add to game state for saving
602
- gameState.gameMessages.push(message);
603
- }
604
 
605
- function explore() {
606
- if (gameState.inCombat) {
607
- addGameMessage('You are already in combat!', 'error');
608
- return;
609
- }
610
-
611
- // 70% chance to find an enemy
612
- if (Math.random() < 0.7) {
613
- startCombat();
614
- } else {
615
- // 30% chance to find something else
616
- const randomEvent = Math.random();
617
-
618
- if (randomEvent < 0.5) {
619
- // Found gold
620
- const goldFound = Math.floor(Math.random() * 10) + 5;
621
- gameState.player.gold += goldFound;
622
- updateCharacterDisplay();
623
- addGameMessage(`You found ${goldFound} gold coins on the ground!`, 'success');
624
  } else {
625
- // Found a health potion
626
- gameState.player.inventory.push({
627
- name: 'Health Potion',
628
- type: 'consumable',
629
- effect: 'heal',
630
- amount: 30,
631
- icon: 'fa-flask'
632
- });
633
- addGameMessage('You found a Health Potion!', 'success');
634
  }
 
 
 
 
 
 
 
635
  }
636
- }
637
-
638
- function startCombat() {
639
- gameState.inCombat = true;
640
-
641
- // Select a random enemy
642
- const randomEnemyIndex = Math.floor(Math.random() * enemies.length);
643
- gameState.currentEnemy = {...enemies[randomEnemyIndex]};
644
-
645
- // Update combat UI
646
- document.getElementById('combat-area').classList.remove('hidden');
647
- document.getElementById('enemy-name').textContent = gameState.currentEnemy.name;
648
- document.getElementById('enemy-health-text').textContent = `${gameState.currentEnemy.health}/${gameState.currentEnemy.maxHealth}`;
649
- document.getElementById('enemy-health-bar').style.width = '100%';
650
- document.getElementById('enemy-icon').innerHTML = `<i class="fas ${gameState.currentEnemy.icon}"></i>`;
651
-
652
- // Update player stats in combat
653
- document.getElementById('player-health-text').textContent = `${gameState.player.health}/${gameState.player.maxHealth}`;
654
- const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
655
- document.getElementById('player-health-bar').style.width = `${healthPercent}%`;
656
-
657
- addGameMessage(`A wild ${gameState.currentEnemy.name} appears!`, 'warning');
658
- }
659
 
660
- function playerAttack() {
661
- if (!gameState.inCombat || !gameState.currentEnemy) {
662
- addGameMessage('There is nothing to attack!', 'error');
663
- return;
664
- }
665
-
666
- // Calculate player damage
667
- const playerAttackPower = gameState.player.attack + (gameState.player.equipped.weapon ? gameState.player.equipped.weapon.attack : 0);
668
- const damage = Math.max(1, playerAttackPower - Math.floor(gameState.currentEnemy.defense / 2));
669
-
670
- // Apply damage to enemy
671
- gameState.currentEnemy.health -= damage;
672
-
673
- // Update enemy health bar
674
- const enemyHealthPercent = (gameState.currentEnemy.health / gameState.currentEnemy.maxHealth) * 100;
675
- document.getElementById('enemy-health-bar').style.width = `${Math.max(0, enemyHealthPercent)}%`;
676
- document.getElementById('enemy-health-text').textContent = `${Math.max(0, gameState.currentEnemy.health)}/${gameState.currentEnemy.maxHealth}`;
677
-
678
- // Show damage text
679
- showDamageText(document.querySelector('#combat-area .relative:last-child'), damage);
680
-
681
- addGameMessage(`You attack the ${gameState.currentEnemy.name} for ${damage} damage!`, 'success');
682
-
683
- // Check if enemy is defeated
684
- if (gameState.currentEnemy.health <= 0) {
685
- enemyDefeated();
686
- return;
 
 
 
 
687
  }
688
-
689
- // Enemy attacks back
690
- setTimeout(() => {
691
- enemyAttack();
692
- }, 1000);
693
- }
694
 
695
- function playerSpell() {
696
- if (!gameState.inCombat || !gameState.currentEnemy) {
697
- addGameMessage('There is nothing to attack!', 'error');
698
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
699
  }
700
-
701
- if (gameState.player.mana < 15) {
702
- addGameMessage('Not enough mana to cast a spell!', 'error');
703
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
704
  }
705
-
706
- // Use mana
707
- gameState.player.mana -= 15;
708
- updateCharacterDisplay();
709
-
710
- // Calculate spell damage (more powerful than regular attack)
711
- let spellDamage;
712
- if (gameState.player.class === 'mage') {
713
- spellDamage = Math.max(3, 15 + Math.floor(Math.random() * 10));
714
- } else {
715
- spellDamage = Math.max(3, 10 + Math.floor(Math.random() * 5));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
716
  }
717
-
718
- // Apply damage to enemy
719
- gameState.currentEnemy.health -= spellDamage;
720
-
721
- // Update enemy health bar
722
- const enemyHealthPercent = (gameState.currentEnemy.health / gameState.currentEnemy.maxHealth) * 100;
723
- document.getElementById('enemy-health-bar').style.width = `${Math.max(0, enemyHealthPercent)}%`;
724
- document.getElementById('enemy-health-text').textContent = `${Math.max(0, gameState.currentEnemy.health)}/${gameState.currentEnemy.maxHealth}`;
725
-
726
- // Show damage text
727
- showDamageText(document.querySelector('#combat-area .relative:last-child'), spellDamage, 'blue');
728
-
729
- addGameMessage(`You cast a spell on the ${gameState.currentEnemy.name} for ${spellDamage} damage!`, 'success');
730
-
731
- // Check if enemy is defeated
732
- if (gameState.currentEnemy.health <= 0) {
733
- enemyDefeated();
734
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
735
  }
736
-
737
- // Enemy attacks back
738
- setTimeout(() => {
739
- enemyAttack();
740
- }, 1000);
741
- }
742
 
743
- function playerDefend() {
744
- if (!gameState.inCombat || !gameState.currentEnemy) {
745
- addGameMessage('There is nothing to defend against!', 'error');
746
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  }
748
-
749
- addGameMessage(`You take a defensive stance, reducing damage from the next attack.`, 'info');
750
-
751
- // Enemy attacks with reduced damage
752
- setTimeout(() => {
753
- // Calculate enemy damage (reduced by 50% when defending)
754
- const enemyDamage = Math.max(1, Math.floor((gameState.currentEnemy.attack - (gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0))) / 2));
755
 
756
  // Apply damage to player
757
  gameState.player.health -= enemyDamage;
@@ -766,231 +976,183 @@
766
  // Show damage text
767
  showDamageText(document.querySelector('#combat-area .relative:first-child'), enemyDamage);
768
 
769
- addGameMessage(`The ${gameState.currentEnemy.name} attacks you for ${enemyDamage} damage (reduced by your defense)!`, 'warning');
770
 
771
  // Check if player is defeated
772
  if (gameState.player.health <= 0) {
773
  playerDefeated();
774
  }
775
- }, 1000);
776
- }
777
-
778
- function playerFlee() {
779
- if (!gameState.inCombat || !gameState.currentEnemy) {
780
- addGameMessage('There is nothing to flee from!', 'error');
781
- return;
782
  }
783
-
784
- // 60% chance to flee successfully
785
- if (Math.random() < 0.6) {
786
- addGameMessage(`You successfully fled from the ${gameState.currentEnemy.name}!`, 'success');
787
- endCombat();
788
- } else {
789
- addGameMessage(`You failed to flee! The ${gameState.currentEnemy.name} attacks you!`, 'error');
790
 
791
- // Enemy attacks
792
- setTimeout(() => {
793
- enemyAttack();
794
- }, 1000);
 
 
 
 
 
 
 
795
  }
796
- }
797
 
798
- function enemyAttack() {
799
- if (!gameState.inCombat || !gameState.currentEnemy) return;
800
-
801
- // Calculate enemy damage
802
- const enemyDamage = Math.max(1, gameState.currentEnemy.attack - (gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0)));
803
-
804
- // Apply damage to player
805
- gameState.player.health -= enemyDamage;
806
-
807
- // Update player health bar
808
- const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
809
- document.getElementById('player-health-bar').style.width = `${Math.max(0, healthPercent)}%`;
810
- document.getElementById('player-health-text').textContent = `${Math.max(0, gameState.player.health)}/${gameState.player.maxHealth}`;
811
- document.getElementById('health-bar').style.width = `${Math.max(0, healthPercent)}%`;
812
- document.getElementById('health-text').textContent = `${Math.max(0, gameState.player.health)}/${gameState.player.maxHealth}`;
813
-
814
- // Show damage text
815
- showDamageText(document.querySelector('#combat-area .relative:first-child'), enemyDamage);
816
-
817
- addGameMessage(`The ${gameState.currentEnemy.name} attacks you for ${enemyDamage} damage!`, 'warning');
818
-
819
- // Check if player is defeated
820
- if (gameState.player.health <= 0) {
821
- playerDefeated();
822
  }
823
- }
824
 
825
- function enemyDefeated() {
826
- addGameMessage(`You defeated the ${gameState.currentEnemy.name}!`, 'success');
827
-
828
- // Gain experience and gold
829
- gameState.player.exp += gameState.currentEnemy.exp;
830
- gameState.player.gold += gameState.currentEnemy.gold;
831
-
832
- addGameMessage(`Gained ${gameState.currentEnemy.exp} experience and ${gameState.currentEnemy.gold} gold.`, 'success');
833
-
834
- // Check for level up
835
- checkLevelUp();
836
-
837
- // End combat
838
- endCombat();
839
- }
840
-
841
- function playerDefeated() {
842
- addGameMessage(`You were defeated by the ${gameState.currentEnemy.name}!`, 'error');
843
- addGameMessage('You wake up in town, having lost some gold and experience.', 'warning');
844
-
845
- // Penalty for dying
846
- gameState.player.exp = Math.max(0, gameState.player.exp - 10);
847
- gameState.player.gold = Math.max(0, gameState.player.gold - 5);
848
-
849
- // Restore some health
850
- gameState.player.health = Math.floor(gameState.player.maxHealth * 0.3);
851
-
852
- // Update display
853
- updateCharacterDisplay();
854
-
855
- // End combat
856
- endCombat();
857
- }
858
 
859
- function endCombat() {
860
- gameState.inCombat = false;
861
- gameState.currentEnemy = null;
862
- document.getElementById('combat-area').classList.add('hidden');
863
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
864
 
865
- function checkLevelUp() {
866
- if (gameState.player.exp >= gameState.player.expToNextLevel) {
867
- gameState.player.level++;
868
- gameState.player.exp -= gameState.player.expToNextLevel;
869
- gameState.player.expToNextLevel = Math.floor(gameState.player.expToNextLevel * 1.2);
870
-
871
- // Improve stats
872
- gameState.player.maxHealth += 10;
873
- gameState.player.health = gameState.player.maxHealth;
874
- gameState.player.maxMana += 5;
875
- gameState.player.mana = gameState.player.maxMana;
876
- gameState.player.attack += 2;
877
- gameState.player.defense += 1;
878
-
879
- addGameMessage(`Level up! You are now level ${gameState.player.level}!`, 'success');
880
- addGameMessage('Your stats have improved!', 'info');
881
 
 
882
  updateCharacterDisplay();
883
  }
884
- }
885
 
886
- function rest() {
887
- if (gameState.inCombat) {
888
- addGameMessage('You cannot rest while in combat!', 'error');
889
- return;
 
 
 
 
890
  }
891
-
892
- // Restore health and mana
893
- const healthRestored = Math.floor(gameState.player.maxHealth * 0.3);
894
- const manaRestored = Math.floor(gameState.player.maxMana * 0.3);
895
-
896
- gameState.player.health = Math.min(gameState.player.maxHealth, gameState.player.health + healthRestored);
897
- gameState.player.mana = Math.min(gameState.player.maxMana, gameState.player.mana + manaRestored);
898
-
899
- addGameMessage(`You rest and recover ${healthRestored} health and ${manaRestored} mana.`, 'success');
900
- updateCharacterDisplay();
901
- }
902
 
903
- function visitTown() {
904
- if (gameState.inCombat) {
905
- addGameMessage('You cannot visit town while in combat!', 'error');
906
- return;
907
  }
908
-
909
- document.getElementById('town-area').classList.remove('hidden');
910
- addGameMessage('You enter the town square.', 'info');
911
- }
912
 
913
- function leaveTown() {
914
- document.getElementById('town-area').classList.add('hidden');
915
- addGameMessage('You leave the town.', 'info');
916
- }
917
-
918
- function visitShop() {
919
- addGameMessage('The shop is currently closed. Come back later!', 'info');
920
- }
921
-
922
- function visitTavern() {
923
- addGameMessage('You enjoy a drink at the tavern and hear rumors of a dragon in the mountains.', 'info');
924
- }
925
-
926
- function visitGuild() {
927
- addGameMessage('The Adventurer\'s Guild has no quests available right now.', 'info');
928
- }
929
 
930
- function train() {
931
- if (gameState.inCombat) {
932
- addGameMessage('You cannot train while in combat!', 'error');
933
- return;
934
  }
935
-
936
- // Training costs gold but improves stats
937
- if (gameState.player.gold < 5) {
938
- addGameMessage('You need at least 5 gold to train!', 'error');
939
- return;
940
  }
941
-
942
- gameState.player.gold -= 5;
943
-
944
- // Random stat improvement
945
- const statToImprove = ['attack', 'defense'][Math.floor(Math.random() * 2)];
946
- const improvement = 1;
947
-
948
- if (statToImprove === 'attack') {
949
- gameState.player.attack += improvement;
950
- addGameMessage(`After training, your attack increased by ${improvement}! (Cost: 5 gold)`, 'success');
951
- } else {
952
- gameState.player.defense += improvement;
953
- addGameMessage(`After training, your defense increased by ${improvement}! (Cost: 5 gold)`, 'success');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
954
  }
955
-
956
- updateCharacterDisplay();
957
- }
958
 
959
- function openInventory() {
960
- document.getElementById('inventory-modal').classList.remove('hidden');
961
- }
962
 
963
- function closeInventory() {
964
- document.getElementById('inventory-modal').classList.add('hidden');
965
- }
966
 
967
- function openQuests() {
968
- addGameMessage('You have no active quests at the moment.', 'info');
969
- }
970
 
971
- function saveGame() {
972
- localStorage.setItem('epicRpgSave', JSON.stringify(gameState));
973
- addGameMessage('Game saved successfully!', 'success');
974
- }
975
 
976
- function loadGame() {
977
- const savedGame = localStorage.getItem('epicRpgSave');
978
-
979
- if (savedGame) {
980
- try {
981
- const parsedGame = JSON.parse(savedGame);
982
- Object.assign(gameState, parsedGame);
983
-
984
- document.getElementById('main-menu').classList.add('hidden');
985
- document.getElementById('game-screen').classList.remove('hidden');
986
-
987
- updateCharacterDisplay();
988
- addGameMessage(`Welcome back, ${gameState.player.name}! Game loaded successfully.`, 'success');
989
- } catch (e) {
990
- addGameMessage('Failed to load saved game.', 'error');
991
- }
992
- } else {
993
- addGameMessage('No saved game found.', 'error');
994
  }
995
  }
996
 
@@ -1024,7 +1186,7 @@
1024
 
1025
  // Initialize game
1026
  document.addEventListener('DOMContentLoaded', () => {
1027
- addGameMessage('Welcome to Epic RPG Adventure!');
1028
  });
1029
  </script>
1030
  <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=lunarflu/rpg" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Monstergirl RPG Adventure</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>
 
52
  transform: translateY(-5px);
53
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
54
  }
55
+ .monstergirl-img {
56
+ width: 120px;
57
+ height: 120px;
58
+ object-fit: cover;
59
+ border-radius: 50%;
60
+ border: 3px solid #f472b6;
61
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
62
+ }
63
  </style>
64
  </head>
65
  <body class="bg-gray-900 text-white font-sans">
66
  <div class="game-container min-h-screen flex flex-col items-center justify-center p-4">
67
  <!-- Main Menu -->
68
  <div id="main-menu" class="text-center fade-in">
69
+ <h1 class="text-6xl font-bold mb-8 text-pink-400">Monstergirl RPG</h1>
70
  <div class="space-y-4">
71
+ <button onclick="startNewGame()" class="bg-pink-600 hover:bg-pink-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
72
+ <i class="fas fa-heart mr-2"></i> New Game
73
  </button>
74
+ <button onclick="loadGame()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
75
  <i class="fas fa-folder-open mr-2"></i> Load Game
76
  </button>
77
+ <button onclick="showCredits()" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-3 px-6 rounded-lg text-xl w-64 transition-all hover:scale-105">
78
  <i class="fas fa-info-circle mr-2"></i> Credits
79
  </button>
80
  </div>
 
82
 
83
  <!-- Character Creation -->
84
  <div id="character-creation" class="hidden text-center w-full max-w-4xl">
85
+ <h2 class="text-4xl font-bold mb-8 text-pink-400">Create Your Hero</h2>
86
 
87
  <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
88
  <!-- Warrior -->
 
146
  </div>
147
  </div>
148
 
149
+ <button onclick="finalizeCharacter()" class="bg-pink-600 hover:bg-pink-700 text-white font-bold py-3 px-8 rounded-lg text-xl transition-all hover:scale-105">
150
+ <i class="fas fa-heart mr-2"></i> Begin Adventure
151
  </button>
152
  </div>
153
 
 
170
  <span>Health</span>
171
  <span id="health-text">100/100</span>
172
  </div>
173
+ <div class="w-full bg-gray-700 rounded-full h-4">
174
+ <div id="health-bar" class="health-bar bg-red-500 h-4 rounded-full" style="width: 100%"></div>
175
+ </div>
176
+ </div>
177
+
178
+ <div class="mb-4">
179
+ <div class="flex justify-between mb-1">
180
+ <span>Mana</span>
181
+ <span id="mana-text">50/50</span>
182
+ </div>
183
+ <div class="w-full bg-gray-700 rounded-full h-4">
184
+ <div id="mana-bar" class="health-bar bg-blue-500 h-4 rounded-full" style="width: 100%"></div>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="mb-4">
189
+ <div class="flex justify-between mb-1">
190
+ <span>Experience</span>
191
+ <span id="exp-text">0/100</span>
192
+ </div>
193
+ <div class="w-full bg-gray-700 rounded-full h-4">
194
+ <div id="exp-bar" class="health-bar bg-yellow-500 h-4 rounded-full" style="width: 0%"></div>
195
+ </div>
196
+ </div>
197
+
198
+ <div class="grid grid-cols-2 gap-2 mb-4">
199
+ <div class="bg-gray-700 p-2 rounded">
200
+ <div class="text-sm text-gray-300">Level</div>
201
+ <div class="font-bold" id="level-text">1</div>
202
+ </div>
203
+ <div class="bg-gray-700 p-2 rounded">
204
+ <div class="text-sm text-gray-300">Gold</div>
205
+ <div class="font-bold" id="gold-text">10</div>
206
+ </div>
207
+ <div class="bg-gray-700 p-2 rounded">
208
+ <div class="text-sm text-gray-300">Attack</div>
209
+ <div class="font-bold" id="attack-text">10</div>
210
+ </div>
211
+ <div class="bg-gray-700 p-2 rounded">
212
+ <div class="text-sm text-gray-300">Defense</div>
213
+ <div class="font-bold" id="defense-text">5</div>
214
+ </div>
215
+ </div>
216
+
217
+ <button onclick="openInventory()" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded mb-2">
218
+ <i class="fas fa-backpack mr-2"></i> Inventory
219
+ </button>
220
+ <button onclick="openQuests()" class="w-full bg-green-600 hover:bg-green-700 text-white py-2 rounded mb-2">
221
+ <i class="fas fa-scroll mr-2"></i> Quests
222
+ </button>
223
+ <button onclick="saveGame()" class="w-full bg-purple-600 hover:bg-purple-700 text-white py-2 rounded">
224
+ <i class="fas fa-save mr-2"></i> Save Game
225
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  </div>
227
+
228
+ <!-- Main Game Area -->
229
+ <div class="flex-1">
230
+ <!-- Game Messages -->
231
+ <div id="game-messages" class="bg-gray-800 bg-opacity-90 rounded-lg p-4 mb-4 h-40 overflow-y-auto">
232
+ <p class="text-pink-300">Welcome to Monstergirl RPG!</p>
233
+ <p>Create your character and begin your journey.</p>
234
+ </div>
235
+
236
+ <!-- Action Buttons -->
237
+ <div class="grid grid-cols-2 gap-4 mb-6">
238
+ <button onclick="explore()" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
239
+ <i class="fas fa-heart mr-2"></i> Meet Girls
240
+ </button>
241
+ <button onclick="rest()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
242
+ <i class="fas fa-bed mr-2"></i> Rest
243
+ </button>
244
+ <button onclick="visitTown()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
245
+ <i class="fas fa-city mr-2"></i> Visit Town
246
+ </button>
247
+ <button onclick="train()" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg transition-all hover:scale-105">
248
+ <i class="fas fa-dumbbell mr-2"></i> Train
249
+ </button>
250
+ </div>
251
+
252
+ <!-- Combat Area -->
253
+ <div id="combat-area" class="hidden bg-gray-800 bg-opacity-90 rounded-lg p-6">
254
+ <div class="flex flex-col md:flex-row justify-between items-center mb-8">
255
+ <!-- Player -->
256
+ <div class="text-center mb-6 md:mb-0 relative">
257
+ <div class="text-6xl mb-2" id="player-combat-icon">
258
+ <i class="fas fa-user"></i>
259
+ </div>
260
+ <h4 class="text-xl font-bold" id="player-combat-name">Hero</h4>
261
+ <div class="w-full bg-gray-700 rounded-full h-3 mt-2">
262
+ <div id="player-health-bar" class="health-bar bg-red-500 h-3 rounded-full" style="width: 100%"></div>
263
+ </div>
264
+ <div class="text-sm" id="player-health-text">100/100</div>
265
+ </div>
266
+
267
+ <!-- VS -->
268
+ <div class="text-2xl font-bold mx-4 mb-6 md:mb-0">VS</div>
269
+
270
+ <!-- Enemy -->
271
+ <div class="text-center relative">
272
+ <img id="enemy-image" src="" alt="Monstergirl" class="monstergirl-img mx-auto mb-2">
273
+ <h4 class="text-xl font-bold" id="enemy-name">Goblin Girl</h4>
274
+ <div class="w-full bg-gray-700 rounded-full h-3 mt-2">
275
+ <div id="enemy-health-bar" class="health-bar bg-red-500 h-3 rounded-full" style="width: 100%"></div>
276
+ </div>
277
+ <div class="text-sm" id="enemy-health-text">30/30</div>
278
+ </div>
279
+ </div>
280
+
281
+ <!-- Combat Actions -->
282
+ <div id="combat-actions" class="grid grid-cols-2 gap-4">
283
+ <button onclick="playerAttack()" class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg">
284
+ <i class="fas fa-heart-broken mr-2"></i> Attack
285
+ </button>
286
+ <button onclick="playerSpell()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg">
287
+ <i class="fas fa-magic mr-2"></i> Cast Spell
288
+ </button>
289
+ <button onclick="playerDefend()" class="bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg">
290
+ <i class="fas fa-shield-alt mr-2"></i> Defend
291
+ </button>
292
+ <button onclick="playerFlee()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg">
293
+ <i class="fas fa-running mr-2"></i> Flee
294
+ </button>
295
+ </div>
296
+ </div>
297
+
298
+ <!-- Town Area -->
299
+ <div id="town-area" class="hidden bg-gray-800 bg-opacity-90 rounded-lg p-6">
300
+ <h3 class="text-2xl font-bold mb-4">Town Square</h3>
301
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
302
+ <button onclick="visitShop()" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg">
303
+ <i class="fas fa-shopping-cart mr-2"></i> Shop
304
+ </button>
305
+ <button onclick="visitTavern()" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg">
306
+ <i class="fas fa-beer mr-2"></i> Tavern
307
+ </button>
308
+ <button onclick="visitGuild()" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-4 rounded-lg">
309
+ <i class="fas fa-scroll mr-2"></i> Adventurer's Guild
310
+ </button>
311
+ <button onclick="leaveTown()" class="bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg">
312
+ <i class="fas fa-door-open mr-2"></i> Leave Town
313
+ </button>
314
+ </div>
315
+ </div>
316
  </div>
 
317
  </div>
318
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
+ <!-- Inventory Modal -->
321
+ <div id="inventory-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
322
+ <div class="bg-gray-800 rounded-lg p-6 w-full max-w-2xl max-h-[80vh] overflow-y-auto">
323
+ <div class="flex justify-between items-center mb-4">
324
+ <h3 class="text-2xl font-bold">Inventory</h3>
325
+ <button onclick="closeInventory()" class="text-gray-400 hover:text-white">
326
+ <i class="fas fa-times"></i>
327
+ </button>
328
+ </div>
329
+
330
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
331
+ <div class="bg-gray-700 p-4 rounded-lg text-center">
332
+ <div class="text-3xl mb-2"><i class="fas fa-sword"></i></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  <div class="font-bold">Iron Sword</div>
334
  <div class="text-sm text-gray-300">Attack +5</div>
335
+ <button class="mt-2 bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">
336
+ Equip
337
+ </button>
338
  </div>
339
+ <div class="bg-gray-700 p-4 rounded-lg text-center">
340
+ <div class="text-3xl mb-2"><i class="fas fa-shield-alt"></i></div>
 
 
 
 
341
  <div class="font-bold">Wooden Shield</div>
342
  <div class="text-sm text-gray-300">Defense +3</div>
343
+ <button class="mt-2 bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">
344
+ Equip
345
+ </button>
346
+ </div>
347
+ <div class="bg-gray-700 p-4 rounded-lg text-center">
348
+ <div class="text-3xl mb-2"><i class="fas fa-flask"></i></div>
349
+ <div class="font-bold">Health Potion</div>
350
+ <div class="text-sm text-gray-300">Restores 30 HP</div>
351
+ <button class="mt-2 bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm">
352
+ Use
353
+ </button>
354
+ </div>
355
+ <div class="bg-gray-700 p-4 rounded-lg text-center">
356
+ <div class="text-3xl mb-2"><i class="fas fa-flask"></i></div>
357
+ <div class="font-bold">Mana Potion</div>
358
+ <div class="text-sm text-gray-300">Restores 20 MP</div>
359
+ <button class="mt-2 bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm">
360
+ Use
361
+ </button>
362
+ </div>
363
+ </div>
364
+
365
+ <h4 class="text-xl font-bold mb-3">Equipped Items</h4>
366
+ <div class="grid grid-cols-2 gap-4">
367
+ <div class="bg-gray-700 p-3 rounded-lg">
368
+ <div class="flex items-center">
369
+ <div class="text-2xl mr-3"><i class="fas fa-sword"></i></div>
370
+ <div>
371
+ <div class="font-bold">Iron Sword</div>
372
+ <div class="text-sm text-gray-300">Attack +5</div>
373
+ </div>
374
+ </div>
375
+ </div>
376
+ <div class="bg-gray-700 p-3 rounded-lg">
377
+ <div class="flex items-center">
378
+ <div class="text-2xl mr-3"><i class="fas fa-shield-alt"></i></div>
379
+ <div>
380
+ <div class="font-bold">Wooden Shield</div>
381
+ <div class="text-sm text-gray-300">Defense +3</div>
382
+ </div>
383
+ </div>
384
  </div>
385
  </div>
386
  </div>
387
  </div>
 
 
388
 
389
+ <!-- Credits Modal -->
390
+ <div id="credits-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
391
+ <div class="bg-gray-800 rounded-lg p-6 w-full max-w-md">
392
+ <div class="flex justify-between items-center mb-4">
393
+ <h3 class="text-2xl font-bold">Credits</h3>
394
+ <button onclick="hideCredits()" class="text-gray-400 hover:text-white">
395
+ <i class="fas fa-times"></i>
396
+ </button>
397
+ </div>
398
+
399
+ <div class="space-y-4">
400
+ <div>
401
+ <h4 class="text-xl font-bold text-pink-400">Monstergirl RPG</h4>
402
+ <p class="text-gray-300">Created with HTML, CSS, and JavaScript</p>
403
+ </div>
404
+
405
+ <div>
406
+ <h4 class="font-bold">Developer</h4>
407
+ <p class="text-gray-300">Your Name Here</p>
408
+ </div>
409
+
410
+ <div>
411
+ <h4 class="font-bold">Special Thanks</h4>
412
+ <ul class="list-disc list-inside text-gray-300">
413
+ <li>Tailwind CSS</li>
414
+ <li>Font Awesome</li>
415
+ <li>All the wonderful monstergirl artists</li>
416
+ </ul>
417
+ </div>
418
+
419
+ <div class="pt-4 border-t border-gray-700">
420
+ <p class="text-sm text-gray-400">© 2023 All Rights Reserved</p>
421
+ </div>
422
+ </div>
423
  </div>
424
  </div>
425
  </div>
 
 
426
 
427
+ <script>
428
+ // Game State
429
+ const gameState = {
430
+ player: {
431
+ name: '',
432
+ class: '',
433
+ gender: '',
434
+ level: 1,
435
+ exp: 0,
436
+ expToNextLevel: 100,
437
+ health: 100,
438
+ maxHealth: 100,
439
+ mana: 50,
440
+ maxMana: 50,
441
+ attack: 10,
442
+ defense: 5,
443
+ gold: 10,
444
+ inventory: [
445
+ { name: 'Iron Sword', type: 'weapon', attack: 5, icon: 'fa-sword' },
446
+ { name: 'Wooden Shield', type: 'shield', defense: 3, icon: 'fa-shield-alt' },
447
+ { name: 'Health Potion', type: 'consumable', effect: 'heal', amount: 30, icon: 'fa-flask' },
448
+ { name: 'Mana Potion', type: 'consumable', effect: 'mana', amount: 20, icon: 'fa-flask' }
449
+ ],
450
+ equipped: {
451
+ weapon: { name: 'Iron Sword', type: 'weapon', attack: 5, icon: 'fa-sword' },
452
+ shield: { name: 'Wooden Shield', type: 'shield', defense: 3, icon: 'fa-shield-alt' }
453
+ }
454
+ },
455
+ currentEnemy: null,
456
+ inCombat: false,
457
+ gameMessages: []
458
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
 
460
+ // Cute Monstergirl Enemies with images
461
+ const enemies = [
462
+ {
463
+ name: 'Goblin Girl',
464
+ health: 30,
465
+ maxHealth: 30,
466
+ attack: 8,
467
+ defense: 2,
468
+ exp: 20,
469
+ gold: 5,
470
+ image: 'https://i.imgur.com/JK7Wf0x.jpg',
471
+ description: 'A mischievous green-skinned girl with pointy ears and a playful attitude.'
472
+ },
473
+ {
474
+ name: 'Catgirl',
475
+ health: 25,
476
+ maxHealth: 25,
477
+ attack: 9,
478
+ defense: 2,
479
+ exp: 22,
480
+ gold: 7,
481
+ image: 'https://i.imgur.com/VQ5Zf3E.jpg',
482
+ description: 'A feline-human hybrid with cute ears and tail who loves to play.'
483
+ },
484
+ {
485
+ name: 'Bunny Girl',
486
+ health: 35,
487
+ maxHealth: 35,
488
+ attack: 7,
489
+ defense: 3,
490
+ exp: 25,
491
+ gold: 8,
492
+ image: 'https://i.imgur.com/8X9vY7H.jpg',
493
+ description: 'A fluffy-eared girl who hops around with boundless energy.'
494
+ },
495
+ {
496
+ name: 'Fox Girl',
497
+ health: 28,
498
+ maxHealth: 28,
499
+ attack: 10,
500
+ defense: 2,
501
+ exp: 24,
502
+ gold: 9,
503
+ image: 'https://i.imgur.com/3RkLZ2t.jpg',
504
+ description: 'A cunning kitsune with multiple tails and a playful trickster nature.'
505
+ },
506
+ {
507
+ name: 'Slime Girl',
508
+ health: 45,
509
+ maxHealth: 45,
510
+ attack: 6,
511
+ defense: 6,
512
+ exp: 28,
513
+ gold: 10,
514
+ image: 'https://i.imgur.com/qM9cB1P.jpg',
515
+ description: 'A gelatinous girl who can change her shape at will, very squishy!'
516
+ },
517
+ {
518
+ name: 'Dragon Girl',
519
+ health: 60,
520
+ maxHealth: 60,
521
+ attack: 15,
522
+ defense: 8,
523
+ exp: 50,
524
+ gold: 25,
525
+ image: 'https://i.imgur.com/7wGpL0z.jpg',
526
+ description: 'A powerful draconic beauty with scales, wings, and a fiery personality.'
527
+ },
528
+ {
529
+ name: 'Wolf Girl',
530
+ health: 40,
531
+ maxHealth: 40,
532
+ attack: 11,
533
+ defense: 4,
534
+ exp: 30,
535
+ gold: 12,
536
+ image: 'https://i.imgur.com/5tNf8Yq.jpg',
537
+ description: 'A wild girl with wolf ears and tail, fiercely loyal to her pack.'
538
+ },
539
+ {
540
+ name: 'Mermaid',
541
+ health: 35,
542
+ maxHealth: 35,
543
+ attack: 8,
544
+ defense: 5,
545
+ exp: 26,
546
+ gold: 15,
547
+ image: 'https://i.imgur.com/9XvLQ2f.jpg',
548
+ description: 'A beautiful sea maiden with a fish tail, sings enchanting melodies.'
549
+ },
550
+ {
551
+ name: 'Angel',
552
+ health: 50,
553
+ maxHealth: 50,
554
+ attack: 12,
555
+ defense: 7,
556
+ exp: 40,
557
+ gold: 20,
558
+ image: 'https://i.imgur.com/4kL9s2r.jpg',
559
+ description: 'A celestial being with pure white wings and a divine presence.'
560
+ },
561
+ {
562
+ name: 'Demon Girl',
563
+ health: 45,
564
+ maxHealth: 45,
565
+ attack: 14,
566
+ defense: 5,
567
+ exp: 38,
568
+ gold: 18,
569
+ image: 'https://i.imgur.com/2sVp7Qk.jpg',
570
+ description: 'A seductive temptress with horns and a tail, full of mischief.'
571
+ },
572
+ {
573
+ name: 'Vampire Girl',
574
+ health: 42,
575
+ maxHealth: 42,
576
+ attack: 13,
577
+ defense: 6,
578
+ exp: 35,
579
+ gold: 22,
580
+ image: 'https://i.imgur.com/1wX9vY7.jpg',
581
+ description: 'An elegant nocturnal beauty with sharp fangs and a taste for blood.'
582
+ },
583
+ {
584
+ name: 'Ghost Girl',
585
+ health: 30,
586
+ maxHealth: 30,
587
+ attack: 9,
588
+ defense: 8,
589
+ exp: 25,
590
+ gold: 10,
591
+ image: 'https://i.imgur.com/3RtLZ2t.jpg',
592
+ description: 'A translucent spirit girl who can phase through walls and objects.'
593
+ },
594
+ {
595
+ name: 'Centaur Girl',
596
+ health: 55,
597
+ maxHealth: 55,
598
+ attack: 12,
599
+ defense: 9,
600
+ exp: 45,
601
+ gold: 25,
602
+ image: 'https://i.imgur.com/7vGpL0z.jpg',
603
+ description: 'A majestic half-human half-horse girl with incredible strength.'
604
+ },
605
+ {
606
+ name: 'Lamia',
607
+ health: 48,
608
+ maxHealth: 48,
609
+ attack: 13,
610
+ defense: 7,
611
+ exp: 42,
612
+ gold: 20,
613
+ image: 'https://i.imgur.com/5sNf8Yq.jpg',
614
+ description: 'A serpentine beauty with a long snake tail, both alluring and dangerous.'
615
+ },
616
+ {
617
+ name: 'Harpy',
618
+ health: 38,
619
+ maxHealth: 38,
620
+ attack: 11,
621
+ defense: 4,
622
+ exp: 32,
623
+ gold: 15,
624
+ image: 'https://i.imgur.com/9YvLQ2f.jpg',
625
+ description: 'A winged girl with talons who can soar through the skies.'
626
+ }
627
+ ];
628
 
629
+ // Game Functions
630
+ function startNewGame() {
631
+ document.getElementById('main-menu').classList.add('hidden');
632
+ document.getElementById('character-creation').classList.remove('hidden');
633
+ addGameMessage('Begin your adventure by creating your character.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
  }
 
 
 
635
 
636
+ function selectClass(characterClass) {
637
+ const cards = document.querySelectorAll('.character-card');
638
+ cards.forEach(card => card.classList.remove('ring-2', 'ring-pink-400'));
639
+
640
+ const selectedCard = document.querySelector(`.character-card:nth-child(${characterClass === 'warrior' ? 1 : characterClass === 'mage' ? 2 : 3})`);
641
+ selectedCard.classList.add('ring-2', 'ring-pink-400');
642
+
643
+ gameState.player.class = characterClass;
644
+
645
+ // Update stats based on class
646
+ if (characterClass === 'warrior') {
647
+ gameState.player.maxHealth = 120;
648
+ gameState.player.health = 120;
649
+ gameState.player.attack = 12;
650
+ gameState.player.defense = 8;
651
+ gameState.player.mana = 30;
652
+ gameState.player.maxMana = 30;
653
+ } else if (characterClass === 'mage') {
654
+ gameState.player.maxHealth = 70;
655
+ gameState.player.health = 70;
656
+ gameState.player.attack = 8;
657
+ gameState.player.defense = 3;
658
+ gameState.player.mana = 80;
659
+ gameState.player.maxMana = 80;
660
+ } else if (characterClass === 'rogue') {
661
+ gameState.player.maxHealth = 90;
662
+ gameState.player.health = 90;
663
+ gameState.player.attack = 10;
664
+ gameState.player.defense = 5;
665
+ gameState.player.mana = 50;
666
+ gameState.player.maxMana = 50;
667
+ }
668
+
669
+ addGameMessage(`You selected the ${characterClass} class.`);
670
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
671
 
672
+ function finalizeCharacter() {
673
+ const nameInput = document.getElementById('character-name');
674
+ const genderSelect = document.getElementById('character-gender');
675
+
676
+ if (!nameInput.value.trim()) {
677
+ addGameMessage('Please enter a name for your character.', 'error');
678
+ return;
679
+ }
680
+
681
+ if (!gameState.player.class) {
682
+ addGameMessage('Please select a class for your character.', 'error');
683
+ return;
684
+ }
685
+
686
+ gameState.player.name = nameInput.value.trim();
687
+ gameState.player.gender = genderSelect.value;
688
+
689
+ // Start the game
690
+ document.getElementById('character-creation').classList.add('hidden');
691
+ document.getElementById('game-screen').classList.remove('hidden');
692
+
693
+ // Update character display
694
+ updateCharacterDisplay();
695
+
696
+ addGameMessage(`Welcome, ${gameState.player.name} the ${gameState.player.class}! Your adventure begins now.`, 'success');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  }
 
 
 
 
698
 
699
+ function updateCharacterDisplay() {
700
+ // Update character panel
701
+ document.getElementById('character-display-name').textContent = gameState.player.name;
702
+ document.getElementById('character-display-class').textContent = `Class: ${capitalizeFirstLetter(gameState.player.class)}`;
703
+
704
+ // Update stats
705
+ document.getElementById('health-text').textContent = `${gameState.player.health}/${gameState.player.maxHealth}`;
706
+ document.getElementById('mana-text').textContent = `${gameState.player.mana}/${gameState.player.maxMana}`;
707
+ document.getElementById('exp-text').textContent = `${gameState.player.exp}/${gameState.player.expToNextLevel}`;
708
+ document.getElementById('level-text').textContent = gameState.player.level;
709
+ document.getElementById('gold-text').textContent = gameState.player.gold;
710
+ document.getElementById('attack-text').textContent = gameState.player.attack + (gameState.player.equipped.weapon ? gameState.player.equipped.weapon.attack : 0);
711
+ document.getElementById('defense-text').textContent = gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0);
712
+
713
+ // Update health bar
714
+ const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
715
+ document.getElementById('health-bar').style.width = `${healthPercent}%`;
716
+
717
+ // Update mana bar
718
+ const manaPercent = (gameState.player.mana / gameState.player.maxMana) * 100;
719
+ document.getElementById('mana-bar').style.width = `${manaPercent}%`;
720
+
721
+ // Update exp bar
722
+ const expPercent = (gameState.player.exp / gameState.player.expToNextLevel) * 100;
723
+ document.getElementById('exp-bar').style.width = `${expPercent}%`;
724
+
725
+ // Update character icon based on class
726
+ const characterIcon = document.getElementById('character-icon');
727
+ const playerCombatIcon = document.getElementById('player-combat-icon');
728
+
729
+ if (gameState.player.class === 'warrior') {
730
+ characterIcon.innerHTML = '<i class="fas fa-shield-alt text-red-500"></i>';
731
+ playerCombatIcon.innerHTML = '<i class="fas fa-shield-alt text-red-500"></i>';
732
+ } else if (gameState.player.class === 'mage') {
733
+ characterIcon.innerHTML = '<i class="fas fa-hat-wizard text-blue-500"></i>';
734
+ playerCombatIcon.innerHTML = '<i class="fas fa-hat-wizard text-blue-500"></i>';
735
+ } else if (gameState.player.class === 'rogue') {
736
+ characterIcon.innerHTML = '<i class="fas fa-user-ninja text-green-500"></i>';
737
+ playerCombatIcon.innerHTML = '<i class="fas fa-user-ninja text-green-500"></i>';
738
+ }
739
+
740
+ // Update player combat name
741
+ document.getElementById('player-combat-name').textContent = gameState.player.name;
742
  }
 
 
 
 
 
 
 
 
743
 
744
+ function addGameMessage(message, type = 'info') {
745
+ const messagesDiv = document.getElementById('game-messages');
746
+ const messageElement = document.createElement('p');
747
+
748
+ if (type === 'error') {
749
+ messageElement.className = 'text-red-400';
750
+ } else if (type === 'success') {
751
+ messageElement.className = 'text-green-400';
752
+ } else if (type === 'warning') {
753
+ messageElement.className = 'text-yellow-400';
 
 
 
 
 
 
 
 
 
754
  } else {
755
+ messageElement.className = 'text-gray-300';
 
 
 
 
 
 
 
 
756
  }
757
+
758
+ messageElement.textContent = message;
759
+ messagesDiv.appendChild(messageElement);
760
+ messagesDiv.scrollTop = messagesDiv.scrollHeight;
761
+
762
+ // Add to game state for saving
763
+ gameState.gameMessages.push(message);
764
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
 
766
+ function explore() {
767
+ if (gameState.inCombat) {
768
+ addGameMessage('You are already in combat!', 'error');
769
+ return;
770
+ }
771
+
772
+ // 70% chance to find an enemy
773
+ if (Math.random() < 0.7) {
774
+ startCombat();
775
+ } else {
776
+ // 30% chance to find something else
777
+ const randomEvent = Math.random();
778
+
779
+ if (randomEvent < 0.5) {
780
+ // Found gold
781
+ const goldFound = Math.floor(Math.random() * 10) + 5;
782
+ gameState.player.gold += goldFound;
783
+ updateCharacterDisplay();
784
+ addGameMessage(`You found ${goldFound} gold coins on the ground!`, 'success');
785
+ } else {
786
+ // Found a health potion
787
+ gameState.player.inventory.push({
788
+ name: 'Health Potion',
789
+ type: 'consumable',
790
+ effect: 'heal',
791
+ amount: 30,
792
+ icon: 'fa-flask'
793
+ });
794
+ addGameMessage('You found a Health Potion!', 'success');
795
+ }
796
+ }
797
  }
 
 
 
 
 
 
798
 
799
+ function startCombat() {
800
+ gameState.inCombat = true;
801
+
802
+ // Select a random enemy
803
+ const randomEnemyIndex = Math.floor(Math.random() * enemies.length);
804
+ gameState.currentEnemy = {...enemies[randomEnemyIndex]};
805
+
806
+ // Update combat UI
807
+ document.getElementById('combat-area').classList.remove('hidden');
808
+ document.getElementById('enemy-name').textContent = gameState.currentEnemy.name;
809
+ document.getElementById('enemy-health-text').textContent = `${gameState.currentEnemy.health}/${gameState.currentEnemy.maxHealth}`;
810
+ document.getElementById('enemy-health-bar').style.width = '100%';
811
+ document.getElementById('enemy-image').src = gameState.currentEnemy.image;
812
+ document.getElementById('enemy-image').alt = gameState.currentEnemy.name;
813
+
814
+ // Update player stats in combat
815
+ document.getElementById('player-health-text').textContent = `${gameState.player.health}/${gameState.player.maxHealth}`;
816
+ const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
817
+ document.getElementById('player-health-bar').style.width = `${healthPercent}%`;
818
+
819
+ addGameMessage(`You encounter a ${gameState.currentEnemy.name}! ${gameState.currentEnemy.description}`, 'warning');
820
  }
821
+
822
+ function playerAttack() {
823
+ if (!gameState.inCombat || !gameState.currentEnemy) {
824
+ addGameMessage('There is nothing to attack!', 'error');
825
+ return;
826
+ }
827
+
828
+ // Calculate player damage
829
+ const playerAttackPower = gameState.player.attack + (gameState.player.equipped.weapon ? gameState.player.equipped.weapon.attack : 0);
830
+ const damage = Math.max(1, playerAttackPower - Math.floor(gameState.currentEnemy.defense / 2));
831
+
832
+ // Apply damage to enemy
833
+ gameState.currentEnemy.health -= damage;
834
+
835
+ // Update enemy health bar
836
+ const enemyHealthPercent = (gameState.currentEnemy.health / gameState.currentEnemy.maxHealth) * 100;
837
+ document.getElementById('enemy-health-bar').style.width = `${Math.max(0, enemyHealthPercent)}%`;
838
+ document.getElementById('enemy-health-text').textContent = `${Math.max(0, gameState.currentEnemy.health)}/${gameState.currentEnemy.maxHealth}`;
839
+
840
+ // Show damage text
841
+ showDamageText(document.querySelector('#combat-area .relative:last-child'), damage);
842
+
843
+ addGameMessage(`You attack the ${gameState.currentEnemy.name} for ${damage} damage!`, 'success');
844
+
845
+ // Check if enemy is defeated
846
+ if (gameState.currentEnemy.health <= 0) {
847
+ enemyDefeated();
848
+ return;
849
+ }
850
+
851
+ // Enemy attacks back
852
+ setTimeout(() => {
853
+ enemyAttack();
854
+ }, 1000);
855
  }
856
+
857
+ function playerSpell() {
858
+ if (!gameState.inCombat || !gameState.currentEnemy) {
859
+ addGameMessage('There is nothing to attack!', 'error');
860
+ return;
861
+ }
862
+
863
+ if (gameState.player.mana < 15) {
864
+ addGameMessage('Not enough mana to cast a spell!', 'error');
865
+ return;
866
+ }
867
+
868
+ // Use mana
869
+ gameState.player.mana -= 15;
870
+ updateCharacterDisplay();
871
+
872
+ // Calculate spell damage (more powerful than regular attack)
873
+ let spellDamage;
874
+ if (gameState.player.class === 'mage') {
875
+ spellDamage = Math.max(3, 15 + Math.floor(Math.random() * 10));
876
+ } else {
877
+ spellDamage = Math.max(3, 10 + Math.floor(Math.random() * 5));
878
+ }
879
+
880
+ // Apply damage to enemy
881
+ gameState.currentEnemy.health -= spellDamage;
882
+
883
+ // Update enemy health bar
884
+ const enemyHealthPercent = (gameState.currentEnemy.health / gameState.currentEnemy.maxHealth) * 100;
885
+ document.getElementById('enemy-health-bar').style.width = `${Math.max(0, enemyHealthPercent)}%`;
886
+ document.getElementById('enemy-health-text').textContent = `${Math.max(0, gameState.currentEnemy.health)}/${gameState.currentEnemy.maxHealth}`;
887
+
888
+ // Show damage text
889
+ showDamageText(document.querySelector('#combat-area .relative:last-child'), spellDamage, 'blue');
890
+
891
+ addGameMessage(`You cast a spell on the ${gameState.currentEnemy.name} for ${spellDamage} damage!`, 'success');
892
+
893
+ // Check if enemy is defeated
894
+ if (gameState.currentEnemy.health <= 0) {
895
+ enemyDefeated();
896
+ return;
897
+ }
898
+
899
+ // Enemy attacks back
900
+ setTimeout(() => {
901
+ enemyAttack();
902
+ }, 1000);
903
  }
904
+
905
+ function playerDefend() {
906
+ if (!gameState.inCombat || !gameState.currentEnemy) {
907
+ addGameMessage('There is nothing to defend against!', 'error');
908
+ return;
909
+ }
910
+
911
+ addGameMessage(`You take a defensive stance, reducing damage from the next attack.`, 'info');
912
+
913
+ // Enemy attacks with reduced damage
914
+ setTimeout(() => {
915
+ // Calculate enemy damage (reduced by 50% when defending)
916
+ const enemyDamage = Math.max(1, Math.floor((gameState.currentEnemy.attack - (gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0))) / 2));
917
+
918
+ // Apply damage to player
919
+ gameState.player.health -= enemyDamage;
920
+
921
+ // Update player health bar
922
+ const healthPercent = (gameState.player.health / gameState.player.maxHealth) * 100;
923
+ document.getElementById('player-health-bar').style.width = `${Math.max(0, healthPercent)}%`;
924
+ document.getElementById('player-health-text').textContent = `${Math.max(0, gameState.player.health)}/${gameState.player.maxHealth}`;
925
+ document.getElementById('health-bar').style.width = `${Math.max(0, healthPercent)}%`;
926
+ document.getElementById('health-text').textContent = `${Math.max(0, gameState.player.health)}/${gameState.player.maxHealth}`;
927
+
928
+ // Show damage text
929
+ showDamageText(document.querySelector('#combat-area .relative:first-child'), enemyDamage);
930
+
931
+ addGameMessage(`The ${gameState.currentEnemy.name} attacks you for ${enemyDamage} damage (reduced by your defense)!`, 'warning');
932
+
933
+ // Check if player is defeated
934
+ if (gameState.player.health <= 0) {
935
+ playerDefeated();
936
+ }
937
+ }, 1000);
938
  }
 
 
 
 
 
 
939
 
940
+ function playerFlee() {
941
+ if (!gameState.inCombat || !gameState.currentEnemy) {
942
+ addGameMessage('There is nothing to flee from!', 'error');
943
+ return;
944
+ }
945
+
946
+ // 60% chance to flee successfully
947
+ if (Math.random() < 0.6) {
948
+ addGameMessage(`You successfully fled from the ${gameState.currentEnemy.name}!`, 'success');
949
+ endCombat();
950
+ } else {
951
+ addGameMessage(`You failed to flee! The ${gameState.currentEnemy.name} attacks you!`, 'error');
952
+
953
+ // Enemy attacks
954
+ setTimeout(() => {
955
+ enemyAttack();
956
+ }, 1000);
957
+ }
958
  }
959
+
960
+ function enemyAttack() {
961
+ if (!gameState.inCombat || !gameState.currentEnemy) return;
962
+
963
+ // Calculate enemy damage
964
+ const enemyDamage = Math.max(1, gameState.currentEnemy.attack - (gameState.player.defense + (gameState.player.equipped.shield ? gameState.player.equipped.shield.defense : 0)));
 
965
 
966
  // Apply damage to player
967
  gameState.player.health -= enemyDamage;
 
976
  // Show damage text
977
  showDamageText(document.querySelector('#combat-area .relative:first-child'), enemyDamage);
978
 
979
+ addGameMessage(`The ${gameState.currentEnemy.name} attacks you for ${enemyDamage} damage!`, 'warning');
980
 
981
  // Check if player is defeated
982
  if (gameState.player.health <= 0) {
983
  playerDefeated();
984
  }
 
 
 
 
 
 
 
985
  }
986
+
987
+ function enemyDefeated() {
988
+ addGameMessage(`You defeated the ${gameState.currentEnemy.name}!`, 'success');
 
 
 
 
989
 
990
+ // Gain experience and gold
991
+ gameState.player.exp += gameState.currentEnemy.exp;
992
+ gameState.player.gold += gameState.currentEnemy.gold;
993
+
994
+ addGameMessage(`Gained ${gameState.currentEnemy.exp} experience and ${gameState.currentEnemy.gold} gold.`, 'success');
995
+
996
+ // Check for level up
997
+ checkLevelUp();
998
+
999
+ // End combat
1000
+ endCombat();
1001
  }
 
1002
 
1003
+ function playerDefeated() {
1004
+ addGameMessage(`You were defeated by the ${gameState.currentEnemy.name}!`, 'error');
1005
+ addGameMessage('You wake up in town, having lost some gold and experience.', 'warning');
1006
+
1007
+ // Penalty for dying
1008
+ gameState.player.exp = Math.max(0, gameState.player.exp - 10);
1009
+ gameState.player.gold = Math.max(0, gameState.player.gold - 5);
1010
+
1011
+ // Restore some health
1012
+ gameState.player.health = Math.floor(gameState.player.maxHealth * 0.3);
1013
+
1014
+ // Update display
1015
+ updateCharacterDisplay();
1016
+
1017
+ // End combat
1018
+ endCombat();
 
 
 
 
 
 
 
 
1019
  }
 
1020
 
1021
+ function endCombat() {
1022
+ gameState.inCombat = false;
1023
+ gameState.currentEnemy = null;
1024
+ document.getElementById('combat-area').classList.add('hidden');
1025
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1026
 
1027
+ function checkLevelUp() {
1028
+ if (gameState.player.exp >= gameState.player.expToNextLevel) {
1029
+ gameState.player.level++;
1030
+ gameState.player.exp -= gameState.player.expToNextLevel;
1031
+ gameState.player.expToNextLevel = Math.floor(gameState.player.expToNextLevel * 1.2);
1032
+
1033
+ // Improve stats
1034
+ gameState.player.maxHealth += 10;
1035
+ gameState.player.health = gameState.player.maxHealth;
1036
+ gameState.player.maxMana += 5;
1037
+ gameState.player.mana = gameState.player.maxMana;
1038
+ gameState.player.attack += 2;
1039
+ gameState.player.defense += 1;
1040
+
1041
+ addGameMessage(`Level up! You are now level ${gameState.player.level}!`, 'success');
1042
+ addGameMessage('Your stats have improved!', 'info');
1043
+
1044
+ updateCharacterDisplay();
1045
+ }
1046
+ }
1047
 
1048
+ function rest() {
1049
+ if (gameState.inCombat) {
1050
+ addGameMessage('You cannot rest while in combat!', 'error');
1051
+ return;
1052
+ }
1053
+
1054
+ // Restore health and mana
1055
+ const healthRestored = Math.floor(gameState.player.maxHealth * 0.3);
1056
+ const manaRestored = Math.floor(gameState.player.maxMana * 0.3);
1057
+
1058
+ gameState.player.health = Math.min(gameState.player.maxHealth, gameState.player.health + healthRestored);
1059
+ gameState.player.mana = Math.min(gameState.player.maxMana, gameState.player.mana + manaRestored);
 
 
 
 
1060
 
1061
+ addGameMessage(`You rest and recover ${healthRestored} health and ${manaRestored} mana.`, 'success');
1062
  updateCharacterDisplay();
1063
  }
 
1064
 
1065
+ function visitTown() {
1066
+ if (gameState.inCombat) {
1067
+ addGameMessage('You cannot visit town while in combat!', 'error');
1068
+ return;
1069
+ }
1070
+
1071
+ document.getElementById('town-area').classList.remove('hidden');
1072
+ addGameMessage('You enter the town square.', 'info');
1073
  }
 
 
 
 
 
 
 
 
 
 
 
1074
 
1075
+ function leaveTown() {
1076
+ document.getElementById('town-area').classList.add('hidden');
1077
+ addGameMessage('You leave the town.', 'info');
 
1078
  }
 
 
 
 
1079
 
1080
+ function visitShop() {
1081
+ addGameMessage('The shop is currently closed. Come back later!', 'info');
1082
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
 
1084
+ function visitTavern() {
1085
+ addGameMessage('You enjoy a drink at the tavern and hear rumors of a dragon girl in the mountains.', 'info');
 
 
1086
  }
1087
+
1088
+ function visitGuild() {
1089
+ addGameMessage('The Adventurer\'s Guild has no quests available right now.', 'info');
 
 
1090
  }
1091
+
1092
+ function train() {
1093
+ if (gameState.inCombat) {
1094
+ addGameMessage('You cannot train while in combat!', 'error');
1095
+ return;
1096
+ }
1097
+
1098
+ // Training costs gold but improves stats
1099
+ if (gameState.player.gold < 5) {
1100
+ addGameMessage('You need at least 5 gold to train!', 'error');
1101
+ return;
1102
+ }
1103
+
1104
+ gameState.player.gold -= 5;
1105
+
1106
+ // Random stat improvement
1107
+ const statToImprove = ['attack', 'defense'][Math.floor(Math.random() * 2)];
1108
+ const improvement = 1;
1109
+
1110
+ if (statToImprove === 'attack') {
1111
+ gameState.player.attack += improvement;
1112
+ addGameMessage(`After training, your attack increased by ${improvement}! (Cost: 5 gold)`, 'success');
1113
+ } else {
1114
+ gameState.player.defense += improvement;
1115
+ addGameMessage(`After training, your defense increased by ${improvement}! (Cost: 5 gold)`, 'success');
1116
+ }
1117
+
1118
+ updateCharacterDisplay();
1119
  }
 
 
 
1120
 
1121
+ function openInventory() {
1122
+ document.getElementById('inventory-modal').classList.remove('hidden');
1123
+ }
1124
 
1125
+ function closeInventory() {
1126
+ document.getElementById('inventory-modal').classList.add('hidden');
1127
+ }
1128
 
1129
+ function openQuests() {
1130
+ addGameMessage('You have no active quests at the moment.', 'info');
1131
+ }
1132
 
1133
+ function saveGame() {
1134
+ localStorage.setItem('monstergirlRpgSave', JSON.stringify(gameState));
1135
+ addGameMessage('Game saved successfully!', 'success');
1136
+ }
1137
 
1138
+ function loadGame() {
1139
+ const savedGame = localStorage.getItem('monstergirlRpgSave');
1140
+
1141
+ if (savedGame) {
1142
+ try {
1143
+ const parsedGame = JSON.parse(savedGame);
1144
+ Object.assign(gameState, parsedGame);
1145
+
1146
+ document.getElementById('main-menu').classList.add('hidden');
1147
+ document.getElementById('game-screen').classList.remove('hidden');
1148
+
1149
+ updateCharacterDisplay();
1150
+ addGameMessage(`Welcome back, ${gameState.player.name}! Game loaded successfully.`, 'success');
1151
+ } catch (e) {
1152
+ addGameMessage('Failed to load saved game.', 'error');
1153
+ }
1154
+ } else {
1155
+ addGameMessage('No saved game found.', 'error');
1156
  }
1157
  }
1158
 
 
1186
 
1187
  // Initialize game
1188
  document.addEventListener('DOMContentLoaded', () => {
1189
+ addGameMessage('Welcome to Monstergirl RPG!');
1190
  });
1191
  </script>
1192
  <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=lunarflu/rpg" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>