From 5784b2328a3f6946c7dfa7919cef87bdaf1f87d9 Mon Sep 17 00:00:00 2001 From: raeleus Date: Sat, 12 Oct 2024 15:25:27 -0700 Subject: [PATCH] Added #setdamage and #setweaponproficiency. Also resolved crash when enemies cast spells and other tweaks. --- Input.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++--------- Output.js | 6 ++++ 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/Input.js b/Input.js index e25cf2f..60e846f 100644 --- a/Input.js +++ b/Input.js @@ -77,6 +77,8 @@ const turnSynonyms = ["turn", "doturn", "taketurn"] const fleeSynonyms = ["flee", "retreat", "runaway", "endcombat"] const versionSynonyms = ["version", "ver", "showversion"] const setupEnemySynonyms = ["setupenemy"] +const setDamageSynonyms = ["setdamage"] +const setProficiencySynonyms = ["setproficiency", "setweaponproficiency"] const helpSynonyms = ["help"] const modifier = (text) => { @@ -217,6 +219,8 @@ const modifier = (text) => { if (text == null) text = processCommandSynonyms(command, commandName, fleeSynonyms, doFlee) if (text == null) text = processCommandSynonyms(command, commandName, turnSynonyms, doTurn) if (text == null) text = processCommandSynonyms(command, commandName, setupEnemySynonyms, doSetupEnemy) + if (text == null) text = processCommandSynonyms(command, commandName, setDamageSynonyms, doSetDamage) + if (text == null) text = processCommandSynonyms(command, commandName, setProficiencySynonyms, doSetProficiency) if (text == null) text = processCommandSynonyms(command, commandName, helpSynonyms, doHelp) if (text == null) { var character = getCharacter() @@ -789,7 +793,9 @@ function init() { rangedStat: null, experience: 0, health: 10, - ac: 10 + ac: 10, + damage: "1d6", + proficiency: 2 } } @@ -810,6 +816,8 @@ function init() { state.characters.forEach(x => { if (x.ac == null) x.ac = 10 + if (x.damage == null) x.damage = "1d6" + if (x.proficiency == null) x.proficiency = 2 }) } @@ -855,6 +863,8 @@ function doCreate(command) { state.tempCharacter.meleeStat = "Strength" state.tempCharacter.rangedStat = "Dexterity" state.tempCharacter.ac = 10 + state.tempCharacter.damage = "1d6" + state.tempCharacter.proficiency = 2 state.show = "create" return " " @@ -1507,7 +1517,8 @@ function doAttack(command) { var modifier = 0 var stat = character.stats.find(x => x.name.toLowerCase() == statText.toLowerCase()) - if (stat != null) modifier = getModifier(stat.value) + modifier = character.proficiency + if (stat != null) modifier += getModifier(stat.value) var targetRoll = 15 if (/^\d+$/.test(difficultyText)) targetRoll = difficultyText @@ -1518,7 +1529,9 @@ function doAttack(command) { var enemyString if (state.initiativeOrder.length > 0) { - var damage = score == 20 ? calculateRoll("2d6") + calculateRoll("2d6") : calculateRoll("2d6") + var damage + if (/^\d*d\d+((\+|-)d+)?$/gi.test(character.damage)) damage = score == 20 ? calculateRoll(character.damage) + calculateRoll(character.damage) : calculateRoll(character.damage) + else damage = parseInt(character.damage) var damageMatches = targetText.match(/\d*d\d+((\+|-)d+)?/gi) if (damageMatches != null) damage = score == 20 ? calculateRoll(damageMatches[0]) + calculateRoll(damageMatches[0]) : calculateRoll(damageMatches[0]) @@ -1530,7 +1543,7 @@ function doAttack(command) { for (var enemy of state.enemies) { if (targetText.toLowerCase().includes(enemy.name.toLowerCase())) { if (usingDefaultDifficulty) targetRoll = enemy.ac - if (score + modifier >= targetRoll) { + if (score == 20 || score + modifier >= targetRoll) { if (score == 20) enemyString += ` Critical Damage: ${damage}` else enemyString += ` Damage: ${damage}` enemy.health = Math.max(0, enemy.health - damage) @@ -2064,7 +2077,7 @@ function doInitiative(command) { if (state.enemies.length == 0) { state.show = "none" - return "\n[Error: No enemies! Call #addenemy or #generateencounter]\n" + return "\n[Error: No enemies! Call #addenemy or #encounter]\n" } createInitiativeOrder() @@ -2168,13 +2181,12 @@ function doTurn(command) { if (hit) { var damage = isNaN(activeCharacter.damage) ? calculateRoll(activeCharacter.damage) : activeCharacter.damage target.health = Math.max(target.health - damage, 0) - text += `${activeCharacterName} attacks ${targetNameAdjustedCase} for ${damage} damage! \n` - - if (target.health == 0) text += `${toTitleCase(target.name)} ${areWord} unconscious!\n` - else text += `${toTitleCase(target.name)} ${areWord} at ${target.health} health.\n` + text += `${activeCharacterName} attacks ${targetNameAdjustedCase} for ${damage} damage!\n` + if (target.health == 0) text += ` ${toTitleCase(target.name)} ${areWord} unconscious! \n` + else text += ` ${toTitleCase(target.name)} ${areWord} at ${target.health} health.\n` } else text += `${activeCharacterName} attacks ${targetNameAdjustedCase} but misses!\n` } else { - var spell = activeCharacter.spells[getRandomInteger(0, activeCharacter.spells.length)] + var spell = activeCharacter.spells[getRandomInteger(0, activeCharacter.spells.length - 1)] var diceMatches = spell.match(/(?<=^.*)\d*d\d+((\+|-)\d+)?$/gi) if (diceMatches == null) text += `${activeCharacterName} casts spell ${spell}!` else { @@ -2185,9 +2197,9 @@ function doTurn(command) { text += `${activeCharacterName} casts spell ${spell} at ${targetNameAdjustedCase} for ${damage} damage!` - if (target.health == 0) text += `${toTitleCase(target.name)} ${areWord} unconscious!\n` - else text += `${toTitleCase(target.name)} ${areWord} at ${target.health} health.\n` - } else text += `${activeCharacterName} casts spell ${spell} at ${targetNameAdjustedCase} but misses!` + if (target.health == 0) text += ` ${toTitleCase(target.name)} ${areWord} unconscious!\n` + else text += ` ${toTitleCase(target.name)} ${areWord} at ${target.health} health.\n` + } else text += `${activeCharacterName} casts spell ${spell} at ${targetNameAdjustedCase} but misses!\n` } } return text @@ -2863,6 +2875,52 @@ function doVersion(command) { return `[${version}]` } +function doSetDamage(command) { + var character = getCharacter() + var arg0 = getArgument(command, 0) + if (arg0 == null) { + state.show = "none" + return "\n[Error: Not enough parameters. See #help]\n" + } + + if (/^\d*d\d+((\+|-)\d+)?$/gi.test(arg0)) { + character.damage = arg0 + } else if (!isNaN(arg0)) { + character.damage = parseInt(arg0) + } else { + state.show = "none" + return "\n[Error: Not a number. See #help]\n" + } + + var possessiveName = getPossessiveName(character.name) + + state.show = "none" + return `\n[${possessiveName} attack damage is set to ${character.damage}]\n` +} + +function doSetProficiency(command) { + var character = getCharacter() + var arg0 = getArgument(command, 0) + if (arg0 == null) { + state.show = "none" + return "\n[Error: Not enough parameters. See #help]\n" + } + + if (/^\d*d\d+((\+|-)\d+)?$/gi.test(arg0)) { + character.hitModifier = calculateRoll(arg0) + } else if (!isNaN(arg0)) { + character.hitModifier = parseInt(arg0) + } else { + state.show = "none" + return "\n[Error: Not a number. See #help]\n" + } + + var possessiveName = getPossessiveName(character.name) + + state.show = "none" + return `\n[${possessiveName} proficiency is set to ${character.hitModifier}]\n` +} + function doReset(command) { state.notes = [] state.characters = [] diff --git a/Output.js b/Output.js index 652b9fc..2ea03d0 100644 --- a/Output.js +++ b/Output.js @@ -86,6 +86,8 @@ const modifier = (text) => { text += `Class: ${character.className}\n` text += `Health: ${character.health}/${getHealthMax()}\n` text += `Armor Class: ${character.ac}\n` + text += `Damage: ${character.damage}\n` + text += `Weapon Proficiency: ${character.proficiency}\n` text += `Experience: ${character.experience}\n` text += `Level: ${getLevel(character.experience)}\n` var nextLevel = getNextLevelXp(character.experience) @@ -338,6 +340,10 @@ const modifier = (text) => { text += "\n Decreases the enemy's health by the specified damage or dice_roll. If an enemy isn't specified, the character calling the command is damaged. Reaching 0 causes the character to become \"unconscious\"." text += "\n#setac value" text += "\n Sets the armor class of the character. The default is 10" + text += "\n#setdamage value or dice_roll" + text += "\n Sets the default damage that the character causes when attacking. If a dice_roll is specified, a randomized damage will be calculated at the time of the attack. The default is 1d6" + text += "\n#setweaponproficiency value or dice_roll" + text += "\n Sets the weapon proficiency of the character which affects the chance to hit. If a dice_roll is specified, a randomized value is calculated. The default is 2" text += "\n#rest" text += "\n Sets all of the characters' health to their maximums. Use #shortrest to only restore half health. This command increases the day counter and displays the number of days since your adventure began." text += "\n#showday"