Skip to content

New experimental release

Pre-release
Pre-release

Choose a tag to compare

@InfusedStormblessed InfusedStormblessed released this 05 Feb 18:33
· 45 commits to main since this release
ce83c42

It doesn't work and I am honestly not sure why, but I added an EXP bar. If anyone knows how to fix it, please help me.

`

<title>Cosmere Adventure</title> <style> /* Basic CSS styling to make the game look nicer */ body { font-family: Arial, sans-serif; background-color: #000080; }
    h1 {
        color: #ffffff;
    }

    #gameOutput {
        font-size: 20px;
        font-weight: bold;
        text-align: center;
        margin: 20px;
        background-color: #fff;
        border: 1px solid #ccc;
        border-radius: 5px;
        padding: 15px;
    }

    .button-container {
        display: flex;
        justify-content: center;
        margin: 10px 0;
    }

    button {
        background-color: #4CAF50;
        color: white;
        padding: 10px 20px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        margin: 0 5px;
    }

    button:hover {
        background-color: #45a049;
    }

    #endGameButton {
        background-color: #f44336;
    }

    #endGameButton:hover {
        background-color: #e91e63;
    }

    #healthBars {
        display: flex;
        justify-content: space-between;
        margin: 20px;
        font-weight: bold;
    }

    .health {
        width: 200px;
        height: 20px;
        background-color: #ddd;
        border-radius: 5px;
        position: relative;
    }

    .health span {
        height: 100%;
        display: block;
        border-radius: 5px;
    }

    #expBar {
        width: 100%;
        height: 20px;
        background-color: #ddd;
        border-radius: 5px;
        margin: 20px 0;
    }

    #expSpan {
        height: 100%;
        display: block;
        background-color: #4CAF50;
        border-radius: 5px;
        width: 0; /* Initial width of the EXP bar */
    }

    #attackMenu {
        display: none;
        background-color: white;
        border: 1px solid #ccc;
        border-radius: 5px;
        padding: 10px;
        position: absolute;
    }

    .attackOption {
        cursor: pointer;
        padding: 5px;
    }

    .attackOption:hover {
        background-color: #f0f0f0;
    }
</style>

Cosmere Adventure

Welcome to your adventure! Select a character to begin.

<div class="button-container">
    <button id="characterSelectionButton">Character Selection</button>
    <button id="exploreButton" disabled>Explore</button>
    <button id="loadGameButton" disabled>Load Game</button>
    <button id="saveGameButton" disabled>Save Game</button>
    <button id="inventoryButton" disabled>Inventory</button>
    <button id="endGameButton">End Game</button>
</div>

<div id="healthBars" style="display: none;">
    <div id="playerHealthBar" class="health">
        <span id="playerHealthSpan" style="background-color: green; width: 100%;"></span>
    </div>
    <div id="enemyHealthBar" class="health">
        <span id="enemyHealthSpan" style="background-color: red; width: 100%;"></span>
    </div>
</div>

<!-- Experience Bar -->
<div id="expBar">
    <span id="expSpan"></span>
</div>

<div id="attackMenu" style="display: none;">
    <p>Select an attack:</p>
    <div id="attackOptionsContainer"></div>
    <button id="closeAttackMenuButton">Close</button>
</div>

<div id="locationSelection" style="display: none;">
    <p>Choose a location to explore:</p>
    <button id="luthadelButton" style="display: none;">Luthadel</button>
    <button id="stormlandsButton">Stormlands</button>
    <button id="rithmatistButton">Rithmatist's Academy</button>
    <button id="elendelButton" style="display: none;">Elendel</button>
    <button id="alethkarButton">Alethkar</button>
    <button id="urithiruButton">Urithiru</button>
    <button id="kholinarButton">Kholinar</button>
    <button id="thaylenCityButton">Thaylen City</button>
    <button id="scadrialButton" style="display: none;">Scadrial (General)</button>
</div>

<div id="postBattleChoices" style="display: none;">
    <p>What do you do?</p>
    <button id="attackButton">Attack</button>
    <button id="defendButton">Defend</button>
    <button id="specialButton">Use Special Ability</button>
</div>

<div id="npcInteraction" style="display: none;">
    <p>You encounter an NPC! What do you want to do?</p>
    <button id="talkButton">Talk</button>
    <button id="ignoreButton">Ignore</button>
    <p id="npcLoreOutput" style="margin-top: 10px;"></p>
</div>

<script>
    document.addEventListener("DOMContentLoaded", function() {
        // Game variables
        let player = null;
        let playerHealth = 100;
        let playerDamage = 0;
        let playerDefence = 0;
        let playerLevel = 1;
        let playerEXP = 0;
        let playerGold = 10;
        let currentEnemyHealth = null;
        let currentEnemyType = "";
        let playerInventory = [];
        let loreIndex = 0; // To track which lore to display next

        // Lore segments for NPC interaction
        const loreSegments = [
            "The Stormlight Archive is a high fantasy series by Brandon Sanderson.",
            "The series takes place in a world called Roshar, where large storms called Highstorms frequent.",
            "The main character, Kaladin, is a soldier who discovers he has the ability to manipulate the winds."
        ];

        // Attacks for each character
        const attacks = {
            Vin: ["Steel Swipe", "Iron Blast", "Copper Charm", "Atium Shadow", "Tin Enhancements", "Mistborn Assault", "God Metal Strike"],
            Kaladin: ["Wind Slash", "Storm Slam", "Shield Bash", "Protective Shield", "Cleansing Storm", "Syl's Embrace", "Radiant Destruction"],
            Szeth: ["Honorblade Strike", "Windrunner's Fury", "Fury of the Honorblade", "Skybreaker's Visage", "Transcendent Blade", "Gift of the Stormfather"],
            Dalinar: ["Bondsmith's Wield", "Armored Charge", "Forging Strength", "Call of the Thrill", "Unyielding Resolve", "Blackthorn's Wrath"],
        };

        // Unique Abilities
        const specialAbilities = {
            Vin: [
                { name: "Allomantic Burst", description: "Unleash a powerful Allomantic energy burst.", bonusDamage: 15, unlockedAtLevel: 2 },
                { name: "Atium Rush", description: "Burn the powerful metal, Atium, making yourself invincible for a time.", bonusDamage: 40, unlockedAtLevel: 5 },
            ],
            Kaladin: [
                { name: "Wave of Stormlight", description: "Generate a wave of Stormlight that damages and pushes back enemies.", bonusDamage: 18, unlockedAtLevel: 1 },
                { name: "Cleansing Storm", description: "Create a storm that heals allies.", healAmount                    { name: "Cleansing Storm", description: "Create a storm that heals allies.", healAmount: 20, unlockedAtLevel: 3 },
            ],
            Szeth: [
                { name: "Well of Ascension", description: "Attack with the power of the Honorblade, dealing devastating damage.", bonusDamage: 20, unlockedAtLevel: 1 },
                { name: "Transcendent Blade", description: "Unleash a powerful strike with your Honorblade.", bonusDamage: 25, unlockedAtLevel: 4 },
            ],
            Dalinar: [
                { name: "Bondsmith's Resolve", description: "Rally your strength to heal and bolster defenses.", healAmount: 20, unlockedAtLevel: 1 },
                { name: "Call of the Thrill", description: "Unleash a frenzy of power, gaining additional attack for a short time.", bonusDamage: 10, unlockedAtLevel: 3 },
            ]
        };

        // Save/Load system
        const saveGame = () => {
            const gameData                const gameData = {
                player,
                playerHealth,
                playerDamage,
                playerDefence,
                playerLevel,
                playerEXP,
                playerGold,
                playerInventory,
                loreIndex // Save the current lore index
            };
            localStorage.setItem('savedGame', JSON.stringify(gameData));
            document.getElementById("gameOutput").innerText = "Game saved successfully!";
        };

        const loadGame = () => {
            const savedData = JSON.parse(localStorage.getItem('savedGame'));
            if (savedData) {
                Object.assign(window, savedData);
                document.getElementById("gameOutput").innerText = "Game loaded successfully!";
                updateDisplay();
            } else {
                document.getElementById("gameOutput").innerText = "No saved game found.";
            }
        };

        const updateDisplay = () => {
            document.getElementById("gameOutput").innerText = `Welcome back, ${player}! Your health: ${playerHealth}, Level: ${playerLevel}, EXP: ${playerEXP}`;
            exploreButton.disabled = false;
            locationSelection.style.display = "none"; // Hide location selection until explore is clicked
            postBattleChoices.style.display = "none"; // Hide battle options
            inventoryButton.disabled = false;
            updateHealthBars();
            updateEXPBar(); // Update the EXP bar when displaying the player status
        };

        // Health bar update function
        const updateHealthBars = () => {
            const playerHealthPercentage = (playerHealth / 100) * 100;
            document.getElementById('playerHealthSpan').style.width = `${playerHealthPercentage}%`;
        
            if (currentEnemyHealth) {
                const enemyHealthPercentage = (currentEnemyHealth / 100) * 100; // assuming max health is 100 for simplicity
                document.getElementById('enemyHealthSpan').style.width = `${enemyHealthPercentage}%`;
            }
        };

        // EXP bar update function
        const updateEXPBar = () => {
            const expRequiredForNextLevel = playerLevel * 100; // Example: 100 EXP required to level up
            const expPercentage = (playerEXP / expRequiredForNextLevel) * 100;
            document.getElementById('expSpan').style.width = `${Math.min(expPercentage, 100)}%`; // Make sure it doesn't exceed 100%
        };

        // Check and set location buttons based on selected character
        const updateLocationButtons = () => {
            const isRosharan = ["Dalinar", "Kaladin", "Szeth"].includes(player);
            const isVin = player === "Vin";

            // Show/Hide relevant buttons
            document.getElementById("luthadelButton").style.display = isRosharan ? "none" : "block";
            document.getElementById("elendelButton").style.display = isRosharan ? "none" : "block";
            document.getElementById("scadrialButton").style.display = isRosharan ? "none" : "block";
            document.getElementById("urithiruButton").style.display = isVin ? "none" : "block";
            document.getElementById("kholinarButton").style.display = isVin ? "none" : "block";
            document.getElementById("stormlandsButton").style.display = isVin ? "none" : "block";
            document.getElementById("thaylenCityButton").style.display = isVin ? "none" : "block";
            document.getElementById("alethkarButton").style.display = isVin ? "none" : "block";
        };

        // Enemies specific to locations
        const enemies = {
            Luthadel: {
                "Steel Inquisitor": { health: 70, damage: 15 },
                "Colossus": { health: 100, damage: 25 },
            },
            Stormlands: {
                "Shardbearer": { health: 90, damage: 20 },
                "Parshendi": { health: 60, damage: 18 },
            },
            "Rithmatist's Academy": {
                "Rithmatist": { health: 80, damage: 15 },
                "Animated Defender": { health: 70, damage: 12 },
            },
            Elendel: {
                "Nobleman": { health: 50, damage: 10 },
                "Kandra": { health: 75, damage: 20 },
            },
            Alethkar: {
                "Prisoner of War": { health: 60, damage: 12 },
                "Shin Warrior": { health: 85, damage: 16 },
            },
            Urithiru: {
                "Skybreaker": { health: 100, damage: 30 },
                "Windrunner": { health: 95, damage: 25 },
            },
            Kholinar: {
                "Fused": { health: 120, damage: 28 },
                "Amaram's Soldiers": { health: 80, damage: 20 },
            },
            "Thaylen City": {
                "Thaylen Merchant": { health: 50, damage: 14 },
                "Thaylen Assassin": { health: 70, damage: 18 },
            },
            "Scadrial (General)": {
                "Thieving Crew": { health: 65, damage: 15 },
                "Benevolent Mistwraith": { health: 90, damage: 22 },
            }
        };

        // Save queries to HTML elements
        const exploreButton = document.getElementById("exploreButton");
        const characterSelectionButton = document.getElementById("characterSelectionButton");
        const loadGameButton = document.getElementById("loadGameButton");
        const saveGameButton = document.getElementById("saveGameButton");
        const inventoryButton = document.getElementById("inventoryButton");
        const endGameButton = document.getElementById("endGameButton");
        const luthadelButton = document.getElementById("luthadelButton");
        const stormlandsButton = document.getElementById("stormlandsButton");
        const rithmatistButton = document.getElementById("rithmatistButton");
        const elendelButton = document.getElementById("elendelButton");
        const alethkarButton = document.getElementById("alethkarButton");
        const urithiruButton = document.getElementById("urithiruButton");
        const kholinarButton = document.getElementById("kholinarButton");
        const thaylenCityButton = document.getElementById("thaylenCityButton");
        const scadrialButton = document.getElementById("scadrialButton");
        const attackButton = document.getElementById("attackButton");
        const defendButton = document.getElementById("defendButton");
        const specialButton = document.getElementById("specialButton");
        const postBattleChoices = document.getElementById("postBattleChoices");
        const locationSelection = document.getElementById("locationSelection");
        const attackMenu = document.getElementById("attackMenu");
        const attackOptionsContainer = document.getElementById("attackOptionsContainer");
        const closeAttackMenuButton = document.getElementById("closeAttackMenuButton");
        const talkButton = document.getElementById("talkButton");
        const ignoreButton = document.getElementById("ignoreButton");
        const npcInteraction = document.getElementById("npcInteraction");
        const npcLoreOutput = document.getElementById("npcLoreOutput");

        // Character Selection
        characterSelectionButton.addEventListener("click", () => {
            const character = prompt("Choose your character: Vin (Mistborn), Kaladin (Windrunner), Szeth (Assassin in White), Dalinar (Bondsmith):").trim();
            if (["Vin", "Kaladin", "Szeth", "Dalinar"].includes(character)) {
                player = character;
                playerDamage = character === "Vin" ? 10 : character === "Kaladin" ? 8 : character === "Szeth" ? 15 : 18;
                playerDefence = character === "Vin" ? 5 : character === "Kaladin" ? 6 : character === "Szeth" ? 4 : 7;
                document.getElementById("gameOutput").innerText = `You have chosen ${player}. Ready for adventure!`;
                exploreButton.disabled = false;
                loadGameButton.disabled = false;
                saveGameButton.disabled = false;
                inventoryButton.disabled = false;
                locationSelection.style.display = "none"; // Hide location selection until explore is clicked

                // Update available locations based on character
                updateLocationButtons();
            } else {
                document.getElementById("gameOutput").innerText = "Invalid character selection.";
            }
        });

        // Save Game
        saveGameButton.addEventListener("click", saveGame);

        // Load Game
        loadGameButton.addEventListener("click", loadGame);

        // Explore Button
        exploreButton.addEventListener("click", () => {
            console.log("Explore button clicked!");
            document.getElementById("gameOutput").innerText = "Select a location to explore.";
            locationSelection.style.display = "block";
        });

        // Location selection
        luthadelButton.addEventListener("click", () => startBattle("Luthadel"));
        stormlandsButton.addEventListener("click", () => startBattle("Stormlands"));
        rithmatistButton.addEventListener("click", () => startBattle("Rithmatist's Academy"));
        elendelButton.addEventListener("click", () => startBattle("Elendel"));
        alethkarButton.addEventListener("click", () => startBattle("Alethkar"));
        urithiruButton.addEventListener("click", () => startBattle("Urithiru"));
        kholinarButton.addEventListener("click", () => startBattle("Kholinar"));
        thaylenCityButton.addEventListener("click", () => startBattle("Thaylen City"));
        scadrialButton.addEventListener("click", () => startBattle("Scadrial (General)"));

        // Start Battle
        function startBattle(location) {
            const enemyNames = Object.keys(enemies[location]);
            const enemyName = enemyNames[Math.floor(Math.random() * enemyNames.length)];

            currentEnemyHealth = enemies[location][enemyName].health;
            currentEnemyType = enemyName;
            document.getElementById("gameOutput").innerText = `You have entered ${location}. Prepare for battle against ${currentEnemyType}!`;

            // Show health bars
            document.getElementById('healthBars').style.display = 'flex';
            updateHealthBars();

            // 50% chance to encounter an NPC
            if (Math.random() < 0.5) {
                npcInteraction.style.display = "block";
                document.getElementById("gameOutput").innerText += `\nYou encounter an NPC! What will you do?`;
            } else {
                postBattleChoices.style.display = "block"; // Show battle options
            }
        }

        // Show Attack Menu
        const showAttackMenu = (isSpecial) => {
            attackOptionsContainer.innerHTML = ""; // Clear previous options

            const attackList = isSpecial ? 
                specialAbilities[player].filter(ab => playerLevel >= ab.unlockedAtLevel) : 
                attacks[player];

            attackList.forEach((attack) => {
                const attackDiv = document.createElement("div");
                attackDiv.className = "attackOption";
                attackDiv.innerText = attack.name || attack; // Use name if it exists, otherwise use the attack name.
                attackDiv.onclick = () => {
                    isSpecial ? useSpecialAbility(attack) : useAttack(attack); // Call appropriate function based on type
                    attackMenu.style.display = "none"; // Hide attack menu after use
                };
                attackOptionsContainer.appendChild(attackDiv);
            });

            attackMenu.style.display = "block"; // Show the menu
        };

        // Attack Button
        attackButton.addEventListener("click", () => showAttackMenu(false));

        // Special Ability Button
        specialButton.addEventListener("click", () => showAttackMenu(true));

        // Close Attack Menu Button
        closeAttackMenuButton.addEventListener("click", () => {
            attackMenu.style.display = "none"; // Close the attack menu
        });

        // Use Attack or Special Ability
        const useAttack = (attackName) => {
            if (currentEnemyHealth > 0) {
                let damage = playerDamage; // Assuming all normal attacks do playerDamage
                currentEnemyHealth -= damage;
                document.getElementById("gameOutput").innerText += `\nYou used ${attackName} against ${currentEnemyType} for ${damage} damage.`;
                updateHealthBars(); // Update health bars after attack
                checkEnemyDefeated();
            }
        };

        const useSpecialAbility = (ability) => {
            if (currentEnemyHealth > 0) {
                let damage = ability.bonusDamage || 0;
                if (damage) {
                    currentEnemyHealth -= damage;
                    document.getElementById("gameOutput").innerText += `\nYou used ${ability.name} and dealt ${damage} extra damage to ${currentEnemyType}.`;
                }
                updateHealthBars(); // Update health bars after ability use
                checkEnemyDefeated();
            }
        };

        // Check if enemy is defeated
        const checkEnemyDefeated = () => {
            if (currentEnemyHealth <= 0) {
                document.getElementById("gameOutput").innerText += `\nYou defeated ${currentEnemyType}! You earn 50 experience points.`;
                playerEXP += 50;
                updateEXPBar(); // Update EXP bar when experience is gained

                // Level up if enough EXP is gained
                if (playerEXP >= playerLevel * 100) {
                    playerLevel++;
                    document.getElementById("gameOutput").innerText += `\nCongratulations! You leveled up to Level ${playerLevel}!`;
                }

                // Unlock new attacks based on level
                unlockAbilities();
                
                // Hide post battle choices
                postBattleChoices.style.display = "none"; 
            } else {
                enemyTurn(); // Enemy attacks back if still alive
            }
        };

        // Enemy Turn
        const enemyTurn = () => {
            if (currentEnemyHealth > 0) {
                const enemyDamage = Math.max(0, enemies[currentEnemyType].damage - playerDefence); // Prevent negative damage
                playerHealth -= enemyDamage;
                document.getElementById("gameOutput").innerText += `\n${currentEnemyType} attacked you for ${enemyDamage} damage. Your health is now ${playerHealth}.`;
                updateHealthBars(); // Update health after enemy attack
                if (playerHealth <= 0) {
                    endGame("You have been defeated by " + currentEnemyType + "... Game over.");
                }
            }
        };

        const unlockAbilities = () => {
            if (playerLevel === 5) {
                document.getElementById("gameOutput").innerText += `\nCongratulations! You gained access to the special ability: Atium Rush!`;
            } else if (playerLevel === 10) {
                document.getElementById("gameOutput").innerText += `\nYou have reached level 10! You gained access to God Metal abilities!`;
            }
        };

        // NPC Interaction
        talkButton.addEventListener("click", () => {
            if (loreIndex < loreSegments.length) {
                npcLoreOutput.innerText = loreSegments[loreIndex];
                loreIndex++; // Increment the lore index for the next segment
            } else {
                npcLoreOutput.innerText = "You've already learned all you can from this NPC.";
            }
        });

        ignoreButton.addEventListener("click", () => {
            document.getElementById("gameOutput").innerText += "\nYou chose to ignore the NPC.";
            npcInteraction.style.display = "none";
            postBattleChoices.style.display = "block"; // Show battle options directly after ignoring the NPC
        });

        // End Game
        endGameButton.addEventListener("click", () => {
            endGame("Game over. Your final level was: " + playerLevel);
        });

        // End game function
        function endGame(message) {
            document.getElementById("gameOutput").innerText = message;
            disableAllButtons();
            postBattleChoices.style.display = "none"; // Hide battle options
            locationSelection.style.display = "none"; // Hide location selection
            npcInteraction.style.display = "none"; // Hide NPC interaction
            document.getElementById('healthBars').style.display = 'none'; // Hide health bars
        }

        // Disable all buttons
        function disableAllButtons() {
            const buttons = document.querySelectorAll("button");
            buttons.forEach(button => button.disabled = true);
            endGameButton.disabled = false; // Allow ending the game
        }

        // Inventory Display
        inventoryButton.addEventListener("click", () => {
            const inventoryList = playerInventory.length ? playerInventory.join(", ") : "Your inventory is empty.";
            document.getElementById("gameOutput").innerText = `Your inventory: ${inventoryList}`;
        });
    });
</script>
`. That is obviously the game code, in case anyone wants to take a look at it.