protected static float combatPriority(
    Actor actor, Actor enemy, float winReward, float lossCost, boolean report
  ) {
    if (actor == enemy) return 0 ;
    if (report) I.say("  Basic combat reward/cost: "+winReward+"/"+lossCost) ;
    
    float danger = Retreat.dangerAtSpot(enemy, actor, enemy) ;
    final float chance = Visit.clamp(1 - danger, 0.1f, 0.9f) ;
    
    final Target enemyTargets = enemy.targetFor(null) ;
    float hostility = hostility(enemy) ;
    hostility *= PARAMOUNT * actor.mind.relationValue(enemyTargets) ;
    winReward += hostility ;
    lossCost -= hostility / 2 ;
    winReward -= actor.mind.relationValue(enemy) * PARAMOUNT ;
    
    if (winReward < 0) return 0 ;
    winReward *= actor.traits.scaleLevel(AGGRESSIVE) ;
    
    if (report) {
      I.say(
        "  "+actor+" considering COMBAT with "+enemy+
        ", time: "+actor.world().currentTime()
      ) ;
      I.say(
        "  Danger level: "+danger+
        "\n  Appeal before chance: "+winReward+", chance: "+chance
      ) ;
    }
    if (chance <= 0) {
      if (report) I.say("  No chance of victory!\n") ;
      return 0 ;
    }
    float appeal = (winReward * chance) - ((1 - chance) * lossCost) ;
    if (report) I.say("  Final appeal: "+appeal+"\n") ;
    return appeal ;
  }