@@ -361,19 +361,31 @@ async function simulateBattleStep(
361361 const isCrit = critRoll < attacker . critChance ;
362362 damage = isCrit ? Math . floor ( baseDamage * 1.8 ) : baseDamage ;
363363
364+ const speedDifference = Math . max ( 0 , defender . speed - attacker . speed ) ;
365+ const baseDodgeChance = 0.15 ;
366+ const speedDodgeBonus = speedDifference * 0.01 ;
367+ const totalDodgeChance = baseDodgeChance + speedDodgeBonus ;
368+
364369 const defenseRoll = Math . random ( ) ;
365- const canBlock =
366- abilityUsed !== "Airstrike" && abilityUsed !== "Great Will" ;
370+ const canBlock = abilityUsed !== "Airstrike" && abilityUsed !== "Great Will" ;
367371
368- if ( defenseRoll < 0.15 ) {
372+ if ( defenseRoll < totalDodgeChance ) {
369373 damage = 0 ;
370374 action = "dodge" ;
371- narration = `💨 **${ defender . name } ** ${ battleNarrations . dodge [
372- Math . floor ( Math . random ( ) * battleNarrations . dodge . length )
373- ]
374- . replace ( "{defender}" , "" )
375- . replace ( "{attacker}" , `**${ attacker . name } **` ) } `;
376- } else if ( defenseRoll < 0.3 && canBlock ) {
375+ const dodgeMessage =
376+ speedDifference > 0
377+ ? `💨 **${ defender . name } ** ${ battleNarrations . dodge [
378+ Math . floor ( Math . random ( ) * battleNarrations . dodge . length )
379+ ]
380+ . replace ( "{defender}" , "" )
381+ . replace ( "{attacker}" , `**${ attacker . name } **` ) } *(+${ speedDifference } % dodge from speed)*`
382+ : `💨 **${ defender . name } ** ${ battleNarrations . dodge [
383+ Math . floor ( Math . random ( ) * battleNarrations . dodge . length )
384+ ]
385+ . replace ( "{defender}" , "" )
386+ . replace ( "{attacker}" , `**${ attacker . name } **` ) } `;
387+ narration = dodgeMessage ;
388+ } else if ( defenseRoll < totalDodgeChance + 0.15 && canBlock ) {
377389 damage = Math . max ( 1 , damage - defender . defense ) ;
378390 action = "block" ;
379391 narration = `🛡️ **${ defender . name } ** ${ battleNarrations . block [
@@ -382,11 +394,7 @@ async function simulateBattleStep(
382394 . replace ( "{defender}" , "" )
383395 . replace ( "{attacker}" , `**${ attacker . name } **` ) } `;
384396 } else {
385- if ( abilityUsed === "Relic of Exo" ) {
386- damage = Math . max ( 1 , damage ) ;
387- } else {
388- damage = Math . max ( 1 , damage - Math . floor ( defender . defense / 2 ) ) ;
389- }
397+ damage = Math . max ( 1 , damage - Math . floor ( defender . defense / 2 ) ) ;
390398
391399 if ( isCrit ) {
392400 narration = `💥 ${ battleNarrations . criticalHit [
@@ -413,7 +421,7 @@ async function simulateBattleStep(
413421 }
414422
415423 defender . hp = Math . max ( 0 , defender . hp - damage ) ;
416- if ( ! narration . includes ( "HP" ) ) {
424+ if ( ! narration . includes ( "HP" ) && ! narration . includes ( "dmg" ) ) {
417425 narration += ` **(${ damage } dmg)**` ;
418426 }
419427 }
0 commit comments