Added hit modifier to enemy attacks.

This commit is contained in:
raeleus 2024-10-11 00:08:04 -07:00
parent feccfa1557
commit 066aa5ba03
3 changed files with 275 additions and 245 deletions

113
Input.js
View file

@ -592,6 +592,12 @@ function handleSetupEnemyStep(text) {
}
return text
case 4:
if (!isNaN(text)) {
state.tempEnemy.hitModifier = Math.max(0, parseInt(text))
state.setupEnemyStep++
}
return text
case 5:
if (/^\d*d\d+((\+|-)\d+)?$/gi.test(text)) {
state.tempEnemy.damage = text
state.setupEnemyStep++
@ -600,7 +606,7 @@ function handleSetupEnemyStep(text) {
state.setupEnemyStep++
}
return text
case 5:
case 6:
if (/^\d*d\d+((\+|-)\d+)?$/gi.test(text)) {
state.tempEnemy.initiative = calculateRoll(text)
state.setupEnemyStep++
@ -609,7 +615,7 @@ function handleSetupEnemyStep(text) {
state.setupEnemyStep++
}
return text
case 6:
case 7:
if (text.toLowerCase() == "s") {
state.setupEnemyStep = 500
}
@ -618,7 +624,7 @@ function handleSetupEnemyStep(text) {
state.setupEnemyStep++
}
return text
case 7:
case 8:
if (text.toLowerCase() == "s") {
state.setupEnemyStep = 500
}
@ -632,79 +638,79 @@ function handleSetupEnemyStep(text) {
switch (parseInt(text)) {
case 1:
state.tempEnemy = createEnemy("Animated Armor", calculateRoll("6d8+6"), 18, "1d6+2", "d20")
state.tempEnemy = createEnemy("Animated Armor", calculateRoll("6d8+6"), 18, 6, "1d6+2", "d20")
break
case 2:
state.tempEnemy = createEnemy("Awakened Shrub", calculateRoll("2d+6"), 9, "1d4-1", "d20-1")
state.tempEnemy = createEnemy("Awakened Shrub", calculateRoll("2d+6"), 9, -3, "1d4-1", "d20-1")
break
case 3:
state.tempEnemy = createEnemy("Brigand", calculateRoll("5d8+10"), 11, "1d6+2", "d20")
state.tempEnemy = createEnemy("Brigand", calculateRoll("5d8+10"), 11, 6, "1d6+2", "d20")
break
case 4:
state.tempEnemy = createEnemy("Black Bear", calculateRoll("3d8+6"), 11, "2d4+2", "d20")
state.tempEnemy = createEnemy("Black Bear", calculateRoll("3d8+6"), 11, 6, "2d4+2", "d20")
break
case 5:
state.tempEnemy = createEnemy("Boar", calculateRoll("2d8+2"), 11, "1d6+1", "d20")
state.tempEnemy = createEnemy("Boar", calculateRoll("2d8+2"), 11, 4, "1d6+1", "d20")
break
case 6:
state.tempEnemy = createEnemy("Cockatrice", calculateRoll("6d6+6"), 11, "1d4+1", "d20+1", "Petrifying Bite1d4+1")
state.tempEnemy = createEnemy("Cockatrice", calculateRoll("6d6+6"), 11, 1, "1d4+1", "d20+1", "Petrifying Bite1d4+1")
break
case 7:
state.tempEnemy = createEnemy("Snake", calculateRoll("2d10+2"), 12, "1d8+2", "d20+2", "Poison Bite2d4+1")
state.tempEnemy = createEnemy("Snake", calculateRoll("2d10+2"), 12, 6, "1d8+2", "d20+2", "Poison Bite2d4+1")
break
case 8:
state.tempEnemy = createEnemy("Dire Wolf", calculateRoll("5d10+10"), 14, "2d6+3", "d20+2")
state.tempEnemy = createEnemy("Dire Wolf", calculateRoll("5d10+10"), 14, 8, "2d6+3", "d20+2")
break
case 9:
state.tempEnemy = createEnemy("Ghoul", calculateRoll("5d8"), 12, "2d6+2", "d20+2")
state.tempEnemy = createEnemy("Ghoul", calculateRoll("5d8"), 12, 3, "2d6+2", "d20+2")
break
case 10:
state.tempEnemy = createEnemy("Giant Centipede", calculateRoll("1d6+1"), 13, "1d4+2", "d20+2")
state.tempEnemy = createEnemy("Giant Centipede", calculateRoll("1d6+1"), 13, 1, "1d4+2", "d20+2")
break
case 11:
state.tempEnemy = createEnemy("Giant Rat", calculateRoll("2d6"), 12, "1d4+2", "d20+2")
state.tempEnemy = createEnemy("Giant Rat", calculateRoll("2d6"), 12, 2, "1d4+2", "d20+2")
break
case 12:
state.tempEnemy = createEnemy("Giant Wolf Spider", calculateRoll("2d8+2"), 13, "1d6+1", "d20+3", "Poison Bite1d6+8")
state.tempEnemy = createEnemy("Giant Wolf Spider", calculateRoll("2d8+2"), 13, 4, "1d6+1", "d20+3", "Poison Bite1d6+8")
break
case 13:
state.tempEnemy = createEnemy("Gnoll", calculateRoll("5d8"), 15, "1d8+2", "d20+1")
state.tempEnemy = createEnemy("Gnoll", calculateRoll("5d8"), 15, 6, "1d8+2", "d20+1")
break
case 14:
state.tempEnemy = createEnemy("Goblin", calculateRoll("2d6"), 15, "1d6+2", "d20+2")
state.tempEnemy = createEnemy("Goblin", calculateRoll("2d6"), 15, 3, "1d6+2", "d20+2")
break
case 15:
state.tempEnemy = createEnemy("Harpy", calculateRoll("7d8+7"), 11, "2d4+1", "d20+1", "Luring Song")
state.tempEnemy = createEnemy("Harpy", calculateRoll("7d8+7"), 11, 4, "2d4+1", "d20+1", "Luring Song")
break
case 16:
state.tempEnemy = createEnemy("Hobgoblin", calculateRoll("2d8+2"), 18, "1d8+1", "d20+1")
state.tempEnemy = createEnemy("Hobgoblin", calculateRoll("2d8+2"), 18, 4, "1d8+1", "d20+1")
break
case 17:
state.tempEnemy = createEnemy("Kobold", calculateRoll("2d6-2"), 12, "1d4+2", "d20+2")
state.tempEnemy = createEnemy("Kobold", calculateRoll("2d6-2"), 12, 2, "1d4+2", "d20+2")
break
case 18:
state.tempEnemy = createEnemy("Orc", calculateRoll("2d8+6"), 13, "1d12+3", "d20+1")
state.tempEnemy = createEnemy("Orc", calculateRoll("2d8+6"), 13, 8, "1d12+3", "d20+1")
break
case 19:
state.tempEnemy = createEnemy("Satyr", calculateRoll("5d8"), 15, "1d8+2", "d20+3")
state.tempEnemy = createEnemy("Satyr", calculateRoll("5d8"), 15, 4, "1d8+2", "d20+3")
break
case 20:
state.tempEnemy = createEnemy("Skeleton", calculateRoll("2d8+4"), 13, "1d6+2", "d20+2")
state.tempEnemy = createEnemy("Skeleton", calculateRoll("2d8+4"), 13, 5, "1d6+2", "d20+2")
break
case 21:
state.tempEnemy = createEnemy("Strige", calculateRoll("1d4"), 14, "1d4+3", "d20+1", "Blood Drain2d4+6")
state.tempEnemy = createEnemy("Stirge", calculateRoll("1d4"), 14, 2, "1d4+3", "d20+1", "Blood Drain2d4+6")
break
case 22:
state.tempEnemy = createEnemy("Warhorse", calculateRoll("3d10+3"), 11, "2d6+4", "d20+1", "Charge")
state.tempEnemy = createEnemy("Warhorse", calculateRoll("3d10+3"), 11, 10, "2d6+4", "d20+1", "Charge")
break
case 23:
state.tempEnemy = createEnemy("Wolf", calculateRoll("2d+2"), 13, "2d4+2", "d20+2")
state.tempEnemy = createEnemy("Wolf", calculateRoll("2d+2"), 13, 6, "2d4+2", "d20+2")
break
case 24:
state.tempEnemy = createEnemy("Worg", calculateRoll("4d10+4"), 13, "2d6+3", "d20+1")
state.tempEnemy = createEnemy("Worg", calculateRoll("4d10+4"), 13, 8, "2d6+3", "d20+1")
break
case 25:
state.tempEnemy = createEnemy("Zombie", calculateRoll("3d8+9"), 8, "1d6+1", "d20-2")
state.tempEnemy = createEnemy("Zombie", calculateRoll("3d8+9"), 8, 4, "1d6+1", "d20-2")
break
}
}
@ -713,7 +719,7 @@ function handleSetupEnemyStep(text) {
state.show = null
state.setupEnemyStep = null
var enemy = createEnemy(state.tempEnemy.name, state.tempEnemy.health, state.tempEnemy.ac, state.tempEnemy.damage, state.tempEnemy.initiative)
var enemy = createEnemy(state.tempEnemy.name, state.tempEnemy.health, state.tempEnemy.ac, state.tempEnemy.hitModifier, state.tempEnemy.damage, state.tempEnemy.initiative)
enemy.spells = [...state.tempEnemy.spells]
var enemyMatches = state.enemies.filter(x => x.name.toLowerCase() == enemy.name.toLowerCase() || x.name.toLowerCase() == `${enemy.name.toLowerCase()} a`)
@ -851,7 +857,7 @@ function doCreate(command) {
function doSetupEnemy(command) {
state.setupEnemyStep = 0
state.tempEnemy = createEnemy("enemy", 20, 10, "2d6", 10)
state.tempEnemy = createEnemy("enemy", 20, 10, 0, "2d6", 10)
state.show = "setupEnemy"
return " "
}
@ -1972,7 +1978,16 @@ function doAddEnemy(command) {
}
ac = parseInt(ac)
var damage = getArgument(command, 3)
var hitModifier = getArgument(command, 3)
if (hitModifier == null) {
state.show = "none"
return "\n[Error: Not enough parameters. See #help]\n"
} else if (isNaN(hitModifier)) {
state.show = "none"
return "\n[Error: Expected a number. See #help]\n"
}
var damage = getArgument(command, 4)
if (damage == null) {
state.show = "none"
return "\n[Error: Not enough parameters. See #help]\n"
@ -1981,7 +1996,7 @@ function doAddEnemy(command) {
return "\n[Error: Expected a number. See #help]\n"
}
var initiative = getArgument(command, 4)
var initiative = getArgument(command, 5)
if (initiative == null) {
state.show = "none"
return "\n[Error: Not enough parameters. See #help]\n"
@ -1995,13 +2010,13 @@ function doAddEnemy(command) {
var spells = []
var spell = null
var index = 5
var index = 6
do {
spell = getArgument(command, index++)
if (spell != null) spells.push(spell)
} while (spell != null)
var enemy = createEnemy(name, health, ac, damage, initiative)
var enemy = createEnemy(name, health, ac, hitModifier, damage, initiative)
enemy.spells = spells
var enemyMatches = state.enemies.filter(x => x.name.toLowerCase() == enemy.name.toLowerCase() || x.name.toLowerCase() == `${enemy.name.toLowerCase()} a`)
@ -2129,27 +2144,33 @@ function doTurn(command) {
var target = characters[getRandomInteger(0, characters.length - 1)]
var areWord = target.name == "You" ? "are" : "is"
var targetNameAdjustedCase = target.name == "You" ? "you" : toTitleCase(target.name)
var hit = calculateRoll(`1d20${activeCharacter.hitModifier > 0 ? "+" + activeCharacter.hitModifier : activeCharacter.hitModifier < 0 ? activeCharacter.hitModifier : ""}`) >= target.ac
var text = `\n[It is ${possessiveName} turn.]\n`
if (getRandomBoolean() || activeCharacter.spells.length == 0) {
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 += `${target.name} ${areWord} unconscious!\n`
else text += `${target.name} ${areWord} at ${target.health} health.\n`
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`
} else text += `${activeCharacterName} attacks ${targetNameAdjustedCase} but misses!\n`
} else {
var spell = activeCharacter.spells[getRandomInteger(0, activeCharacter.spells.length)]
var diceMatches = spell.match(/(?<=^.*)\d*d\d+((\+|-)\d+)?$/gi)
if (diceMatches == null) text += `${activeCharacterName} casts spell ${spell}!`
else {
var damage = calculateRoll(diceMatches[0])
var spell = spell.substring(0, spell.length - diceMatches[0].length)
target.health = Math.max(target.health - damage, 0)
if (hit) {
var damage = calculateRoll(diceMatches[0])
var spell = spell.substring(0, spell.length - diceMatches[0].length)
target.health = Math.max(target.health - damage, 0)
text += `${activeCharacterName} casts spell ${spell} at ${targetNameAdjustedCase} for ${damage} damage!`
if (target.health == 0) text += `${target.name} ${areWord} unconscious!\n`
else text += `${target.name} ${areWord} at ${target.health} health.\n`
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!`
}
}
return text