mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Update ui
This commit is contained in:
parent
e21bb492c1
commit
0c0141cd71
@ -309,7 +309,8 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
|||||||
this.font.setColor(Color.YELLOW);
|
this.font.setColor(Color.YELLOW);
|
||||||
final String fpsString = "FPS: " + Gdx.graphics.getFramesPerSecond();
|
final String fpsString = "FPS: " + Gdx.graphics.getFramesPerSecond();
|
||||||
this.glyphLayout.setText(this.font, fpsString);
|
this.glyphLayout.setText(this.font, fpsString);
|
||||||
this.font.draw(this.batch, fpsString, (this.uiViewport.getMinWorldWidth() - this.glyphLayout.width) / 2, 1100);
|
this.font.draw(this.batch, fpsString, (this.uiViewport.getMinWorldWidth() - this.glyphLayout.width) / 2,
|
||||||
|
1100 * this.meleeUI.getHeightRatioCorrection());
|
||||||
this.batch.end();
|
this.batch.end();
|
||||||
|
|
||||||
Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST);
|
Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST);
|
||||||
|
@ -21,6 +21,8 @@ public abstract class SkeletalNode extends GenericNode {
|
|||||||
public boolean billboardedY;
|
public boolean billboardedY;
|
||||||
public boolean billboardedZ;
|
public boolean billboardedZ;
|
||||||
|
|
||||||
|
public Matrix4 localBlendMatrix;
|
||||||
|
|
||||||
public SkeletalNode() {
|
public SkeletalNode() {
|
||||||
this.pivot = new Vector3();
|
this.pivot = new Vector3();
|
||||||
this.localLocation = new Vector3();
|
this.localLocation = new Vector3();
|
||||||
@ -33,6 +35,7 @@ public abstract class SkeletalNode extends GenericNode {
|
|||||||
this.inverseWorldRotation = new Quaternion();
|
this.inverseWorldRotation = new Quaternion();
|
||||||
this.inverseWorldScale = new Vector3();
|
this.inverseWorldScale = new Vector3();
|
||||||
this.localMatrix = new Matrix4();
|
this.localMatrix = new Matrix4();
|
||||||
|
this.localBlendMatrix = new Matrix4();
|
||||||
this.worldMatrix = new Matrix4();
|
this.worldMatrix = new Matrix4();
|
||||||
this.dontInheritTranslation = false;
|
this.dontInheritTranslation = false;
|
||||||
this.dontInheritRotation = false;
|
this.dontInheritRotation = false;
|
||||||
@ -66,7 +69,7 @@ public abstract class SkeletalNode extends GenericNode {
|
|||||||
this.billboardedZ = false;
|
this.billboardedZ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recalculateTransformation(final Scene scene) {
|
public void recalculateTransformation(final Scene scene, final float blendTimeRatio) {
|
||||||
final Quaternion computedRotation;
|
final Quaternion computedRotation;
|
||||||
Vector3 computedScaling;
|
Vector3 computedScaling;
|
||||||
|
|
||||||
@ -135,6 +138,12 @@ public abstract class SkeletalNode extends GenericNode {
|
|||||||
|
|
||||||
RenderMathUtils.fromRotationTranslationScaleOrigin(computedRotation, this.localLocation, computedScaling,
|
RenderMathUtils.fromRotationTranslationScaleOrigin(computedRotation, this.localLocation, computedScaling,
|
||||||
this.localMatrix, this.pivot);
|
this.localMatrix, this.pivot);
|
||||||
|
if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) {
|
||||||
|
for (int i = 0; i < this.localMatrix.val.length; i++) {
|
||||||
|
this.localMatrix.val[i] = (this.localBlendMatrix.val[i] * blendTimeRatio)
|
||||||
|
+ (this.localMatrix.val[i] * (1 - blendTimeRatio));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RenderMathUtils.mul(this.worldMatrix, this.parent.worldMatrix, this.localMatrix);
|
RenderMathUtils.mul(this.worldMatrix, this.parent.worldMatrix, this.localMatrix);
|
||||||
|
|
||||||
@ -168,6 +177,10 @@ public abstract class SkeletalNode extends GenericNode {
|
|||||||
this.inverseWorldLocation.z = -this.worldLocation.z;
|
this.inverseWorldLocation.z = -this.worldLocation.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void beginBlending() {
|
||||||
|
this.localBlendMatrix.set(this.localMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateChildren(final float dt, final Scene scene) {
|
public void updateChildren(final float dt, final Scene scene) {
|
||||||
for (int i = 0, l = this.children.size(); i < l; i++) {
|
for (int i = 0, l = this.children.size(); i < l; i++) {
|
||||||
this.children.get(i).update(dt, scene);
|
this.children.get(i).update(dt, scene);
|
||||||
|
@ -66,6 +66,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
public DataTexture boneTexture;
|
public DataTexture boneTexture;
|
||||||
public Texture[] replaceableTextures = new Texture[WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT];
|
public Texture[] replaceableTextures = new Texture[WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT];
|
||||||
private float animationSpeed = 1.0f;
|
private float animationSpeed = 1.0f;
|
||||||
|
private float blendTime;
|
||||||
|
private float blendTimeRemaining;
|
||||||
|
|
||||||
public MdxComplexInstance(final MdxModel model) {
|
public MdxComplexInstance(final MdxModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
@ -160,11 +162,14 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
|
|
||||||
if ("SPN".equals(type)) {
|
if ("SPN".equals(type)) {
|
||||||
emitter = new EventObjectSpnEmitter(this, emitterObject);
|
emitter = new EventObjectSpnEmitter(this, emitterObject);
|
||||||
} else if ("SPL".equals(type)) {
|
}
|
||||||
|
else if ("SPL".equals(type)) {
|
||||||
emitter = new EventObjectSplEmitter(this, emitterObject);
|
emitter = new EventObjectSplEmitter(this, emitterObject);
|
||||||
} else if ("UBR".equals(type)) {
|
}
|
||||||
|
else if ("UBR".equals(type)) {
|
||||||
emitter = new EventObjectUbrEmitter(this, emitterObject);
|
emitter = new EventObjectUbrEmitter(this, emitterObject);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
emitter = new EventObjectSndEmitter(this, emitterObject);
|
emitter = new EventObjectSndEmitter(this, emitterObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,18 +236,22 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
|
|
||||||
if (genericObject.parentId == -1) {
|
if (genericObject.parentId == -1) {
|
||||||
node.parent = this;
|
node.parent = this;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
node.parent = nodes[genericObject.parentId];
|
node.parent = nodes[genericObject.parentId];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: single-axis billboarding
|
/// TODO: single-axis billboarding
|
||||||
if (genericObject.billboarded != 0) {
|
if (genericObject.billboarded != 0) {
|
||||||
node.billboarded = true;
|
node.billboarded = true;
|
||||||
} else if (genericObject.billboardedX != 0) {
|
}
|
||||||
|
else if (genericObject.billboardedX != 0) {
|
||||||
node.billboardedX = true;
|
node.billboardedX = true;
|
||||||
} else if (genericObject.billboardedY != 0) {
|
}
|
||||||
|
else if (genericObject.billboardedY != 0) {
|
||||||
node.billboardedY = true;
|
node.billboardedY = true;
|
||||||
} else if (genericObject.billboardedZ != 0) {
|
}
|
||||||
|
else if (genericObject.billboardedZ != 0) {
|
||||||
node.billboardedZ = true;
|
node.billboardedZ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +354,7 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
// If this is a forced update, or this node's local data was updated, or the
|
// If this is a forced update, or this node's local data was updated, or the
|
||||||
// parent node was updated, do a full world update.
|
// parent node was updated, do a full world update.
|
||||||
if (wasReallyDirty) {
|
if (wasReallyDirty) {
|
||||||
node.recalculateTransformation(scene);
|
node.recalculateTransformation(scene, this.blendTimeRemaining / this.blendTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is an instance object associated with this node, and the node is
|
// If there is an instance object associated with this node, and the node is
|
||||||
@ -405,7 +414,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
|
|
||||||
geosetColor[3] = alphaHeap[0];
|
geosetColor[3] = alphaHeap[0];
|
||||||
}
|
}
|
||||||
} else if (forced) {
|
}
|
||||||
|
else if (forced) {
|
||||||
geosetColor[0] = 1;
|
geosetColor[0] = 1;
|
||||||
geosetColor[1] = 1;
|
geosetColor[1] = 1;
|
||||||
geosetColor[2] = 1;
|
geosetColor[2] = 1;
|
||||||
@ -456,7 +466,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
|
|
||||||
uvAnim[4] = scaleHeap[0];
|
uvAnim[4] = scaleHeap[0];
|
||||||
}
|
}
|
||||||
} else if (forced) {
|
}
|
||||||
|
else if (forced) {
|
||||||
uvAnim[0] = 0;
|
uvAnim[0] = 0;
|
||||||
uvAnim[1] = 0;
|
uvAnim[1] = 0;
|
||||||
uvAnim[2] = 0;
|
uvAnim[2] = 0;
|
||||||
@ -525,6 +536,7 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
|
|
||||||
final int lastIntegerFrame = this.frame;
|
final int lastIntegerFrame = this.frame;
|
||||||
this.floatingFrame += frameTime;
|
this.floatingFrame += frameTime;
|
||||||
|
this.blendTimeRemaining -= frameTime;
|
||||||
this.frame = (int) this.floatingFrame;
|
this.frame = (int) this.floatingFrame;
|
||||||
final int integerFrameTime = this.frame - lastIntegerFrame;
|
final int integerFrameTime = this.frame - lastIntegerFrame;
|
||||||
this.counter += integerFrameTime;
|
this.counter += integerFrameTime;
|
||||||
@ -536,7 +548,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
this.floatingFrame = this.frame = (int) interval[0]; // TODO not cast
|
this.floatingFrame = this.frame = (int) interval[0]; // TODO not cast
|
||||||
|
|
||||||
this.resetEventEmitters();
|
this.resetEventEmitters();
|
||||||
} else if (this.sequenceLoopMode == SequenceLoopMode.LOOP_TO_NEXT_ANIMATION) { // faux queued animation
|
}
|
||||||
|
else if (this.sequenceLoopMode == SequenceLoopMode.LOOP_TO_NEXT_ANIMATION) { // faux queued animation
|
||||||
// mode
|
// mode
|
||||||
final float framesPast = this.floatingFrame - interval[1];
|
final float framesPast = this.floatingFrame - interval[1];
|
||||||
|
|
||||||
@ -547,7 +560,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
this.sequenceEnded = false;
|
this.sequenceEnded = false;
|
||||||
this.resetEventEmitters();
|
this.resetEventEmitters();
|
||||||
this.forced = true;
|
this.forced = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.floatingFrame = this.frame = (int) interval[1]; // TODO not cast
|
this.floatingFrame = this.frame = (int) interval[1]; // TODO not cast
|
||||||
this.counter -= integerFrameTime;
|
this.counter -= integerFrameTime;
|
||||||
this.allowParticleSpawn = false;
|
this.allowParticleSpawn = false;
|
||||||
@ -557,7 +571,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.sequenceEnded = true;
|
this.sequenceEnded = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.sequenceEnded = false;
|
this.sequenceEnded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -574,7 +589,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
// Update the batches
|
// Update the batches
|
||||||
this.updateBatches(forced);
|
this.updateBatches(forced);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// let variants = model.variants;
|
// let variants = model.variants;
|
||||||
|
|
||||||
// if (forced || variants.nodes[sequenceId]) {
|
// if (forced || variants.nodes[sequenceId]) {
|
||||||
@ -642,6 +658,7 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
public MdxComplexInstance setSequence(final int id) {
|
public MdxComplexInstance setSequence(final int id) {
|
||||||
final MdxModel model = (MdxModel) this.model;
|
final MdxModel model = (MdxModel) this.model;
|
||||||
|
|
||||||
|
final int lastSequence = this.sequence;
|
||||||
this.sequence = id;
|
this.sequence = id;
|
||||||
|
|
||||||
if (model.ok) {
|
if (model.ok) {
|
||||||
@ -652,7 +669,16 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
this.frame = 0;
|
this.frame = 0;
|
||||||
this.floatingFrame = 0;
|
this.floatingFrame = 0;
|
||||||
this.allowParticleSpawn = false;
|
this.allowParticleSpawn = false;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
|
if ((this.blendTime > 0) && (lastSequence != this.sequence)) {
|
||||||
|
this.blendTimeRemaining = this.blendTime;
|
||||||
|
for (int i = 0, l = this.sortedNodes.length; i < l; i++) {
|
||||||
|
final SkeletalNode node = this.sortedNodes[i];
|
||||||
|
node.beginBlending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.frame = (int) sequences.get(id).getInterval()[0]; // TODO not cast
|
this.frame = (int) sequences.get(id).getInterval()[0]; // TODO not cast
|
||||||
this.floatingFrame = this.frame;
|
this.floatingFrame = this.frame;
|
||||||
this.sequenceEnded = false;
|
this.sequenceEnded = false;
|
||||||
@ -720,7 +746,8 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
*
|
*
|
||||||
* @param ray
|
* @param ray
|
||||||
*/
|
*/
|
||||||
public boolean intersectRayWithCollision(final Ray ray, final Vector3 intersection, final boolean alwaysUseMesh, final boolean onlyUseMesh) {
|
public boolean intersectRayWithCollision(final Ray ray, final Vector3 intersection, final boolean alwaysUseMesh,
|
||||||
|
final boolean onlyUseMesh) {
|
||||||
final MdxModel mdxModel = (MdxModel) this.model;
|
final MdxModel mdxModel = (MdxModel) this.model;
|
||||||
final List<CollisionShape> collisionShapes = mdxModel.collisionShapes;
|
final List<CollisionShape> collisionShapes = mdxModel.collisionShapes;
|
||||||
if (!onlyUseMesh) {
|
if (!onlyUseMesh) {
|
||||||
@ -752,6 +779,10 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
this.animationSpeed = speedRatio;
|
this.animationSpeed = speedRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBlendTime(final float blendTime) {
|
||||||
|
this.blendTime = blendTime;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFrame(final int frame) {
|
public void setFrame(final int frame) {
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.floatingFrame = frame;
|
this.floatingFrame = frame;
|
||||||
|
@ -86,16 +86,9 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitFilterFunction;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitFilterFunction;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
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.CAbilityAttack;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.CWidgetAbilityTargetCheckReceiver;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.PointAbilityTargetCheckReceiver;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
||||||
|
|
||||||
import mpq.MPQArchive;
|
import mpq.MPQArchive;
|
||||||
@ -1275,74 +1268,6 @@ public class War3MapViewer extends ModelViewer {
|
|||||||
return (numElements < 0) ? 1 : (numElements >= MAXIMUM_ACCEPTED) ? MAXIMUM_ACCEPTED : numElements + 1;
|
return (numElements < 0) ? 1 : (numElements >= MAXIMUM_ACCEPTED) ? MAXIMUM_ACCEPTED : numElements + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean orderSmart(final float x, final float y) {
|
|
||||||
mousePosHeap.x = x;
|
|
||||||
mousePosHeap.y = y;
|
|
||||||
boolean ordered = false;
|
|
||||||
for (final RenderUnit unit : this.selected) {
|
|
||||||
for (final CAbility ability : unit.getSimulationUnit().getAbilities()) {
|
|
||||||
if (ability instanceof CAbilityMove) {
|
|
||||||
ability.checkCanUse(this.simulation, unit.getSimulationUnit(), OrderIds.smart,
|
|
||||||
BooleanAbilityActivationReceiver.INSTANCE);
|
|
||||||
if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) {
|
|
||||||
ability.checkCanTarget(this.simulation, unit.getSimulationUnit(), OrderIds.smart, mousePosHeap,
|
|
||||||
PointAbilityTargetCheckReceiver.INSTANCE);
|
|
||||||
final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
|
||||||
if (target != null) {
|
|
||||||
ability.onOrder(this.simulation, unit.getSimulationUnit(), OrderIds.smart, mousePosHeap,
|
|
||||||
false);
|
|
||||||
ordered = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Target not valid.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not ok to use.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not move.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean orderSmart(final RenderUnit target) {
|
|
||||||
boolean ordered = false;
|
|
||||||
for (final RenderUnit unit : this.selected) {
|
|
||||||
for (final CAbility ability : unit.getSimulationUnit().getAbilities()) {
|
|
||||||
if (ability instanceof CAbilityAttack) {
|
|
||||||
ability.checkCanUse(this.simulation, unit.getSimulationUnit(), OrderIds.smart,
|
|
||||||
BooleanAbilityActivationReceiver.INSTANCE);
|
|
||||||
if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) {
|
|
||||||
ability.checkCanTarget(this.simulation, unit.getSimulationUnit(), OrderIds.smart,
|
|
||||||
target.getSimulationUnit(), CWidgetAbilityTargetCheckReceiver.INSTANCE);
|
|
||||||
final CWidget targetWidget = CWidgetAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
|
||||||
if (targetWidget != null) {
|
|
||||||
ability.onOrder(this.simulation, unit.getSimulationUnit(), OrderIds.smart, targetWidget,
|
|
||||||
false);
|
|
||||||
ordered = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Target not valid.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not ok to use.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not move.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void standOnRepeat(final MdxComplexInstance instance) {
|
public void standOnRepeat(final MdxComplexInstance instance) {
|
||||||
instance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
instance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||||
SequenceUtils.randomStandSequence(instance);
|
SequenceUtils.randomStandSequence(instance);
|
||||||
|
@ -38,6 +38,7 @@ public class RenderUnit {
|
|||||||
private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh");
|
private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh");
|
||||||
private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori");
|
private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori");
|
||||||
private static final War3ID ANIM_PROPS = War3ID.fromString("uani");
|
private static final War3ID ANIM_PROPS = War3ID.fromString("uani");
|
||||||
|
private static final War3ID BLEND_TIME = War3ID.fromString("uble");
|
||||||
private static final float[] heapZ = new float[3];
|
private static final float[] heapZ = new float[3];
|
||||||
public final MdxComplexInstance instance;
|
public final MdxComplexInstance instance;
|
||||||
public final MutableGameObject row;
|
public final MutableGameObject row;
|
||||||
@ -124,6 +125,9 @@ public class RenderUnit {
|
|||||||
orientationInterpolationOrdinal = 0;
|
orientationInterpolationOrdinal = 0;
|
||||||
}
|
}
|
||||||
this.orientationInterpolation = OrientationInterpolation.VALUES[orientationInterpolationOrdinal];
|
this.orientationInterpolation = OrientationInterpolation.VALUES[orientationInterpolationOrdinal];
|
||||||
|
|
||||||
|
final float blendTime = row.getFieldAsFloat(BLEND_TIME, 0);
|
||||||
|
instance.setBlendTime(blendTime * 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
|
@ -35,5 +35,5 @@ public interface CommandButtonListener {
|
|||||||
//
|
//
|
||||||
// int getOrderId();
|
// int getOrderId();
|
||||||
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId,
|
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId,
|
||||||
boolean active);
|
int autoCastOrderId, boolean active, boolean autoCastActive);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ 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.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityColdArrows;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
|
|
||||||
|
|
||||||
public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void> {
|
public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void> {
|
||||||
public static final CommandCardPopulatingAbilityVisitor INSTANCE = new CommandCardPopulatingAbilityVisitor();
|
public static final CommandCardPopulatingAbilityVisitor INSTANCE = new CommandCardPopulatingAbilityVisitor();
|
||||||
@ -33,41 +34,54 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void accept(final CAbilityAttack ability) {
|
public Void accept(final CAbilityAttack ability) {
|
||||||
addCommandButton(ability, this.abilityDataUI.getAttackUI(), ability.getHandleId(), OrderIds.attack);
|
addCommandButton(ability, this.abilityDataUI.getAttackUI(), ability.getHandleId(), OrderIds.attack, 0, false);
|
||||||
if (!this.hasStop) {
|
if (!this.hasStop) {
|
||||||
this.hasStop = true;
|
this.hasStop = true;
|
||||||
addCommandButton(null, this.abilityDataUI.getStopUI(), -1, OrderIds.stop);
|
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void accept(final CAbilityMove ability) {
|
public Void accept(final CAbilityMove ability) {
|
||||||
addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move);
|
addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move, 0, false);
|
||||||
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), ability.getHandleId(), OrderIds.holdposition);
|
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), ability.getHandleId(), OrderIds.holdposition, 0,
|
||||||
addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol);
|
false);
|
||||||
|
addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol, 0, false);
|
||||||
if (!this.hasStop) {
|
if (!this.hasStop) {
|
||||||
this.hasStop = true;
|
this.hasStop = true;
|
||||||
addCommandButton(null, this.abilityDataUI.getStopUI(), -1, OrderIds.stop);
|
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId) {
|
@Override
|
||||||
final boolean active;
|
public Void accept(final CAbilityGeneric ability) {
|
||||||
if (this.unit.getCurrentOrder() == null) {
|
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(), ability.getHandleId(),
|
||||||
active = (orderId == OrderIds.stop);
|
OrderIds.channel, 0, false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void accept(final CAbilityColdArrows ability) {
|
||||||
|
final boolean autoCastActive = ability.isAutoCastActive();
|
||||||
|
int autoCastId;
|
||||||
|
if (autoCastActive) {
|
||||||
|
autoCastId = OrderIds.coldarrows;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ability == null) {
|
autoCastId = OrderIds.uncoldarrows;
|
||||||
active = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ability.checkCanUse(this.game, this.unit, orderId, BooleanAbilityActivationReceiver.INSTANCE);
|
|
||||||
active = BooleanAbilityActivationReceiver.INSTANCE.isOk();
|
|
||||||
}
|
}
|
||||||
|
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(), ability.getHandleId(),
|
||||||
|
OrderIds.coldarrowstarg, autoCastId, autoCastActive);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
|
||||||
|
final int autoCastOrderId, final boolean autoCastActive) {
|
||||||
|
final boolean active = ((handleId == this.unit.getCurrentAbilityHandleId())
|
||||||
|
&& (orderId == this.unit.getCurrentOrderId()));
|
||||||
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
||||||
iconUI.getIcon(), handleId, orderId, active);
|
iconUI.getIcon(), handleId, orderId, autoCastOrderId, active, autoCastActive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||||
|
|
||||||
public class CSimulation {
|
public class CSimulation {
|
||||||
private final CUnitData unitData;
|
|
||||||
private final CAbilityData abilityData;
|
private final CAbilityData abilityData;
|
||||||
|
private final CUnitData unitData;
|
||||||
private final List<CUnit> units;
|
private final List<CUnit> units;
|
||||||
private final List<CPlayer> players;
|
private final List<CPlayer> players;
|
||||||
private final List<CAttackProjectile> projectiles;
|
private final List<CAttackProjectile> projectiles;
|
||||||
@ -47,6 +48,7 @@ public class CSimulation {
|
|||||||
private float currentGameDayTimeElapsed;
|
private float currentGameDayTimeElapsed;
|
||||||
private final Map<Integer, CUnit> handleIdToUnit = new HashMap<>();
|
private final Map<Integer, CUnit> handleIdToUnit = new HashMap<>();
|
||||||
private final Map<Integer, CAbility> handleIdToAbility = new HashMap<>();
|
private final Map<Integer, CAbility> handleIdToAbility = new HashMap<>();
|
||||||
|
private transient CommandErrorListener commandErrorListener;
|
||||||
|
|
||||||
public CSimulation(final DataTable miscData, final MutableObjectData parsedUnitData,
|
public CSimulation(final DataTable miscData, final MutableObjectData parsedUnitData,
|
||||||
final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController,
|
final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController,
|
||||||
@ -55,8 +57,8 @@ public class CSimulation {
|
|||||||
this.gameplayConstants = new CGameplayConstants(miscData);
|
this.gameplayConstants = new CGameplayConstants(miscData);
|
||||||
this.simulationRenderController = simulationRenderController;
|
this.simulationRenderController = simulationRenderController;
|
||||||
this.pathingGrid = pathingGrid;
|
this.pathingGrid = pathingGrid;
|
||||||
this.unitData = new CUnitData(parsedUnitData);
|
|
||||||
this.abilityData = new CAbilityData(parsedAbilityData);
|
this.abilityData = new CAbilityData(parsedAbilityData);
|
||||||
|
this.unitData = new CUnitData(parsedUnitData, this.abilityData);
|
||||||
this.units = new ArrayList<>();
|
this.units = new ArrayList<>();
|
||||||
this.projectiles = new ArrayList<>();
|
this.projectiles = new ArrayList<>();
|
||||||
this.newProjectiles = new ArrayList<>();
|
this.newProjectiles = new ArrayList<>();
|
||||||
@ -92,6 +94,13 @@ public class CSimulation {
|
|||||||
neutralPassive.setAlliance(cPlayer, CAllianceType.PASSIVE, true);
|
neutralPassive.setAlliance(cPlayer, CAllianceType.PASSIVE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.commandErrorListener = new CommandErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void showCommandError(final String message) {
|
||||||
|
throw new RuntimeException(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CUnitData getUnitData() {
|
public CUnitData getUnitData() {
|
||||||
@ -208,4 +217,8 @@ public class CSimulation {
|
|||||||
public CPlayer getPlayer(final int index) {
|
public CPlayer getPlayer(final int index) {
|
||||||
return this.players.get(index);
|
return this.players.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandErrorListener getCommandErrorListener() {
|
||||||
|
return this.commandErrorListener;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,16 @@ import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener.CUnitStateNotifier;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener.CUnitStateNotifier;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||||
|
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.CBehaviorMove;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorStop;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehaviorAttack;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrder;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehavior;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
||||||
@ -38,8 +43,9 @@ public class CUnit extends CWidget {
|
|||||||
|
|
||||||
private final List<CAbility> abilities = new ArrayList<>();
|
private final List<CAbility> abilities = new ArrayList<>();
|
||||||
|
|
||||||
private CBehavior currentOrder;
|
private CBehavior currentBehavior;
|
||||||
private final Queue<CBehavior> orderQueue = new LinkedList<>();
|
private COrder currentOrder;
|
||||||
|
private final Queue<COrder> orderQueue = new LinkedList<>();
|
||||||
private final CUnitType unitType;
|
private final CUnitType unitType;
|
||||||
|
|
||||||
private Rectangle collisionRectangle;
|
private Rectangle collisionRectangle;
|
||||||
@ -59,6 +65,12 @@ public class CUnit extends CWidget {
|
|||||||
private final float acquisitionRange;
|
private final float acquisitionRange;
|
||||||
private transient static AutoAttackTargetFinderEnum autoAttackTargetFinderEnum = new AutoAttackTargetFinderEnum();
|
private transient static AutoAttackTargetFinderEnum autoAttackTargetFinderEnum = new AutoAttackTargetFinderEnum();
|
||||||
|
|
||||||
|
private transient CBehaviorMove moveBehavior;
|
||||||
|
private transient CBehaviorAttack attackBehavior;
|
||||||
|
private transient CBehaviorFollow followBehavior;
|
||||||
|
private transient CBehaviorPatrol patrolBehavior;
|
||||||
|
private transient CBehaviorStop stopBehavior;
|
||||||
|
|
||||||
public CUnit(final int handleId, final int playerIndex, final float x, final float y, final float life,
|
public CUnit(final int handleId, final int playerIndex, final float x, final float y, final float life,
|
||||||
final War3ID typeId, final float facing, final float mana, final int maximumLife, final int maximumMana,
|
final War3ID typeId, final float facing, final float mana, final int maximumLife, final int maximumMana,
|
||||||
final int speed, final int defense, final CUnitType unitType) {
|
final int speed, final int defense, final CUnitType unitType) {
|
||||||
@ -75,6 +87,8 @@ public class CUnit extends CWidget {
|
|||||||
this.unitType = unitType;
|
this.unitType = unitType;
|
||||||
this.classifications.addAll(unitType.getClassifications());
|
this.classifications.addAll(unitType.getClassifications());
|
||||||
this.acquisitionRange = unitType.getDefaultAcquisitionRange();
|
this.acquisitionRange = unitType.getDefaultAcquisitionRange();
|
||||||
|
this.stopBehavior = new CBehaviorStop(this);
|
||||||
|
this.currentBehavior = this.stopBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnitAnimationListener(final CUnitAnimationListener unitAnimationListener) {
|
public void setUnitAnimationListener(final CUnitAnimationListener unitAnimationListener) {
|
||||||
@ -185,20 +199,17 @@ public class CUnit extends CWidget {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this.currentOrder != null) {
|
else if (this.currentBehavior != null) {
|
||||||
if (this.currentOrder.update(game)) {
|
this.currentBehavior = this.currentBehavior.update(game);
|
||||||
// remove current order, because it's completed, polling next
|
|
||||||
// item from order queue
|
|
||||||
this.currentOrder = this.orderQueue.poll();
|
|
||||||
this.stateNotifier.ordersChanged();
|
|
||||||
}
|
|
||||||
if (this.currentOrder == null) {
|
|
||||||
// maybe order "stop" here
|
|
||||||
this.unitAnimationListener.playAnimation(true, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// check to auto acquire targets
|
// check to auto acquire targets
|
||||||
|
autoAcquireAttackTargets(game);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void autoAcquireAttackTargets(final CSimulation game) {
|
||||||
if (!this.unitType.getAttacks().isEmpty()) {
|
if (!this.unitType.getAttacks().isEmpty()) {
|
||||||
if (this.collisionRectangle != null) {
|
if (this.collisionRectangle != null) {
|
||||||
tempRect.set(this.collisionRectangle);
|
tempRect.set(this.collisionRectangle);
|
||||||
@ -214,8 +225,6 @@ public class CUnit extends CWidget {
|
|||||||
game.getWorldCollision().enumUnitsInRect(tempRect, autoAttackTargetFinderEnum.reset(game, this));
|
game.getWorldCollision().enumUnitsInRect(tempRect, autoAttackTargetFinderEnum.reset(game, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getEndingDecayTime(final CSimulation game) {
|
public float getEndingDecayTime(final CSimulation game) {
|
||||||
if (this.unitType.isBuilding()) {
|
if (this.unitType.isBuilding()) {
|
||||||
@ -224,7 +233,7 @@ public class CUnit extends CWidget {
|
|||||||
return game.getGameplayConstants().getBoneDecayTime();
|
return game.getGameplayConstants().getBoneDecayTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void order(final CBehavior order, final boolean queue) {
|
public void order(final CSimulation game, final COrder order, final boolean queue) {
|
||||||
if (isDead()) {
|
if (isDead()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -232,14 +241,37 @@ public class CUnit extends CWidget {
|
|||||||
this.orderQueue.add(order);
|
this.orderQueue.add(order);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currentOrder = order;
|
this.currentBehavior = beginOrder(game, order);
|
||||||
this.orderQueue.clear();
|
this.orderQueue.clear();
|
||||||
}
|
}
|
||||||
this.stateNotifier.ordersChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CBehavior getCurrentOrder() {
|
private CBehavior beginOrder(final CSimulation game, final COrder order) {
|
||||||
return this.currentOrder;
|
final boolean omitNotify = (this.currentOrder == null) && (order == null);
|
||||||
|
this.currentOrder = order;
|
||||||
|
if (!omitNotify) {
|
||||||
|
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||||
|
}
|
||||||
|
CBehavior nextBehavior;
|
||||||
|
if (order != null) {
|
||||||
|
nextBehavior = order.begin(game, this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nextBehavior = this.stopBehavior;
|
||||||
|
}
|
||||||
|
return nextBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehavior getCurrentBehavior() {
|
||||||
|
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() {
|
public List<CAbility> getAbilities() {
|
||||||
@ -389,12 +421,12 @@ public class CUnit extends CWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.currentOrder == null) {
|
if (this.currentBehavior == null) {
|
||||||
if (!simulation.getPlayer(getPlayerIndex()).hasAlliance(source.getPlayerIndex(),
|
if (!simulation.getPlayer(getPlayerIndex()).hasAlliance(source.getPlayerIndex(),
|
||||||
CAllianceType.PASSIVE)) {
|
CAllianceType.PASSIVE)) {
|
||||||
for (final CUnitAttack attack : this.unitType.getAttacks()) {
|
for (final CUnitAttack attack : this.unitType.getAttacks()) {
|
||||||
if (source.canBeTargetedBy(simulation, this, attack.getTargetsAllowed())) {
|
if (source.canBeTargetedBy(simulation, this, attack.getTargetsAllowed())) {
|
||||||
this.order(new CBehaviorAttack(this, attack, OrderIds.attack, source), false);
|
this.currentBehavior = getAttackBehavior().reset(attack, source);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +436,7 @@ public class CUnit extends CWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void kill(final CSimulation simulation) {
|
private void kill(final CSimulation simulation) {
|
||||||
this.currentOrder = null;
|
this.currentBehavior = null;
|
||||||
this.orderQueue.clear();
|
this.orderQueue.clear();
|
||||||
this.deathTurnTick = simulation.getGameTurnTick();
|
this.deathTurnTick = simulation.getGameTurnTick();
|
||||||
}
|
}
|
||||||
@ -558,7 +590,7 @@ public class CUnit extends CWidget {
|
|||||||
if (this.source.canReach(unit, this.source.acquisitionRange)
|
if (this.source.canReach(unit, this.source.acquisitionRange)
|
||||||
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
|
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
|
||||||
&& (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) {
|
&& (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) {
|
||||||
this.source.order(new CBehaviorAttack(this.source, attack, OrderIds.attack, unit), false);
|
this.source.currentBehavior = this.source.getAttackBehavior().reset(attack, unit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,4 +598,45 @@ public class CUnit extends CWidget {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CBehaviorMove getMoveBehavior() {
|
||||||
|
return this.moveBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoveBehavior(final CBehaviorMove moveBehavior) {
|
||||||
|
this.moveBehavior = moveBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorAttack getAttackBehavior() {
|
||||||
|
return this.attackBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackBehavior(final CBehaviorAttack attackBehavior) {
|
||||||
|
this.attackBehavior = attackBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorStop getStopBehavior() {
|
||||||
|
return this.stopBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFollowBehavior(final CBehaviorFollow followBehavior) {
|
||||||
|
this.followBehavior = followBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPatrolBehavior(final CBehaviorPatrol patrolBehavior) {
|
||||||
|
this.patrolBehavior = patrolBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorFollow getFollowBehavior() {
|
||||||
|
return this.followBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorPatrol getPatrolBehavior() {
|
||||||
|
return this.patrolBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehavior pollNextOrderBehavior(final CSimulation game) {
|
||||||
|
final COrder order = this.orderQueue.poll();
|
||||||
|
return beginOrder(game, order);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.etheller.warsmash.util.SubscriberSetNotifier;
|
|||||||
public interface CUnitStateListener {
|
public interface CUnitStateListener {
|
||||||
void lifeChanged(); // hp (current) changes
|
void lifeChanged(); // hp (current) changes
|
||||||
|
|
||||||
void ordersChanged();
|
void ordersChanged(int abilityHandleId, int orderId);
|
||||||
|
|
||||||
public static final class CUnitStateNotifier extends SubscriberSetNotifier<CUnitStateListener>
|
public static final class CUnitStateNotifier extends SubscriberSetNotifier<CUnitStateListener>
|
||||||
implements CUnitStateListener {
|
implements CUnitStateListener {
|
||||||
@ -17,9 +17,9 @@ public interface CUnitStateListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ordersChanged() {
|
public void ordersChanged(final int abilityHandleId, final int orderId) {
|
||||||
for (final CUnitStateListener listener : set) {
|
for (final CUnitStateListener listener : set) {
|
||||||
listener.ordersChanged();
|
listener.ordersChanged(abilityHandleId, orderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
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.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||||
|
|
||||||
public interface CAbility extends CAbilityView {
|
public interface CAbility extends CAbilityView {
|
||||||
/* should fire when ability added to unit */
|
/* should fire when ability added to unit */
|
||||||
@ -12,10 +13,10 @@ public interface CAbility extends CAbilityView {
|
|||||||
/* should fire when ability removed from unit */
|
/* should fire when ability removed from unit */
|
||||||
void onRemove(CSimulation game, CUnit unit);
|
void onRemove(CSimulation game, CUnit unit);
|
||||||
|
|
||||||
void onOrder(CSimulation game, CUnit caster, int orderId, CWidget target, boolean queue);
|
CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target);
|
||||||
|
|
||||||
void onOrder(CSimulation game, CUnit caster, int orderId, Vector2 point, boolean queue);
|
CBehavior begin(CSimulation game, CUnit caster, int orderId, Vector2 point);
|
||||||
|
|
||||||
void onOrderNoTarget(CSimulation game, CUnit caster, int orderId, boolean queue);
|
CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,10 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
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.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.StringsToExternalizeLater;
|
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.combat.CWeaponType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehavior;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehaviorAttack;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehaviorMove;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||||
@ -99,6 +97,7 @@ public class CAbilityAttack implements CAbility {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||||
|
unit.setAttackBehavior(new CBehaviorAttack(unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -106,30 +105,28 @@ public class CAbilityAttack implements CAbility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrder(final CSimulation game, final CUnit caster, final int orderId, final CWidget target,
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||||
final boolean queue) {
|
CBehavior behavior = null;
|
||||||
CBehavior order = null;
|
|
||||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||||
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||||
order = new CBehaviorAttack(caster, attack, orderId, target);
|
behavior = caster.getAttackBehavior().reset(attack, target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (order == null) {
|
if (behavior == null) {
|
||||||
order = new CBehaviorMove(caster, orderId, target.getX(), target.getY());
|
behavior = caster.getMoveBehavior().reset(target.getX(), target.getY());
|
||||||
}
|
}
|
||||||
caster.order(order, queue);
|
return behavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrder(final CSimulation game, final CUnit caster, final int orderId, final Vector2 target,
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||||
final boolean queue) {
|
return caster.pollNextOrderBehavior(game);
|
||||||
throw new IllegalArgumentException(StringsToExternalizeLater.MUST_TARGET_WIDGET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrderNoTarget(final CSimulation game, final CUnit caster, final int orderId, final boolean queue) {
|
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||||
throw new IllegalArgumentException(StringsToExternalizeLater.MUST_TARGET_WIDGET);
|
return caster.pollNextOrderBehavior(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
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.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an ability from the object data
|
||||||
|
*/
|
||||||
|
public class CAbilityColdArrows implements CAbility {
|
||||||
|
private final War3ID rawcode;
|
||||||
|
private final int handleId;
|
||||||
|
private boolean autoCastActive;
|
||||||
|
|
||||||
|
public CAbilityColdArrows(final War3ID rawcode, final int handleId) {
|
||||||
|
this.rawcode = rawcode;
|
||||||
|
this.handleId = handleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanUse(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityActivationReceiver receiver) {
|
||||||
|
receiver.useOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target,
|
||||||
|
final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||||
|
switch (orderId) {
|
||||||
|
case OrderIds.coldarrowstarg:
|
||||||
|
receiver.targetOk(target);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final Vector2 target,
|
||||||
|
final AbilityTargetCheckReceiver<Vector2> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityTargetCheckReceiver<Void> receiver) {
|
||||||
|
switch (orderId) {
|
||||||
|
case OrderIds.coldarrows:
|
||||||
|
case OrderIds.uncoldarrows:
|
||||||
|
receiver.targetOk(null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public War3ID getRawcode() {
|
||||||
|
return this.rawcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHandleId() {
|
||||||
|
return this.handleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoCastActive() {
|
||||||
|
return this.autoCastActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T visit(final CAbilityVisitor<T> visitor) {
|
||||||
|
return visitor.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||||
|
CBehavior behavior = null;
|
||||||
|
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||||
|
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||||
|
behavior = caster.getAttackBehavior().reset(attack, target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (behavior != null) {
|
||||||
|
return behavior;
|
||||||
|
}
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||||
|
this.autoCastActive = !this.autoCastActive;
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
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.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an ability from the object data
|
||||||
|
*/
|
||||||
|
public class CAbilityGeneric implements CAbility {
|
||||||
|
private final War3ID rawcode;
|
||||||
|
private final int handleId;
|
||||||
|
|
||||||
|
public CAbilityGeneric(final War3ID rawcode, final int handleId) {
|
||||||
|
this.rawcode = rawcode;
|
||||||
|
this.handleId = handleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public War3ID getRawcode() {
|
||||||
|
return this.rawcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanUse(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityActivationReceiver receiver) {
|
||||||
|
receiver.notAnActiveAbility();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target,
|
||||||
|
final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final Vector2 target,
|
||||||
|
final AbilityTargetCheckReceiver<Vector2> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityTargetCheckReceiver<Void> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHandleId() {
|
||||||
|
return this.handleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T visit(final CAbilityVisitor<T> visitor) {
|
||||||
|
return visitor.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
}
|
@ -4,9 +4,10 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
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.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.StringsToExternalizeLater;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehaviorMove;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.CBehaviorPatrol;
|
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;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||||
@ -31,7 +32,7 @@ public class CAbilityMove implements CAbility {
|
|||||||
switch (orderId) {
|
switch (orderId) {
|
||||||
case OrderIds.smart:
|
case OrderIds.smart:
|
||||||
case OrderIds.patrol:
|
case OrderIds.patrol:
|
||||||
if (target instanceof CUnit) {
|
if ((target instanceof CUnit) && (target != unit)) {
|
||||||
receiver.targetOk(target);
|
receiver.targetOk(target);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -74,7 +75,9 @@ public class CAbilityMove implements CAbility {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||||
|
unit.setMoveBehavior(new CBehaviorMove(unit));
|
||||||
|
unit.setFollowBehavior(new CBehaviorFollow(unit));
|
||||||
|
unit.setPatrolBehavior(new CBehaviorPatrol(unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -83,20 +86,23 @@ public class CAbilityMove implements CAbility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrder(final CSimulation game, final CUnit caster, final int orderId, final CWidget target,
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||||
final boolean queue) {
|
return caster.getFollowBehavior().reset((CUnit) target);
|
||||||
caster.order(new CBehaviorPatrol(caster, orderId, (CUnit) target), queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrder(final CSimulation game, final CUnit caster, final int orderId, final Vector2 target,
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||||
final boolean queue) {
|
if (orderId == OrderIds.patrol) {
|
||||||
caster.order(new CBehaviorMove(caster, orderId, target.x, target.y), queue);
|
return caster.getPatrolBehavior().reset(point);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return caster.getMoveBehavior().reset(point.x, point.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrderNoTarget(final CSimulation game, final CUnit caster, final int orderId, final boolean queue) {
|
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||||
throw new IllegalArgumentException(StringsToExternalizeLater.MUST_TARGET_POINT);
|
return caster.pollNextOrderBehavior(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -12,4 +12,8 @@ public interface CAbilityVisitor<T> {
|
|||||||
T accept(CAbilityAttack ability);
|
T accept(CAbilityAttack ability);
|
||||||
|
|
||||||
T accept(CAbilityMove ability);
|
T accept(CAbilityMove ability);
|
||||||
|
|
||||||
|
T accept(CAbilityGeneric ability);
|
||||||
|
|
||||||
|
T accept(CAbilityColdArrows ability);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public abstract class CAbstractRangedBehavior implements CRangedBehavior {
|
||||||
|
protected final CUnit unit;
|
||||||
|
|
||||||
|
public CAbstractRangedBehavior(final CUnit unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean wasWithinPropWindow = false;
|
||||||
|
protected CWidget target;
|
||||||
|
private boolean wasInRange = false;
|
||||||
|
private CBehaviorMove moveBehavior;
|
||||||
|
|
||||||
|
protected final CAbstractRangedBehavior innerReset(final CWidget target) {
|
||||||
|
this.wasWithinPropWindow = false;
|
||||||
|
this.target = target;
|
||||||
|
this.wasInRange = false;
|
||||||
|
if (!this.unit.isMovementDisabled()) {
|
||||||
|
if ((target instanceof CUnit) && !((CUnit) target).getUnitType().isBuilding()) {
|
||||||
|
this.moveBehavior = this.unit.getMoveBehavior().reset((CUnit) target, this);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.moveBehavior = this.unit.getMoveBehavior().reset(target.getX(), target.getY(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.moveBehavior = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract CBehavior update(CSimulation simulation, boolean withinRange);
|
||||||
|
|
||||||
|
protected abstract boolean checkTargetStillValid(CSimulation simulation);
|
||||||
|
|
||||||
|
protected abstract void resetBeforeMoving(CSimulation simulation);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final CBehavior update(final CSimulation simulation) {
|
||||||
|
if (!checkTargetStillValid(simulation)) {
|
||||||
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
|
}
|
||||||
|
if (!isWithinRange(simulation)) {
|
||||||
|
if (this.moveBehavior == null) {
|
||||||
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
|
}
|
||||||
|
this.wasInRange = false;
|
||||||
|
resetBeforeMoving(simulation);
|
||||||
|
;
|
||||||
|
return this.unit.getMoveBehavior();
|
||||||
|
}
|
||||||
|
this.wasInRange = true;
|
||||||
|
if (!this.unit.isMovementDisabled()) {
|
||||||
|
final float prevX = this.unit.getX();
|
||||||
|
final float prevY = this.unit.getY();
|
||||||
|
final float deltaY = this.target.getY() - prevY;
|
||||||
|
final float deltaX = this.target.getX() - prevX;
|
||||||
|
final double goalAngleRad = Math.atan2(deltaY, deltaX);
|
||||||
|
float goalAngle = (float) Math.toDegrees(goalAngleRad);
|
||||||
|
if (goalAngle < 0) {
|
||||||
|
goalAngle += 360;
|
||||||
|
}
|
||||||
|
float facing = this.unit.getFacing();
|
||||||
|
float delta = goalAngle - facing;
|
||||||
|
final float propulsionWindow = simulation.getGameplayConstants().getAttackHalfAngle();
|
||||||
|
final float turnRate = simulation.getUnitData().getTurnRate(this.unit.getTypeId());
|
||||||
|
|
||||||
|
if (delta < -180) {
|
||||||
|
delta = 360 + delta;
|
||||||
|
}
|
||||||
|
if (delta > 180) {
|
||||||
|
delta = -360 + delta;
|
||||||
|
}
|
||||||
|
final float absDelta = Math.abs(delta);
|
||||||
|
|
||||||
|
if ((absDelta <= 1.0) && (absDelta != 0)) {
|
||||||
|
this.unit.setFacing(goalAngle);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate);
|
||||||
|
if (absDelta < Math.abs(angleToAdd)) {
|
||||||
|
angleToAdd = delta;
|
||||||
|
}
|
||||||
|
facing += angleToAdd;
|
||||||
|
this.unit.setFacing(facing);
|
||||||
|
}
|
||||||
|
if (absDelta < propulsionWindow) {
|
||||||
|
this.wasWithinPropWindow = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If this happens, the unit is facing the wrong way, and has to turn before
|
||||||
|
// moving.
|
||||||
|
this.wasWithinPropWindow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.wasWithinPropWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return update(simulation, this.wasWithinPropWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
|
|
||||||
|
public interface CBehavior {
|
||||||
|
/**
|
||||||
|
* Executes one step of game simulation of the current order, and then returns
|
||||||
|
* the next behavior for the unit after the result of the update cycle.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CBehavior update(CSimulation game);
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.util.WarsmashConstants;
|
||||||
|
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.CWidget;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||||
|
|
||||||
|
public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||||
|
|
||||||
|
public CBehaviorAttack(final CUnit unit) {
|
||||||
|
super(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CUnitAttack unitAttack;
|
||||||
|
private int damagePointLaunchTime;
|
||||||
|
private int backSwingTime;
|
||||||
|
private int thisOrderCooldownEndTime;
|
||||||
|
|
||||||
|
public CBehaviorAttack reset(final CUnitAttack unitAttack, final CWidget target) {
|
||||||
|
super.innerReset(target);
|
||||||
|
this.unitAttack = unitAttack;
|
||||||
|
this.damagePointLaunchTime = 0;
|
||||||
|
this.backSwingTime = 0;
|
||||||
|
this.thisOrderCooldownEndTime = 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinRange(final CSimulation simulation) {
|
||||||
|
float range = this.unitAttack.getRange();
|
||||||
|
if ((this.target instanceof CUnit) && (((CUnit) this.target).getCurrentBehavior() instanceof CBehaviorMove)
|
||||||
|
&& (this.damagePointLaunchTime != 0 /*
|
||||||
|
* only apply range motion buffer if they were already in range and
|
||||||
|
* attacked
|
||||||
|
*/)) {
|
||||||
|
range += this.unitAttack.getRangeMotionBuffer();
|
||||||
|
}
|
||||||
|
return this.unit.canReach(this.target, range)
|
||||||
|
&& (this.unit.distance(this.target) >= this.unit.getUnitType().getMinimumAttackRange());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkTargetStillValid(final CSimulation simulation) {
|
||||||
|
return !this.target.isDead()
|
||||||
|
&& this.target.canBeTargetedBy(simulation, this.unit, this.unitAttack.getTargetsAllowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void resetBeforeMoving(final CSimulation simulation) {
|
||||||
|
this.damagePointLaunchTime = 0;
|
||||||
|
this.thisOrderCooldownEndTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior update(final CSimulation simulation, final boolean withinRange) {
|
||||||
|
final int cooldownEndTime = this.unit.getCooldownEndTime();
|
||||||
|
final int currentTurnTick = simulation.getGameTurnTick();
|
||||||
|
if (withinRange) {
|
||||||
|
if (this.damagePointLaunchTime != 0) {
|
||||||
|
if (currentTurnTick >= this.damagePointLaunchTime) {
|
||||||
|
int minDamage = this.unitAttack.getMinDamage();
|
||||||
|
final int maxDamage = Math.max(0, this.unitAttack.getMaxDamage());
|
||||||
|
if (minDamage > maxDamage) {
|
||||||
|
minDamage = maxDamage;
|
||||||
|
}
|
||||||
|
final int damage;
|
||||||
|
if (maxDamage == 0) {
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
|
else if (minDamage == maxDamage) {
|
||||||
|
damage = minDamage;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
damage = simulation.getSeededRandom().nextInt(maxDamage - minDamage) + minDamage;
|
||||||
|
}
|
||||||
|
this.unitAttack.launch(simulation, this.unit, this.target, damage);
|
||||||
|
this.damagePointLaunchTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (currentTurnTick >= cooldownEndTime) {
|
||||||
|
final float cooldownTime = this.unitAttack.getCooldownTime();
|
||||||
|
final float animationBackswingPoint = this.unitAttack.getAnimationBackswingPoint();
|
||||||
|
final int a1CooldownSteps = (int) (cooldownTime / WarsmashConstants.SIMULATION_STEP_TIME);
|
||||||
|
final int a1BackswingSteps = (int) (animationBackswingPoint / WarsmashConstants.SIMULATION_STEP_TIME);
|
||||||
|
final int a1DamagePointSteps = (int) (this.unitAttack.getAnimationDamagePoint()
|
||||||
|
/ WarsmashConstants.SIMULATION_STEP_TIME);
|
||||||
|
this.unit.setCooldownEndTime(currentTurnTick + a1CooldownSteps);
|
||||||
|
this.thisOrderCooldownEndTime = currentTurnTick + a1CooldownSteps;
|
||||||
|
this.damagePointLaunchTime = currentTurnTick + a1DamagePointSteps;
|
||||||
|
this.backSwingTime = currentTurnTick + a1DamagePointSteps + a1BackswingSteps;
|
||||||
|
this.unit.getUnitAnimationListener().playAnimation(true, PrimaryTag.ATTACK, SequenceUtils.EMPTY, 1.0f,
|
||||||
|
true);
|
||||||
|
this.unit.getUnitAnimationListener().queueAnimation(PrimaryTag.STAND, SequenceUtils.READY, false);
|
||||||
|
}
|
||||||
|
else if ((currentTurnTick >= this.thisOrderCooldownEndTime)) {
|
||||||
|
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
public class CBehaviorFollow extends CAbstractRangedBehavior {
|
||||||
|
|
||||||
|
public CBehaviorFollow(final CUnit unit) {
|
||||||
|
super(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehavior reset(final CUnit target) {
|
||||||
|
return innerReset(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinRange(final CSimulation simulation) {
|
||||||
|
return this.unit.canReach(this.target, this.unit.getAcquisitionRange());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CBehavior update(final CSimulation simulation, final boolean withinRange) {
|
||||||
|
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, false);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkTargetStillValid(final CSimulation simulation) {
|
||||||
|
return !this.target.isDead();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void resetBeforeMoving(final CSimulation simulation) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Point2D.Float;
|
import java.awt.geom.Point2D.Float;
|
||||||
@ -18,35 +18,58 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CPathfindin
|
|||||||
public class CBehaviorMove implements CBehavior {
|
public class CBehaviorMove implements CBehavior {
|
||||||
private static final Rectangle tempRect = new Rectangle();
|
private static final Rectangle tempRect = new Rectangle();
|
||||||
private final CUnit unit;
|
private final CUnit unit;
|
||||||
private final int orderId;
|
|
||||||
private boolean wasWithinPropWindow = false;
|
|
||||||
private List<Point2D.Float> path = null;
|
|
||||||
private final CPathfindingProcessor.GridMapping gridMapping;
|
|
||||||
private final Point2D.Float target;
|
|
||||||
private int searchCycles = 0;
|
|
||||||
private CUnit followUnit;
|
|
||||||
|
|
||||||
public CBehaviorMove(final CUnit unit, final int orderId, final float targetX, final float targetY) {
|
public CBehaviorMove(final CUnit unit) {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
this.orderId = orderId;
|
|
||||||
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
|
||||||
unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS
|
|
||||||
: CPathfindingProcessor.GridMapping.CELLS;
|
|
||||||
this.target = new Point2D.Float(targetX, targetY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CBehaviorMove(final CUnit unit, final int orderId, final CUnit followUnit) {
|
private boolean wasWithinPropWindow = false;
|
||||||
this.unit = unit;
|
private List<Point2D.Float> path = null;
|
||||||
this.orderId = orderId;
|
private CPathfindingProcessor.GridMapping gridMapping;
|
||||||
|
private Point2D.Float target;
|
||||||
|
private int searchCycles = 0;
|
||||||
|
private CUnit followUnit;
|
||||||
|
private CRangedBehavior rangedBehavior;
|
||||||
|
|
||||||
|
public CBehaviorMove reset(final float targetX, final float targetY) {
|
||||||
|
return reset(targetX, targetY, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorMove reset(final float targetX, final float targetY, final CRangedBehavior rangedBehavior) {
|
||||||
|
this.wasWithinPropWindow = false;
|
||||||
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
||||||
unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS
|
this.unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS
|
||||||
|
: CPathfindingProcessor.GridMapping.CELLS;
|
||||||
|
this.target = new Point2D.Float(targetX, targetY);
|
||||||
|
this.path = null;
|
||||||
|
this.searchCycles = 0;
|
||||||
|
this.followUnit = null;
|
||||||
|
this.rangedBehavior = rangedBehavior;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorMove reset(final CUnit followUnit) {
|
||||||
|
return reset(followUnit, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehaviorMove reset(final CUnit followUnit, final CRangedBehavior rangedBehavior) {
|
||||||
|
this.wasWithinPropWindow = false;
|
||||||
|
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
||||||
|
this.unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS
|
||||||
: CPathfindingProcessor.GridMapping.CELLS;
|
: CPathfindingProcessor.GridMapping.CELLS;
|
||||||
this.target = new Point2D.Float(followUnit.getX(), followUnit.getY());
|
this.target = new Point2D.Float(followUnit.getX(), followUnit.getY());
|
||||||
|
this.path = null;
|
||||||
|
this.searchCycles = 0;
|
||||||
this.followUnit = followUnit;
|
this.followUnit = followUnit;
|
||||||
|
this.rangedBehavior = rangedBehavior;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(final CSimulation simulation) {
|
public CBehavior update(final CSimulation simulation) {
|
||||||
|
if ((this.rangedBehavior != null) && this.rangedBehavior.isWithinRange(simulation)) {
|
||||||
|
return this.rangedBehavior;
|
||||||
|
}
|
||||||
final float prevX = this.unit.getX();
|
final float prevX = this.unit.getX();
|
||||||
final float prevY = this.unit.getY();
|
final float prevY = this.unit.getY();
|
||||||
|
|
||||||
@ -119,7 +142,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
this.searchCycles < 4);
|
this.searchCycles < 4);
|
||||||
System.out.println("new path (for target) " + this.path);
|
System.out.println("new path (for target) " + this.path);
|
||||||
if (this.path.isEmpty()) {
|
if (this.path.isEmpty()) {
|
||||||
return true;
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float currentTargetX;
|
float currentTargetX;
|
||||||
@ -217,7 +240,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
this.searchCycles = 0;
|
this.searchCycles = 0;
|
||||||
}
|
}
|
||||||
if (this.path.isEmpty()) {
|
if (this.path.isEmpty()) {
|
||||||
return true;
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
System.out.println(this.path);
|
System.out.println(this.path);
|
||||||
@ -249,7 +272,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
deltaY = currentTargetY - nextY;
|
deltaY = currentTargetY - nextY;
|
||||||
deltaX = currentTargetX - nextX;
|
deltaX = currentTargetX - nextX;
|
||||||
if ((deltaX == 0.000f) && (deltaY == 0.000f) && this.path.isEmpty()) {
|
if ((deltaX == 0.000f) && (deltaY == 0.000f) && this.path.isEmpty()) {
|
||||||
return true;
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
}
|
}
|
||||||
System.out.println("new target: " + currentTargetX + "," + currentTargetY);
|
System.out.println("new target: " + currentTargetX + "," + currentTargetY);
|
||||||
System.out.println("new delta: " + deltaX + "," + deltaY);
|
System.out.println("new delta: " + deltaX + "," + deltaY);
|
||||||
@ -274,7 +297,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
SequenceUtils.EMPTY, 1.0f, true);
|
SequenceUtils.EMPTY, 1.0f, true);
|
||||||
}
|
}
|
||||||
this.wasWithinPropWindow = false;
|
this.wasWithinPropWindow = false;
|
||||||
return false;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +313,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
this.searchCycles++;
|
this.searchCycles++;
|
||||||
System.out.println("new path " + this.path);
|
System.out.println("new path " + this.path);
|
||||||
if (this.path.isEmpty() || (this.searchCycles > 5)) {
|
if (this.path.isEmpty() || (this.searchCycles > 5)) {
|
||||||
return true;
|
return this.unit.pollNextOrderBehavior(simulation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.WALK, SequenceUtils.EMPTY, 1.0f,
|
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.WALK, SequenceUtils.EMPTY, 1.0f,
|
||||||
@ -309,12 +332,7 @@ public class CBehaviorMove implements CBehavior {
|
|||||||
this.wasWithinPropWindow = false;
|
this.wasWithinPropWindow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return this;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrderId() {
|
|
||||||
return this.orderId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||||
|
|
||||||
|
public class CBehaviorPatrol implements CRangedBehavior {
|
||||||
|
|
||||||
|
private final CUnit unit;
|
||||||
|
private Vector2 target;
|
||||||
|
private Vector2 startPoint;
|
||||||
|
|
||||||
|
public CBehaviorPatrol(final CUnit unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CBehavior reset(final Vector2 target) {
|
||||||
|
this.target = target;
|
||||||
|
this.startPoint = new Vector2(this.unit.getX(), this.unit.getY());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinRange(final CSimulation simulation) {
|
||||||
|
return this.unit.distance(this.target.x, this.target.y) <= simulation.getGameplayConstants()
|
||||||
|
.getCloseEnoughRange(); // TODO this is not how it was meant to be used
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior update(final CSimulation simulation) {
|
||||||
|
final Vector2 temp = this.target;
|
||||||
|
this.target = this.startPoint;
|
||||||
|
this.startPoint = temp;
|
||||||
|
return this.unit.getMoveBehavior().reset(this.target.x, this.target.y, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
public class CBehaviorStop implements CBehavior {
|
||||||
|
|
||||||
|
private final CUnit unit;
|
||||||
|
|
||||||
|
public CBehaviorStop(final CUnit unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior update(final CSimulation game) {
|
||||||
|
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true);
|
||||||
|
return this.unit.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
|
|
||||||
|
public interface CRangedBehavior extends CBehavior {
|
||||||
|
boolean isWithinRange(final CSimulation simulation);
|
||||||
|
}
|
@ -1,27 +1,24 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data;
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data;
|
||||||
|
|
||||||
import com.etheller.warsmash.units.manager.MutableObjectData;
|
import com.etheller.warsmash.units.manager.MutableObjectData;
|
||||||
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
|
|
||||||
import com.etheller.warsmash.util.ImageUtils;
|
|
||||||
import com.etheller.warsmash.util.War3ID;
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityColdArrows;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
|
||||||
|
|
||||||
public class CAbilityData {
|
public class CAbilityData {
|
||||||
private static final War3ID ABILITY_ICON = War3ID.fromString("aart");
|
private static final War3ID COLD_ARROWS = War3ID.fromString("ACcw");
|
||||||
private final MutableObjectData abilityData;
|
private final MutableObjectData abilityData;
|
||||||
|
|
||||||
public CAbilityData(final MutableObjectData abilityData) {
|
public CAbilityData(final MutableObjectData abilityData) {
|
||||||
this.abilityData = abilityData;
|
this.abilityData = abilityData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIconPath(final War3ID id, final int level) {
|
public CAbility createAbility(final String ability, final int handleId) {
|
||||||
final MutableGameObject mutableGameObject = this.abilityData.get(id);
|
final War3ID war3Id = War3ID.fromString(ability);
|
||||||
if (mutableGameObject == null) {
|
if (war3Id.equals(COLD_ARROWS)) {
|
||||||
return ImageUtils.DEFAULT_ICON_PATH;
|
return new CAbilityColdArrows(war3Id, handleId);
|
||||||
}
|
}
|
||||||
final String iconPath = mutableGameObject.getFieldAsString(ABILITY_ICON, level);
|
return new CAbilityGeneric(war3Id, handleId);
|
||||||
if ((iconPath == null) || "".equals(iconPath)) {
|
|
||||||
return ImageUtils.DEFAULT_ICON_PATH;
|
|
||||||
}
|
|
||||||
return iconPath;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,11 +118,15 @@ public class CUnitData {
|
|||||||
private static final War3ID CLASSIFICATION = War3ID.fromString("utyp");
|
private static final War3ID CLASSIFICATION = War3ID.fromString("utyp");
|
||||||
private static final War3ID DEATH_TIME = War3ID.fromString("udtm");
|
private static final War3ID DEATH_TIME = War3ID.fromString("udtm");
|
||||||
private static final War3ID TARGETED_AS = War3ID.fromString("utar");
|
private static final War3ID TARGETED_AS = War3ID.fromString("utar");
|
||||||
|
|
||||||
|
private static final War3ID ABILITIES_NORMAL = War3ID.fromString("uabi");
|
||||||
private final MutableObjectData unitData;
|
private final MutableObjectData unitData;
|
||||||
private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>();
|
private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>();
|
||||||
|
private final CAbilityData abilityData;
|
||||||
|
|
||||||
public CUnitData(final MutableObjectData unitData) {
|
public CUnitData(final MutableObjectData unitData, final CAbilityData abilityData) {
|
||||||
this.unitData = unitData;
|
this.unitData = unitData;
|
||||||
|
this.abilityData = abilityData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CUnit create(final CSimulation simulation, final int playerIndex, final War3ID typeId, final float x,
|
public CUnit create(final CSimulation simulation, final int playerIndex, final War3ID typeId, final float x,
|
||||||
@ -135,6 +139,7 @@ public class CUnitData {
|
|||||||
final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0);
|
final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0);
|
||||||
final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0);
|
final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0);
|
||||||
final int defense = unitType.getFieldAsInteger(DEFENSE, 0);
|
final int defense = unitType.getFieldAsInteger(DEFENSE, 0);
|
||||||
|
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
|
||||||
|
|
||||||
final CUnitType unitTypeInstance = getUnitTypeInstance(typeId, buildingPathingPixelMap, unitType);
|
final CUnitType unitTypeInstance = getUnitTypeInstance(typeId, buildingPathingPixelMap, unitType);
|
||||||
|
|
||||||
@ -146,6 +151,9 @@ public class CUnitData {
|
|||||||
if (!unitTypeInstance.getAttacks().isEmpty()) {
|
if (!unitTypeInstance.getAttacks().isEmpty()) {
|
||||||
unit.add(simulation, new CAbilityAttack(handleIdAllocator.createId()));
|
unit.add(simulation, new CAbilityAttack(handleIdAllocator.createId()));
|
||||||
}
|
}
|
||||||
|
for (final String ability : abilityList.split(",")) {
|
||||||
|
unit.add(simulation, this.abilityData.createAbility(ability, handleIdAllocator.createId()));
|
||||||
|
}
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +192,8 @@ public class CUnitData {
|
|||||||
final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK1_DAMAGE_POINT, 0);
|
final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK1_DAMAGE_POINT, 0);
|
||||||
final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_FULL_DMG, 0);
|
final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_FULL_DMG, 0);
|
||||||
final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_HALF_DMG, 0);
|
final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_QUARTER_DMG, 0);
|
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_QUARTER_DMG,
|
||||||
|
0);
|
||||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_AREA_OF_EFFECT_TARGETS, 0));
|
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_AREA_OF_EFFECT_TARGETS, 0));
|
||||||
final CAttackType attackType = CAttackType
|
final CAttackType attackType = CAttackType
|
||||||
@ -202,8 +211,8 @@ public class CUnitData {
|
|||||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK1_TARGET_COUNT, 0);
|
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK1_TARGET_COUNT, 0);
|
||||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
final float projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
||||||
final String projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
final String projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
||||||
final boolean projectileHomingEnabled = unitType.getFieldAsBoolean(ATTACK1_PROJECTILE_HOMING_ENABLED,
|
final boolean projectileHomingEnabled = unitType
|
||||||
0);
|
.getFieldAsBoolean(ATTACK1_PROJECTILE_HOMING_ENABLED, 0);
|
||||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
||||||
final int range = unitType.getFieldAsInteger(ATTACK1_RANGE, 0);
|
final int range = unitType.getFieldAsInteger(ATTACK1_RANGE, 0);
|
||||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK1_RANGE_MOTION_BUFFER, 0);
|
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK1_RANGE_MOTION_BUFFER, 0);
|
||||||
@ -215,11 +224,13 @@ public class CUnitData {
|
|||||||
.parseWeaponType(unitType.getFieldAsString(ATTACK1_WEAPON_TYPE, 0));
|
.parseWeaponType(unitType.getFieldAsString(ATTACK1_WEAPON_TYPE, 0));
|
||||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor, damageDice,
|
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||||
damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled, projectileSpeed,
|
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||||
range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType));
|
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||||
} catch (Exception exc) {
|
weaponType));
|
||||||
|
}
|
||||||
|
catch (final Exception exc) {
|
||||||
System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +241,8 @@ public class CUnitData {
|
|||||||
final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK2_DAMAGE_POINT, 0);
|
final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK2_DAMAGE_POINT, 0);
|
||||||
final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_FULL_DMG, 0);
|
final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_FULL_DMG, 0);
|
||||||
final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_HALF_DMG, 0);
|
final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_QUARTER_DMG, 0);
|
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_QUARTER_DMG,
|
||||||
|
0);
|
||||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_AREA_OF_EFFECT_TARGETS, 0));
|
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_AREA_OF_EFFECT_TARGETS, 0));
|
||||||
final CAttackType attackType = CAttackType
|
final CAttackType attackType = CAttackType
|
||||||
@ -248,8 +260,8 @@ public class CUnitData {
|
|||||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK2_TARGET_COUNT, 0);
|
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK2_TARGET_COUNT, 0);
|
||||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
final float projectileArc = unitType.getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
||||||
final String projectileArt = unitType.getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
final String projectileArt = unitType.getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
||||||
final boolean projectileHomingEnabled = unitType.getFieldAsBoolean(ATTACK2_PROJECTILE_HOMING_ENABLED,
|
final boolean projectileHomingEnabled = unitType
|
||||||
0);
|
.getFieldAsBoolean(ATTACK2_PROJECTILE_HOMING_ENABLED, 0);
|
||||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
||||||
final int range = unitType.getFieldAsInteger(ATTACK2_RANGE, 0);
|
final int range = unitType.getFieldAsInteger(ATTACK2_RANGE, 0);
|
||||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK2_RANGE_MOTION_BUFFER, 0);
|
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK2_RANGE_MOTION_BUFFER, 0);
|
||||||
@ -261,11 +273,13 @@ public class CUnitData {
|
|||||||
.parseWeaponType(unitType.getFieldAsString(ATTACK2_WEAPON_TYPE, 0));
|
.parseWeaponType(unitType.getFieldAsString(ATTACK2_WEAPON_TYPE, 0));
|
||||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor, damageDice,
|
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||||
damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled, projectileSpeed,
|
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||||
range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType));
|
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||||
} catch (Exception exc) {
|
weaponType));
|
||||||
|
}
|
||||||
|
catch (final Exception exc) {
|
||||||
System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
|
||||||
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
|
||||||
|
|
||||||
public interface CBehavior {
|
|
||||||
/**
|
|
||||||
* Executes one step of game simulation of the current order, returning true if
|
|
||||||
* the order has completed. Many orders may wrap the move order and spend a
|
|
||||||
* number of simulation steps moving to get within range of the target point
|
|
||||||
* before completing.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
boolean update(CSimulation game);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the Order ID of the order, useful for determining which icon to
|
|
||||||
* highlight on the unit's command card.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int getOrderId();
|
|
||||||
}
|
|
@ -1,177 +0,0 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
|
||||||
|
|
||||||
import com.etheller.warsmash.util.WarsmashConstants;
|
|
||||||
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.CWidget;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
|
||||||
|
|
||||||
public class CBehaviorAttack implements CBehavior {
|
|
||||||
private final CUnit unit;
|
|
||||||
private final int orderId;
|
|
||||||
private boolean wasWithinPropWindow = false;
|
|
||||||
private final CUnitAttack unitAttack;
|
|
||||||
private final CWidget target;
|
|
||||||
private int damagePointLaunchTime;
|
|
||||||
private int backSwingTime;
|
|
||||||
private CBehavior moveOrder;
|
|
||||||
private int thisOrderCooldownEndTime;
|
|
||||||
private boolean wasInRange = false;
|
|
||||||
|
|
||||||
public CBehaviorAttack(final CUnit unit, final CUnitAttack unitAttack, final int orderId, final CWidget target) {
|
|
||||||
this.unit = unit;
|
|
||||||
this.unitAttack = unitAttack;
|
|
||||||
this.orderId = orderId;
|
|
||||||
this.target = target;
|
|
||||||
createMoveOrder(unit, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createMoveOrder(final CUnit unit, final CWidget target) {
|
|
||||||
if (!unit.isMovementDisabled()) { // TODO: Check mobility instead
|
|
||||||
if ((target instanceof CUnit) && !(((CUnit) target).getUnitType().isBuilding())) {
|
|
||||||
this.moveOrder = new CBehaviorMove(unit, this.orderId, (CUnit) target);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.moveOrder = new CBehaviorMove(unit, this.orderId, target.getX(), target.getY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.moveOrder = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean update(final CSimulation simulation) {
|
|
||||||
if (this.target.isDead()
|
|
||||||
|| !this.target.canBeTargetedBy(simulation, this.unit, this.unitAttack.getTargetsAllowed())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
float range = this.unitAttack.getRange();
|
|
||||||
if ((this.target instanceof CUnit) && (((CUnit) this.target).getCurrentOrder() instanceof CBehaviorMove)
|
|
||||||
&& (this.damagePointLaunchTime != 0 /*
|
|
||||||
* only apply range motion buffer if they were already in range and
|
|
||||||
* attacked
|
|
||||||
*/)) {
|
|
||||||
range += this.unitAttack.getRangeMotionBuffer();
|
|
||||||
}
|
|
||||||
if (!this.unit.canReach(this.target, range)
|
|
||||||
|| (this.unit.distance(this.target) < this.unit.getUnitType().getMinimumAttackRange())) {
|
|
||||||
if (this.moveOrder == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.moveOrder.update(simulation)) {
|
|
||||||
return true; // we just cant reach them
|
|
||||||
}
|
|
||||||
this.wasInRange = false;
|
|
||||||
this.damagePointLaunchTime = 0;
|
|
||||||
this.thisOrderCooldownEndTime = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.wasInRange = true;
|
|
||||||
if (!this.unit.isMovementDisabled()) {
|
|
||||||
final float prevX = this.unit.getX();
|
|
||||||
final float prevY = this.unit.getY();
|
|
||||||
final float deltaY = this.target.getY() - prevY;
|
|
||||||
final float deltaX = this.target.getX() - prevX;
|
|
||||||
final double goalAngleRad = Math.atan2(deltaY, deltaX);
|
|
||||||
float goalAngle = (float) Math.toDegrees(goalAngleRad);
|
|
||||||
if (goalAngle < 0) {
|
|
||||||
goalAngle += 360;
|
|
||||||
}
|
|
||||||
float facing = this.unit.getFacing();
|
|
||||||
float delta = goalAngle - facing;
|
|
||||||
final float propulsionWindow = simulation.getGameplayConstants().getAttackHalfAngle();
|
|
||||||
final float turnRate = simulation.getUnitData().getTurnRate(this.unit.getTypeId());
|
|
||||||
|
|
||||||
if (delta < -180) {
|
|
||||||
delta = 360 + delta;
|
|
||||||
}
|
|
||||||
if (delta > 180) {
|
|
||||||
delta = -360 + delta;
|
|
||||||
}
|
|
||||||
final float absDelta = Math.abs(delta);
|
|
||||||
|
|
||||||
if ((absDelta <= 1.0) && (absDelta != 0)) {
|
|
||||||
this.unit.setFacing(goalAngle);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate);
|
|
||||||
if (absDelta < Math.abs(angleToAdd)) {
|
|
||||||
angleToAdd = delta;
|
|
||||||
}
|
|
||||||
facing += angleToAdd;
|
|
||||||
this.unit.setFacing(facing);
|
|
||||||
}
|
|
||||||
if (absDelta < propulsionWindow) {
|
|
||||||
this.wasWithinPropWindow = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If this happens, the unit is facing the wrong way, and has to turn before
|
|
||||||
// moving.
|
|
||||||
this.wasWithinPropWindow = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.wasWithinPropWindow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int cooldownEndTime = this.unit.getCooldownEndTime();
|
|
||||||
final int currentTurnTick = simulation.getGameTurnTick();
|
|
||||||
if (this.wasWithinPropWindow) {
|
|
||||||
if (this.damagePointLaunchTime != 0) {
|
|
||||||
if (currentTurnTick >= this.damagePointLaunchTime) {
|
|
||||||
int minDamage = this.unitAttack.getMinDamage();
|
|
||||||
final int maxDamage = Math.max(0, this.unitAttack.getMaxDamage());
|
|
||||||
if (minDamage > maxDamage) {
|
|
||||||
minDamage = maxDamage;
|
|
||||||
}
|
|
||||||
final int damage;
|
|
||||||
if (maxDamage == 0) {
|
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
else if (minDamage == maxDamage) {
|
|
||||||
damage = minDamage;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
damage = simulation.getSeededRandom().nextInt(maxDamage - minDamage) + minDamage;
|
|
||||||
}
|
|
||||||
this.unitAttack.launch(simulation, this.unit, this.target, damage);
|
|
||||||
this.damagePointLaunchTime = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (currentTurnTick >= cooldownEndTime) {
|
|
||||||
final float cooldownTime = this.unitAttack.getCooldownTime();
|
|
||||||
final float animationBackswingPoint = this.unitAttack.getAnimationBackswingPoint();
|
|
||||||
final int a1CooldownSteps = (int) (cooldownTime / WarsmashConstants.SIMULATION_STEP_TIME);
|
|
||||||
final int a1BackswingSteps = (int) (animationBackswingPoint / WarsmashConstants.SIMULATION_STEP_TIME);
|
|
||||||
final int a1DamagePointSteps = (int) (this.unitAttack.getAnimationDamagePoint()
|
|
||||||
/ WarsmashConstants.SIMULATION_STEP_TIME);
|
|
||||||
this.unit.setCooldownEndTime(currentTurnTick + a1CooldownSteps);
|
|
||||||
this.thisOrderCooldownEndTime = currentTurnTick + a1CooldownSteps;
|
|
||||||
this.damagePointLaunchTime = currentTurnTick + a1DamagePointSteps;
|
|
||||||
this.backSwingTime = currentTurnTick + a1DamagePointSteps + a1BackswingSteps;
|
|
||||||
this.unit.getUnitAnimationListener().playAnimation(true, PrimaryTag.ATTACK, SequenceUtils.EMPTY, 1.0f,
|
|
||||||
true);
|
|
||||||
this.unit.getUnitAnimationListener().queueAnimation(PrimaryTag.STAND, SequenceUtils.READY, false);
|
|
||||||
}
|
|
||||||
else if ((currentTurnTick >= this.thisOrderCooldownEndTime)) {
|
|
||||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrderId() {
|
|
||||||
return this.orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
|
||||||
|
|
||||||
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.CWidget;
|
|
||||||
|
|
||||||
public class CBehaviorPatrol implements CBehavior {
|
|
||||||
private final CUnit unit;
|
|
||||||
private final int orderId;
|
|
||||||
private final CWidget target;
|
|
||||||
private CBehavior moveOrder;
|
|
||||||
|
|
||||||
public CBehaviorPatrol(final CUnit unit, final int orderId, final CUnit target) {
|
|
||||||
this.unit = unit;
|
|
||||||
this.orderId = orderId;
|
|
||||||
this.target = target;
|
|
||||||
createMoveOrder(unit, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createMoveOrder(final CUnit unit, final CUnit target) {
|
|
||||||
if (!unit.isMovementDisabled()) { // TODO: Check mobility instead
|
|
||||||
if ((target instanceof CUnit) && !(target.getUnitType().isBuilding())) {
|
|
||||||
this.moveOrder = new CBehaviorMove(unit, this.orderId, target);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.moveOrder = new CBehaviorMove(unit, this.orderId, target.getX(), target.getY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.moveOrder = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean update(final CSimulation simulation) {
|
|
||||||
if (this.target.isDead()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final float range = this.unit.getAcquisitionRange();
|
|
||||||
if (!this.unit.canReach(this.target, range)) {
|
|
||||||
if (this.moveOrder == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.moveOrder.update(simulation)) {
|
|
||||||
return true; // we just cant reach them
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!this.unit.isMovementDisabled()) {
|
|
||||||
final float prevX = this.unit.getX();
|
|
||||||
final float prevY = this.unit.getY();
|
|
||||||
final float deltaY = this.target.getY() - prevY;
|
|
||||||
final float deltaX = this.target.getX() - prevX;
|
|
||||||
final double goalAngleRad = Math.atan2(deltaY, deltaX);
|
|
||||||
float goalAngle = (float) Math.toDegrees(goalAngleRad);
|
|
||||||
if (goalAngle < 0) {
|
|
||||||
goalAngle += 360;
|
|
||||||
}
|
|
||||||
float facing = this.unit.getFacing();
|
|
||||||
float delta = goalAngle - facing;
|
|
||||||
final float turnRate = simulation.getUnitData().getTurnRate(this.unit.getTypeId());
|
|
||||||
|
|
||||||
if (delta < -180) {
|
|
||||||
delta = 360 + delta;
|
|
||||||
}
|
|
||||||
if (delta > 180) {
|
|
||||||
delta = -360 + delta;
|
|
||||||
}
|
|
||||||
final float absDelta = Math.abs(delta);
|
|
||||||
|
|
||||||
if ((absDelta <= 1.0) && (absDelta != 0)) {
|
|
||||||
this.unit.setFacing(goalAngle);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate);
|
|
||||||
if (absDelta < Math.abs(angleToAdd)) {
|
|
||||||
angleToAdd = delta;
|
|
||||||
}
|
|
||||||
facing += angleToAdd;
|
|
||||||
this.unit.setFacing(facing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
}
|
|
||||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrderId() {
|
|
||||||
return this.orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
|
||||||
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
|
||||||
|
|
||||||
public class CBehaviorStop implements CBehavior {
|
|
||||||
private final int orderId;
|
|
||||||
|
|
||||||
public CBehaviorStop(final int orderId) {
|
|
||||||
this.orderId = orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean update(final CSimulation game) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrderId() {
|
|
||||||
return this.orderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
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.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||||
|
|
||||||
|
public interface COrder {
|
||||||
|
int getAbilityHandleId();
|
||||||
|
|
||||||
|
int getOrderId();
|
||||||
|
|
||||||
|
CBehavior begin(final CSimulation game, CUnit caster);
|
||||||
|
|
||||||
|
final StringMsgTargetCheckReceiver<?> targetCheckReceiver = new StringMsgTargetCheckReceiver<>();
|
||||||
|
final StringMsgAbilityActivationReceiver abilityActivationReceiver = new StringMsgAbilityActivationReceiver();
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
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.behaviors.CBehavior;
|
||||||
|
|
||||||
|
public class COrderNoTarget implements COrder {
|
||||||
|
private final int abilityHandleId;
|
||||||
|
private final int orderId;
|
||||||
|
|
||||||
|
public COrderNoTarget(final int abilityHandleId, final int orderId) {
|
||||||
|
this.abilityHandleId = abilityHandleId;
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAbilityHandleId() {
|
||||||
|
return this.abilityHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrderId() {
|
||||||
|
return this.orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||||
|
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||||
|
return ability.beginNoTarget(game, caster, this.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
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;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||||
|
|
||||||
|
public class COrderTargetPoint implements COrder {
|
||||||
|
private final int abilityHandleId;
|
||||||
|
private final int orderId;
|
||||||
|
private final Vector2 target;
|
||||||
|
|
||||||
|
public COrderTargetPoint(final int abilityHandleId, final int orderId, final Vector2 target) {
|
||||||
|
this.abilityHandleId = abilityHandleId;
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAbilityHandleId() {
|
||||||
|
return this.abilityHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrderId() {
|
||||||
|
return this.orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 getTarget() {
|
||||||
|
return this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||||
|
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||||
|
ability.checkCanUse(game, caster, this.orderId, this.abilityActivationReceiver.reset());
|
||||||
|
if (this.abilityActivationReceiver.isUseOk()) {
|
||||||
|
final StringMsgTargetCheckReceiver<Vector2> targetReceiver = (StringMsgTargetCheckReceiver<Vector2>) targetCheckReceiver;
|
||||||
|
ability.checkCanTarget(game, caster, this.orderId, this.target, targetReceiver);
|
||||||
|
if (targetReceiver.getTarget() != null) {
|
||||||
|
return ability.begin(game, caster, this.orderId, this.target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.getCommandErrorListener().showCommandError(targetReceiver.getMessage());
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.getCommandErrorListener().showCommandError(this.abilityActivationReceiver.getMessage());
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,52 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders;
|
||||||
|
|
||||||
public class COrderTargetWidget {
|
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.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||||
|
|
||||||
|
public class COrderTargetWidget implements COrder {
|
||||||
|
private final int abilityHandleId;
|
||||||
|
private final int orderId;
|
||||||
|
private final int targetHandleId;
|
||||||
|
|
||||||
|
public COrderTargetWidget(final int abilityHandleId, final int orderId, final int targetHandleId) {
|
||||||
|
this.abilityHandleId = abilityHandleId;
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.targetHandleId = targetHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAbilityHandleId() {
|
||||||
|
return this.abilityHandleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrderId() {
|
||||||
|
return this.orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||||
|
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||||
|
ability.checkCanUse(game, caster, this.orderId, abilityActivationReceiver.reset());
|
||||||
|
if (abilityActivationReceiver.isUseOk()) {
|
||||||
|
final CUnit target = game.getUnit(this.targetHandleId);
|
||||||
|
final StringMsgTargetCheckReceiver<CWidget> targetReceiver = (StringMsgTargetCheckReceiver<CWidget>) targetCheckReceiver;
|
||||||
|
ability.checkCanTarget(game, caster, this.orderId, target, targetReceiver);
|
||||||
|
if (targetReceiver.getTarget() != null) {
|
||||||
|
return ability.begin(game, caster, this.orderId, targetReceiver.getTarget());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.getCommandErrorListener().showCommandError(targetReceiver.getMessage());
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
game.getCommandErrorListener().showCommandError(this.abilityActivationReceiver.getMessage());
|
||||||
|
return caster.pollNextOrderBehavior(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,14 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
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.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderNoTarget;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetPoint;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetWidget;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||||
|
|
||||||
public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
||||||
private final CSimulation game;
|
private final CSimulation game;
|
||||||
private final CommandErrorListener errorListener;
|
private final CommandErrorListener errorListener;
|
||||||
private final StringMsgTargetCheckReceiver<?> targetCheckReceiver = new StringMsgTargetCheckReceiver<>();
|
|
||||||
private final StringMsgAbilityActivationReceiver abilityActivationReceiver = new StringMsgAbilityActivationReceiver();
|
|
||||||
|
|
||||||
private <T> StringMsgTargetCheckReceiver<T> targetCheckReceiver() {
|
|
||||||
return (StringMsgTargetCheckReceiver<T>) this.targetCheckReceiver.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CPlayerUnitOrderExecutor(final CSimulation game, final CommandErrorListener errorListener) {
|
public CPlayerUnitOrderExecutor(final CSimulation game, final CommandErrorListener errorListener) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
@ -25,77 +18,24 @@ public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||||
final int targetHandleId, final boolean queue) {
|
final int targetHandleId, final boolean queue) {
|
||||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
final CAbility ability = this.game.getAbility(abilityHandleId);
|
unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId), queue);
|
||||||
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
|
||||||
if (this.abilityActivationReceiver.isUseOk()) {
|
|
||||||
final CUnit target = this.game.getUnit(targetHandleId);
|
|
||||||
final StringMsgTargetCheckReceiver<CWidget> targetReceiver = this.<CWidget>targetCheckReceiver();
|
|
||||||
ability.checkCanTarget(this.game, unit, orderId, target, targetReceiver);
|
|
||||||
if (targetReceiver.getTarget() != null) {
|
|
||||||
ability.onOrder(this.game, unit, orderId, target, queue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(targetReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x,
|
public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x,
|
||||||
final float y, final boolean queue) {
|
final float y, final boolean queue) {
|
||||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
final CAbility ability = this.game.getAbility(abilityHandleId);
|
unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new Vector2(x, y)), queue);
|
||||||
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
|
||||||
if (this.abilityActivationReceiver.isUseOk()) {
|
|
||||||
final Vector2 target = new Vector2(x, y);
|
|
||||||
final StringMsgTargetCheckReceiver<Vector2> targetReceiver = this.<Vector2>targetCheckReceiver();
|
|
||||||
ability.checkCanTarget(this.game, unit, orderId, target, targetReceiver);
|
|
||||||
if (targetReceiver.getTarget() != null) {
|
|
||||||
ability.onOrder(this.game, unit, orderId, target, queue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(targetReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||||
final boolean queue) {
|
final boolean queue) {
|
||||||
final CUnit unit = this.game.getUnit(unitHandleId);
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
final CAbility ability = this.game.getAbility(abilityHandleId);
|
unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId), queue);
|
||||||
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
|
||||||
if (this.abilityActivationReceiver.isUseOk()) {
|
|
||||||
final StringMsgTargetCheckReceiver<Void> targetReceiver = this.<Void>targetCheckReceiver();
|
|
||||||
ability.checkCanTargetNoTarget(this.game, unit, orderId, targetReceiver);
|
|
||||||
if (targetReceiver.getMessage() == null) {
|
|
||||||
ability.onOrderNoTarget(this.game, unit, orderId, queue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(targetReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
||||||
|
|
||||||
public interface CPlayerUnitOrderListener {
|
public interface CPlayerUnitOrderListener {
|
||||||
boolean issueTargetOrder(int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, boolean queue);
|
void issueTargetOrder(int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, boolean queue);
|
||||||
|
|
||||||
boolean issuePointOrder(int unitHandleId, int abilityHandleId, int orderId, float x, float y, boolean queue);
|
void issuePointOrder(int unitHandleId, int abilityHandleId, int orderId, float x, float y, boolean queue);
|
||||||
|
|
||||||
// Below: used for "DROP ITEM AT POINT" ????
|
// Below: used for "DROP ITEM AT POINT" ????
|
||||||
// boolean issueTargetAndPointOrder(int unitHandleId, int orderId, int targetHandleId, float x, float y);
|
// boolean issueTargetAndPointOrder(int unitHandleId, int orderId, int targetHandleId, float x, float y);
|
||||||
|
|
||||||
boolean issueImmediateOrder(int unitHandleId, int abilityHandleId, int orderId, boolean queue);
|
void issueImmediateOrder(int unitHandleId, int abilityHandleId, int orderId, boolean queue);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
private CommandButton commandButton;
|
private CommandButton commandButton;
|
||||||
private int abilityHandleId;
|
private int abilityHandleId;
|
||||||
private int orderId;
|
private int orderId;
|
||||||
|
private int autoCastOrderId;
|
||||||
private final CommandCardCommandListener commandCardCommandListener;
|
private final CommandCardCommandListener commandCardCommandListener;
|
||||||
|
|
||||||
public CommandCardIcon(final String name, final UIFrame parent,
|
public CommandCardIcon(final String name, final UIFrame parent,
|
||||||
@ -45,7 +46,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
this.iconFrame.setVisible(false);
|
this.iconFrame.setVisible(false);
|
||||||
this.activeHighlightFrame.setVisible(false);
|
this.activeHighlightFrame.setVisible(false);
|
||||||
this.cooldownFrame.setVisible(false);
|
this.cooldownFrame.setVisible(false);
|
||||||
this.autocastFrame.setVisible(false);
|
this.autocastFrame.setSequence(PrimaryTag.DEATH);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (commandButton.isEnabled()) {
|
if (commandButton.isEnabled()) {
|
||||||
@ -64,19 +65,24 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
this.cooldownFrame
|
this.cooldownFrame
|
||||||
.setFrameByRatio(1 - (commandButton.getCooldownRemaining() / commandButton.getCooldown()));
|
.setFrameByRatio(1 - (commandButton.getCooldownRemaining() / commandButton.getCooldown()));
|
||||||
}
|
}
|
||||||
this.autocastFrame.setVisible(commandButton.isAutoCastActive());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId,
|
public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId,
|
||||||
final boolean active) {
|
final int autoCastOrderId, final boolean active, final boolean autoCastActive) {
|
||||||
this.iconFrame.setVisible(true);
|
this.iconFrame.setVisible(true);
|
||||||
this.activeHighlightFrame.setVisible(active);
|
this.activeHighlightFrame.setVisible(active);
|
||||||
this.cooldownFrame.setVisible(false);
|
this.cooldownFrame.setVisible(false);
|
||||||
this.autocastFrame.setVisible(false);
|
if (autoCastActive) {
|
||||||
|
this.autocastFrame.setSequence(PrimaryTag.STAND);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.autocastFrame.setSequence(-1);
|
||||||
|
}
|
||||||
this.iconFrame.setTexture(texture);
|
this.iconFrame.setTexture(texture);
|
||||||
this.abilityHandleId = abilityHandleId;
|
this.abilityHandleId = abilityHandleId;
|
||||||
this.orderId = orderId;
|
this.orderId = orderId;
|
||||||
|
this.autoCastOrderId = autoCastOrderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,7 +108,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
||||||
}
|
}
|
||||||
else if (button == Input.Buttons.RIGHT) {
|
else if (button == Input.Buttons.RIGHT) {
|
||||||
this.commandCardCommandListener.toggleAutoCastAbility(this.abilityHandleId);
|
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.autoCastOrderId);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,10 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
|||||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
||||||
import com.etheller.warsmash.datasources.DataSource;
|
import com.etheller.warsmash.datasources.DataSource;
|
||||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||||
import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition;
|
import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition;
|
||||||
@ -77,7 +76,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
private static final Vector3 clickLocationTemp = new Vector3();
|
private static final Vector3 clickLocationTemp = new Vector3();
|
||||||
private static final Vector2 clickLocationTemp2 = new Vector2();
|
private static final Vector2 clickLocationTemp2 = new Vector2();
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final Viewport uiViewport;
|
private final ExtendViewport uiViewport;
|
||||||
private final FreeTypeFontGenerator fontGenerator;
|
private final FreeTypeFontGenerator fontGenerator;
|
||||||
private final Scene uiScene;
|
private final Scene uiScene;
|
||||||
private final Scene portraitScene;
|
private final Scene portraitScene;
|
||||||
@ -137,10 +136,15 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
private int selectedSoundCount = 0;
|
private int selectedSoundCount = 0;
|
||||||
private final ActiveCommandUnitTargetFilter activeCommandUnitTargetFilter;
|
private final ActiveCommandUnitTargetFilter activeCommandUnitTargetFilter;
|
||||||
|
|
||||||
public MeleeUI(final DataSource dataSource, final Viewport uiViewport, final FreeTypeFontGenerator fontGenerator,
|
// TODO these corrections are used for old hardcoded UI stuff, we should
|
||||||
final Scene uiScene, final Scene portraitScene, final CameraPreset[] cameraPresets,
|
// probably remove them later
|
||||||
final CameraRates cameraRates, final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener,
|
private final float widthRatioCorrection;
|
||||||
final CPlayerUnitOrderListener unitOrderListener) {
|
private final float heightRatioCorrection;
|
||||||
|
|
||||||
|
public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport,
|
||||||
|
final FreeTypeFontGenerator fontGenerator, final Scene uiScene, final Scene portraitScene,
|
||||||
|
final CameraPreset[] cameraPresets, final CameraRates cameraRates, final War3MapViewer war3MapViewer,
|
||||||
|
final RootFrameListener rootFrameListener, final CPlayerUnitOrderListener unitOrderListener) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.uiViewport = uiViewport;
|
this.uiViewport = uiViewport;
|
||||||
this.fontGenerator = fontGenerator;
|
this.fontGenerator = fontGenerator;
|
||||||
@ -161,11 +165,15 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.activeButtonTexture = ImageUtils.getBLPTexture(war3MapViewer.mapMpq,
|
this.activeButtonTexture = ImageUtils.getBLPTexture(war3MapViewer.mapMpq,
|
||||||
"UI\\Widgets\\Console\\Human\\CommandButton\\human-activebutton.blp");
|
"UI\\Widgets\\Console\\Human\\CommandButton\\human-activebutton.blp");
|
||||||
this.activeCommandUnitTargetFilter = new ActiveCommandUnitTargetFilter();
|
this.activeCommandUnitTargetFilter = new ActiveCommandUnitTargetFilter();
|
||||||
|
this.widthRatioCorrection = this.uiViewport.getMinWorldWidth() / 1600f;
|
||||||
|
this.heightRatioCorrection = this.uiViewport.getMinWorldHeight() / 1200f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) {
|
private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) {
|
||||||
final Rectangle minimapDisplayArea = new Rectangle(18.75f, 13.75f, 278.75f, 276.25f);
|
final Rectangle minimapDisplayArea = new Rectangle(18.75f * this.widthRatioCorrection,
|
||||||
|
13.75f * this.heightRatioCorrection, 278.75f * this.widthRatioCorrection,
|
||||||
|
276.25f * this.heightRatioCorrection);
|
||||||
Texture minimapTexture = null;
|
Texture minimapTexture = null;
|
||||||
if (war3MapViewer.dataSource.has("war3mapMap.tga")) {
|
if (war3MapViewer.dataSource.has("war3mapMap.tga")) {
|
||||||
try {
|
try {
|
||||||
@ -396,11 +404,6 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.errorMessageFrame.setText(message);
|
this.errorMessageFrame.setText(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toggleAutoCastAbility(final int abilityHandleId) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(final float deltaTime) {
|
public void update(final float deltaTime) {
|
||||||
this.portrait.update();
|
this.portrait.update();
|
||||||
|
|
||||||
@ -468,8 +471,6 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.cameraManager.updateCamera();
|
this.cameraManager.updateCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ShapeRenderer shapeRenderer = new ShapeRenderer();
|
|
||||||
|
|
||||||
public void render(final SpriteBatch batch, final BitmapFont font20, final GlyphLayout glyphLayout) {
|
public void render(final SpriteBatch batch, final BitmapFont font20, final GlyphLayout glyphLayout) {
|
||||||
this.rootFrame.render(batch, font20, glyphLayout);
|
this.rootFrame.render(batch, font20, glyphLayout);
|
||||||
if (this.selectedUnit != null) {
|
if (this.selectedUnit != null) {
|
||||||
@ -658,10 +659,11 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon,
|
public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon,
|
||||||
final int abilityHandleId, final int orderId, final boolean active) {
|
final int abilityHandleId, final int orderId, final int autoCastId, final boolean active,
|
||||||
|
final boolean autoCastActive) {
|
||||||
final int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX));
|
final int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX));
|
||||||
final int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY));
|
final int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY));
|
||||||
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, active);
|
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active, autoCastActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resize(final Rectangle viewport) {
|
public void resize(final Rectangle viewport) {
|
||||||
@ -670,10 +672,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void positionPortrait() {
|
public void positionPortrait() {
|
||||||
this.projectionTemp1.x = 422;
|
this.projectionTemp1.x = 422 * this.widthRatioCorrection;
|
||||||
this.projectionTemp1.y = 57;
|
this.projectionTemp1.y = 57 * this.heightRatioCorrection;
|
||||||
this.projectionTemp2.x = 422 + 167;
|
this.projectionTemp2.x = (422 + 167) * this.widthRatioCorrection;
|
||||||
this.projectionTemp2.y = 57 + 170;
|
this.projectionTemp2.y = (57 + 170) * this.heightRatioCorrection;
|
||||||
this.uiViewport.project(this.projectionTemp1);
|
this.uiViewport.project(this.projectionTemp1);
|
||||||
this.uiViewport.project(this.projectionTemp2);
|
this.uiViewport.project(this.projectionTemp2);
|
||||||
|
|
||||||
@ -752,7 +754,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ordersChanged() {
|
public void ordersChanged(final int abilityHandleId, final int orderId) {
|
||||||
clearCommandCard();
|
clearCommandCard();
|
||||||
this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this,
|
this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this,
|
||||||
this.war3MapViewer.getAbilityDataUI());
|
this.war3MapViewer.getAbilityDataUI());
|
||||||
@ -798,10 +800,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.activeCommandUnitTargetFilter);
|
this.activeCommandUnitTargetFilter);
|
||||||
final boolean shiftDown = isShiftDown();
|
final boolean shiftDown = isShiftDown();
|
||||||
if (rayPickUnit != null) {
|
if (rayPickUnit != null) {
|
||||||
if (this.unitOrderListener.issueTargetOrder(
|
this.unitOrderListener.issueTargetOrder(
|
||||||
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
||||||
this.activeCommand.getHandleId(), this.activeCommandOrderId,
|
this.activeCommand.getHandleId(), this.activeCommandOrderId,
|
||||||
rayPickUnit.getSimulationUnit().getHandleId(), shiftDown)) {
|
rayPickUnit.getSimulationUnit().getHandleId(), shiftDown);
|
||||||
if (getSelectedUnit().soundset.yesAttack
|
if (getSelectedUnit().soundset.yesAttack
|
||||||
.playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
.playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
portraitTalk();
|
portraitTalk();
|
||||||
@ -813,7 +815,6 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.activeCommandOrderId = -1;
|
this.activeCommandOrderId = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
||||||
clickLocationTemp2.set(clickLocationTemp.x, clickLocationTemp.y);
|
clickLocationTemp2.set(clickLocationTemp.x, clickLocationTemp.y);
|
||||||
@ -829,12 +830,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
else {
|
else {
|
||||||
this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0);
|
this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0);
|
||||||
}
|
}
|
||||||
if (this.unitOrderListener.issuePointOrder(
|
this.unitOrderListener.issuePointOrder(
|
||||||
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
||||||
this.activeCommand.getHandleId(), this.activeCommandOrderId, clickLocationTemp2.x,
|
this.activeCommand.getHandleId(), this.activeCommandOrderId, clickLocationTemp2.x,
|
||||||
clickLocationTemp2.y, shiftDown)) {
|
clickLocationTemp2.y, shiftDown);
|
||||||
if (getSelectedUnit().soundset.yes.playUnitResponse(
|
if (getSelectedUnit().soundset.yes
|
||||||
this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
.playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
portraitTalk();
|
portraitTalk();
|
||||||
}
|
}
|
||||||
this.selectedSoundCount = 0;
|
this.selectedSoundCount = 0;
|
||||||
@ -843,7 +844,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.activeCommand = null;
|
this.activeCommand = null;
|
||||||
this.activeCommandOrderId = -1;
|
this.activeCommandOrderId = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -975,4 +976,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getHeightRatioCorrection() {
|
||||||
|
return this.heightRatioCorrection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,4 @@ package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
|||||||
|
|
||||||
public interface CommandCardCommandListener {
|
public interface CommandCardCommandListener {
|
||||||
void startUsingAbility(int abilityHandleId, int orderId);
|
void startUsingAbility(int abilityHandleId, int orderId);
|
||||||
|
|
||||||
void toggleAutoCastAbility(int abilityHandleId);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user