use of megamek.common.actions.ChargeAttackAction in project spoon by INRIA.
the class TestBot method firstPass.
/**
*************************************************************************
* first pass, filter moves based upon present case
*************************************************************************
*/
public void firstPass(CEntity self) {
ArrayList enemies = getEnemyEntities();
Object[] move_array;
if (self.getEntity().isSelectableThisTurn() && !self.moved) {
move_array = self.getAllMoves().values().toArray();
} else {
move_array = new Object[] { self.current };
}
for (int i = 0; i < move_array.length; i++) {
MoveOption option = (MoveOption) move_array[i];
option.setState();
for (int e = 0; e < enemies.size(); e++) {
// for each enemy
Entity en = (Entity) enemies.get(e);
// ignore loaded units
if (en.getPosition() == null) {
continue;
}
CEntity enemy = centities.get(en);
int[] modifiers = option.getModifiers(enemy.getEntity());
if (modifiers[MoveOption.DEFENCE_MOD] == ToHitData.IMPOSSIBLE && modifiers[MoveOption.ATTACK_MOD] == ToHitData.IMPOSSIBLE) {
continue;
}
int enemy_hit_arc = CEntity.getThreatHitArc(enemy.current.getFinalCoords(), enemy.current.getFinalFacing(), option.getFinalCoords());
int self_hit_arc = CEntity.getThreatHitArc(option.getFinalCoords(), option.getFinalFacing(), enemy.current.getFinalCoords());
if (!enemy.getEntity().isImmobile() && modifiers[MoveOption.DEFENCE_MOD] != ToHitData.IMPOSSIBLE) {
self.engaged = true;
int mod = modifiers[MoveOption.DEFENCE_MOD];
double max = option.getMaxModifiedDamage(enemy.current, mod, modifiers[MoveOption.DEFENCE_PC]);
if (en.isSelectableThisTurn()) {
enemy.current.addStep(MovePath.STEP_TURN_RIGHT);
max = Math.max(option.getMaxModifiedDamage(enemy.current, mod + 1, modifiers[MoveOption.DEFENCE_PC]), max);
enemy.current.removeLastStep();
enemy.current.addStep(MovePath.STEP_TURN_LEFT);
max = Math.max(option.getMaxModifiedDamage(enemy.current, mod + 1, modifiers[MoveOption.DEFENCE_PC]), max);
// return to original facing
enemy.current.removeLastStep();
}
max = self.getThreatUtility(max, self_hit_arc);
if (enemy.getEntity().isProne())
max *= enemy.base_psr_odds;
MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);
di.threat = max;
di.max_threat = max;
option.threat += max;
option.tv.add(max + " Threat " + e + "\n");
}
/*
* As a first approximation, take the maximum to a single
* target
*/
if (!option.isPhysical) {
if (modifiers[MoveOption.ATTACK_MOD] != ToHitData.IMPOSSIBLE) {
self.engaged = true;
double max = enemy.current.getMaxModifiedDamage(option, modifiers[0], modifiers[MoveOption.ATTACK_PC]);
max = enemy.getThreatUtility(max, enemy_hit_arc);
MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);
di.damage = max;
di.min_damage = max;
option.tv.add(max + " Damage " + e + "\n");
option.damage = Math.max(max, option.damage);
}
} else {
CEntity target = centities.get(option.getPhysicalTargetId());
try {
if (target.getEntity().getId() == enemy.getEntity().getId()) {
if (!target.isPhysicalTarget) {
ToHitData toHit = null;
double self_threat = 0;
double damage = 0;
if (option.isJumping()) {
self.current.setState();
toHit = DfaAttackAction.toHit(game, option.getEntity().getId(), target.getEntity(), option);
damage = 2 * DfaAttackAction.getDamageFor(option.getEntity());
self_threat = option.getCEntity().getThreatUtility(DfaAttackAction.getDamageTakenBy(option.getEntity()), ToHitData.SIDE_REAR) * Compute.oddsAbove(toHit.getValue()) / 100;
self_threat += option.getCEntity().getThreatUtility(.1 * self.getEntity().getWeight(), ToHitData.SIDE_REAR);
self_threat *= 100 / option.getCEntity().getEntity().getWeight();
} else {
self.current.setState();
toHit = new ChargeAttackAction(option.getEntity(), target.getEntity()).toHit(game, option);
damage = ChargeAttackAction.getDamageFor(option.getEntity(), option.getHexesMoved());
self_threat = option.getCEntity().getThreatUtility(ChargeAttackAction.getDamageTakenBy(option.getEntity(), target.getEntity()), ToHitData.SIDE_FRONT) * (Compute.oddsAbove(toHit.getValue()) / 100);
option.setState();
}
damage = target.getThreatUtility(damage, toHit.getSideTable()) * Compute.oddsAbove(toHit.getValue()) / 100;
// mechs
if (!option.isJumping())
damage *= Math.sqrt((double) enemy.bv / (double) self.bv);
// 12
if (toHit.getValue() > 10)
damage = 0;
// 7 or less is good
if (toHit.getValue() < 8)
damage *= 1.5;
// this is all you are good for
if (self.range_damages[CEntity.RANGE_SHORT] < 5)
damage *= 2;
MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);
di.damage = damage;
di.min_damage = damage;
option.damage = damage;
option.movement_threat += self_threat;
} else {
option.threat += Integer.MAX_VALUE;
}
}
} catch (Exception e1) {
e1.printStackTrace();
option.threat += Integer.MAX_VALUE;
}
}
}
// -- end while of each enemy
self.current.setState();
}
// -- end while of first pass
// top balanced
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 100);
// top damage
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 100);
}
Aggregations