Transaction

fe51df7a52d15b7ca973d26e152c99a15ac0999c564cc02069e911c2de172645
( - )
204,749
2021-01-13 05:36:11
1
22,190 B

3 Outputs

Total Output:
  • jrun cryptofightsM©U{"in":0,"ref":["8e5d26176cc5ce4f2734e2fb8abb6da01237f5c1736839adf8a82659ecbe85d6_o1","0e660dbbccc19c47e388dbd07832821da0083f020eced33c3f49d195df5427bc_o1","be7daf36641ba33aad8f42e02adbbcb48fb88cc0c6ac6b56f4c85369dcd2dfa1_o1","507b9cffbeb94c2386e054f3d63617f7b091e0bdb1619a99c3cd04e309be45f3_o1","f97d4ac2a3d6f5ed09fad4a4f341619dc5a3773d9844ff95c99c5d4f8388de2f_o1"],"out":["aeb215e0f4dbf335423d808303b1f06b0533a6bd54fbe58c493dffc41a1e7e31"],"del":[],"cre":["n2Bd4cWhEQK1aVjb1R7EBGV9mrw3etvSdC"],"exec":[{"op":"DEPLOY","data":["class Attack extends KronoClass {\n static run(battle, state, dice, timestamp, toHitBonus = 0, toDmgBonus = 0, attackType = Constants.SkillType.Attack) {\n const {Ability, DamageType, EquipSlot, ItemProperty, SkillType, StatusEffect, ItemType, Bonus} = Constants;\n let playerName = BattleUtils.getPrettifiedPlayerName(battle, state);\n let opponentName = BattleUtils.getOpponentName(battle, state);\n let log = `${playerName} uses <sprite name=\"${BattleUtils.parseSkillName(attackType)}\">${BattleUtils.parseSkillName(attackType)}\\n`;\n\n const attacker = battle.battlePlayers[state.playerToAct];\n const attackerItems = [battle.battlePlayers[state.playerToAct].mainhand, battle.battlePlayers[state.playerToAct].offhand, battle.battlePlayers[state.playerToAct].armor];\n\n var mainhand = {...attackerItems[0]};\n if (mainhand == null || mainhand.type == null) {\n\n mainhand = {};\n mainhand.diceCount = 1;\n mainhand.properties = Object.keys(ItemProperty).map(() => false);\n\n if(attacker.fighter.skills.includes(SkillType.Unarmed)){\n mainhand.diceFaces = 8;\n mainhand.properties[ItemProperty.Swift] = true;\n }else{\n mainhand.diceFaces = 4;\n }\n mainhand.properties[ItemProperty.Heavy] = true;\n mainhand.properties[ItemProperty.Brutal] = true;\n mainhand.properties[ItemProperty.Assault] = true;\n\n expect(ItemType).toBeDefined('ItemType is null');\n expect(Bonus).toBeDefined('ItemBonus is null');\n expect(DamageType).toBeDefined('DamageType is null');\n\n mainhand.displayName= 'Barefists';\n mainhand.description= 'Pair of hands.';\n mainhand.type= ItemType.Club;\n mainhand.levelRequired= 1;\n mainhand.abilityScoreRequired= Object.keys(Ability).map(()=> 1 );\n mainhand.bonuses= Object.keys(Bonus).map(()=> 0 );\n mainhand.critChanceBonus= 1;\n mainhand.baseDamageType= 2;\n mainhand.damageBonus= Object.keys(DamageType).map(()=> 0 );\n mainhand.damageReduction= Object.keys(DamageType).map(()=> 0 );\n mainhand.quality= 1;\n\n attackerItems[0] = mainhand;\n }\n\n let defenderState = state.fighterStates[state.playerToAct === 0 ? 1 : 0];\n let attackerState = state.fighterStates[state.playerToAct];\n\n const defenderPlayer = battle.battlePlayers[state.playerToAct ? 0 : 1];\n\n // Bob attacks Tim\n let resultMessage = `${playerName} attacks ${opponentName} : `; // goes up\n\n // Process pre-attack saving throws actionLogs\n if (BattleUtils.isUnderStatusEffect(defenderState, StatusEffect.Hidden, defenderState.turnCounter)) { // Spot\n state.actionLogs.push(this.makeSpotActionLog(battle, state, dice, attackerState, defenderState, state.playerToAct));\n }\n\n if (!BattleUtils.isUnderStatusEffect(defenderState, StatusEffect.Hidden, defenderState.turnCounter)) {\n\n let attackActionLog = {\n actionLogMessage: log\n };\n attackActionLog.playerIndex = state.playerToAct;\n attackActionLog.skillType = attackType;\n attackActionLog.results = [];\n\n const attackerStr = attacker.fighter.abilityScores[Ability.Strength];\n const attackerDex = attacker.fighter.abilityScores[Ability.Dexterity];\n\n for (var i = 0; i < 2; i++) {\n let weapon = attackerItems[i];\n let multiattackImmune = BattleUtils.isUnderStatusEffect(defenderState, StatusEffect.Meditative, defenderState.turnCounter);\n\n if (weapon && !(multiattackImmune && i > 0)) {\n expect(Constants.DamageTypeNames[weapon.baseDamageType]).toBeDefined(`Weapon with unknown damage type while processing attack, ${weapon.baseDamageType} not in ${JSON.stringify(Constants.DamageTypeNames)}`);\n // Find out 'to hit' ability\n var toHitAbility = Ability.Intelligence;\n // Weapon is brutal or ambivalent + player has str > dex\n if (weapon.properties[ItemProperty.Brutal] || (weapon.properties[ItemProperty.Ambivalent] && attackerStr >= attackerDex)) {\n toHitAbility = Ability.Strength;\n } else {\n // Weapon is dextrous or ambivalent + player has dex > str\n if (weapon.properties[ItemProperty.Dexterous] || (weapon.properties[ItemProperty.Ambivalent] && attackerDex >= attackerStr)) {\n toHitAbility = Ability.Dexterity;\n }\n }\n\n // Find out 'to damage' ability\n let toDmgAbility = Ability.Intelligence;\n // Weapon is Assault\n if (weapon.properties[ItemProperty.Assault]) {\n toDmgAbility = Ability.Strength;\n } else {\n // Weapon is Precision\n if (weapon.properties[ItemProperty.Precision]) {\n toDmgAbility = Ability.Dexterity;\n }\n }\n\n var dmgType = attacker.fighter.skills.includes(SkillType.Warmongering) ? DamageType.Warfare : weapon.baseDamageType;\n expect(Constants.DamageTypeNames[dmgType]).toBeDefined(`Unknown damage type during attack, ${dmgType} not in ${Constants.DamageTypeNames}`);\n \n var critChanceBonus = (attacker.fighter.skills.includes(SkillType.Precise) && weapon.properties[ItemProperty.Precision]) ? 1 : 0;\n\n if (attacker.fighter.skills.includes(SkillType.Ambidextrous) && attackerItems[EquipSlot.Mainhand] && attackerItems[EquipSlot.Offhand] && i === 0) {\n toHitBonus += 2;\n }\n\n if (attackActionLog.results.length > 0) {\n if (attackActionLog.results[attackActionLog.results.length - 1].damageOutput[0].defenderHp <= 0) {\n break;\n }\n }\n\n let result = this.makeResult(battle, state, dice, toHitAbility, toDmgAbility, toHitBonus, toDmgBonus, critChanceBonus, dmgType, weapon.diceCount, weapon.diceFaces, defenderPlayer, resultMessage, attackType, weapon.damageBonus);\n attackActionLog.results.push(result);\n\n if (weapon.properties[ItemProperty.Swift] && !multiattackImmune) {\n if (attackActionLog.results.length > 0) {\n if (attackActionLog.results[attackActionLog.results.length - 1].damageOutput[0].defenderHp <= 0) {\n break;\n }\n }\n let result = this.makeResult(battle, state, dice, toHitAbility, toDmgAbility, toHitBonus, toDmgBonus, critChanceBonus, dmgType, weapon.diceCount, weapon.diceFaces, defenderPlayer, resultMessage, attackType, weapon.damageBonus);\n attackActionLog.results.push(result);\n }\n }\n if (attackType === SkillType.Stun) {\n break;\n }\n }\n state.actionLogs.push(attackActionLog);\n }\n\n this.processPostAttackStatus(state, battle, attackerState, defenderState, attackType, defenderState.hp, dice, defenderPlayer);\n\n return BattleUtils.endTurn(battle, state, dice);\n }\n\n static processPostAttackStatus(state, battle, attackerState, defenderState, attackType, defenderHp, dice, defenderPlayer) {\n const {Outcome, SkillType, StatusEffect} = Constants;\n let wasHit = false;\n let wasCrit = false;\n\n state.actionLogs.forEach(actionLog => {\n actionLog.results.forEach(result => {\n if ((result.outcome === Outcome.Success || result.outcome === Outcome.Critical)) {\n wasHit = true;\n }\n if (result.outcome === Outcome.Critical) {\n wasCrit = true;\n }\n });\n });\n\n // On Hit\n if (wasHit) {\n if (BattleUtils.isUnderStatusEffect(attackerState, StatusEffect.Poisonous, attackerState.turnCounter)) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Poisoned, 2, false);\n }\n\n if (attackType === SkillType.Stun || attackType === SkillType.Freeze) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Stunned, 1, false);\n }\n\n if (attackType === SkillType.Chill) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Demoralized, 1, false);\n }\n }\n if (attackType === SkillType.PinningStrike) {\n if (wasCrit) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Stunned, 2, false);\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Marked, 3, true);\n } else {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Marked, 1, false);\n }\n }\n\n // On Attack\n if (attackType === SkillType.Gore) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Demoralized, 1, true);\n }\n\n if (attackType === SkillType.LockAndLoad) {\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Demoralized, 3, false);\n BattleUtils.applyStatusEffect(state.actionLogs[state.actionLogs.length - 1], battle, state, StatusEffect.Inspired, 3, true);\n }\n if (defenderHp > 0) {\n if (BattleUtils.isUnderStatusEffect(attackerState, StatusEffect.Hidden, attackerState.turnCounter)) {\n state.actionLogs.push(this.makeSpotActionLog(battle, state, dice, defenderState, attackerState, state.playerToAct ? 0 : 1));\n }\n\n if (defenderPlayer.skills.includes(SkillType.Vengeful) && wasHit) {\n state.actionLogs.push(BattleUtils.makeStatusEffectActionLog(battle, state, SkillType.Vengeful, StatusEffect.Cursed, 1, '', true));\n }\n\n if (defenderPlayer.fighter.skills.includes(SkillType.Opportunistic) && !wasHit) {\n state.actionLogs.push(BattleUtils.makeStatusEffectActionLog(battle, state, SkillType.Opportunistic, StatusEffect.Inspired, 1, '', false));\n }\n }\n }\n\n static makeResult(battle, state, dice, toHitAbility, toDmgAbility, toHitBonus, toDmgBonus, critChanceBonus, dmgType, diceCount, diceFaces, defenderPlayer, log, attackType = Constants.SkillType.Attack, weaponDmgBonus) {\n const {Ability, Outcome, RollType, SkillType, StatusEffect} = Constants;\n const defenderState = state.fighterStates[state.playerToAct ? 0 : 1];\n const attackerState = state.fighterStates[state.playerToAct];\n const attacker = battle.battlePlayers[state.playerToAct];\n\n /* #region attack_roll */\n let roll = {\n type: RollType.ToHit,\n ability: toHitAbility,\n size: 20,\n value: dice.roll(1, 20)\n };\n var rolls = [roll];\n\n // Advantage\n if (BattleUtils.isUnderStatusEffect(attackerState, StatusEffect.Hidden, attackerState.turnCounter) ||\n BattleUtils.isUnderStatusEffect(attackerState, StatusEffect.Inspired, attackerState.turnCounter) ||\n BattleUtils.isUnderStatusEffect(defenderState, StatusEffect.Marked, attackerState.turnCounter)) {\n rolls.push({\n type: RollType.ToHit,\n ability: toHitAbility,\n size: 20,\n value: dice.roll(1, 20)\n });\n\n if (rolls[rolls.length - 1].value > roll.value) {\n roll.discarded = true;\n roll = rolls[rolls.length - 1];\n } else {\n rolls[rolls.length - 1].discarded = true;\n }\n }\n\n if (BattleUtils.isUnderStatusEffect(attackerState, StatusEffect.Demoralized, attackerState.turnCounter)) {\n rolls.push({\n type: RollType.ToHit,\n ability: toHitAbility,\n size: 20,\n value: dice.roll(1, 20)\n });\n\n if (rolls[rolls.length - 1].value < roll.value) {\n roll.discarded = true;\n roll = rolls[rolls.length - 1];\n } else {\n rolls[rolls.length - 1].discarded = true;\n }\n }\n /* #endregion */\n\n // Process bonuses for selected dice\n roll.bonusFromAbility = attackerState.modifiers[toHitAbility];\n roll.bonusFromSkill = toHitBonus;\n roll.totalBonus = roll.bonusFromAbility + roll.bonusFromSkill;\n\n let outcome = Outcome.Fail;\n if (roll.value + roll.totalBonus > defenderState.evasion) {\n outcome = Outcome.Success;\n let critImmune = BattleUtils.isUnderStatusEffect(defenderState, StatusEffect.Meditative, defenderState.turnCounter);\n if (roll.value > 20 - (attackerState.critChance + critChanceBonus) && !critImmune) {\n outcome = Outcome.Critical;\n }\n }\n\n // *Hit* (10 + 1 + 1) = 12\n log += `*${BattleUtils.parseAttackOutcome(outcome)}* (${roll.value} + ${roll.bonusFromAbility} + ${roll.bonusFromSkill} = ${roll.value + roll.totalBonus})\\n`;\n\n let preResultDescription = `You need more than ${defenderState.evasion} <sprite name=Dexterity-d20> to hit`;\n let damage = 0;\n\n if (outcome !== Outcome.Fail) {\n if (attackType !== SkillType.Stun && attackType !== SkillType.PinningStrike) {\n var damageRoll = BattleUtils.rollDmgDice(toDmgAbility, diceCount, diceFaces, dice, rolls, RollType.ToDamage);\n damage += damageRoll;\n if (attackType === SkillType.Gore) {\n toDmgBonus += damageRoll;\n damage += damageRoll;\n }\n } else {\n rolls.push({\n type: RollType.ToDamage,\n ability: toDmgAbility,\n size: 0,\n value: 0\n });\n }\n\n // Process to dmg bonuses\n roll = rolls[rolls.length - 1];\n roll.bonusFromAbility = attackerState.modifiers[toDmgAbility];\n roll.bonusFromSkill = toDmgBonus;\n roll.totalBonus = roll.bonusFromSkill;\n if (!attacker.fighter.skills.includes(SkillType.Cirurgical)) {\n roll.totalBonus += roll.bonusFromAbility;\n }\n damage += roll.totalBonus;\n if (attackType === SkillType.DirtyFighting) {\n let dirtyRoll = dice.roll(1, 4);\n rolls.push({\n type: RollType.ToDamage,\n ability: toHitAbility,\n size: 4,\n value: dirtyRoll\n });\n damage += dirtyRoll;\n }\n if (attackType === SkillType.SneakAttack) {\n let isImproved = attacker.fighter.skills.includes(SkillType.ImprovedSneakAttack);\n let sneakRoll = dice.roll(1, isImproved ? 8 : 6);\n rolls.push({\n type: RollType.ToDamage,\n ability: toHitAbility,\n size: isImproved ? 8 : 6,\n value: sneakRoll\n });\n damage += sneakRoll;\n }\n if (outcome === Outcome.Critical && attackType !== SkillType.DirtyFighting) {\n damage += BattleUtils.rollDmgDice(toDmgAbility, diceCount, diceFaces, dice, rolls, RollType.WeaponCrit);\n // Roll a die with the same number of faces as\n // the fighter's dexterity modifier rounded up to nearest even number\n let critModifier = attackerState.modifiers[Ability.Dexterity];\n if (attackType === SkillType.LightningBolt) {\n critModifier += attackerState.modifiers[Ability.Intelligence];\n }\n if (attackType === SkillType.Shock) {\n critModifier += 1;\n }\n if (critModifier > 0) {\n let faces = critModifier % 2 === 0 ? critModifier : critModifier + 1;\n let fighterCritNativeRoll = dice.roll(1, faces);\n rolls.push({\n type: RollType.FighterCrit,\n ability: Ability.Dexterity,\n size: faces,\n value: fighterCritNativeRoll\n });\n damage += fighterCritNativeRoll;\n }\n }\n if (damage < 0) {\n damage = 0;\n }\n\n if (weaponDmgBonus) {\n weaponDmgBonus.forEach(bonus => {\n damage += bonus;\n });\n }\n\n\n let result = BattleUtils.makeDamageResult(battle, state, defenderState, defenderPlayer, damage, dmgType, rolls, outcome, preResultDescription);\n log += result.resultMessage;\n result.resultMessage = log;\n return result;\n } else {\n return {\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: attackerState.statusEffectsRound,\n hpIncrement: 0,\n attackerHp: attackerState.hp,\n preResultDescription: preResultDescription,\n resultMessage: log\n };\n }\n }\n\n // Abstract this out to a saving throw\n static makeSpotActionLog(battle, state, dice, spotterState, spoteeState, spotterIndex) {\n const {Ability, Outcome, RollType, SkillType, StatusEffect} = Constants;\n let savingThrows = [];\n\n if (BattleUtils.isUnderStatusEffect(spoteeState, StatusEffect.Hidden, spoteeState.turnCounter)) {\n var spoteeName = BattleUtils.getPrettifiedName(battle, spotterIndex);\n\n const attackerState = state.fighterStates[state.playerToAct];\n\n let savingThrow = dice.roll(1, 20);\n let attackerIntMod = spotterState.modifiers[Ability.Intelligence];\n let defenderEvasion = spoteeState.evasion;\n let rollResult = attackerIntMod + savingThrow;\n let outcome = rollResult >= defenderEvasion ?\n Outcome.Success : Outcome.Fail;\n\n savingThrows.push({\n type: RollType.Intelligence,\n ability: Ability.Intelligence,\n size: 20,\n value: savingThrow\n });\n\n if (outcome === Outcome.Success) { // found opponent\n spoteeState.statusEffectsRound[StatusEffect.Hidden] = 0;\n }\n\n return {\n playerIndex: spotterIndex,\n skillType: SkillType.Attack,\n results: [{\n rolls: savingThrows,\n outcome: outcome,\n damageOutput: [{\n damage: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n defenderHp: spoteeState.hp,\n defenderReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n }],\n attackerStatusEffectsIncrement: spotterState.statusEffectsDurations,\n hpIncrement: 0,\n attackerHp: attackerState.hp\n }],\n actionLogMessage: `${spoteeName} <gradient=!log-color>Intelligence Save vs. Evasion : *${BattleUtils.parseSkillOutcome(outcome)}* (${savingThrow} + ${attackerIntMod} = ${rollResult} vs. DC ${defenderEvasion})`\n };\n }\n }\n}",{"affectsOpponent":true,"deps":{"BattleUtils":{"$jig":0},"Constants":{"$jig":1},"Dice":{"$jig":2},"KronoClass":{"$jig":3},"expect":{"$jig":4}},"description":"Attack Action","displayName":"Attack","handle":"attack","hash":"8567eb5eb3d39bb7c88269dbc01e97323e7bb2677e2ee54921315e878c8fce98","isAttackAction":true,"requiredLevel":0,"skillType":0}]}]}
    https://whatsonchain.com/tx/fe51df7a52d15b7ca973d26e152c99a15ac0999c564cc02069e911c2de172645