package com.lyndir.omicron.cli.command;
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
import java.util.Optional;
import com.google.common.collect.Iterators;
import com.lyndir.lhunath.opal.math.Vec2;
import com.lyndir.lhunath.opal.system.util.ConversionUtils;
import com.lyndir.omicron.api.*;
import com.lyndir.omicron.api.util.Maybe;
import com.lyndir.omicron.cli.OmicronCLI;
import java.util.Iterator;
/**
* <i>10 07, 2012</i>
*
* @author lhunath
*/
@CommandGroup(name = "fire", abbr = "f", desc = "Fire weapons at a target.")
public class FireCommand extends Command {
public FireCommand(final OmicronCLI omicron) {
super( omicron );
}
@Override
public void evaluate(final Iterator<String> tokens) {
Optional<IGameController> gameController = getOmicron().getGameController();
if (!gameController.isPresent()) {
err( "No game is running. Create one with the 'create' command." );
return;
}
Optional<IPlayer> localPlayerOptional = getOmicron().getLocalPlayer();
if (!localPlayerOptional.isPresent()) {
err( "No local player in the game." );
return;
}
IPlayer localPlayer = localPlayerOptional.get();
String objectIDArgument = Iterators.getNext( tokens, null );
if (objectIDArgument == null) {
err( "Missing objectID. Syntax: objectID dX dY [level]" );
return;
}
if ("help".equals( objectIDArgument )) {
inf( "Usage: objectID dX dY [level]" );
inf( " objectID: The ID of the object to fire with (see list objects)." );
inf( " dU: The delta from the current position's x to the target x." );
inf( " dV: The delta from the current position's y to the target y." );
inf( " weapon: The index of the weapon to fire with (optional, default=0 (primary))." );
inf( " level: The level into which to target the weapon (optional, default=current)." );
return;
}
String duArgument = Iterators.getNext( tokens, null );
if (duArgument == null) {
err( "Missing dU. Syntax: objectID dX dY [level]" );
return;
}
String dvArgument = Iterators.getNext( tokens, null );
if (dvArgument == null) {
err( "Missing dV. Syntax: objectID dX dY [level]" );
return;
}
int objectId = ConversionUtils.toIntegerNN( objectIDArgument );
int dx = ConversionUtils.toIntegerNN( duArgument );
int dy = ConversionUtils.toIntegerNN( dvArgument );
// Find the game object for the given ID.
Maybe<? extends IGameObject> maybeObject = localPlayer.getController().getObject( objectId );
if (maybeObject.presence() != Maybe.Presence.PRESENT) {
err( "No observable object with ID: %s", objectId );
return;
}
IGameObject gameObject = maybeObject.get();
ITile location = gameObject.getLocation().get();
String weaponIndexOrLevelArgument = Iterators.getNext( tokens, null );
Optional<Integer> optionalWeaponIndex = ConversionUtils.toInteger( weaponIndexOrLevelArgument );
int weaponIndex = 0;
if (optionalWeaponIndex.isPresent()) {
weaponIndex = optionalWeaponIndex.get();
weaponIndexOrLevelArgument = Iterators.getNext( tokens, null );
}
final String levelArgument = ifNotNullElse( weaponIndexOrLevelArgument, location.getLevel().getType().getName() );
Optional<? extends ILevel> level = gameController.get().getGame().getLevels().stream().filter(
aLevel -> aLevel.getType().getName().equalsIgnoreCase( levelArgument ) ).findFirst();
if (!level.isPresent()) {
err( "No such level in this game: %s", levelArgument );
return;
}
// Check to see if it's mobile by finding its mobility module.
Optional<IWeaponModule> optionalWeapon = gameObject.getModule( PublicModuleType.WEAPON, weaponIndex );
if (!optionalWeapon.isPresent()) {
if (weaponIndex == 0)
err( "Object has no weapons: %s", gameObject );
else
err( "Object has no weapon at index %d: %s", weaponIndex, gameObject );
return;
}
IWeaponModule weaponModule = optionalWeapon.get();
// Find the target tile.
Vec2 targetCoordinate = location.getPosition().translate( dx, dy );
Optional<? extends ITile> target = level.get().getTile( targetCoordinate );
if (!target.isPresent()) {
err( "No tile in level: %s, at position: %s", level.get().getType().getName(), targetCoordinate );
return;
}
// Fire at the target.
try {
if (!weaponModule.getController().fireAt( target.get() )) {
err( "Firing not possible." );
return;
}
inf( "Fired at: %s", target.get().getContents() );
}
catch (final IWeaponModuleController.OutOfRangeException ignored) {
err( "Couldn't fire, target out of range: %s", target.get() );
}
catch (final IWeaponModuleController.OutOfRepeatsException ignored) {
err( "Couldn't fire, weapon out of repeats." );
}
catch (final IWeaponModuleController.OutOfAmmunitionException ignored) {
err( "Couldn't fire, weapon out of ammunition." );
}
}
}