diff --git a/Input.js b/Input.js index dc4d78b..18dbf2e 100644 --- a/Input.js +++ b/Input.js @@ -82,6 +82,10 @@ const setProficiencySynonyms = ["setproficiency", "setweaponproficiency"] const healPartySynonyms = ["healparty", "healcharacters"] const blockSynonyms = ["block", "parry", "nullify", "invalidate"] const repeatTurnSynonyms = ["repeatturn", "repeat"] +const basicDeckSynonyms = ["basicdeck"] +const cardShopSynonyms = ["cardshop", "stragedyshop", "cardstore", "stragedystore"] +const stragedySynonyms = ["stragedy", "playgame", "game", "startgame", "begingame", "playcards", "playstragedy", "startstragedy", "beginstragedy"] +const addCardSynonyms = ["addcard"] const helpSynonyms = ["help"] const modifier = (text) => { @@ -95,12 +99,17 @@ const modifier = (text) => { } if (state.setupEnemyStep != null) { - state.setupEnemyStep text = handleSetupEnemyStep(text) if (state.setupEnemyStep != null) return { text } else text = rawText } + if (state.stragedyShopStep != null) { + text = handleStragedyShopStep(text) + if (state.stragedyShopStep != null) return { text } + else text = rawText + } + if (state.initialized == null || !text.includes("#")) { state.initialized = true; return { text } @@ -227,6 +236,10 @@ const modifier = (text) => { if (text == null) text = processCommandSynonyms(command, commandName, healPartySynonyms, doHealParty) if (text == null) text = processCommandSynonyms(command, commandName, blockSynonyms, doBlock) if (text == null) text = processCommandSynonyms(command, commandName, repeatTurnSynonyms, doRepeatTurn) + if (text == null) text = processCommandSynonyms(command, commandName, basicDeckSynonyms, doBasicDeck) + if (text == null) text = processCommandSynonyms(command, commandName, cardShopSynonyms, doCardShop) + if (text == null) text = processCommandSynonyms(command, commandName, stragedySynonyms, doStragedy) + if (text == null) text = processCommandSynonyms(command, commandName, addCardSynonyms, doAddCard) if (text == null) text = processCommandSynonyms(command, commandName, helpSynonyms, doHelp) if (text == null) { var character = getCharacter() @@ -1258,6 +1271,149 @@ function doSetupEnemy(command) { return " " } +function doBasicDeck(command) { + var character = getCharacter() + var takeWord = character.name == "You" ? "take" : "takes" + doTake("take Stragedy Ace Card") + doTake("take Stragedy Ace Card") + doTake("take Stragedy 2 Card") + doTake("take Stragedy 2 Card") + doTake("take Stragedy 3 Card") + doTake("take Stragedy 3 Card") + doTake("take Stragedy 4 Card") + doTake("take Stragedy 4 Card") + doTake("take Stragedy 5 Card") + doTake("take Stragedy 5 Card") + doTake("take Stragedy 6 Card") + doTake("take Stragedy 6 Card") + doTake("take Stragedy 7 Card") + doTake("take Stragedy 7 Card") + doTake("take Stragedy 8 Card") + doTake("take Stragedy 8 Card") + doTake("take Stragedy 9 Card") + doTake("take Stragedy 9 Card") + doTake("take Stragedy Jack Card") + doTake("take Stragedy Jack Card") + return `${toTitleCase(character.name)} ${takeWord} the Stragedy Basic Deck` +} + +function doCardShop(command) { + state.stragedyShopStep = 0 + state.show = "stragedyShop" + return " " +} + +function handleStragedyShopStep(text) { + state.show = "stragedyShop" + + if (/^\s*>.*says? ".*/.test(text)) { + text = text.replace(/^\s*>.*says? "/, "") + text = text.replace(/"\s*$/, "") + } else if (/^\s*>\s.*/.test(text)) { + text = text.replace(/\s*> /, "") + for (var i = 0; i < info.characters.length; i++) { + var matchString = info.characters[i] == "" ? "You " : `${info.characters[i]} ` + if (text.startsWith(matchString)) { + text = text.replace(matchString, "") + break + } + } + text = text.replace(/\.?\s*$/, "") + } else { + text = text.replace(/^\s+/, "") + } + + if (text.toLowerCase() == "q") { + state.stragedyShopStep = 500 + return text + } + + switch (state.stragedyShopStep) { + case 0: + case 1: + if (isNaN(text)) return text + var index = parseInt(text) - 1 + if (index < 0 || index >= state.cardDeals.length) return text + + var item = state.cardDeals[index] + var price = state.cardPrices[index] + + var character = getCharacter() + var goldIndex = character.inventory.findIndex(x => x.name.toLowerCase() == "gold") + var gold = goldIndex == -1 ? 0 : character.inventory[goldIndex].quantity + + if (price > gold) { + state.stragedyShopStep = 2 + return text + } + + doTake(`take Stragedy ${item} Card`) + character.inventory[goldIndex].quantity -= price + + state.cardDeals.splice(index, 1) + state.cardPrices.splice(index, 1) + + state.stragedyShopStep = 1 + break + case 500: + state.show = null + state.stragedyShopStep = null + break + } + return text +} + +function doStragedy(command) { + state.stragedyTurn = "intro" + state.show = "stragedy" + return " " +} + +function doAddCard(command) { + var arg0 = getArgument(command, 0) + if (arg0 == null) { + arg0 = "" + } + + arg0 = arg0.toLowerCase() + switch(arg0) { + case "a": + case "ace": + return doTake("take Stragedy Ace Card") + case "j": + case "jack": + return doTake("take Stragedy Jack Card") + case "q": + case "queen": + return doTake("take Stragedy Queen Card") + case "k": + case "king": + return doTake("take Stragedy King Card") + case "?": + case "joker": + return doTake("take Stragedy Joker Card") + case "w": + case "witch": + return doTake("take Stragedy Witch Card") + case "p": + case "priest": + return doTake("take Stragedy Priest Card") + case "b": + case "brigand": + return doTake("take Stragedy Brigand Card") + case "common": + return doTake(`take Stragedy ${getRandomFromList("2", "3", "4", "5", "6", "7", "8", "9")} Card`) + case "rare": + return doTake(`take Stragedy ${getRandomFromList("10", "Ace", "Jack")} Card`) + case "epic": + return doTake(`take Stragedy ${getRandomFromList("Queen", "King", "Joker")} Card`) + case "legendary": + return doTake(`take Stragedy ${getRandomFromList("Witch", "Priest", "Brigand")} Card`) + default: + return doTake(`take Stragedy ${getRandomFromList("2", "3", "4", "5", "6", "7", "8", "9", "10", "Ace", "Jack", "Queen", "King", "Joker", "Witch", "Priest", "Brigand")} Card`) + } +} + function doBio(command) { state.show = "bio" return " " @@ -1757,6 +1913,8 @@ function doRest(command) { var commandName = getCommandName(command) state.day++ state.enemies = [] + state.cardDeals = null + state.cardPrices = null var healingFactor = 1 var text diff --git a/Library.js b/Library.js index d2a2ba9..1902297 100644 --- a/Library.js +++ b/Library.js @@ -16,6 +16,10 @@ function getRandom(seed) { return x - Math.floor(x) } +function getRandomFromList(...choices) { + return choices[getRandomInteger(0, choices.length - 1)] +} + function shuffle(array, seed) { let currentIndex = array.length while (currentIndex != 0) { diff --git a/Output.js b/Output.js index 9005cd3..191ca04 100644 --- a/Output.js +++ b/Output.js @@ -87,6 +87,12 @@ const modifier = (text) => { break } break + case "stragedy": + text += handleStragedy() + break + case "stragedyShop": + text += handleStragedyShop() + break case "bio": text += `*** ${possessiveName.toUpperCase()} BIO ***\n` text += `Class: ${character.className}\n` @@ -547,4 +553,82 @@ function mapReplace(map, x, y, character) { return map } +function handleStragedy() { + var text = " " + switch (state.stragedyTurn) { + case "intro": + text = `**Stragedy** +Welcome to Stragedy! A trading card game of wits, strategy, and tragic outcomes! +Please see the game manual on github for rules, tactics, and a complete tutorial: github.com/raeleus/Hashtag-DnD/ +` + break + } + + return text +} + +function handleStragedyShop() { + var character = getCharacter() + var goldIndex = character.inventory.findIndex(x => x.name.toLowerCase() == "gold") + var gold = goldIndex == -1 ? 0 : character.inventory[goldIndex].quantity + var text = " " + var seed = state.day + if (state.cardDeals == null) { + state.cardDeals = ["2", "3", "4", "5", "6", "7", "8", "9"] + state.cardPrices = [400, 400, 400, 400, 400, 400, 400, 400, 2000] + var items = ["10", "Ace", "Jack"] + state.cardDeals.push(items[Math.floor(getRandom(seed) * 3)]) + seed += 100 + if (getRandom(seed) > .6) { + items = ["Queen", "King", "Joker"] + state.cardDeals.push(getRandomFromList(items[Math.floor(getRandom(seed) * 3)])) + seed += 100 + state.cardPrices.push(5000) + } + if (getRandom(seed) > .9) { + items = ["Witch", "Priest", "Brigand"] + state.cardDeals.push(getRandomFromList(items[Math.floor(getRandom(seed) * 3)])) + seed += 100 + state.cardPrices.push(12000) + } + } + + switch (state.stragedyShopStep) { + case 0: + text = `**Welcome to the Stragedy Shop** +Deals change every day!` + break + case 1: + text = "Card purchased!" + break + case 2: + text = "You do not have enough gold!" + } + + switch (state.stragedyShopStep) { + case 0: + case 1: + case 2: + text += ` +Select a number from the list below to purchase a card: + +` + if (state.cardDeals.length == 0) text += "There are no cards left for sale!\n" + for (var i = 0; i < state.cardDeals.length; i++) { + text += `${i + 1}. Stragedy ${state.cardDeals[i]} Card for ${state.cardPrices[i]} gold\n` + } + + text += ` +You have ${gold} gold +Enter the number or q to quit: +` + break + case 500: + text = "Thank you for shopping at the Stragedy Shop!" + break + } + + return text +} + modifier(text) \ No newline at end of file diff --git a/story-cards.json b/story-cards.json index 792b1e3..e82d7ca 100644 --- a/story-cards.json +++ b/story-cards.json @@ -150,5 +150,77 @@ "title": "Spiritual Weapon", "description": "", "useForCharacterCreation": false + }, + { + "keys": "Stragedy", + "value": "A trading card game passed down through the generations. The magical cards are rare and have incredible value. Players use the cards to have friendly battles.", + "type": "item", + "title": "Stragedy Card Game", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Ace", + "value": "Sends all cards that have the number that this card is played on to the discard pile.", + "type": "item", + "title": "Stragedy Ace Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Jack", + "value": "Sends the targeted card back to the discard pile. The player can then draw a card from the discard pile and take another turn.", + "type": "item", + "title": "Stragedy Jack Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Queen", + "value": "Removes the value of the numbered card that this is played on and adds it to the opponent.", + "type": "item", + "title": "Stragedy Queen Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy King", + "value": "Doubles the value of the numbered card that this is played on both sides of the battlefield.", + "type": "item", + "title": "Stragedy King Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Joker", + "value": "Increases the total of the numbered card that this is placed on to get a score of 30. It cannot subtract points if you bust, however.", + "type": "item", + "title": "Stragedy Joker Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Witch", + "value": "Forces the opponent to play a card directly from their draw pile or a random one chosen from their hand. If it can't be played, they must discard their hand.", + "type": "item", + "title": "Stragedy Witch Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Priest", + "value": "Prevents the numbered card that this is played on from causing you to bust. It subtracts down to 30.", + "type": "item", + "title": "Stragedy Priest Card", + "description": "", + "useForCharacterCreation": false + }, + { + "keys": "Stragedy Brigand", + "value": "Your opponent must discard 5 cards from their draw pile.", + "type": "item", + "title": "Stragedy Brigand Card", + "description": "", + "useForCharacterCreation": false } ] \ No newline at end of file