mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Improve hold position and show shift click waypoints
This commit is contained in:
parent
9a2dc090ca
commit
fa1656922f
@ -38,3 +38,4 @@ Path06="."
|
||||
FilePath="PeonMiningMultiHall.w3x"
|
||||
//FilePath="QuadtreeBugs.w3x"
|
||||
//FilePath="test2.w3x"
|
||||
//FilePath="FarseerHoldPositionTest.w3x"
|
||||
|
@ -6,7 +6,7 @@ import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
public class Quadtree<T> {
|
||||
private static final int MAX_DEPTH = 9;
|
||||
private static final int MAX_DEPTH = 9; // 2^9 = 512, and 512 is the biggest map size...
|
||||
private static final int SPLIT_THRESHOLD = 6;
|
||||
|
||||
private final Rectangle bounds;
|
||||
|
@ -508,6 +508,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final float height = War3MapViewer.this.terrain.getGroundHeight(targetX, targetY)
|
||||
+ target.getFlyHeight() + target.getImpactZ();
|
||||
|
||||
System.out.println(
|
||||
"Spawning INSTANT: " + missileArt + " at " + targetX + ", " + targetY + ", " + height);
|
||||
final MdxModel model = (MdxModel) load(missileArt, War3MapViewer.this.mapPathSolver,
|
||||
War3MapViewer.this.solverParams);
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance();
|
||||
|
@ -1,14 +1,7 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.rendersim;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.etheller.warsmash.parsers.mdlx.Sequence;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.IndexedSequence;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||
|
||||
public class RenderAttackInstant implements RenderEffect {
|
||||
@ -18,14 +11,15 @@ public class RenderAttackInstant implements RenderEffect {
|
||||
final float yaw) {
|
||||
this.modelInstance = modelInstance;
|
||||
final MdxModel model = (MdxModel) this.modelInstance.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = SequenceUtils.selectSequence(PrimaryTag.DEATH, SequenceUtils.EMPTY, sequences,
|
||||
true);
|
||||
if (sequence != null) {
|
||||
this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP);
|
||||
this.modelInstance.setSequence(sequence.index);
|
||||
}
|
||||
// final List<Sequence> sequences = model.getSequences();
|
||||
// final IndexedSequence sequence = SequenceUtils.selectSequence(PrimaryTag.DEATH, SequenceUtils.EMPTY, sequences,
|
||||
// true);
|
||||
// if ((sequence != null) && (sequence.index != -1)) {
|
||||
// this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP);
|
||||
// this.modelInstance.setSequence(sequence.index);
|
||||
// }
|
||||
this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, yaw);
|
||||
System.out.println("creating " + this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,6 +27,7 @@ public class RenderAttackInstant implements RenderEffect {
|
||||
|
||||
final boolean everythingDone = this.modelInstance.sequenceEnded;
|
||||
if (everythingDone) {
|
||||
System.out.println("removing " + this);
|
||||
war3MapViewer.worldScene.removeInstance(this.modelInstance);
|
||||
}
|
||||
return everythingDone;
|
||||
|
@ -79,8 +79,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
|
||||
if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) {
|
||||
addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move, 0, false,
|
||||
false);
|
||||
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), ability.getHandleId(), OrderIds.holdposition,
|
||||
0, false, false);
|
||||
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), 0, OrderIds.holdposition, 0, false, false);
|
||||
addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol, 0,
|
||||
false, false);
|
||||
if (!this.hasStop) {
|
||||
|
@ -27,6 +27,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorStop;
|
||||
@ -58,7 +59,6 @@ public class CUnit extends CWidget {
|
||||
private final List<CAbility> abilities = new ArrayList<>();
|
||||
|
||||
private CBehavior currentBehavior;
|
||||
private COrder currentOrder;
|
||||
private final Queue<COrder> orderQueue = new LinkedList<>();
|
||||
private final CUnitType unitType;
|
||||
|
||||
@ -86,12 +86,15 @@ public class CUnit extends CWidget {
|
||||
private transient CBehaviorFollow followBehavior;
|
||||
private transient CBehaviorPatrol patrolBehavior;
|
||||
private transient CBehaviorStop stopBehavior;
|
||||
private transient CBehaviorHoldPosition holdPositionBehavior;
|
||||
private boolean constructing = false;
|
||||
private float constructionProgress;
|
||||
private boolean hidden = false;
|
||||
private boolean paused = false;
|
||||
private boolean acceptingOrders = true;
|
||||
private boolean invulnerable = false;
|
||||
private boolean holdingPosition = false;
|
||||
private COrder currentOrder = null;
|
||||
private CUnit workerInside;
|
||||
private final War3ID[] buildQueue = new War3ID[WarsmashConstants.BUILD_QUEUE_SIZE];
|
||||
private final QueueItemType[] buildQueueTypes = new QueueItemType[WarsmashConstants.BUILD_QUEUE_SIZE];
|
||||
@ -259,7 +262,7 @@ public class CUnit extends CWidget {
|
||||
player.setFoodCap(player.getFoodCap() + this.unitType.getFoodMade());
|
||||
}
|
||||
game.unitConstructFinishEvent(this);
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
this.stateNotifier.ordersChanged();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -307,13 +310,17 @@ public class CUnit extends CWidget {
|
||||
if (this.currentBehavior != null) {
|
||||
final CBehavior lastBehavior = this.currentBehavior;
|
||||
this.currentBehavior = this.currentBehavior.update(game);
|
||||
if (lastBehavior != this.currentBehavior) {
|
||||
lastBehavior.end(game);
|
||||
this.currentBehavior.begin(game);
|
||||
}
|
||||
if (this.currentBehavior.getHighlightOrderId() != lastBehavior.getHighlightOrderId()) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
this.stateNotifier.ordersChanged();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// check to auto acquire targets
|
||||
autoAcquireAttackTargets(game);
|
||||
autoAcquireAttackTargets(game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -330,7 +337,7 @@ public class CUnit extends CWidget {
|
||||
}
|
||||
}
|
||||
|
||||
public void autoAcquireAttackTargets(final CSimulation game) {
|
||||
public boolean autoAcquireAttackTargets(final CSimulation game, final boolean disableMove) {
|
||||
if (!this.unitType.getAttacks().isEmpty()) {
|
||||
if (this.collisionRectangle != null) {
|
||||
tempRect.set(this.collisionRectangle);
|
||||
@ -343,8 +350,11 @@ public class CUnit extends CWidget {
|
||||
tempRect.y -= halfSize;
|
||||
tempRect.width += halfSize * 2;
|
||||
tempRect.height += halfSize * 2;
|
||||
game.getWorldCollision().enumUnitsInRect(tempRect, autoAttackTargetFinderEnum.reset(game, this));
|
||||
game.getWorldCollision().enumUnitsInRect(tempRect,
|
||||
autoAttackTargetFinderEnum.reset(game, this, disableMove));
|
||||
return autoAttackTargetFinderEnum.foundAnyTarget;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public float getEndingDecayTime(final CSimulation game) {
|
||||
@ -359,26 +369,35 @@ public class CUnit extends CWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
final CAbility ability = game.getAbility(order.getAbilityHandleId());
|
||||
if (ability != null) {
|
||||
// Allow the ability to response to the order without actually placing itself in
|
||||
// the queue, nor modifying (interrupting) the queue.
|
||||
if (!ability.checkBeforeQueue(game, this, order.getOrderId())) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
return;
|
||||
if (order != null) {
|
||||
final CAbility ability = game.getAbility(order.getAbilityHandleId());
|
||||
if (ability != null) {
|
||||
// Allow the ability to response to the order without actually placing itself in
|
||||
// the queue, nor modifying (interrupting) the queue.
|
||||
if (!ability.checkBeforeQueue(game, this, order.getOrderId())) {
|
||||
this.stateNotifier.ordersChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((queue || !this.acceptingOrders) && (this.currentOrder != null)) {
|
||||
if ((queue || !this.acceptingOrders) && ((this.currentBehavior != this.stopBehavior)
|
||||
&& (this.currentBehavior != this.holdPositionBehavior))) {
|
||||
this.orderQueue.add(order);
|
||||
this.stateNotifier.waypointsChanged();
|
||||
}
|
||||
else {
|
||||
this.currentBehavior = beginOrder(game, order);
|
||||
this.orderQueue.clear();
|
||||
final boolean omitNotify = (this.currentOrder == null) && (order == null);
|
||||
if (!omitNotify) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
setHoldingPosition(false);
|
||||
if (this.currentBehavior != null) {
|
||||
this.currentBehavior.end(game);
|
||||
}
|
||||
this.currentBehavior = beginOrder(game, order);
|
||||
if (this.currentBehavior != null) {
|
||||
this.currentBehavior.begin(game);
|
||||
}
|
||||
this.orderQueue.clear();
|
||||
this.stateNotifier.ordersChanged();
|
||||
this.stateNotifier.waypointsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,7 +408,12 @@ public class CUnit extends CWidget {
|
||||
nextBehavior = order.begin(game, this);
|
||||
}
|
||||
else {
|
||||
nextBehavior = this.stopBehavior;
|
||||
if (this.holdingPosition) {
|
||||
nextBehavior = this.holdPositionBehavior;
|
||||
}
|
||||
else {
|
||||
nextBehavior = this.stopBehavior;
|
||||
}
|
||||
}
|
||||
return nextBehavior;
|
||||
}
|
||||
@ -398,14 +422,6 @@ public class CUnit extends CWidget {
|
||||
return this.currentBehavior;
|
||||
}
|
||||
|
||||
public int getCurrentAbilityHandleId() {
|
||||
return this.currentOrder == null ? 0 : this.currentOrder.getAbilityHandleId();
|
||||
}
|
||||
|
||||
public int getCurrentOrderId() {
|
||||
return this.currentOrder == null ? OrderIds.stop : this.currentOrder.getOrderId();
|
||||
}
|
||||
|
||||
public List<CAbility> getAbilities() {
|
||||
return this.abilities;
|
||||
}
|
||||
@ -625,7 +641,8 @@ public class CUnit extends CWidget {
|
||||
CAllianceType.PASSIVE)) {
|
||||
for (final CUnitAttack attack : this.unitType.getAttacks()) {
|
||||
if (source.canBeTargetedBy(simulation, this, attack.getTargetsAllowed())) {
|
||||
this.currentBehavior = getAttackBehavior().reset(OrderIds.attack, attack, source);
|
||||
this.currentBehavior = getAttackBehavior().reset(OrderIds.attack, attack, source, false);
|
||||
this.currentBehavior.begin(simulation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -635,6 +652,9 @@ public class CUnit extends CWidget {
|
||||
}
|
||||
|
||||
private void kill(final CSimulation simulation) {
|
||||
if (this.currentBehavior != null) {
|
||||
this.currentBehavior.end(simulation);
|
||||
}
|
||||
this.currentBehavior = null;
|
||||
this.orderQueue.clear();
|
||||
if (this.constructing) {
|
||||
@ -809,10 +829,15 @@ public class CUnit extends CWidget {
|
||||
private static final class AutoAttackTargetFinderEnum implements CUnitEnumFunction {
|
||||
private CSimulation game;
|
||||
private CUnit source;
|
||||
private boolean disableMove;
|
||||
private boolean foundAnyTarget;
|
||||
|
||||
private AutoAttackTargetFinderEnum reset(final CSimulation game, final CUnit source) {
|
||||
private AutoAttackTargetFinderEnum reset(final CSimulation game, final CUnit source,
|
||||
final boolean disableMove) {
|
||||
this.game = game;
|
||||
this.source = source;
|
||||
this.disableMove = disableMove;
|
||||
this.foundAnyTarget = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -824,8 +849,13 @@ public class CUnit extends CWidget {
|
||||
if (this.source.canReach(unit, this.source.acquisitionRange)
|
||||
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
|
||||
&& (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) {
|
||||
if (this.source.currentBehavior != null) {
|
||||
this.source.currentBehavior.end(this.game);
|
||||
}
|
||||
this.source.currentBehavior = this.source.getAttackBehavior().reset(OrderIds.attack, attack,
|
||||
unit);
|
||||
unit, this.disableMove);
|
||||
this.source.currentBehavior.begin(this.game);
|
||||
this.foundAnyTarget = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -862,6 +892,10 @@ public class CUnit extends CWidget {
|
||||
this.patrolBehavior = patrolBehavior;
|
||||
}
|
||||
|
||||
public void setHoldPositionBehavior(final CBehaviorHoldPosition holdPositionBehavior) {
|
||||
this.holdPositionBehavior = holdPositionBehavior;
|
||||
}
|
||||
|
||||
public CBehaviorFollow getFollowBehavior() {
|
||||
return this.followBehavior;
|
||||
}
|
||||
@ -870,9 +904,20 @@ public class CUnit extends CWidget {
|
||||
return this.patrolBehavior;
|
||||
}
|
||||
|
||||
public CBehaviorHoldPosition getHoldPositionBehavior() {
|
||||
return this.holdPositionBehavior;
|
||||
}
|
||||
|
||||
public CBehavior pollNextOrderBehavior(final CSimulation game) {
|
||||
if (this.holdingPosition) {
|
||||
// kind of a stupid hack, meant to align in feel with some behaviors that were
|
||||
// observed on War3
|
||||
return this.holdPositionBehavior;
|
||||
}
|
||||
final COrder order = this.orderQueue.poll();
|
||||
return beginOrder(game, order);
|
||||
final CBehavior nextOrderBehavior = beginOrder(game, order);
|
||||
this.stateNotifier.waypointsChanged();
|
||||
return nextOrderBehavior;
|
||||
}
|
||||
|
||||
public boolean isMoving() {
|
||||
@ -1087,7 +1132,7 @@ public class CUnit extends CWidget {
|
||||
ability.checkCanTarget(this.game, this.trainedUnit, this.rallyOrderId, target, targetCheckReceiver);
|
||||
if (targetCheckReceiver.isTargetable()) {
|
||||
this.trainedUnit.order(this.game,
|
||||
new COrderTargetPoint(ability.getHandleId(), this.rallyOrderId, target), false);
|
||||
new COrderTargetPoint(ability.getHandleId(), this.rallyOrderId, target, false), false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1109,9 +1154,8 @@ public class CUnit extends CWidget {
|
||||
.<CWidget>getInstance().reset();
|
||||
ability.checkCanTarget(game, trainedUnit, rallyOrderId, target, targetCheckReceiver);
|
||||
if (targetCheckReceiver.isTargetable()) {
|
||||
trainedUnit.order(game,
|
||||
new COrderTargetWidget(ability.getHandleId(), rallyOrderId, target.getHandleId()),
|
||||
false);
|
||||
trainedUnit.order(game, new COrderTargetWidget(ability.getHandleId(), rallyOrderId,
|
||||
target.getHandleId(), false), false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1166,4 +1210,16 @@ public class CUnit extends CWidget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setHoldingPosition(final boolean holdingPosition) {
|
||||
this.holdingPosition = holdingPosition;
|
||||
}
|
||||
|
||||
public Queue<COrder> getOrderQueue() {
|
||||
return this.orderQueue;
|
||||
}
|
||||
|
||||
public COrder getCurrentOrder() {
|
||||
return this.currentOrder;
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ import com.etheller.warsmash.util.SubscriberSetNotifier;
|
||||
public interface CUnitStateListener {
|
||||
void lifeChanged(); // hp (current) changes
|
||||
|
||||
void ordersChanged(int abilityHandleId, int orderId);
|
||||
void ordersChanged();
|
||||
|
||||
void queueChanged();
|
||||
|
||||
void rallyPointChanged();
|
||||
|
||||
void waypointsChanged();
|
||||
|
||||
public static final class CUnitStateNotifier extends SubscriberSetNotifier<CUnitStateListener>
|
||||
implements CUnitStateListener {
|
||||
@Override
|
||||
@ -21,9 +23,9 @@ public interface CUnitStateListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ordersChanged(final int abilityHandleId, final int orderId) {
|
||||
public void ordersChanged() {
|
||||
for (final CUnitStateListener listener : set) {
|
||||
listener.ordersChanged(abilityHandleId, orderId);
|
||||
listener.ordersChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,5 +42,12 @@ public interface CUnitStateListener {
|
||||
listener.rallyPointChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointsChanged() {
|
||||
for (final CUnitStateListener listener : set) {
|
||||
listener.waypointsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ public class CAbilityAttack extends AbstractCAbility {
|
||||
CBehavior behavior = null;
|
||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.attack, attack, target);
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.attack, attack, target, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -131,7 +131,7 @@ public class CAbilityAttack extends AbstractCAbility {
|
||||
CBehavior behavior = null;
|
||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||
if (attack.getWeaponType().isAttackGroundSupported()) {
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.attackground, attack, point);
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.attackground, attack, point, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
@ -77,6 +78,7 @@ public class CAbilityMove extends AbstractCAbility {
|
||||
unit.setMoveBehavior(new CBehaviorMove(unit));
|
||||
unit.setFollowBehavior(new CBehaviorFollow(unit));
|
||||
unit.setPatrolBehavior(new CBehaviorPatrol(unit));
|
||||
unit.setHoldPositionBehavior(new CBehaviorHoldPosition(unit));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -107,6 +109,9 @@ public class CAbilityMove extends AbstractCAbility {
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
if (orderId == OrderIds.holdposition) {
|
||||
caster.setHoldingPosition(true);
|
||||
}
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class CAbilityColdArrows extends AbstractCAbility {
|
||||
CBehavior behavior = null;
|
||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.coldarrowstarg, attack, target);
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.coldarrowstarg, attack, target, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ public final class AbilityTargetStillAliveAndTargetableVisitor implements Abilit
|
||||
|
||||
@Override
|
||||
public Boolean accept(final CUnit target) {
|
||||
return !target.isDead() && target.canBeTargetedBy(this.simulation, this.unit, this.targetsAllowed);
|
||||
return !target.isDead() && !target.isHidden()
|
||||
&& target.canBeTargetedBy(this.simulation, this.unit, this.targetsAllowed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,7 +14,7 @@ public class AbilityTargetStillAliveVisitor implements AbilityTargetVisitor<Bool
|
||||
|
||||
@Override
|
||||
public Boolean accept(final CUnit target) {
|
||||
return !target.isDead();
|
||||
return !target.isDead() && !target.isHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,7 @@ public abstract class CAbstractRangedBehavior implements CRangedBehavior {
|
||||
protected AbilityTarget target;
|
||||
private boolean wasWithinPropWindow = false;
|
||||
private boolean wasInRange = false;
|
||||
private boolean disableMove = false;
|
||||
private CBehaviorMove moveBehavior;
|
||||
|
||||
protected final CAbstractRangedBehavior innerReset(final AbilityTarget target) {
|
||||
@ -45,7 +46,7 @@ public abstract class CAbstractRangedBehavior implements CRangedBehavior {
|
||||
return this.unit.pollNextOrderBehavior(simulation);
|
||||
}
|
||||
if (!isWithinRange(simulation)) {
|
||||
if (this.moveBehavior == null) {
|
||||
if ((this.moveBehavior == null) || this.disableMove) {
|
||||
return this.unit.pollNextOrderBehavior(simulation);
|
||||
}
|
||||
this.wasInRange = false;
|
||||
@ -103,4 +104,8 @@ public abstract class CAbstractRangedBehavior implements CRangedBehavior {
|
||||
return update(simulation, this.wasWithinPropWindow);
|
||||
}
|
||||
|
||||
public void setDisableMove(final boolean disableMove) {
|
||||
this.disableMove = disableMove;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,5 +11,9 @@ public interface CBehavior {
|
||||
*/
|
||||
CBehavior update(CSimulation game);
|
||||
|
||||
void begin(CSimulation game);
|
||||
|
||||
void end(CSimulation game);
|
||||
|
||||
int getHighlightOrderId();
|
||||
}
|
||||
|
@ -24,13 +24,15 @@ public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||
private int backSwingTime;
|
||||
private int thisOrderCooldownEndTime;
|
||||
|
||||
public CBehaviorAttack reset(final int highlightOrderId, final CUnitAttack unitAttack, final AbilityTarget target) {
|
||||
public CBehaviorAttack reset(final int highlightOrderId, final CUnitAttack unitAttack, final AbilityTarget target,
|
||||
final boolean disableMove) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
super.innerReset(target);
|
||||
this.unitAttack = unitAttack;
|
||||
this.damagePointLaunchTime = 0;
|
||||
this.backSwingTime = 0;
|
||||
this.thisOrderCooldownEndTime = 0;
|
||||
setDisableMove(disableMove);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -115,4 +117,14 @@ public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,4 +44,14 @@ public class CBehaviorFollow extends CAbstractRangedBehavior {
|
||||
protected void resetBeforeMoving(final CSimulation simulation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CBehaviorHoldPosition implements CBehavior {
|
||||
|
||||
private final CUnit unit;
|
||||
|
||||
public CBehaviorHoldPosition(final CUnit unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return OrderIds.holdposition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior update(final CSimulation game) {
|
||||
if (this.unit.autoAcquireAttackTargets(game, true)) {
|
||||
// kind of a hack
|
||||
return this.unit.getCurrentBehavior();
|
||||
}
|
||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true);
|
||||
return this.unit.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -400,4 +400,14 @@ public class CBehaviorMove implements CBehavior {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,14 @@ public class CBehaviorPatrol implements CRangedBehavior {
|
||||
return this.unit.getMoveBehavior().reset(this.target, this, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,9 +21,21 @@ public class CBehaviorStop implements CBehavior {
|
||||
|
||||
@Override
|
||||
public CBehavior update(final CSimulation game) {
|
||||
this.unit.autoAcquireAttackTargets(game);
|
||||
if (this.unit.autoAcquireAttackTargets(game, false)) {
|
||||
return this.unit.getCurrentBehavior();
|
||||
}
|
||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true);
|
||||
return this.unit.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -93,4 +93,14 @@ public class CBehaviorOrcBuild extends CAbstractRangedBehavior {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -157,4 +157,14 @@ public class CBehaviorHarvest extends CAbstractRangedBehavior implements Ability
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -121,23 +121,25 @@ public class CBehaviorReturnResources extends CAbstractRangedBehavior implements
|
||||
double nearestDropoffDistance = Float.MAX_VALUE;
|
||||
for (final CUnit unit : simulation.getUnits()) {
|
||||
if (unit.getPlayerIndex() == this.unit.getPlayerIndex()) {
|
||||
boolean acceptedUnit = false;
|
||||
for (final CAbility ability : unit.getAbilities()) {
|
||||
if (ability instanceof CAbilityReturnResources) {
|
||||
final CAbilityReturnResources abilityReturnResources = (CAbilityReturnResources) ability;
|
||||
if (abilityReturnResources.accepts(this.abilityHarvest.getCarriedResourceType())) {
|
||||
acceptedUnit = true;
|
||||
break;
|
||||
if (unit.visit(AbilityTargetStillAliveVisitor.INSTANCE)) {
|
||||
boolean acceptedUnit = false;
|
||||
for (final CAbility ability : unit.getAbilities()) {
|
||||
if (ability instanceof CAbilityReturnResources) {
|
||||
final CAbilityReturnResources abilityReturnResources = (CAbilityReturnResources) ability;
|
||||
if (abilityReturnResources.accepts(this.abilityHarvest.getCarriedResourceType())) {
|
||||
acceptedUnit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (acceptedUnit) {
|
||||
// TODO maybe use distance squared, problem is that we're using this
|
||||
// inefficient more complex distance function on unit
|
||||
final double distance = unit.distanceSquaredNoCollision(this.unit);
|
||||
if (distance < nearestDropoffDistance) {
|
||||
nearestDropoffDistance = distance;
|
||||
nearestDropoffPoint = unit;
|
||||
if (acceptedUnit) {
|
||||
// TODO maybe use distance squared, problem is that we're using this
|
||||
// inefficient more complex distance function on unit
|
||||
final double distance = unit.distanceSquaredNoCollision(this.unit);
|
||||
if (distance < nearestDropoffDistance) {
|
||||
nearestDropoffDistance = distance;
|
||||
nearestDropoffPoint = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,4 +171,14 @@ public class CBehaviorReturnResources extends CAbstractRangedBehavior implements
|
||||
return nearestMine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(final CSimulation game) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||
@ -13,6 +14,10 @@ public interface COrder {
|
||||
|
||||
CBehavior begin(final CSimulation game, CUnit caster);
|
||||
|
||||
AbilityTarget getTarget(CSimulation game);
|
||||
|
||||
boolean isQueued();
|
||||
|
||||
final StringMsgTargetCheckReceiver<?> targetCheckReceiver = new StringMsgTargetCheckReceiver<>();
|
||||
final StringMsgAbilityActivationReceiver abilityActivationReceiver = new StringMsgAbilityActivationReceiver();
|
||||
}
|
||||
|
@ -3,15 +3,19 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||
|
||||
public class COrderNoTarget implements COrder {
|
||||
private final int abilityHandleId;
|
||||
private final int orderId;
|
||||
private final boolean queued;
|
||||
|
||||
public COrderNoTarget(final int abilityHandleId, final int orderId) {
|
||||
public COrderNoTarget(final int abilityHandleId, final int orderId, final boolean queued) {
|
||||
this.abilityHandleId = abilityHandleId;
|
||||
this.orderId = orderId;
|
||||
this.queued = queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,14 +28,35 @@ public class COrderNoTarget implements COrder {
|
||||
return this.orderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQueued() {
|
||||
return this.queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||
if ((ability == null) && (this.orderId == OrderIds.stop)) {
|
||||
// stop
|
||||
return caster.getStopBehavior();
|
||||
ability.checkCanUse(game, caster, this.orderId, this.abilityActivationReceiver.reset());
|
||||
if (this.abilityActivationReceiver.isUseOk()) {
|
||||
final StringMsgTargetCheckReceiver<Void> targetReceiver = (StringMsgTargetCheckReceiver<Void>) targetCheckReceiver;
|
||||
ability.checkCanTargetNoTarget(game, caster, this.orderId, targetReceiver);
|
||||
if (targetReceiver.getMessage() == null) {
|
||||
return ability.beginNoTarget(game, caster, this.orderId);
|
||||
}
|
||||
else {
|
||||
game.getCommandErrorListener().showCommandError(targetReceiver.getMessage());
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
}
|
||||
return ability.beginNoTarget(game, caster, this.orderId);
|
||||
else {
|
||||
game.getCommandErrorListener().showCommandError(this.abilityActivationReceiver.getMessage());
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbilityTarget getTarget(final CSimulation game) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
@ -12,11 +11,14 @@ public class COrderTargetPoint implements COrder {
|
||||
private final int abilityHandleId;
|
||||
private final int orderId;
|
||||
private final AbilityPointTarget target;
|
||||
private final boolean queued;
|
||||
|
||||
public COrderTargetPoint(final int abilityHandleId, final int orderId, final AbilityPointTarget target) {
|
||||
public COrderTargetPoint(final int abilityHandleId, final int orderId, final AbilityPointTarget target,
|
||||
final boolean queued) {
|
||||
this.abilityHandleId = abilityHandleId;
|
||||
this.orderId = orderId;
|
||||
this.target = target;
|
||||
this.queued = queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -29,10 +31,16 @@ public class COrderTargetPoint implements COrder {
|
||||
return this.orderId;
|
||||
}
|
||||
|
||||
public Vector2 getTarget() {
|
||||
@Override
|
||||
public AbilityPointTarget getTarget(final CSimulation game) {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQueued() {
|
||||
return this.queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||
|
@ -4,6 +4,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||
|
||||
@ -11,11 +12,14 @@ public class COrderTargetWidget implements COrder {
|
||||
private final int abilityHandleId;
|
||||
private final int orderId;
|
||||
private final int targetHandleId;
|
||||
private final boolean queued;
|
||||
|
||||
public COrderTargetWidget(final int abilityHandleId, final int orderId, final int targetHandleId) {
|
||||
public COrderTargetWidget(final int abilityHandleId, final int orderId, final int targetHandleId,
|
||||
final boolean queued) {
|
||||
this.abilityHandleId = abilityHandleId;
|
||||
this.orderId = orderId;
|
||||
this.targetHandleId = targetHandleId;
|
||||
this.queued = queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -28,6 +32,17 @@ public class COrderTargetWidget implements COrder {
|
||||
return this.orderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbilityTarget getTarget(final CSimulation game) {
|
||||
final CUnit target = game.getUnit(this.targetHandleId);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQueued() {
|
||||
return this.queued;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||
|
@ -6,6 +6,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderNoTarget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetPoint;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||
|
||||
public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
||||
@ -21,21 +22,33 @@ public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
||||
public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||
final int targetHandleId, final boolean queue) {
|
||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||
unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId), queue);
|
||||
unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId, queue), queue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x,
|
||||
final float y, final boolean queue) {
|
||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||
unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new AbilityPointTarget(x, y)), queue);
|
||||
unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new AbilityPointTarget(x, y), queue),
|
||||
queue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||
final boolean queue) {
|
||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||
unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId), queue);
|
||||
if (abilityHandleId == 0) {
|
||||
if (orderId == OrderIds.stop) {
|
||||
unit.order(this.game, null, queue);
|
||||
}
|
||||
else if (orderId == OrderIds.holdposition) {
|
||||
unit.order(this.game, null, queue);
|
||||
unit.setHoldingPosition(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId, queue), queue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,8 +4,11 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@ -113,6 +116,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileSplash;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrder;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
||||
@ -241,6 +245,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
private final RallyPositioningVisitor rallyPositioningVisitor;
|
||||
private final CPlayer localPlayer;
|
||||
private MeleeUIAbilityActivationReceiver meleeUIAbilityActivationReceiver;
|
||||
private MdxModel waypointModel;
|
||||
private final List<MdxComplexInstance> waypointModelInstances = new ArrayList<>();
|
||||
|
||||
public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport,
|
||||
final FreeTypeFontGenerator fontGenerator, final Scene uiScene, final Scene portraitScene,
|
||||
@ -618,6 +624,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.rallyPointInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
SequenceUtils.randomStandSequence(this.rallyPointInstance);
|
||||
this.rallyPointInstance.hide();
|
||||
this.waypointModel = (MdxModel) this.war3MapViewer.load(
|
||||
War3MapViewer.mdx(this.rootFrame.getSkinField("WaypointIndicator")), this.war3MapViewer.mapPathSolver,
|
||||
this.war3MapViewer.solverParams);
|
||||
|
||||
this.rootFrame.positionBounds(this.rootFrame, this.uiViewport);
|
||||
|
||||
@ -1062,12 +1071,19 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
|
||||
private final class RallyPositioningVisitor implements AbilityTargetVisitor<Void> {
|
||||
private MdxComplexInstance rallyPointInstance = null;
|
||||
|
||||
public RallyPositioningVisitor reset(final MdxComplexInstance rallyPointInstance) {
|
||||
this.rallyPointInstance = rallyPointInstance;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final AbilityPointTarget target) {
|
||||
MeleeUI.this.rallyPointInstance.setParent(null);
|
||||
this.rallyPointInstance.setParent(null);
|
||||
final float rallyPointX = target.getX();
|
||||
final float rallyPointY = target.getY();
|
||||
MeleeUI.this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY));
|
||||
return null;
|
||||
}
|
||||
@ -1094,14 +1110,14 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
if (index != -1) {
|
||||
final MdxNode attachment = renderUnit.instance.getAttachment(index);
|
||||
MeleeUI.this.rallyPointInstance.setParent(attachment);
|
||||
MeleeUI.this.rallyPointInstance.setLocation(0, 0, 0);
|
||||
this.rallyPointInstance.setParent(attachment);
|
||||
this.rallyPointInstance.setLocation(0, 0, 0);
|
||||
}
|
||||
else {
|
||||
MeleeUI.this.rallyPointInstance.setParent(null);
|
||||
this.rallyPointInstance.setParent(null);
|
||||
final float rallyPointX = target.getX();
|
||||
final float rallyPointY = target.getY();
|
||||
MeleeUI.this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY));
|
||||
}
|
||||
return null;
|
||||
@ -1109,20 +1125,20 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
|
||||
@Override
|
||||
public Void accept(final CDestructable target) {
|
||||
MeleeUI.this.rallyPointInstance.setParent(null);
|
||||
this.rallyPointInstance.setParent(null);
|
||||
final float rallyPointX = target.getX();
|
||||
final float rallyPointY = target.getY();
|
||||
MeleeUI.this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CItem target) {
|
||||
MeleeUI.this.rallyPointInstance.setParent(null);
|
||||
this.rallyPointInstance.setParent(null);
|
||||
final float rallyPointX = target.getX();
|
||||
final float rallyPointY = target.getY();
|
||||
MeleeUI.this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
this.rallyPointInstance.setLocation(rallyPointX, rallyPointY,
|
||||
MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY));
|
||||
return null;
|
||||
}
|
||||
@ -1233,6 +1249,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.selectWorkerInsideFrame.setVisible(false);
|
||||
this.rallyPointInstance.hide();
|
||||
this.rallyPointInstance.detach();
|
||||
repositionWaypointFlags(null);
|
||||
}
|
||||
else {
|
||||
unit.getSimulationUnit().addStateListener(this);
|
||||
@ -1255,7 +1272,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.war3MapViewer.simulation.getPlayer(simulationUnit.getPlayerIndex()).getColorIndex());
|
||||
this.rallyPointInstance.show();
|
||||
this.rallyPointInstance.detach();
|
||||
rallyPoint.visit(this.rallyPositioningVisitor);
|
||||
rallyPoint.visit(this.rallyPositioningVisitor.reset(this.rallyPointInstance));
|
||||
this.rallyPointInstance.setScene(this.war3MapViewer.worldScene);
|
||||
}
|
||||
else {
|
||||
@ -1264,6 +1281,79 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waypointsChanged() {
|
||||
if (this.selectedUnit != null) {
|
||||
final CUnit simulationUnit = this.selectedUnit.getSimulationUnit();
|
||||
repositionWaypointFlags(simulationUnit);
|
||||
}
|
||||
else {
|
||||
repositionWaypointFlags(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void repositionWaypointFlags(final CUnit simulationUnit) {
|
||||
final Iterator<COrder> iterator;
|
||||
int orderIndex = 0;
|
||||
if (simulationUnit != null) {
|
||||
final Queue<COrder> orderQueue = simulationUnit.getOrderQueue();
|
||||
iterator = orderQueue.iterator();
|
||||
final COrder order = simulationUnit.getCurrentOrder();
|
||||
if ((order != null) && order.isQueued()) {
|
||||
final MdxComplexInstance waypointModelInstance = getOrCreateWaypointIndicator(orderIndex);
|
||||
final AbilityTarget target = order.getTarget(this.war3MapViewer.simulation);
|
||||
if (target != null) {
|
||||
waypointModelInstance.show();
|
||||
waypointModelInstance.detach();
|
||||
target.visit(this.rallyPositioningVisitor.reset(waypointModelInstance));
|
||||
waypointModelInstance.setScene(this.war3MapViewer.worldScene);
|
||||
}
|
||||
else {
|
||||
waypointModelInstance.hide();
|
||||
waypointModelInstance.detach();
|
||||
}
|
||||
orderIndex++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
iterator = Collections.emptyIterator();
|
||||
}
|
||||
for (; (orderIndex < this.waypointModelInstances.size()) || (iterator.hasNext()); orderIndex++) {
|
||||
final MdxComplexInstance waypointModelInstance = getOrCreateWaypointIndicator(orderIndex);
|
||||
if (iterator.hasNext()) {
|
||||
final COrder order = iterator.next();
|
||||
final AbilityTarget target = order.getTarget(this.war3MapViewer.simulation);
|
||||
if (target != null) {
|
||||
waypointModelInstance.show();
|
||||
waypointModelInstance.detach();
|
||||
target.visit(this.rallyPositioningVisitor.reset(waypointModelInstance));
|
||||
waypointModelInstance.setScene(this.war3MapViewer.worldScene);
|
||||
}
|
||||
else {
|
||||
waypointModelInstance.hide();
|
||||
waypointModelInstance.detach();
|
||||
}
|
||||
}
|
||||
else {
|
||||
waypointModelInstance.hide();
|
||||
waypointModelInstance.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MdxComplexInstance getOrCreateWaypointIndicator(final int index) {
|
||||
while (index >= this.waypointModelInstances.size()) {
|
||||
final MdxComplexInstance waypointModelInstance = (MdxComplexInstance) this.waypointModel.addInstance();
|
||||
waypointModelInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z,
|
||||
this.war3MapViewer.simulation.getGameplayConstants().getBuildingAngle()));
|
||||
waypointModelInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
SequenceUtils.randomStandSequence(waypointModelInstance);
|
||||
waypointModelInstance.hide();
|
||||
this.waypointModelInstances.add(waypointModelInstance);
|
||||
}
|
||||
return this.waypointModelInstances.get(index);
|
||||
}
|
||||
|
||||
private void reloadSelectedUnitUI(final RenderUnit unit) {
|
||||
final CUnit simulationUnit = unit.getSimulationUnit();
|
||||
this.unitLifeText.setText(
|
||||
@ -1277,6 +1367,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.unitManaText.setText("");
|
||||
}
|
||||
repositionRallyPoint(simulationUnit);
|
||||
repositionWaypointFlags(simulationUnit);
|
||||
if (simulationUnit.getBuildQueue()[0] != null) {
|
||||
for (int i = 0; i < this.queueIconFrames.length; i++) {
|
||||
final QueueItemType queueItemType = simulationUnit.getBuildQueueTypes()[i];
|
||||
@ -1558,7 +1649,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ordersChanged(final int abilityHandleId, final int orderId) {
|
||||
public void ordersChanged() {
|
||||
reloadSelectedUnitUI(this.selectedUnit);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user