Battle.groovy
package net.ebdon.trk21;
import groovy.transform.*;
/**
* @file
* @author Terry Ebdon
* @date January 2019
* @copyright Terry Ebdon, 2019
* 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.
*/
@ToString(includePackage=false,includeNames=true)
@Canonical
@groovy.util.logging.Log4j2
final class Battle {
EnemyFleet enemyFleet;
FederationShip ship;
DamageControl dc;
Closure pcReporter;
Closure fleetAttackReporter;
PropertyResourceBundle rb;
private int nextTargetIndex = 1;
Expando getNextTarget() {
log.trace "There are ${enemyFleet.numKlingonBatCrInQuad} enemy ships here."
log.trace "Getting target $nextTargetIndex"
assert nextTargetIndex >= 0
assert nextTargetIndex <= 1 + enemyFleet.maxKlingonBCinQuad
Expando rv = null
if ( enemyFleet.numKlingonBatCrInQuad > 0 ) {
if ( nextTargetIndex <= enemyFleet.maxKlingonBCinQuad ) {
final def enemyShip = enemyFleet.klingons[ nextTargetIndex ]
if ( enemyShip[3] > 0 ) {
log.info "Creating target expando from $enemyShip"
rv = new Expando(
id: nextTargetIndex,
name: "Enemy ship No. $nextTargetIndex",
energy: enemyShip[3],
sector: new Coords2d( *enemyShip[1..2] ) /// @ todo fix this.
)
} else {
log.trace "Enemy ship No. $nextTargetIndex is dead, or never existed... recursing..."
++nextTargetIndex
rv = getNextTarget()
}
++nextTargetIndex
}
} else {
log.info "Nothing to fire at; no enemy ships in this quadrant."
}
rv
}
/// @todo Localise Battle.hitOnFleetShip()
def hitOnFleetShip( final target, final int hitAmount ) {
pcReporter sprintf( '%d unit hit on %s at sector %d - %d',
hitAmount, target.name, target.sector.last(), target.sector.first() )
enemyFleet.with {
hitOnShip( target.id, hitAmount )
if (shipExists(target.id)) {
pcReporter sprintf( '\t(%d left)%n', energy(target.id) )
} else {
pcReporter rb.getString( 'battle.enemy.destroyed' )
}
}
}
void phaserAttackFleet( final int energy ) {
assert energy > 0
assert enemyFleet && ship && dc && pcReporter && fleetAttackReporter
new PhaserControl( dc, pcReporter, ship, this ).fire( energy )
enemyRespondsToAttack()
}
@TypeChecked
void enemyRespondsToAttack() {
enemyFleet.regroup()
if ( enemyFleet.canAttack() ) {
if ( ship.isProtectedByStarBase() ) {
/// @todo localise this with 'starbase.shields'
fleetAttackReporter 'Star Base shields protect the Enterprise.'
} else {
enemyFleet.attack( ship.position.sector, fleetAttackReporter )
}
}
}
/// @todo implement battle.fireTorpedo()
@TypeChecked
void fireTorpedo( course ) {
pcReporter "Battle#fireTorpedo is not yet implemented"
enemyRespondsToAttack()
}
}