use of megamek.common.Entity in project megameklab by MegaMek.
the class MovementView method setMovementModToolTips.
private void setMovementModToolTips(Entity en) {
StringJoiner walkTooltip = new StringJoiner(", ");
StringJoiner runTooltip = new StringJoiner(", ");
StringJoiner jumpTooltip = new StringJoiner(", ");
if (en.hasModularArmor()) {
walkTooltip.add("-1 (Modular armor)");
jumpTooltip.add("-1 (Modular armor)");
}
if (en instanceof Mech) {
if (((Mech) en).hasMPReducingHardenedArmor()) {
runTooltip.add("-1 (Hardened armor)");
}
if (((Mech) en).hasArmedMASC()) {
runTooltip.add("MASC/Supercharger");
}
int medShields = ((Mech) en).getNumberOfShields(MiscType.S_SHIELD_MEDIUM);
int lgShields = ((Mech) en).getNumberOfShields(MiscType.S_SHIELD_LARGE);
if (lgShields + medShields > 0) {
walkTooltip.add(String.format("-%d (Shield)", lgShields + medShields));
}
if (lgShields > 0) {
jumpTooltip.add("No Jump (Large Shield)");
}
} else if (en.hasWorkingMisc(MiscType.F_MASC)) {
runTooltip.add("Supercharger");
} else if (en.hasWorkingMisc(MiscType.F_JET_BOOSTER)) {
runTooltip.add("Jet Booster");
}
Optional<Mounted> partialWing = en.getMisc().stream().filter(m -> m.getType().hasFlag(MiscType.F_PARTIAL_WING)).findAny();
if (partialWing.isPresent()) {
int bonus = 2;
if (en instanceof Mech) {
bonus = ((Mech) en).getPartialWingJumpBonus(partialWing.get());
}
jumpTooltip.add(String.format("+%d (Partial wing)", bonus));
}
txtWalkFinal.setToolTipText(walkTooltip.length() > 0 ? walkTooltip.toString() : null);
txtRunFinal.setToolTipText(runTooltip.length() > 0 ? runTooltip.toString() : null);
txtJumpFinal.setToolTipText(jumpTooltip.length() > 0 && en.getOriginalJumpMP(true) > 0 ? jumpTooltip.toString() : null);
}
use of megamek.common.Entity in project megameklab by MegaMek.
the class UnitPrintQueueDialog method actionPerformed.
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == bCancel) {
dispose();
}
if (ae.getSource() == bPrint) {
UnitPrintManager.printAllUnits(units, chSinglePrint.isSelected());
dispose();
}
if (ae.getSource().equals(bSelectCache)) {
UnitLoadingDialog unitLoadingDialog = new UnitLoadingDialog(clientgui);
unitLoadingDialog.setVisible(true);
UnitSelectorDialog viewer = new UnitSelectorDialog(clientgui, unitLoadingDialog, true);
viewer.setVisible(false);
Entity entity = viewer.getChosenEntity();
if (entity != null) {
units.add(entity);
refresh();
}
} else if (ae.getSource().equals(bSelectFile)) {
String filePathName = System.getProperty("user.dir").toString() + "/data/mechfiles/";
JFileChooser f = new JFileChooser(filePathName);
f.setLocation(clientgui.getLocation().x + 150, clientgui.getLocation().y + 100);
f.setDialogTitle("Print Unit File");
f.setMultiSelectionEnabled(true);
FileNameExtensionFilter filter = new FileNameExtensionFilter("Unit Files", "blk", "mtf");
// Add a filter
f.setFileFilter(filter);
int returnVal = f.showOpenDialog(clientgui);
if ((returnVal != JFileChooser.APPROVE_OPTION) || (f.getSelectedFile() == null)) {
// I want a file, y'know!
return;
}
for (File entityFile : f.getSelectedFiles()) {
try {
Entity tempEntity = new MechFileParser(entityFile).getEntity();
units.add(tempEntity);
} catch (Exception ex) {
ex.printStackTrace();
}
}
refresh();
} else if (ae.getSource().equals(bRemove)) {
if (unitList.getSelectedIndices().length > 0) {
for (int pos = unitList.getSelectedIndices().length - 1; pos >= 0; pos--) {
units.remove(unitList.getSelectedIndices()[pos]);
}
refresh();
}
}
}
use of megamek.common.Entity in project spoon by INRIA.
the class TestBot method calculateMove.
public MoveOption[] calculateMove(Entity entity) {
java.util.Vector enemy_array = game.getValidTargets(entity);
java.util.Vector entities = game.getEntitiesVector();
CEntity self = centities.get(entity);
Object[] move_array;
int friends = entities.size() - enemy_array.size();
/**
*********************************************************************
* Second pass, combination moves/firing based only on the present
* case, since only one mech moves at a time
*********************************************************************
*/
move_array = self.pass.values().toArray();
self.pass.clear();
for (int j = 0; j < move_array.length && friends > 2; j++) {
MoveOption option = (MoveOption) move_array[j];
for (int e = 0; e < enemy_array.size(); e++) {
Entity en = (Entity) enemy_array.elementAt(e);
CEntity enemy = centities.get(en);
for (Enumeration f = entities.elements(); f.hasMoreElements(); ) {
Entity other = (Entity) f.nextElement();
if (other.isEnemyOf(self.entity)) {
continue;
}
MoveOption foption = centities.get(other).current;
double threat_divisor = 1;
MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);
if (foption.getDamageInfo(enemy, false) != null) {
option.damage += (enemy.canMove() ? .1 : .2) * di.damage;
threat_divisor += foption.getCEntity().canMove() ? .4 : .6;
}
option.threat -= di.threat;
di.threat /= threat_divisor;
option.threat += di.threat;
}
}
}
// top balanced
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 50);
// top damage
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 50);
/**
*********************************************************************
* third pass, (not so bad) oppurtunistic planner gives preference to
* good ranges/defensive positions based upon the mech characterization
*********************************************************************
*/
move_array = self.pass.values().toArray();
self.pass.clear();
for (int j = 0; j < move_array.length; j++) {
MoveOption option = (MoveOption) move_array[j];
option.setState();
double adjustment = 0;
double temp_adjustment = 0;
for (int e = 0; e < enemy_array.size(); e++) {
// for each enemy
Entity en = (Entity) enemy_array.elementAt(e);
CEntity enemy = centities.get(en);
int current_range = self.current.getFinalCoords().distance(enemy.current.getFinalCoords());
int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());
if (range > self.long_range) {
temp_adjustment += (!(range < enemy.long_range) ? .5 : 1) * (1 + self.range_damages[self.range]) * (Math.max(range - self.long_range - .5 * Math.max(self.jumpMP, .8 * self.runMP), 0));
}
if ((self.range == CEntity.RANGE_SHORT && (current_range > 5 || range > 9)) || (self.range_damages[CEntity.RANGE_SHORT] < 4 && current_range > 10)) {
temp_adjustment += ((enemy.range > CEntity.RANGE_SHORT) ? .5 : 1) * (Math.max(1 + self.range_damages[CEntity.RANGE_SHORT], 5)) * Math.max(range - .5 * Math.max(self.jumpMP, .8 * self.runMP), 0);
} else if (self.range == CEntity.RANGE_MEDIUM) {
temp_adjustment += ((current_range < 6 || current_range > 12) ? 1 : .25) * ((enemy.range > CEntity.RANGE_SHORT) ? .5 : 1) * (1 + self.range_damages[CEntity.RANGE_MEDIUM]) * Math.abs(range - .5 * Math.max(self.jumpMP, .8 * self.runMP));
} else if (option.damage < .25 * self.range_damages[CEntity.RANGE_LONG]) {
temp_adjustment += ((range < 10) ? .25 : 1) * (Math.max(1 + self.range_damages[CEntity.RANGE_LONG], 3)) * (1 / (1 + option.threat));
}
adjustment += Math.sqrt(temp_adjustment * enemy.bv / self.bv);
// I would always like to face the opponent
if (!(enemy.getEntity().isProne() || enemy.getEntity().isImmobile()) && CEntity.getThreatHitArc(option.getFinalCoords(), option.getFinalFacing(), enemy.getEntity().getPosition()) != ToHitData.SIDE_FRONT) {
int fa = CEntity.getFiringAngle(option.getFinalCoords(), option.getFinalFacing(), enemy.getEntity().getPosition());
if (fa > 90 && fa < 270) {
int distance = option.getFinalCoords().distance(enemy.current.getFinalCoords());
double mod = 1;
if (fa > 130 && fa < 240)
mod = 2;
// big formula that says don't do it
mod *= ((Math.max(self.jumpMP, .8 * self.runMP) < 5) ? 2 : 1) * ((double) self.bv / (double) 50) * Math.sqrt(((double) self.bv) / enemy.bv) / ((double) distance / 6 + 1);
option.self_threat += mod;
option.tv.add(mod + " " + fa + " Back to enemy\n");
}
}
}
adjustment *= self.overall_armor_percent * self.strategy.attack / enemy_array.size();
// fix for hiding in level 2 water
// To a greedy bot, it always seems nice to stay in here...
IHex h = game.getBoard().getHex(option.getFinalCoords());
if (h.containsTerrain(Terrains.WATER) && h.surface() > (self.getEntity().getElevation() + ((option.getFinalProne()) ? 0 : 1))) {
double mod = (self.getEntity().heat + option.getMovementheatBuildup() <= 7) ? 100 : 30;
adjustment += self.bv / mod;
}
// add them in now, then re-add them later
if (self.range > CEntity.RANGE_SHORT) {
int ele_dif = game.getBoard().getHex(option.getFinalCoords()).getElevation() - game.getBoard().getHex(self.current.getFinalCoords()).getElevation();
adjustment -= (Math.max(ele_dif, 0) + 1) * ((double) Compute.getTargetTerrainModifier(game, option.getEntity()).getValue() + 1);
}
// close the range if nothing else and healthy
if (option.damage < .25 * self.range_damages[self.range] && adjustment < self.range_damages[self.range]) {
for (int e = 0; e < enemy_array.size(); e++) {
Entity en = (Entity) enemy_array.elementAt(e);
CEntity enemy = centities.get(en);
int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());
if (range > 5)
adjustment += Math.pow(self.overall_armor_percent, 2) * Math.sqrt((double) (range - 4) * enemy.bv / (double) self.bv) / enemy_array.size();
}
}
if (option.damage < .25 * (1 + self.range_damages[self.range])) {
option.self_threat += 2 * adjustment;
} else if (option.damage < .5 * (1 + self.range_damages[self.range])) {
option.self_threat += adjustment;
}
option.tv.add(option.self_threat + " Initial Damage Adjustment " + "\n");
}
// top balanced
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 30);
// top damage
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 30);
// reduce self threat, and add bonus for terrain
for (Iterator i = self.pass.values().iterator(); i.hasNext(); ) {
MoveOption option = (MoveOption) i.next();
option.setState();
option.self_damage *= .5;
option.self_threat *= .5;
// TODO: should scale to the unit bv
double terrain = 2 * ((double) Compute.getTargetTerrainModifier(game, option.getEntity()).getValue());
option.tv.add(terrain + " Terrain Adjusment " + "\n");
option.self_threat -= terrain;
}
move_array = self.pass.values().toArray();
self.pass.clear();
/**
*********************************************************************
* fourth pass, speculation on top moves use averaging to filter
*********************************************************************
*/
for (int e = 0; e < enemy_array.size(); e++) {
// for each enemy
Entity en = (Entity) enemy_array.elementAt(e);
CEntity enemy = centities.get(en);
// engage in speculation on "best choices" when you loose iniative
if (enemy.canMove()) {
Object[] enemy_move_array = enemy.pass.values().toArray();
Vector to_check = new Vector();
// check some enemy moves
for (int j = 0; j < move_array.length; j++) {
MoveOption option = null;
to_check.clear();
option = (MoveOption) move_array[j];
option.setState();
// check for damning hexes specifically
// could also look at intervening defensive
Vector coord = new Vector();
Coords back = option.getFinalCoords().translated((option.getFinalFacing() + 3) % 6);
coord.add(back);
coord.add(back.translated((option.getFinalFacing() + 2) % 6));
coord.add(back.translated((option.getFinalFacing() + 4) % 6));
coord.add(option.getFinalCoords().translated((option.getFinalFacing())));
coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 1) % 6));
coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 2) % 6));
coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 4) % 6));
coord.add(option.getFinalCoords().translated((option.getFinalFacing() + 5) % 6));
Iterator ci = coord.iterator();
while (ci.hasNext()) {
Coords test = (Coords) ci.next();
List c = enemy.findMoves(test);
if (c.size() != 0)
to_check.addAll(c);
}
int range = option.getFinalCoords().distance(enemy.current.getFinalCoords());
int compare = 0;
if ((enemy.long_range) > range - Math.max(enemy.jumpMP, enemy.runMP)) {
compare = 30;
} else if (enemy.long_range > range) {
compare = 10;
}
double mod = this.enemies_moved / this.getEnemyEntities().size();
compare *= (1 + mod);
for (int k = 0; k <= compare && k < enemy_move_array.length; k++) {
if (enemy_move_array.length < compare) {
to_check.add(enemy_move_array[k]);
} else {
int value = Compute.randomInt(enemy_move_array.length);
if (value % 2 == 1) {
to_check.add(enemy_move_array[value]);
} else {
to_check.add(enemy_move_array[k]);
}
}
}
Iterator eo = to_check.iterator();
while (eo.hasNext()) {
MoveOption enemy_option = (MoveOption) eo.next();
double max_threat = 0;
double max_damage = 0;
enemy_option.setState();
int enemy_hit_arc = CEntity.getThreatHitArc(enemy_option.getFinalCoords(), enemy_option.getFinalFacing(), option.getFinalCoords());
int self_hit_arc = CEntity.getThreatHitArc(enemy_option.getFinalCoords(), enemy_option.getFinalFacing(), option.getFinalCoords());
if (enemy_option.isJumping()) {
enemy_hit_arc = Compute.ARC_FORWARD;
}
int[] modifiers = option.getModifiers(enemy_option.getEntity());
if (modifiers[1] != ToHitData.IMPOSSIBLE) {
self.engaged = true;
if (!enemy_option.isJumping()) {
max_threat = option.getMaxModifiedDamage(enemy_option, modifiers[1], modifiers[MoveOption.DEFENCE_PC]);
} else {
max_threat = .8 * enemy.getModifiedDamage((modifiers[MoveOption.DEFENCE_PC] == 1) ? CEntity.TT : ToHitData.SIDE_FRONT, enemy_option.getFinalCoords().distance(option.getFinalCoords()), modifiers[1]);
}
max_threat = self.getThreatUtility(max_threat, self_hit_arc);
}
if (modifiers[0] != ToHitData.IMPOSSIBLE) {
self.engaged = true;
max_damage = enemy_option.getMaxModifiedDamage(option, modifiers[0], modifiers[MoveOption.ATTACK_PC]);
max_damage = enemy.getThreatUtility(max_damage, enemy_hit_arc);
if (option.isPhysical) {
if (centities.get(option.getPhysicalTargetId()).getEntity().getId() == enemy.getEntity().getId()) {
max_damage = option.getDamage(enemy);
} else {
max_damage = 0;
}
}
}
MoveOption.DamageInfo di = option.getDamageInfo(enemy, true);
di.max_threat = Math.max(max_threat, di.max_threat);
di.min_damage = Math.min(di.min_damage, max_damage);
if (max_threat - max_damage > di.threat - di.damage) {
di.threat = max_threat;
di.damage = max_damage;
option.tv.add(max_threat + " Spec Threat " + e + "\n");
option.tv.add(max_damage + " Spec Damage " + e + "\n");
}
}
// update estimates
option.damage = 0;
option.threat = 0;
for (Iterator i = option.damageInfos.keySet().iterator(); i.hasNext(); ) {
// my damage is the average of expected and min
CEntity cen = (CEntity) i.next();
// rescale
MoveOption.DamageInfo di = option.getDamageInfo(cen, true);
di.min_damage /= cen.strategy.target;
di.damage /= cen.strategy.target;
option.damage += (di.min_damage + di.damage) / 2;
// my threat is average of absolute worst, and expected
option.threat = Math.max(option.threat, di.max_threat + di.threat) / 2;
di.threat = (di.max_threat + 2 * di.threat) / 3;
}
}
// restore enemy
enemy.current.setState();
}
self.current.setState();
}
// --end move speculation
// top balanced
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(1, 1), 20);
// top damage
filterMoves(move_array, self.pass, new MoveOption.WeightedComparator(.5, 1), 20);
// reduce transient damage estimates
for (Iterator i = self.pass.values().iterator(); i.hasNext(); ) {
MoveOption option = (MoveOption) i.next();
option.self_threat *= .5;
option.self_damage *= .5;
}
move_array = self.pass.values().toArray();
self.pass.clear();
/**
*********************************************************************
* fourth pass, final damage and threat approximation --prevents moves
* that from the previous pass would cause the mech to die
*********************************************************************
*/
if (self.engaged) {
for (int j = 0; j < move_array.length; j++) {
MoveOption option = (MoveOption) move_array[j];
option.setState();
GAAttack temp = this.bestAttack(option);
if (temp != null) {
option.damage = (option.damage + temp.getFittestChromosomesFitness()) / 2;
} else {
option.damage /= 2;
}
for (int e = 0; e < enemy_array.size(); e++) {
// for each
// enemy
Entity en = (Entity) enemy_array.elementAt(e);
CEntity enemy = centities.get(en);
if (!enemy.canMove()) {
option.setThreat(enemy, (option.getThreat(enemy) + this.attackUtility(enemy.current, self)) / 2);
option.tv.add(option.getThreat(enemy) + " Revised Threat " + e + " \n");
if (!option.isPhysical) {
if (temp != null) {
option.setDamage(enemy, (option.getDamage(enemy) + temp.getDamageUtility(enemy)) / 2);
} else {
// probably zero, but just in case
option.setDamage(enemy, option.getMinDamage(enemy));
}
option.tv.add(option.getDamage(enemy) + " Revised Damage " + e + " \n");
// this needs to be reworked
if (option.getFinalCoords().distance(enemy.current.getFinalCoords()) == 1) {
PhysicalOption p = pcalc.getBestPhysicalAttack(option.getEntity(), enemy.getEntity(), game);
if (p != null) {
option.setDamage(enemy, option.getDamage(enemy) + p.expectedDmg);
option.tv.add(p.expectedDmg + " Physical Damage " + e + " \n");
}
p = pcalc.getBestPhysicalAttack(enemy.getEntity(), option.getEntity(), game);
if (p != null) {
option.setThreat(enemy, option.getThreat(enemy) + .5 * p.expectedDmg);
option.tv.add(.5 * p.expectedDmg + " Physical Threat " + e + " \n");
}
}
}
} else if (!option.isPhysical) {
// enemy can move (not
if (temp != null) {
option.setDamage(enemy, (2 * option.getDamage(enemy) + temp.getDamageUtility(enemy)) / 3);
} else {
option.setDamage(enemy, option.getMinDamage(enemy));
}
} else {
// get a more accurate estimate
option.setDamage(enemy, option.getDamage(enemy) / Math.sqrt((double) enemy.bv / (double) self.bv));
option.damage = option.getDamage(enemy);
}
}
option.threat = 0;
for (Iterator i = option.damageInfos.values().iterator(); i.hasNext(); ) {
option.threat += ((MoveOption.DamageInfo) i.next()).threat;
}
option.tv.add(option.threat + " Revised Threat Utility\n");
option.tv.add(option.damage + " Revised Damage Utility\n");
}
}
Arrays.sort(move_array, new MoveOption.WeightedComparator(1, 1));
self.current.setState();
/**
*********************************************************************
* Return top twenty moves to the lance algorithm
*********************************************************************
*/
MoveOption[] result = new MoveOption[Math.min(move_array.length, 20)];
int offset = 0;
for (int i = 0; i < Math.min(move_array.length, 20); i++) {
MoveOption next = (MoveOption) move_array[i];
if (next.isPhysical && self.range_damages[CEntity.RANGE_SHORT] > 5 && next.doomed) {
if (offset + 20 < move_array.length) {
next = (MoveOption) move_array[offset + 20];
offset++;
}
}
result[i] = next;
}
return result;
}
use of megamek.common.Entity in project spoon by INRIA.
the class TestBot method calculateFiringTurn.
public void calculateFiringTurn() {
int first_entity = game.getFirstEntityNum();
int entity_num = first_entity;
int best_entity = first_entity;
double max = java.lang.Double.MIN_VALUE;
int[] results = null;
Vector winner = null;
int arc = 0;
if (entity_num == -1) {
return;
}
do {
Entity en = game.getEntity(entity_num);
CEntity cen = centities.get(en);
GAAttack test = bestAttack(cen.current, null, 3);
if (test != null && test.getFittestChromosomesFitness() > max) {
max = test.getFittestChromosomesFitness();
results = test.getResultChromosome();
arc = test.getFiringArc();
best_entity = entity_num;
winner = test.getAttack();
}
entity_num = game.getNextEntityNum(entity_num);
} while (entity_num != first_entity && entity_num != -1);
java.util.Vector av = new java.util.Vector();
// maximum already selected (or default)
Entity en = game.getEntity(best_entity);
if (results != null) {
Entity primary_target = (Entity) game.getEntitiesVector().elementAt(results[results.length - 1]);
TreeMap tm = new TreeMap(new AttackOption.Sorter(centities.get(primary_target)));
for (int i = 0; i < results.length - 1; i++) {
AttackOption a = (AttackOption) ((Vector) winner.elementAt(i)).elementAt(results[i]);
if (a.target != null) {
a.target.expected_damage[a.toHit.getSideTable()] += a.value;
a.target.hasTakenDamage = true;
tm.put(a, a);
}
}
Iterator i = tm.values().iterator();
while (i.hasNext()) {
AttackOption a = (AttackOption) i.next();
av.addElement(new WeaponAttackAction(en.getId(), a.target.getEntity().getId(), en.getEquipmentNum(a.weapon)));
}
}
switch(arc) {
case 1:
av.insertElementAt(new TorsoTwistAction(en.getId(), (en.getFacing() + 5) % 6), 0);
break;
case 2:
av.insertElementAt(new TorsoTwistAction(en.getId(), (en.getFacing() + 1) % 6), 0);
break;
}
sendAttackData(best_entity, av);
}
use of megamek.common.Entity in project spoon by INRIA.
the class TestBot method initFiring.
protected void initFiring() {
java.util.Vector entities = game.getEntitiesVector();
for (int i = 0; i < entities.size(); i++) {
Entity entity = (Entity) entities.elementAt(i);
CEntity centity = centities.get(entity);
centity.reset();
centity.enemy_num = i;
}
for (Iterator i = this.getEnemyEntities().iterator(); i.hasNext(); ) {
Entity entity = (Entity) i.next();
CEntity centity = centities.get(entity);
if (entity.isMakingDfa() || entity.isCharging()) {
// try to prevent a physical attack from happening
// but should take into account the toHit of the attack
centity.strategy.target = 2.5;
}
}
}
Aggregations