Transaction

8e5d26176cc5ce4f2734e2fb8abb6da01237f5c1736839adf8a82659ecbe85d6
( - )
204,743
2021-01-13 05:36:11
1
33,690 B

3 Outputs

Total Output:
  • jrun cryptofightsM•‚{"in":0,"ref":["0e660dbbccc19c47e388dbd07832821da0083f020eced33c3f49d195df5427bc_o1","be7daf36641ba33aad8f42e02adbbcb48fb88cc0c6ac6b56f4c85369dcd2dfa1_o1","507b9cffbeb94c2386e054f3d63617f7b091e0bdb1619a99c3cd04e309be45f3_o1","589e107231b17445bc648ace9e1a852d201409a3ed42280c3f5ff4033c1a28ac_o1","f97d4ac2a3d6f5ed09fad4a4f341619dc5a3773d9844ff95c99c5d4f8388de2f_o1"],"out":["71d232a6f89a99aca5a36099074b587e5d7f2be4c4d748c02af4ff416b85a565"],"del":[],"cre":["n2Bd4cWhEQK1aVjb1R7EBGV9mrw3etvSdC"],"exec":[{"op":"DEPLOY","data":["class BattleUtils extends KronoClass {\n static isUnderStatusEffect(fighterState, statusEffect, round) {\n return fighterState.statusEffectsRound[statusEffect] > round;\n }\n\n static validateRandom(random, prevRandom) {\n let hashBytes = new Uint8Array(32);\n for (let i = 0; i < 64; i += 2) {\n hashBytes[i / 2] = parseInt(random.slice(i, i + 2), 16);\n }\n return Sha256.hashToHex(hashBytes) === prevRandom;\n }\n\n static rollDmgDice(ability, diceCount, diceFaces, dice, rolls, type) {\n let damage = 0;\n for (var i = 0; i < diceCount; ++i) {\n let toDamageNativeRoll = diceFaces === 0 ? 0 : dice.roll(1, diceFaces);\n rolls.push({\n type: type,\n ability: ability,\n size: diceFaces,\n value: toDamageNativeRoll\n });\n damage += toDamageNativeRoll;\n }\n return damage;\n }\n\n static max(arr) {\n var highest = Number.NEGATIVE_INFINITY;\n var tmp;\n for (var i = arr.length - 1; i >= 0; i--) {\n tmp = arr[i];\n if (tmp > highest) highest = tmp;\n }\n return highest;\n }\n\n static min(arr) {\n var lowest = Number.POSITIVE_INFINITY;\n var tmp;\n for (var i = arr.length - 1; i >= 0; i--) {\n tmp = arr[i];\n if (tmp < lowest) lowest = tmp;\n }\n return lowest;\n }\n\n static applyStatusEffect(actionLog, battle, state, statusEffect, increment, applyToAttacker = true) {\n if (applyToAttacker) {\n state.fighterStates[state.playerToAct].statusEffectsRound[statusEffect] = state.fighterStates[state.playerToAct].turnCounter + increment + 1;\n if (!actionLog.results[actionLog.results.length - 1].attackerStatusEffectsIncrement) {\n actionLog.results[actionLog.results.length - 1].attackerStatusEffectsIncrement = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n actionLog.results[actionLog.results.length - 1].attackerStatusEffectsIncrement[statusEffect] = increment;\n actionLog.actionLogMessage += BattleUtils.getPrettifiedPlayerName(battle, state, !applyToAttacker);\n } else {\n state.fighterStates[state.playerToAct ? 0 : 1].statusEffectsRound[statusEffect] = state.fighterStates[state.playerToAct ? 0 : 1].turnCounter + increment;\n if (!actionLog.results[actionLog.results.length - 1].defenderStatusEffectsIncrement) {\n actionLog.results[actionLog.results.length - 1].defenderStatusEffectsIncrement = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n actionLog.results[actionLog.results.length - 1].defenderStatusEffectsIncrement[statusEffect] = increment;\n actionLog.actionLogMessage += BattleUtils.getOpponentName(battle, state, applyToAttacker);\n }\n\n if(increment > 90){\n actionLog.actionLogMessage += `<gradient=!status-effect><i> is ${BattleUtils.parseStatusEffect(statusEffect)}\\n`;\n }else{\n actionLog.actionLogMessage += `<gradient=!status-effect><i> is ${BattleUtils.parseStatusEffect(statusEffect)} for ${increment} turns</i>\\n`;\n }\n }\n\n static makeStatusEffectActionLog(battle, state, skill, statusEffect, increment, log, applyToAttacker = true) {\n let attackerState = state.fighterStates[state.playerToAct];\n let defenderState = state.fighterStates[state.playerToAct ? 0 : 1];\n\n let actionLog = {\n playerIndex: state.playerToAct,\n skillType: skill,\n results: [{\n rolls: [],\n outcome: Constants.Outcome.Success,\n damageOutput: [{\n damage: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderHp: defenderState.hp,\n defenderReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n }],\n hpIncrement: 0,\n attackerHp: attackerState.hp\n }],\n actionLogMessage: log\n };\n\n this.applyStatusEffect(actionLog, battle, state, statusEffect, increment, applyToAttacker);\n\n return actionLog;\n }\n\n static abilityCheckAndApplyStatusEffect(battle, state, dice, skill, attackerAbility, defenderAbility, statusEffect, duration, applyToAttacker, log) {\n const attackerState = state.fighterStates[state.playerToAct];\n const defenderState = state.fighterStates[state.playerToAct ? 0 : 1];\n var playerName = BattleUtils.getPrettifiedPlayerName(battle, state);\n\n // Rolls\n let nativeRoll = dice.roll(1, 20);\n let rolls = [];\n rolls.push({\n type: defenderAbility,\n ability: attackerAbility,\n size: 20,\n value: nativeRoll\n });\n\n // Check\n const defenderDC = 10 + defenderState.modifiers[defenderAbility];\n const attackerMod = attackerState.modifiers[attackerAbility];\n const outcome = nativeRoll + attackerMod >= defenderDC ?\n Constants.Outcome.Success : \n Constants.Outcome.Fail;\n\n log += `${playerName} <gradient=!log-color>attempts to ${BattleUtils.parseSkillName(skill)} : *${BattleUtils.parseSkillOutcome(outcome)}* : (${nativeRoll} + ${attackerMod} vs ${defenderDC} DC)\\n`;\n\n // Success\n if (outcome === Constants.Outcome.Success) {\n var al = BattleUtils.makeStatusEffectActionLog(battle, state, skill, statusEffect, duration, log, applyToAttacker);\n al.results[0].rolls = rolls;\n al.results[0].outcome = outcome;\n return al;\n }\n\n // Failure\n return {\n playerIndex: state.playerToAct,\n skillType: skill,\n results: [{\n rolls: rolls,\n outcome: outcome,\n damageOutput: [{\n damage: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderHp: defenderState.hp,\n defenderReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n }],\n attackerStatusEffectsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n hpIncrement: 0,\n attackerHp: attackerState.hp\n }],\n actionLogMessage: log\n };\n }\n\n static parseAbility(ability) {\n return ability === 0 ? 'Strength' : (ability === 1 ? 'Dexterity' : 'Intelligence');\n }\n\n static parseAttackOutcome(outcome) {\n return outcome === 0 ? 'Miss' : (outcome === 1 ? 'Hit' : 'Critical');\n }\n\n static parseSkillOutcome(outcome) {\n return outcome === 0 ? 'Fail' : (outcome === 1 ? 'Success' : 'Critical');\n }\n\n static getPrettifiedName(battle, playerIndex) {\n return `<gradient=!player${playerIndex}-color><b>${battle.battlePlayers[playerIndex].fighter.displayName.toUpperCase()}</b><gradient=!log-color>`;\n }\n\n static getPrettifiedPlayerName(battle, state, switchAttacker = false) {\n let attackerIndex = switchAttacker ? (state.playerToAct ? 0 : 1) : state.playerToAct;\n return this.getPrettifiedName(battle, attackerIndex);\n }\n\n static getOpponentName(battle, state, switchAttacker = false) {\n let attackerIndex = switchAttacker ? state.playerToAct : (!state.playerToAct ? 1 : 0);\n return this.getPrettifiedName(battle, attackerIndex);\n }\n\n static parseSkillName(skill) {\n switch (skill) {\n case Constants.SkillType.Attack:\n return 'Attack';\n case Constants.SkillType.BattleCry:\n return 'Battle Cry';\n case Constants.SkillType.Burn:\n return 'Burn';\n case Constants.SkillType.Chill:\n return 'Chill';\n case Constants.SkillType.Cleanse:\n return 'Cleanse';\n case Constants.SkillType.CoatWeapon:\n return 'Coat Weapon';\n case Constants.SkillType.Curse:\n return 'Curse';\n case Constants.SkillType.DirtyFighting:\n return 'Dirty Fighting';\n case Constants.SkillType.Fireball:\n return 'Fireball';\n case Constants.SkillType.Focus:\n return 'Focus';\n case Constants.SkillType.Freeze:\n return 'Freeze';\n case Constants.SkillType.Gore:\n return 'Gore';\n case Constants.SkillType.Heal:\n return 'Heal';\n case Constants.SkillType.Hex:\n return 'Hex';\n case Constants.SkillType.Hide:\n return 'Hide';\n case Constants.SkillType.LightningBolt:\n return 'Lightning Bolt';\n case Constants.SkillType.LockAndLoad:\n return 'Lock And Load';\n case Constants.SkillType.Mark:\n return 'Mark';\n case Constants.SkillType.Meditate:\n return 'Meditate';\n case Constants.SkillType.PhaseShift:\n return 'Phase Shift';\n case Constants.SkillType.PinningStrike:\n return 'Pinning Strike';\n case Constants.SkillType.PowerAttack:\n return 'Power Attack';\n case Constants.SkillType.SecondWind:\n return 'Second Wind';\n case Constants.SkillType.Shock:\n return 'Shock';\n case Constants.SkillType.Smite:\n return 'Smite';\n case Constants.SkillType.SneakAttack:\n return 'Sneak Attack';\n case Constants.SkillType.Stun:\n return 'Stun';\n case Constants.SkillType.Taunt:\n return 'Taunt';\n }\n }\n\n static parseStatusEffect(statusEffect) {\n switch (statusEffect) {\n case Constants.StatusEffect.Cursed:\n return 'cursed';\n case Constants.StatusEffect.Ethereal:\n return 'ethereal';\n case Constants.StatusEffect.Focused:\n return 'focused';\n case Constants.StatusEffect.Hexed:\n return 'hexed';\n case Constants.StatusEffect.Hidden:\n return 'hidden';\n case Constants.StatusEffect.Inspired:\n return 'inspired';\n case Constants.StatusEffect.Marked:\n return 'marked';\n case Constants.StatusEffect.Meditative:\n return 'meditative';\n case Constants.StatusEffect.Poisoned:\n return 'poisoned';\n case Constants.StatusEffect.Slowed:\n return 'slowed';\n case Constants.StatusEffect.Stunned:\n return 'stunned';\n case Constants.StatusEffect.Taunted:\n return 'taunted';\n case Constants.StatusEffect.Poisonous:\n return 'poisonous';\n case Constants.StatusEffect.Demoralized:\n return 'demoralized';\n }\n }\n\n static getItemResistance(item, defenderResistance) {\n if (item) {\n for (var j = 0; j < 10; j++) {\n if (item.damageReduction[j]) {\n defenderResistance[j] += item.damageReduction[j];\n }\n }\n }\n }\n\n // Compute resistance according to items\n static getDefenderResistance(player) {\n var defenderResistance = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n this.getItemResistance(player.mainhand, defenderResistance);\n this.getItemResistance(player.offhand, defenderResistance);\n this.getItemResistance(player.armor, defenderResistance);\n\n if (player.fighter.skills.includes(Constants.SkillType.Armored)) {\n if (player.fighter.skills.includes(Constants.SkillType.ImprovedArmored)) {\n for (var i = 0; i < 10; i++) {\n defenderResistance[i] += 1;\n }\n }else{\n defenderResistance[Constants.DamageType.Slashing] += 1;\n defenderResistance[Constants.DamageType.Piercing] += 1;\n defenderResistance[Constants.DamageType.Bludgeoning] += 1;\n }\n }\n\n if (player.fighter.skills.includes(Constants.SkillType.Dwarven)) {\n defenderResistance[Constants.DamageType.Slashing] += 1;\n defenderResistance[Constants.DamageType.Piercing] += 1;\n defenderResistance[Constants.DamageType.Bludgeoning] += 1;\n // for (var j = 0; j < defenderResistance.length; j++) {\n // defenderResistance[j] += 1;\n // }\n }\n\n return defenderResistance;\n }\n\n static buildBattleState(players, dice) {\n const diceRolls = players.map(() => dice.roll(1, 20));\n const fighterStates = players.map((player, i) => {\n const fighterState = this.buildFighterState(player);\n fighterState.initiative = fighterState.modifiers[Constants.Ability.Dexterity] +\n diceRolls[i];\n if (player.fighter.skills.includes(Constants.SkillType.Elven)) {\n fighterState.initiative += 10;\n }\n fighterState.turnCounter = 0;\n return fighterState;\n });\n\n let logMessage = '';\n let playerToAct;\n if (fighterStates[0].initiative === fighterStates[1].initiative) {\n if (fighterStates[0].modifiers[Constants.Ability.Dexterity] === fighterStates[1].modifiers[Constants.Ability.Dexterity]) {\n logMessage += '\\n<gradient=!log-color>It\\'s a tie, tossing a coin';\n playerToAct = dice.roll(1, 2) - 1;\n } else {\n playerToAct = fighterStates[0].modifiers[Constants.Ability.Dexterity] > fighterStates[1].modifiers[Constants.Ability.Dexterity] ? 0 : 1;\n logMessage += `\\n<gradient=!player${playerToAct}-color><b>${players[playerToAct].fighter.displayName.toUpperCase()}</b> <gradient=!log-color>has higher dexterity`;\n }\n } else {\n playerToAct = fighterStates[0].initiative > fighterStates[1].initiative ? 0 : 1;\n }\n\n const actionLogs = fighterStates.map((fighterState, i) => {\n return {\n playerIndex: i,\n skillType: Constants.SkillType.Focus,\n results: [{\n rolls: [{\n type: Constants.RollType.Initiative,\n ability: Constants.Ability.Dexterity,\n size: 20,\n value: diceRolls[i],\n discarded: false,\n bonusFromAbility: fighterState.modifiers[Constants.Ability.Dexterity],\n bonusFromSkill: 0,\n totalBonus: fighterState.modifiers[Constants.Ability.Dexterity]\n }],\n outcome: playerToAct === i ?\n Constants.Outcome.Success :\n Constants.Outcome.Fail,\n damageOutput: [{\n damage: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderHp: fighterStates[i ? 0 : 1].maxHP,\n defenderReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n }],\n attackerStatusEffectsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderStatusEffectsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n hpIncrement: 0,\n attackerHp: fighterState.maxHP\n }],\n actionLogMessage: `<gradient=!player${i}-color><b>${players[i].fighter.displayName.toUpperCase()}</b> <gradient=!log-color>attempts Initiative: ${diceRolls[i] + fighterState.modifiers[Constants.Ability.Dexterity]}` + (players[i].fighter.skills.includes(Constants.SkillType.Elven) ? ' + 10' : '')\n };\n });\n logMessage += `\\n<gradient=!player${playerToAct}-color><b>${players[playerToAct].fighter.displayName.toUpperCase()}</b> <gradient=!log-color>won Initiative`;\n actionLogs[playerToAct ? 0 : 1].actionLogMessage += logMessage;\n return {\n status: Constants.Status.Open,\n fighterStates,\n playerToAct,\n actionLogs\n };\n }\n\n static buildFighterState(battlePlayer) {\n const fighter = battlePlayer.fighter;\n\n // Construct fighter states\n const items = [battlePlayer.mainhand, battlePlayer.offhand, battlePlayer.armor];\n const derivedStats = BattleUtils.getDerivedStats(fighter,items);\n const fighterModifiers = derivedStats.modifiers;\n\n const hpIncrement = derivedStats.hpIncrement + fighter.hpBonus;\n\n // Create fighter state\n const fighterState = {\n abilityScoreBonuses: derivedStats.abilityScoreBonuses,\n abilityScores: derivedStats.abilityScores,\n modifiers: fighterModifiers,\n evasion: derivedStats.evasion,\n hp: fighterModifiers[Constants.Ability.Strength] + 10 + hpIncrement,\n maxHP: fighterModifiers[Constants.Ability.Strength] + 10 + hpIncrement,\n critChance: derivedStats.critChance,\n statusEffectsRound: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n areLoaded: [false, false, false],\n validActions: BattleUtils.getValidActions(battlePlayer.skills, false, true, battlePlayer.mainhand)\n };\n return fighterState;\n }\n\n // Derived unmutable stats (HP and MaxHP are mutable)\n static getDerivedStats(fighter, items) {\n let abilityScores = KronoClass.deepClone(fighter.abilityScores);\n let abilityScoreBonuses = [0, 0, 0];\n for(var i = 0; i<items.length; i++){\n const item = items[i]; \n if(item){\n abilityScores[Constants.Ability.Strength] += item.bonuses[Constants.Bonus.Strength];\n abilityScoreBonuses[Constants.Ability.Strength] += item.bonuses[Constants.Bonus.Strength];\n abilityScores[Constants.Ability.Dexterity] += item.bonuses[Constants.Bonus.Dexterity];\n abilityScoreBonuses[Constants.Ability.Dexterity] += item.bonuses[Constants.Bonus.Dexterity];\n abilityScores[Constants.Ability.Intelligence] += item.bonuses[Constants.Bonus.Intelligence];\n abilityScoreBonuses[Constants.Ability.Intelligence] += item.bonuses[Constants.Bonus.Intelligence];\n }\n }\n\n let modifiers = BattleUtils.getModifiers(abilityScores);\n let evasion = modifiers[Constants.Ability.Dexterity] + 10;\n let critChance = 1;\n let hpIncrement = fighter.skills.includes(Constants.SkillType.Durable) ? (fighter.level * 2) : 0;\n\n if (fighter.skills.includes(Constants.SkillType.Elven)) {\n evasion += 1;\n }\n\n if (fighter.skills.includes(Constants.SkillType.Slippery)) {\n evasion += 2;\n }\n\n if (fighter.skills.includes(Constants.SkillType.Cirurgical)) {\n critChance += 1;\n }\n\n if (fighter.skills.includes(Constants.SkillType.Strong)){\n modifiers[Constants.Ability.Strength] += 1;\n }\n\n return {\n abilityScoreBonuses: abilityScoreBonuses,\n abilityScores: abilityScores,\n modifiers: modifiers,\n evasion: evasion,\n critChance: critChance,\n hpIncrement: hpIncrement\n };\n }\n\n static getModifiers(abilityScores) {\n return [\n parseInt((abilityScores[Constants.Ability.Strength] - 10) / 2),\n parseInt((abilityScores[Constants.Ability.Dexterity] - 10) / 2),\n parseInt((abilityScores[Constants.Ability.Intelligence] - 10) / 2)\n ];\n }\n\n static getValidActions(skills = [], isTaunted, isHidden, mainhand) {\n return skills.map(skill => {\n return skill &&\n (!isTaunted || skill.isAttackAction) &&\n (skill.skillType !== Constants.SkillType.SneakAttack || isHidden) &&\n (skill.skillType !== Constants.SkillType.LockAndLoad || (mainhand != null && mainhand.properties.length > Constants.ItemProperty.Loading && mainhand.properties[Constants.ItemProperty.Loading])) &&\n (skill.skillType !== Constants.SkillType.Stun || (mainhand != null && mainhand.properties.length > Constants.ItemProperty.Brutal && mainhand.properties[Constants.ItemProperty.Brutal]))/* &&\n ((mainhand == null || mainhand.type == Constants.ItemType.Wizardstaff) && !skill.isAttackAction)*/;\n });\n }\n\n static computeFighterStates(battle, state) {\n var fighterStates = state.fighterStates;\n\n for (var i = 0; i < 2; i++) {\n // initialize mutable derived stats\n const items = [battle.battlePlayers[i].mainhand, battle.battlePlayers[i].offhand, battle.battlePlayers[i].armor];\n var derivedStats = BattleUtils.getDerivedStats(battle.battlePlayers[i].fighter, items);\n fighterStates[i].abilityScoreBonuses = derivedStats.abilityScoreBonuses;\n fighterStates[i].abilityScores = derivedStats.abilityScores;\n fighterStates[i].modifiers = derivedStats.modifiers;\n fighterStates[i].evasion = derivedStats.evasion;\n fighterStates[i].initiative = derivedStats.initiative;\n fighterStates[i].critChance = derivedStats.critChance;\n\n // offset modifiers and derived stats according to status effects\n if (BattleUtils.isUnderStatusEffect(fighterStates[i], Constants.StatusEffect.Hexed, fighterStates[i].turnCounter)) {\n fighterStates[i].modifiers[Constants.Ability.Dexterity] -= fighterStates[i].modifiers[Constants.Ability.Intelligence];\n }\n\n if (BattleUtils.isUnderStatusEffect(fighterStates[i], Constants.StatusEffect.Focused, fighterStates[i].turnCounter)) {\n fighterStates[i].modifiers[Constants.Ability.Intelligence] += fighterStates[i].modifiers[Constants.Ability.Intelligence];\n }\n\n fighterStates[i].validActions = BattleUtils.getValidActions(\n battle.battlePlayers[i].skills, \n BattleUtils.isUnderStatusEffect(fighterStates[i], Constants.StatusEffect.Taunted, fighterStates[i].turnCounter), \n BattleUtils.isUnderStatusEffect(fighterStates[i], Constants.StatusEffect.Hidden, fighterStates[i].turnCounter), \n battle.battlePlayers[i].mainhand\n );\n fighterStates[i].evasion = BattleUtils.isUnderStatusEffect(fighterStates[i], Constants.StatusEffect.Ethereal, fighterStates[i].turnCounter) ? \n fighterStates[i].evasion + fighterStates[i].modifiers[Constants.Ability.Intelligence] : \n fighterStates[i].evasion;\n }\n\n return fighterStates;\n }\n\n static skipTurn(battle, state, dice) {\n const defenderState = state.fighterStates[state.playerToAct ? 0 : 1];\n const attackerState = state.fighterStates[state.playerToAct];\n var actionLog = {\n playerIndex: state.playerToAct,\n actionLogMessage: `${this.getPrettifiedPlayerName(battle, state, false)} skipped turn`,\n results: [{\n rolls: [],\n outcome: Constants.Outcome.Success,\n damageOutput: [\n {\n damage: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderHp: defenderState.hp,\n defenderReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n }\n ],\n effectDurationsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n hpIncrement: 0,\n attackerHp: attackerState.hp\n }]\n };\n state.actionLogs.push(actionLog);\n\n return this.endTurn(battle, state, dice);\n }\n\n static endTurn(battle, state, dice) {\n var attackerIndex = state.playerToAct;\n var defenderIndex = state.playerToAct ? 0 : 1;\n\n if (state.fighterStates[0].hp > 0 && state.fighterStates[1].hp > 0) {\n if ( BattleUtils.isUnderStatusEffect(state.fighterStates[attackerIndex], Constants.StatusEffect.Cursed, state.fighterStates[attackerIndex].turnCounter)) {\n if (state.actionLogs[state.actionLogs.length - 1].skillType === Constants.SkillType.Vengeful) {\n let vengefulLog = `${this.getPrettifiedPlayerName(battle, state, true)} is vengeful\\n`;\n state.actionLogs.push(this.makeDamageActionLog(\n battle, \n state, \n state.fighterStates[attackerIndex], \n battle.battlePlayers[attackerIndex], 1, \n Constants.DamageType.Necrotic, \n [], \n Constants.Outcome.Success, \n Constants.SkillType.Vengeful, \n vengefulLog, \n '', \n true\n ));\n } else {\n state.actionLogs.push(this.makeDamageActionLog(\n battle, \n state, \n state.fighterStates[attackerIndex], \n battle.battlePlayers[attackerIndex], \n 1, \n Constants.DamageType.Necrotic, \n [], \n Constants.Outcome.Success, \n Constants.SkillType.Curse, \n '', \n '', \n true\n ));\n }\n }\n if ( BattleUtils.isUnderStatusEffect(\n state.fighterStates[attackerIndex], \n Constants.StatusEffect.Poisoned, \n state.fighterStates[attackerIndex].turnCounter)\n ) {\n var damage = dice.roll(1, 4);\n var roll = [{\n type: Constants.RollType.ToDamage,\n ability: Constants.Ability.Dexterity,\n size: 4,\n value: damage\n }];\n state.actionLogs.push(this.makeDamageActionLog(battle, state, state.fighterStates[attackerIndex], battle.battlePlayers[attackerIndex], damage, Constants.DamageType.Poison, roll, Constants.Outcome.Success, Constants.SkillType.CoatWeapon, '', '', true));\n }\n\n let fatigueThreshold = 7; // TODO: I'd like this to be a global const, but not quite sure how to do that right now\n if (state.fighterStates[attackerIndex].turnCounter > fatigueThreshold) {\n let fatigueLog = `${this.getPrettifiedPlayerName(battle, state)} is fatigued\\n`;\n state.actionLogs.push(this.makeDamageActionLog(\n battle, \n state, \n state.fighterStates[attackerIndex], \n battle.battlePlayers[attackerIndex], \n state.fighterStates[attackerIndex].turnCounter - fatigueThreshold, \n Constants.DamageType.Necrotic, \n [], \n Constants.Outcome.Success, \n Constants.SkillType.Curse, \n fatigueLog, \n '', \n true\n ));\n }\n\n if (BattleUtils.isUnderStatusEffect(state.fighterStates[defenderIndex], Constants.StatusEffect.Stunned, battle.turnCount)) {\n state.fighterStates[defenderIndex].turnCounter++;\n }else{\n state.playerToAct = (state.playerToAct + 1) % 2;\n }\n \n }\n \n if (state.fighterStates[0].hp <= 0 || state.fighterStates[1].hp <= 0) {\n const victorIndex = state.fighterStates.findIndex(fs => fs.hp > 0);\n var switchAttacker = victorIndex != attackerIndex;\n\n var results = state.actionLogs[state.actionLogs.length - 1].results;\n results[results.length - 1].resultMessage += `${this.getPrettifiedPlayerName(battle, state, switchAttacker)} won`;\n\n state.playerToAct = victorIndex;\n state.victor = {\n pubkey: battle.battlePlayers[victorIndex].pubkey,\n owner: battle.battlePlayers[victorIndex].owner,\n fighter: battle.battlePlayers[victorIndex].fighter,\n };\n state.status = Constants.Status.Complete;\n }\n\n state.fighterStates = BattleUtils.computeFighterStates(battle, state);\n state.fighterStates[attackerIndex].turnCounter++;\n\n return state;\n }\n\n static makeDamageActionLog(battle, state, defenderState, defenderPlayer, damage, damageType, rolls, outcome, skillType, log, preResultDescription, damageSelf = false) {\n return {\n playerIndex: state.playerToAct,\n skillType: skillType,\n results: [this.makeDamageResult(battle, state, defenderState, defenderPlayer, damage, damageType, rolls, outcome, preResultDescription, damageSelf)],\n actionLogMessage: log\n };\n }\n\n static makeDamageResult(battle, state, damageeState, damageePlayer, damage, damageType, rolls, outcome, preResultDescription, damageSelf = false) {\n expect(Constants.DamageTypeNames[damageType]).toBeDefined(`Unknown damage type ${damageType} in ${Constants.DamageTypeNames}`);\n\n var playerName = BattleUtils.getPrettifiedPlayerName(battle, state);\n var opponentName = BattleUtils.getOpponentName(battle, state);\n\n let damageMap = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n damageMap[damageType] = damage;\n\n let defenderReduction = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n let resistance = this.getDefenderResistance(damageePlayer)[damageType];\n let inflictedDamage = damage - resistance;\n inflictedDamage = (inflictedDamage < 0) ? 0 : inflictedDamage;\n defenderReduction[damageType] = damage - inflictedDamage;\n damageeState.hp -= inflictedDamage;\n expect(inflictedDamage).toBeInteger(`${playerName} inflicted unknown damage`);\n\n\n let resultMessage = `${playerName} damages ${opponentName} : ${inflictedDamage} (${damage} ${Constants.DamageTypeNames[damageType]}${resistance > 0 ? ` - ${resistance} Resist` : ''})\\n`;\n if(damageSelf){\n resultMessage = `${playerName} takes damage : ${inflictedDamage} (${damage} ${Constants.DamageTypeNames[damageType]}${resistance > 0 ? ` - ${resistance} Resist` : ''})\\n`;\n }\n\n return {\n rolls: rolls,\n outcome: outcome,\n damageOutput: [{\n damage: damageMap,\n defenderHp: damageSelf ? state.fighterStates[state.playerToAct ? 0 : 1].hp : this.max([damageeState.hp, 0]),\n defenderReduction: defenderReduction\n }],\n attackerStatusEffectsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n hpIncrement: 0,\n attackerHp: damageSelf ? damageeState.hp : state.fighterStates[state.playerToAct].hp,\n preResultDescription: preResultDescription,\n resultMessage: resultMessage\n };\n }\n\n\n static directDamage(battle, state, dice, diceCount, diceFaces, defenderState, defenderPlayer, damageType, skill, log) {\n\n let rolls = [];\n let nativeRoll = diceFaces > 0 ? dice.roll(diceCount, diceFaces) : 0;\n rolls.push({\n type: 5,\n ability: Constants.Ability.Strength,\n size: diceFaces,\n value: nativeRoll\n });\n\n return this.makeDamageActionLog(battle, state, defenderState, defenderPlayer, nativeRoll, damageType, rolls, Constants.Outcome.Success, skill, log);\n }\n\n static append(dest, src) {\n for (var i = 0; i < src.length; i++) {\n dest.push(src[i]);\n }\n return dest;\n }\n\n static getDefenderMaxAbility(battle, state) {\n var abilities = battle.battlePlayers[state.playerToAct ? 0 : 1].fighter.abilityScores;\n var max = this.max(abilities);\n for (let i = 0; i < 3; ++i) {\n if (abilities[i] === max) {\n return i;\n }\n }\n return 2;\n }\n}",{"deps":{"Constants":{"$jig":0},"Dice":{"$jig":1},"KronoClass":{"$jig":2},"Sha256":{"$jig":3},"expect":{"$jig":4}},"hash":"1ef3b0a57ca08f6c238689d792fc4956ee5095a980080f558e1bfbbc119a1af5"}]}]}
    https://whatsonchain.com/tx/8e5d26176cc5ce4f2734e2fb8abb6da01237f5c1736839adf8a82659ecbe85d6