PhaserControl.groovy
package net.ebdon.trk21;
import static ShipDevice.*;
import static GameSpace.*;
/**
* @file
* @author Terry Ebdon
* @date January 2019
* @copyright
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@groovy.util.logging.Log4j2
final class PhaserControl {
final DamageControl damageControl;
Closure report;
FederationShip ship; /// @todo Break the dependency on FederationShip
Battle battle;
PhaserControl( final DamageControl aDc, final Closure reporter, aShip, aBattle ) {
damageControl = aDc
report = reporter
ship = aShip
battle = aBattle
}
/// @todo Localiser PhaserControl.phasersDisabled()
private void phasersDisabled() {
log.info "Phaser control is disabled."
report "Phaser control is disabled."
}
/// @todo Localiser PhaserControl.phasersOnTarget()
private void phasersOnTarget() {
log.info "Phaser control is enabled. Energy available $ship.energyNow"
report "Phasers locked in on target. Energy available $ship.energyNow"
}
/// @todo Localiser PhaserControl.commandRefused()
private void commandRefused() {
log.warn "Command refused; insufficient energy available."
report "Command refused; insufficient energy available."
}
private def phaserVariance() {
2 + new Random().nextFloat()
}
private float rangeTo( target ) {
log.info "Fire from ${ship.position.sector} at $target"
distanceBetween( ship.position.sector, target.sector )
}
private int targetDamageAmount( fired, distance ) {
[fired, fired / distance * phaserVariance()].min()
}
private void fireAt( final int energyAmount, final Expando target ) {
log.debug 'in fireAt()'
assert ship.position.isValid()
assert target.sector.isValid()
assert energyAmount > 0
final float distance = rangeTo( target )
log.debug sprintf(
"Calculating hit on %s with %d units, range %+1.3f sectors",
target.name, energyAmount, distance )
assert distance > 0
// final float energyHit = energyAmount / distance * phaserVariance()
final int energyHit = targetDamageAmount( energyAmount, distance )
log.info '{} hit with {} of the {} units fired at it.',
target.name, energyHit, energyAmount
battle.hitOnFleetShip target, energyHit
}
void fire( final int energyAmount ) {
log.info "Firing phasers with $energyAmount units."
assert damageControl && report
assert energyAmount > 0
if ( damageControl.isDamaged( DeviceType.phasers ) ) {
phasersDisabled()
} else {
phasersOnTarget()
if (energyAmount > ship.energyNow) {
commandRefused()
} else {
ship.energyReducedByPhaserUse energyAmount
Expando target
while ( target = battle.getNextTarget() ) {
fireAt energyAmount, target
}
}
}
log.info 'Firing phasers -- complete'
}
}