Settings

Blockchain
Network
Unit
Language
Theme
Sound New Block

Transaction

fd7455fa0868b80da50fb2703db3f7bdb6b70bad3b0518600ef19dd17406c612
Timestamp (utc)
2021-05-08 23:06:27
Fee Paid
0.00018227 BSV
(
0.00970880 BSV
-
0.00952653 BSV
)
Fee Rate
505.9 sat/KB
Version
1
Confirmations
301,184
Size Stats
36,009 B

3 Outputs

Total Output:
0.00952653 BSV
  • jrun cryptofightsM¥‹{"in":0,"ref":["013ba7f4d0fe70aef6b6fa0f7a466ce98bfa38b452ddba20e5d7f98547edb303_o1","397d3e4ed2c605de9e9605514eadd083f617bc0256f10d622266492dec63cb31_o1","0388093d0fbe67cbf69791185954954519e087750836a38c57b5041ca4e032a9_o1","03743bfa0fc1c1c0f76b2257827468e77d682b9501b039333b1e094cff2dd0a0_o1","3804f0268973ca6b38d9594211c9662133ca9e53a743c3fdfa9080344e660c04_o1","f97d4ac2a3d6f5ed09fad4a4f341619dc5a3773d9844ff95c99c5d4f8388de2f_o1"],"out":["0aa66117400a4a01c9c15600f4e4e4bf1521d7fddc53cf01b820de79cff24036"],"del":[],"cre":["n2Bd4cWhEQK1aVjb1R7EBGV9mrw3etvSdC"],"exec":[{"op":"DEPLOY","data":["class BattleUtils extends FyxClass {\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 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.slice(-1).pop().attackerStatusEffectsIncrement) {\n actionLog.results.slice(-1).pop().attackerStatusEffectsIncrement = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n actionLog.results.slice(-1).pop().attackerStatusEffectsIncrement[statusEffect] = increment;\n actionLog.actionLogMessage += BattleUtils.getPrettifiedPlayerName(battle, state, !applyToAttacker);\n } else {\n let turnCount = statusEffect == Constants.StatusEffect.Stunned ? battle.turnCount : state.fighterStates[state.playerToAct ? 0 : 1].turnCounter;\n state.fighterStates[state.playerToAct ? 0 : 1].statusEffectsRound[statusEffect] = turnCount + increment;\n if (!actionLog.results.slice(-1).pop().defenderStatusEffectsIncrement) {\n actionLog.results.slice(-1).pop().defenderStatusEffectsIncrement = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n actionLog.results.slice(-1).pop().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, 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.metadata.name.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.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 this.getItemResistance(player.hat, 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 }\n\n return defenderResistance;\n }\n \n static getItemBonus(item, defenderBonus) {\n if (item) {\n for (var j = 0; j < 18; j++) {\n if (item.bonuses[j]) {\n defenderBonus[j] += item.bonuses[j];\n }\n }\n }\n }\n\n // Compute bonuses according to items\n static getItemBonuses(player) {\n var defenderBonus = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n this.getItemBonus(player.mainhand, defenderBonus);\n this.getItemBonus(player.offhand, defenderBonus);\n this.getItemBonus(player.armor, defenderBonus);\n this.getItemBonus(player.hat, defenderBonus);\n\n return defenderBonus;\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] + diceRolls[i];\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.metadata.name.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.metadata.name.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.metadata.name.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 simulateFighterState(battlePlayer) {\n const fighter = battlePlayer.fighter;\n\n // Construct fighter states\n const items = [battlePlayer.mainhand, battlePlayer.offhand, battlePlayer.armor, battlePlayer.hat];\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],\n areLoaded: [false, false, false],\n validActions: BattleUtils.getValidActions(battlePlayer.skills, false, true, battlePlayer.mainhand),\n resistances: BattleUtils.getDefenderResistance(battlePlayer),\n initiative: derivedStats.initiative\n };\n return fighterState;\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, battlePlayer.hat];\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],\n areLoaded: [false, false, false],\n validActions: BattleUtils.getValidActions(battlePlayer.skills, false, false, battlePlayer.mainhand),\n resistances: BattleUtils.getDefenderResistance(battlePlayer),\n initiative: derivedStats.initiative\n };\n return fighterState;\n }\n\n // Derived unmutable stats (HP and MaxHP are mutable)\n static getDerivedStats(fighter, items) {\n let abilityScores = FyxClass.deepClone(fighter.abilityScores);\n let abilityScoreBonuses = [0, 0, 0];\n let evasion = 0;\n let critChance = 1;\n let hpIncrement = fighter.skills.includes(Constants.SkillType.Durable) ? (fighter.level * 2) : 0;\n let initiative = 0;\n\n for( const item of items || []) {\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 evasion += item.bonuses[Constants.Bonus.Evasion];\n critChance += item.bonuses[Constants.Bonus.CritChance];\n initiative += item.bonuses[Constants.Bonus.Initiative];\n }\n }\n\n let modifiers = BattleUtils.getModifiers(abilityScores);\n evasion = modifiers[Constants.Ability.Dexterity] + 10;\n\n if (fighter.skills.includes(Constants.SkillType.Elven)) {\n initiative += 10;\n evasion += 2;\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 initiative: initiative,\n hpIncrement: hpIncrement\n };\n }\n\n static getModifiers(abilityScores) {\n return [\n parseInt(this.floor((abilityScores[Constants.Ability.Strength] - 10) / 2)),\n parseInt(this.floor((abilityScores[Constants.Ability.Dexterity] - 10) / 2)),\n parseInt(this.floor((abilityScores[Constants.Ability.Intelligence] - 10) / 2))\n ];\n }\n\n static floor(value)\n {\n return value>0 ? value >> 0 : (value -.5) >> 0;\n }\n\n static getValidActions(skills = [], isTaunted, isHidden, mainhand) {\n return skills.map(skill => {\n if (skill) {\n if(mainhand != null && mainhand.properties[Constants.ItemProperty.Innocuous])\n {\n return !skill.isAttackAction;\n }\n else\n {\n if(skill.isAttackAction)\n {\n if(isTaunted)\n {\n return false;\n }\n else if(skill.skillType === Constants.SkillType.SneakAttack)\n {\n return isHidden && skills.find(element => element.skillType === Constants.SkillType.Hide) != null;\n }\n else if(skill.skillType === Constants.SkillType.LockAndLoad)\n {\n return mainhand != null && mainhand.properties[Constants.ItemProperty.Loading];\n }\n else if(skill.skillType === Constants.SkillType.Stun)\n {\n return mainhand != null && mainhand.properties[Constants.ItemProperty.Brutal];\n }\n }\n return true;\n }\n }\n else\n {\n return false;\n }\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, battle.battlePlayers[i].hat];\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.slice(-1).pop().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], \n [0,0,0,0,0,1,0,0,0,0],\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 [0,0,0,0,0,1,0,0,0,0],\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], [0,0,0,0,0,0,0,damage,0,0], 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 [0,0,0,0,0,state.fighterStates[attackerIndex].turnCounter - fatigueThreshold,0,0,0,0],\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 if (state.fighterStates[0].hp <= 0 || state.fighterStates[1].hp <= 0) {\n const victorIndex = state.fighterStates[0].hp > state.fighterStates[1].hp ? 0 : 1;\n\n if(victorIndex !== -1) {\n var results = state.actionLogs.slice(-1).pop().results;\n results.slice(-1).pop().resultMessage += `${this.getPrettifiedPlayerName(battle, state, victorIndex)} won`;\n state.playerToAct = victorIndex;\n state.victor = {\n pubkey: battle.battlePlayers[victorIndex].pubkey,\n userId: battle.battlePlayers[victorIndex].userId,\n owner: battle.battlePlayers[victorIndex].owner,\n fighter: battle.battlePlayers[victorIndex].fighter,\n };\n }\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, damageMap, rolls, outcome, skillType, log, preResultDescription, damageSelf = false) {\n return {\n playerIndex: state.playerToAct,\n skillType: skillType,\n results: [this.makeDamageResult(battle, state, defenderState, defenderPlayer, damageMap, rolls, outcome, preResultDescription, damageSelf)],\n actionLogMessage: log\n };\n }\n\n static makeDamageResult(battle, state, damageState, damagePlayer, damageMap, rolls, outcome, preResultDescription, damageSelf = false) {\n var playerName = BattleUtils.getPrettifiedPlayerName(battle, state);\n var opponentName = BattleUtils.getOpponentName(battle, state);\n\n let defenderReduction = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n let resultMessage = '';\n for (let i = 0; i < (damageMap || []).length; i++) {\n let resistance = this.getDefenderResistance(damagePlayer)[i];\n let inflictedDamage = damageMap[i] - resistance;\n inflictedDamage = (inflictedDamage < 0) ? 0 : inflictedDamage;\n defenderReduction[i] = damageMap[i] - inflictedDamage;\n damageState.hp -= inflictedDamage;\n expect(inflictedDamage).toBeInteger(`${playerName} inflicted unknown damage`);\n\n if (damageMap[i] > 0) {\n resultMessage += damageSelf ? `${playerName} takes damage : ` : `${playerName} damages ${opponentName} : `;\n resultMessage += `${inflictedDamage} (${damageMap[i]} ${Constants.DamageTypeNames[i]}${resistance > 0 ? ` - ${resistance} Resist` : ''})\\n`;\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 : Math.max(damageState.hp, 0),\n defenderReduction: defenderReduction\n }],\n attackerStatusEffectsIncrement: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n hpIncrement: 0,\n attackerHp: damageSelf ? damageState.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 const damageMap = Object.keys(Constants.DamageType).map(() => 0);\n damageMap[damageType] = nativeRoll;\n return this.makeDamageActionLog(battle, state, defenderState, defenderPlayer, damageMap, rolls, Constants.Outcome.Success, skill, log);\n }\n\n static getDefenderMaxAbility(battle, state) {\n var abilities = battle.battlePlayers[state.playerToAct ? 0 : 1].fighter.abilityScores;\n var max = Math.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},"FyxClass":{"$jig":2},"Math":{"$jig":3},"Sha256":{"$jig":4},"expect":{"$jig":5}},"hash":"a4f8dc5bc8f51461e689c1e7b9edc962a2de1a394aface5f4d2fc189bde8e93a"}]}]}
    https://whatsonchain.com/tx/fd7455fa0868b80da50fb2703db3f7bdb6b70bad3b0518600ef19dd17406c612