package com.lyndir.omicron.api;
import static com.lyndir.omicron.api.error.ExceptionUtils.assertState;
import com.google.common.collect.ImmutableSet;
import com.lyndir.omicron.api.error.*;
import com.lyndir.omicron.api.util.Maybe;
import java.util.Random;
import java.util.Set;
public class WeaponModule extends Module implements IWeaponModule, IWeaponModuleController {
private static final Random RANDOM = new Random();
private final int firePower;
private final int variance;
private final int range;
private final int repeat;
private final int ammunitionLoad;
private final ImmutableSet<LevelType> supportedLayers;
private int repeated;
private int ammunition;
protected WeaponModule(final ImmutableResourceCost resourceCost, final int firePower, final int variance, final int range,
final int repeat, final int ammunitionLoad, final Set<LevelType> supportedLayers) {
super( resourceCost );
this.firePower = firePower;
this.variance = variance;
this.range = range;
this.repeat = repeat;
this.ammunitionLoad = ammunitionLoad;
this.supportedLayers = ImmutableSet.copyOf( supportedLayers );
ammunition = ammunitionLoad;
}
static Builder0 createWithStandardResourceCost() {
return createWithExtraResourceCost( ResourceCost.immutable() );
}
static Builder0 createWithExtraResourceCost(final ImmutableResourceCost resourceCost) {
return new Builder0( ModuleType.WEAPON.getStandardCost().add( resourceCost ) );
}
@Override
public int getFirePower()
throws NotAuthenticatedException, NotObservableException {
return firePower;
}
@Override
public int getVariance()
throws NotAuthenticatedException, NotObservableException {
return variance;
}
@Override
public int getRange()
throws NotAuthenticatedException, NotObservableException {
return range;
}
@Override
public int getRepeat()
throws NotAuthenticatedException, NotObservableException {
return repeat;
}
@Override
public int getAmmunitionLoad()
throws NotAuthenticatedException, NotObservableException {
return ammunitionLoad;
}
@Override
public int getRepeated() {
return repeated;
}
@Override
public int getAmmunition() {
return ammunition;
}
@Override
public ImmutableSet<LevelType> getSupportedLayers()
throws NotAuthenticatedException, NotObservableException {
assertObservable();
return ImmutableSet.copyOf( supportedLayers );
}
@Override
public boolean fireAt(final ITile target)
throws NotAuthenticatedException, NotOwnedException, NotObservableException, IWeaponModuleController.OutOfRangeException,
IWeaponModuleController.OutOfRepeatsException, IWeaponModuleController.OutOfAmmunitionException {
assertOwned();
Security.assertObservable( target );
assertState( getGameObject().getLocation().get().getPosition().distanceTo( target.getPosition() ) <= range,
IWeaponModuleController.OutOfRangeException.class );
assertState( repeated < repeat, IWeaponModuleController.OutOfRepeatsException.class );
assertState( ammunition > 0, IWeaponModuleController.OutOfAmmunitionException.class );
ChangeInt.From repeatedChange = ChangeInt.from( repeated );
ChangeInt.From ammunitionChange = ChangeInt.from( ammunition );
++repeated;
--ammunition;
getGameObject().getGame()
.getController()
.fireIfObservable( getGameObject() )
.onWeaponFired( this, target, repeatedChange.to( repeated ), ammunitionChange.to( ammunition ) );
Maybe<? extends IGameObject> targetGameObject = target.getContents();
if (targetGameObject.isPresent())
targetGameObject.get().onModule( ModuleType.BASE, 0, module -> {
module.addDamage( firePower + RANDOM.nextInt( variance ) );
return Void.TYPE;
} );
return true;
}
@Override
protected void onReset() {
repeated = 0;
}
@Override
protected void onNewTurn() {
}
@Override
public IWeaponModuleController getController() {
return this;
}
@Override
public IWeaponModule getModule() {
return this;
}
@SuppressWarnings({ "ParameterHidesMemberVariable", "InnerClassFieldHidesOuterClassField" })
static class Builder0 {
private final ImmutableResourceCost resourceCost;
private Builder0(final ImmutableResourceCost resourceCost) {
this.resourceCost = resourceCost;
}
Builder1 firePower(final int firePower) {
return new Builder1( firePower );
}
class Builder1 {
private final int firePower;
private Builder1(final int firePower) {
this.firePower = firePower;
}
Builder2 armor(final int variance) {
return new Builder2( variance );
}
class Builder2 {
private final int variance;
private Builder2(final int variance) {
this.variance = variance;
}
Builder3 range(final int range) {
return new Builder3( range );
}
class Builder3 {
private final int range;
private Builder3(final int range) {
this.range = range;
}
Builder4 repeat(final int repeat) {
return new Builder4( repeat );
}
class Builder4 {
private final int repeat;
private Builder4(final int repeat) {
this.repeat = repeat;
}
Builder5 ammunitionLoad(final int ammunitionLoad) {
return new Builder5( ammunitionLoad );
}
class Builder5 {
private final int ammunitionLoad;
private Builder5(final int ammunitionLoad) {
this.ammunitionLoad = ammunitionLoad;
}
WeaponModule supportedLayers(final Set<LevelType> supportedLayers) {
return new WeaponModule( resourceCost, firePower, variance, range, repeat, ammunitionLoad,
supportedLayers );
}
}
}
}
}
}
}
}