/**
* To-hit number for a ram, assuming that movement has been handled
*/
public ToHitData toHit(IGame game, Targetable target, Coords src,
int elevation, Coords priorSrc, int movement) {
final Entity ae = getEntity(game);
// arguments legal?
if (ae == null) {
throw new IllegalStateException("Attacker is null");
}
// Do to pretreatment of physical attacks, the target may be null.
if (target == null) {
return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is null");
}
if(!(ae instanceof Aero)) {
return new ToHitData(TargetRoll.IMPOSSIBLE, "Attacker is not Aero");
}
if(!(target instanceof Aero)) {
return new ToHitData(TargetRoll.IMPOSSIBLE, "Target is not Aero");
}
if(ae instanceof FighterSquadron || target instanceof FighterSquadron) {
return new ToHitData(TargetRoll.IMPOSSIBLE, "fighter squadrons may not ram nor be the target of a ramming attc");
}
Entity te = null;
if (target.getTargetType() == Targetable.TYPE_ENTITY) {
te = (Entity) target;
}
if (!game.getOptions().booleanOption("friendly_fire")) {
// a friendly unit can never be the target of a direct attack.
if (target.getTargetType() == Targetable.TYPE_ENTITY
&& (((Entity)target).getOwnerId() == ae.getOwnerId()
|| (((Entity)target).getOwner().getTeam() != Player.TEAM_NONE
&& ae.getOwner().getTeam() != Player.TEAM_NONE
&& ae.getOwner().getTeam() == ((Entity)target).getOwner().getTeam())))
return new ToHitData(TargetRoll.IMPOSSIBLE, "A friendly unit can never be the target of a direct attack.");
}
IHex attHex = game.getBoard().getHex(src);
IHex targHex = game.getBoard().getHex(target.getPosition());
final int attackerElevation = elevation + attHex.getElevation();
final int targetElevation = target.getElevation()
+ targHex.getElevation();
ToHitData toHit = null;
// can't target yourself
if (ae.equals(te)) {
return new ToHitData(TargetRoll.IMPOSSIBLE,
"You can't target yourself");
}
// Can't target a transported entity.
if (te != null && Entity.NONE != te.getTransportId()) {
return new ToHitData(TargetRoll.IMPOSSIBLE,
"Target is a passenger.");
}
// check range
if (src.distance(target.getPosition()) > 0) {
return new ToHitData(TargetRoll.IMPOSSIBLE, "Target not in range");
}
// target must be at same elevation level
if (attackerElevation != targetElevation) {
return new ToHitData(TargetRoll.IMPOSSIBLE,
"Target must be at the same elevation level");
}
// can't attack Aero making a different ramming attack
if (te != null && te.isRamming()) {
return new ToHitData(TargetRoll.IMPOSSIBLE,
"Target is already making a ramming attack");
}
//attacker
// target must have moved already
if (te != null && !te.isDone()) {
return new ToHitData(TargetRoll.IMPOSSIBLE,
"Target must be done with movement");
}
//Set the base BTH
int base = 6 + te.getCrew().getPiloting() - ae.getCrew().getPiloting();
toHit = new ToHitData(base, "base");
Aero a = (Aero)ae;
//target type
if(target instanceof SpaceStation) {
toHit.addModifier(-1,"target is a space station");
} else if(target instanceof Warship) {
toHit.addModifier(+1,"target is a warship");
} else if(target instanceof Jumpship) {
toHit.addModifier(+0,"target is a jumpship");
} else if(target instanceof Dropship) {
toHit.addModifier(+2,"target is a dropship");
} else {
toHit.addModifier(+4,"target is a fighter/small craft");
}
//attacker type
if(a instanceof SpaceStation) {
toHit.addModifier(+0,"attacker is a space station");
} else if(a instanceof Warship) {
toHit.addModifier(+1,"attacker is a warship");
} else if(a instanceof Jumpship) {
toHit.addModifier(+0,"attacker is a jumpship");
} else if(a instanceof Dropship) {
toHit.addModifier(-1,"attacker is a dropship");
} else {
toHit.addModifier(-2,"attacker is a fighter/small craft");
}
//can the target unit move
if(target.isImmobile() || te.getWalkMP() == 0)
toHit.addModifier(-2,"target cannot spend thrust");
//sensor damage
if(a.getSensorHits() > 0)
toHit.addModifier(+1, "sensor damage");
//avionics damage
int avionics = a.getAvionicsHits();
if(avionics > 3)
avionics = 3;
if(avionics > 0)
toHit.addModifier(avionics, "avionics damage");
//evading bonuses
if (target.getTargetType() == Targetable.TYPE_ENTITY && te.isEvading()) {
toHit.addModifier(te.getEvasionBonus(), "target is evading");
}
//determine hit direction
toHit.setSideTable(te.sideTable(priorSrc));
toHit.setHitTable(ToHitData.HIT_NORMAL);
// done!
return toHit;