📄 moveoption.java
字号:
this.entity.setSecondaryFacing(facing); this.entity.delta_distance = 0; this.entity.setProne(prone); } else { this.entity.setPosition(getFinalCoords()); this.entity.setFacing(getFinalFacing()); this.entity.setSecondaryFacing(getFinalFacing()); this.entity.setProne(getFinalProne()); this.entity.delta_distance = getHexesMoved(); } this.entity.moved = getLastStepMovementType(); } /** * TODO: replace with more common logic * * approximates the attack and defensive modifies assumes that set state * has been called */ public int[] getModifiers(final Entity te) { //set them at the appropriate positions final Entity ae = this.entity; int attHeight = ae.isProne() ? 0 : 1; int targHeight = te.isProne() ? 0 : 1; int attEl = 0; int targEl = 0; attEl = ae.getElevation() + attHeight; targEl = te.getElevation() + targHeight; boolean pc = false; boolean apc = false; //get all relevent modifiers ToHitData toHita = new ToHitData(); ToHitData toHitd = new ToHitData(); toHita.append(Compute.getAttackerMovementModifier(game, ae.getId())); toHita.append(Compute.getTargetMovementModifier(game, te.getId())); toHita.append(Compute.getTargetTerrainModifier(game, te)); toHita.append(Compute.getAttackerTerrainModifier(game, ae.getId())); toHitd.append(Compute.getAttackerMovementModifier(game, te.getId())); toHitd.append(Compute.getTargetMovementModifier(game, ae.getId())); if (!(this.isPhysical && isJumping())) { toHitd.append(Compute.getTargetTerrainModifier(game, ae)); } toHitd.append(Compute.getAttackerTerrainModifier(game, te.getId())); IHex attHex = game.getBoard().getHex(ae.getPosition()); if (attHex.containsTerrain(Terrains.WATER) && attHex.surface() > attEl) { toHita.addModifier(ToHitData.IMPOSSIBLE, "Attacker in depth 2+ water"); toHitd.addModifier(ToHitData.IMPOSSIBLE, "Defender in depth 2+ water"); } else if (attHex.surface() == attEl && ae.height() > 0) { apc = true; } IHex targHex = game.getBoard().getHex(te.getPosition()); if (targHex.containsTerrain(Terrains.WATER)) { if (targHex.surface() == targEl && te.height() > 0) { pc = true; } else if (targHex.surface() > targEl) { toHita.addModifier(ToHitData.IMPOSSIBLE, "Attacker in depth 2+ water"); toHitd.addModifier(ToHitData.IMPOSSIBLE, "Defender in depth 2+ water"); } } // calc & add attacker los mods LosEffects los = LosEffects.calculateLos(game, ae.getId(), te); toHita.append(los.losModifiers(game)); // save variables pc = los.isTargetCover(); apc = los.isAttackerCover(); // reverse attacker & target partial cover & calc defender los mods int temp = los.getTargetCover(); los.setTargetCover(los.getAttackerCover()); los.setAttackerCover(temp); toHitd.append(los.losModifiers(game)); // heatBuildup if (ae.getHeatFiringModifier() != 0) { toHita.addModifier(ae.getHeatFiringModifier(), "heatBuildup"); } if (te.getHeatFiringModifier() != 0) { toHitd.addModifier(te.getHeatFiringModifier(), "heatBuildup"); } // target immobile if (te.isImmobile()) { toHita.addModifier(-4, "target immobile"); } if (ae.isImmobile()) { toHitd.addModifier(-4, "target immobile"); } final int range = ae.getPosition().distance(te.getPosition()); // target prone if (te.isProne()) { // easier when point-blank if (range == 1) { toHita.addModifier(-2, "target prone and adjacent"); } // harder at range if (range > 1) { toHita.addModifier(1, "target prone and at range"); } } if (ae.isProne()) { // easier when point-blank if (range == 1) { toHitd.addModifier(-2, "target prone and adjacent"); } // harder at range if (range > 1) { toHitd.addModifier(1, "target prone and at range"); } } return new int[] { toHita.getValue(), toHitd.getValue(), apc ? 1 : 0, pc ? 1 : 0 }; } /** * TODO: the result of this calculation should be cached... */ public double getUtility() { //self threat and self damage are considered transient double temp_threat = (this.threat + this.movement_threat + this.self_threat + (double) this.getMovementheatBuildup() / 20) / getCEntity().strategy.attack; double temp_damage = (this.damage + this.self_damage) * this.centity.strategy.attack; if (this.threat + this.movement_threat > 4 * this.centity.avg_armor) { double ratio = (this.threat + this.movement_threat) / (this.centity.avg_armor + .25 * this.centity.avg_iarmor); if (ratio > 2) { temp_threat += this.centity.bv / 15.0; //likely to die this.doomed = true; this.inDanger = true; } else if (ratio > 1) { temp_threat += this.centity.bv / 30.0; //in danger this.inDanger = true; } else { temp_threat += this.centity.bv / 75.0; //in danger this.inDanger = true; } } else if (this.threat + this.movement_threat > 30) { temp_threat += this.centity.entity.getWeight(); } double retVal = temp_threat - temp_damage; // If the move has a chance of making MASC fail... if (hasActiveMASC()) { int mascTN = 0; for (final Enumeration i = getSteps(); i.hasMoreElements();) { MoveStep step = (MoveStep) i.nextElement(); if (step.isUsingMASC() && step.getTargetNumberMASC() > mascTN) { mascTN = step.getTargetNumberMASC(); } } double mascMult = Compute.oddsAbove(mascTN)/100; retVal *= (mascMult > 0) ? mascMult : 0.01; } // If getting up is difficult... if (prone) { PilotingRollData tmpPRD = this.centity.getEntity().checkGetUp(getStep(0)); if ((tmpPRD != null) && ((tmpPRD.getValue() == TargetRoll.IMPOSSIBLE) || (tmpPRD.getValue() == TargetRoll.AUTOMATIC_FAIL))) { retVal *= 0.01; } } return retVal; } /** * get maximum damage in this current state from enemy accounting for torso * twisting and slightly for heat -- the ce passed in is supposed to be the * enemy mech */ public double getMaxModifiedDamage(MoveOption enemy, int modifier, int apc) { double max = 0; int distance = getFinalCoords().distance(enemy.getFinalCoords()); double mod = 1; // heat effect modifiers if (enemy.isJumping() || (enemy.entity.heat + enemy.entity.heatBuildup > 4)) { if (enemy.centity.overheat == CEntity.OVERHEAT_LOW) { mod = .75; } else if (enemy.centity.overheat == CEntity.OVERHEAT_HIGH) { mod = .5; } else { mod = .9; } } int enemy_firing_arcs[] = { 0, MovePath.STEP_TURN_LEFT, MovePath.STEP_TURN_RIGHT }; for (int i = 0; i < enemy_firing_arcs.length; i++) { enemy_firing_arcs[i] = CEntity.getThreatHitArc( enemy.getFinalCoords(), MovePath.getAdjustedFacing(enemy.getFinalFacing(), enemy_firing_arcs[i]), getFinalCoords()); } max = enemy.centity.getModifiedDamage((apc == 1) ? CEntity.TT : enemy_firing_arcs[0], distance, modifier); if (enemy_firing_arcs[1] == ToHitData.SIDE_FRONT) { max = Math.max(max, enemy.centity.getModifiedDamage(CEntity.TT, distance, modifier)); } else { max = Math.max(max, enemy.centity.getModifiedDamage(enemy_firing_arcs[1], distance, modifier)); } if (enemy_firing_arcs[2] == ToHitData.SIDE_FRONT) { max = Math.max(max, enemy.centity.getModifiedDamage(CEntity.TT, distance, modifier)); } else { max = Math.max(max, enemy.centity.getModifiedDamage(enemy_firing_arcs[2], distance, modifier)); } //TODO this is not quite right, but good enough for now... //ideally the pa charaterization should be in centity max *= mod; if (!enemy.getFinalProne() && distance == 1 && enemy_firing_arcs[0] != ToHitData.SIDE_REAR) { IHex h = game.getBoard().getHex(getFinalCoords()); IHex h1 = game.getBoard().getHex(enemy.getFinalCoords()); if (Math.abs(h.getElevation() - h1.getElevation()) < 2) { max += ((h1.getElevation() - h.getElevation() == 1 || getFinalProne()) ? 5 : 1) * ((enemy_firing_arcs[0] == ToHitData.SIDE_FRONT) ? .2 : .05) * centity.entity.getWeight() * Compute.oddsAbove(3 + modifier) / 100 + (1 - enemy.centity.base_psr_odds) * enemy.entity.getWeight() / 10.0; } } return max; } public DamageInfo getDamageInfo(CEntity cen, boolean create) { DamageInfo result = (DamageInfo) damageInfos.get(cen); if (create && result == null) { result = new DamageInfo(); damageInfos.put(cen, result); } return result; } public double getDistUtility() { return getMpUsed() + movement_threat * 100 / centity.bv; } /** * There could still be a problem here, but now it's the * callers problem */ int getPhysicalTargetId() { MoveStep step = getLastStep(); if (step == null) { return -1; } Targetable target = step.getTarget(game); if (target == null) { return -1; } return target.getTargetId(); } public String toString() { return getEntity().getShortName() + " " + getEntity().getId() + " " + getFinalCoords() + " " + super.toString() + "\r\n Utility: " + getUtility() + " \r\n" + tv + "\r\n"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -