}
else emptyList()
}.associateWith { (ship, weaponId, target) ->
- weaponId.expectedAdvantageFromWeaponUsage(state, ship, target) * brain[shipAttackPriority forShip target.id].signedPow(instincts[combatPrioritization])
+ weaponId.expectedAdvantageFromWeaponUsage(state, ship, target) * smoothNegative(brain[shipAttackPriority forShip target.id].signedPow(instincts[combatPrioritization])) * (1 + target.calculateSuffering()).signedPow(instincts[combatPreyOnTheWeak])
}.weightedRandomOrNull()
if (attackWith == null)
doActions.send(PlayerAction.UseAbility(PlayerAbilityType.DonePhase(phase), PlayerAbilityData.DonePhase))
else {
val (ship, weaponId, target) = attackWith
- val targetPickResponse = if (ship.armaments.weaponInstances[weaponId]?.weapon is AreaWeapon)
- PickResponse.Location(target.position.location)
- else
- PickResponse.Ship(target.id)
+ val targetPickResponse = when (val weaponSpec = ship.armaments.weaponInstances[weaponId]?.weapon) {
+ is AreaWeapon -> PickResponse.Location(ship.getWeaponPickRequest(weaponSpec).boundary.closestPointTo(target.position.location))
+ else -> PickResponse.Ship(target.id)
+ }
doActions.send(PlayerAction.UseAbility(PlayerAbilityType.UseWeapon(ship.id, weaponId), PlayerAbilityData.UseWeapon(targetPickResponse)))
+
+ withTimeoutOrNull(50L) { getErrors.receive() }?.let { error ->
+ logWarning("Error when attacking target ship ID ${target.id} with weapon $weaponId of ship ID ${ship.id} - $error")
+
+ val nextState = gameState.value
+ phasePipe.send(nextState.phase to (nextState.doneWithPhase != mySide && (!nextState.phase.usesInitiative || nextState.currentInitiative != mySide.other)))
+ }
}
}
is GamePhase.Repair -> {
val combatAvengeShipwrecks by instinct { Random.nextDouble(0.5, 4.5) }
val combatAvengeShipWeight by instinct { Random.nextDouble(-0.5, 1.5) }
-val combatPrioritization by instinct { Random.nextDouble(-1.0, 1.0) }
+val combatPrioritization by instinct { Random.nextDouble(-1.5, 2.5) }
val combatAvengeAttacks by instinct { Random.nextDouble(0.5, 4.5) }
val combatForgiveTarget by instinct { Random.nextDouble(-1.5, 2.5) }
+val combatPreyOnTheWeak by instinct { Random.nextDouble(-1.5, 2.5) }
val combatFrustratedByFailedAttacks by instinct { Random.nextDouble(-2.5, 5.5) }
val canBeAttackedBy = ship.attackableWithDamageBy(gameState)
val opportunityScore = canAttack.map { (targetId, potentialDamage) ->
- brain[shipAttackPriority forShip targetId].signedPow(instincts[navTunnelVision]) * potentialDamage
+ smoothNegative(brain[shipAttackPriority forShip targetId]).signedPow(instincts[navTunnelVision]) * potentialDamage
}.sum() + (ship.calculateSuffering() * instincts[navLustForBlood])
val vulnerabilityScore = canBeAttackedBy.map { (targetId, potentialDamage) ->
- brain[shipAttackPriority forShip targetId].signedPow(instincts[navTunnelVision]) * potentialDamage
+ smoothNegative(brain[shipAttackPriority forShip targetId]).signedPow(instincts[navTunnelVision]) * potentialDamage
}.sum() * -expm1(-ship.calculateSuffering() * instincts[navSqueamishness])
return instincts[navOptimality].pow(opportunityScore.signedPow(instincts[navAggression]) - vulnerabilityScore.signedPow(instincts[navPassivity]))