mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Fix mouse intersect underground, fix anim blend, icon click sound
This commit is contained in:
parent
238015f21d
commit
bec43bcb3e
@ -157,6 +157,7 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
||||
final Scene portraitScene = this.viewer.addSimpleScene();
|
||||
this.uiScene = this.viewer.addSimpleScene();
|
||||
this.uiScene.alpha = true;
|
||||
this.uiScene.enableAudio();
|
||||
|
||||
// this.mainModel = (MdxModel) this.viewer.load("UI\\Glues\\MainMenu\\MainMenu3D_exp\\MainMenu3D_exp.mdx",
|
||||
|
||||
@ -385,6 +386,11 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
||||
|
||||
@Override
|
||||
public boolean touchUp(final int screenX, final int screenY, final int pointer, final int button) {
|
||||
final float worldScreenY = getHeight() - screenY;
|
||||
|
||||
if (this.meleeUI.touchUp(screenX, screenY, worldScreenY, button)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -346,6 +346,11 @@ public abstract class AbstractRenderableFrame implements UIFrame {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
|
@ -46,4 +46,15 @@ public abstract class AbstractUIFrame extends AbstractRenderableFrame implements
|
||||
}
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
for (final UIFrame childFrame : this.childFrames) {
|
||||
final UIFrame clickedChild = childFrame.touchUp(screenX, screenY, button);
|
||||
if (clickedChild != null) {
|
||||
return clickedChild;
|
||||
}
|
||||
}
|
||||
return super.touchUp(screenX, screenY, button);
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +63,4 @@ public class TextureFrame extends AbstractRenderableFrame {
|
||||
public void setTexture(final TextureRegion texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
}
|
||||
|
@ -34,5 +34,7 @@ public interface UIFrame {
|
||||
|
||||
UIFrame touchDown(float screenX, float screenY, int button);
|
||||
|
||||
UIFrame touchUp(float screenX, float screenY, int button);
|
||||
|
||||
String getName();
|
||||
}
|
||||
|
@ -13,6 +13,9 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
protected static final Quaternion rotationHeap = new Quaternion();
|
||||
protected static final Quaternion rotationHeap2 = new Quaternion();
|
||||
protected static final Vector3 scalingHeap = new Vector3();
|
||||
protected static final Vector3 blendLocationHeap = new Vector3();
|
||||
protected static final Vector3 blendHeap = new Vector3();
|
||||
protected static final Vector3 blendScaleHeap = new Vector3();
|
||||
|
||||
public UpdatableObject object;
|
||||
|
||||
@ -21,7 +24,9 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
public boolean billboardedY;
|
||||
public boolean billboardedZ;
|
||||
|
||||
public Matrix4 localBlendMatrix;
|
||||
public Vector3 localBlendLocation;
|
||||
public Quaternion localBlendRotation;
|
||||
public Vector3 localBlendScale;
|
||||
|
||||
public SkeletalNode() {
|
||||
this.pivot = new Vector3();
|
||||
@ -35,7 +40,9 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
this.inverseWorldRotation = new Quaternion();
|
||||
this.inverseWorldScale = new Vector3();
|
||||
this.localMatrix = new Matrix4();
|
||||
this.localBlendMatrix = new Matrix4();
|
||||
this.localBlendLocation = new Vector3();
|
||||
this.localBlendRotation = new Quaternion(0, 0, 0, 1);
|
||||
this.localBlendScale = new Vector3(1, 1, 1);
|
||||
this.worldMatrix = new Matrix4();
|
||||
this.dontInheritTranslation = false;
|
||||
this.dontInheritRotation = false;
|
||||
@ -70,8 +77,10 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
}
|
||||
|
||||
public void recalculateTransformation(final Scene scene, final float blendTimeRatio) {
|
||||
final float inverseBlendRatio = 1 - blendTimeRatio;
|
||||
final Quaternion computedRotation;
|
||||
Vector3 computedScaling;
|
||||
Vector3 computedLocation;
|
||||
|
||||
if (this.dontInheritScaling) {
|
||||
computedScaling = scalingHeap;
|
||||
@ -86,7 +95,14 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
this.worldScale.z = this.localScale.z;
|
||||
}
|
||||
else {
|
||||
computedScaling = this.localScale;
|
||||
if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) {
|
||||
blendScaleHeap.set(this.localScale).scl(inverseBlendRatio)
|
||||
.add(blendHeap.set(this.localBlendScale).scl(blendTimeRatio));
|
||||
computedScaling = blendScaleHeap;
|
||||
}
|
||||
else {
|
||||
computedScaling = this.localScale;
|
||||
}
|
||||
|
||||
final Vector3 parentScale = this.parent.worldScale;
|
||||
this.worldScale.x = parentScale.x * this.localScale.x;
|
||||
@ -133,18 +149,25 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
computedRotation.setFromAxisRad(billboardAxisHeap, angle);
|
||||
}
|
||||
else {
|
||||
computedRotation = this.localRotation;
|
||||
}
|
||||
|
||||
RenderMathUtils.fromRotationTranslationScaleOrigin(computedRotation, this.localLocation, computedScaling,
|
||||
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));
|
||||
if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) {
|
||||
rotationHeap.set(this.localRotation).slerp(this.localBlendRotation, blendTimeRatio);
|
||||
computedRotation = rotationHeap;
|
||||
}
|
||||
else {
|
||||
computedRotation = this.localRotation;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) {
|
||||
computedLocation = blendLocationHeap.set(this.localLocation).scl(inverseBlendRatio)
|
||||
.add(blendHeap.set(this.localBlendLocation).scl(blendTimeRatio));
|
||||
}
|
||||
else {
|
||||
computedLocation = this.localLocation;
|
||||
}
|
||||
RenderMathUtils.fromRotationTranslationScaleOrigin(computedRotation, computedLocation, computedScaling,
|
||||
this.localMatrix, this.pivot);
|
||||
|
||||
RenderMathUtils.mul(this.worldMatrix, this.parent.worldMatrix, this.localMatrix);
|
||||
|
||||
RenderMathUtils.mul(this.worldRotation, this.parent.worldRotation, computedRotation);
|
||||
@ -178,7 +201,9 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
}
|
||||
|
||||
public void beginBlending() {
|
||||
this.localBlendMatrix.set(this.localMatrix);
|
||||
this.localBlendLocation.set(this.localLocation);
|
||||
this.localBlendRotation.set(this.localRotation);
|
||||
this.localBlendScale.set(this.localScale);
|
||||
}
|
||||
|
||||
public void updateChildren(final float dt, final Scene scene) {
|
||||
|
@ -12,244 +12,255 @@ import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag;
|
||||
|
||||
public class SequenceUtils {
|
||||
public static final EnumSet<SecondaryTag> EMPTY = EnumSet.noneOf(SecondaryTag.class);
|
||||
public static final EnumSet<SecondaryTag> READY = EnumSet.of(SecondaryTag.READY);
|
||||
public static final EnumSet<SecondaryTag> FLESH = EnumSet.of(SecondaryTag.FLESH);
|
||||
public static final EnumSet<SecondaryTag> BONE = EnumSet.of(SecondaryTag.BONE);
|
||||
public static final EnumSet<SecondaryTag> EMPTY = EnumSet.noneOf(SecondaryTag.class);
|
||||
public static final EnumSet<SecondaryTag> READY = EnumSet.of(SecondaryTag.READY);
|
||||
public static final EnumSet<SecondaryTag> FLESH = EnumSet.of(SecondaryTag.FLESH);
|
||||
public static final EnumSet<SecondaryTag> TALK = EnumSet.of(SecondaryTag.TALK);
|
||||
public static final EnumSet<SecondaryTag> BONE = EnumSet.of(SecondaryTag.BONE);
|
||||
|
||||
private static final StandSequenceComparator STAND_SEQUENCE_COMPARATOR = new StandSequenceComparator();
|
||||
private static final SecondaryTagSequenceComparator SECONDARY_TAG_SEQUENCE_COMPARATOR = new SecondaryTagSequenceComparator(STAND_SEQUENCE_COMPARATOR);
|
||||
private static final StandSequenceComparator STAND_SEQUENCE_COMPARATOR = new StandSequenceComparator();
|
||||
private static final SecondaryTagSequenceComparator SECONDARY_TAG_SEQUENCE_COMPARATOR = new SecondaryTagSequenceComparator(
|
||||
STAND_SEQUENCE_COMPARATOR);
|
||||
|
||||
public static List<IndexedSequence> filterSequences(final String type, final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = new ArrayList<>();
|
||||
public static List<IndexedSequence> filterSequences(final String type, final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = new ArrayList<>();
|
||||
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
final String name = sequence.getName().split("-")[0].trim().toLowerCase();
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
final String name = sequence.getName().split("-")[0].trim().toLowerCase();
|
||||
|
||||
if (name.equals(type)) {
|
||||
filtered.add(new IndexedSequence(sequence, i));
|
||||
}
|
||||
}
|
||||
if (name.equals(type)) {
|
||||
filtered.add(new IndexedSequence(sequence, i));
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private static List<IndexedSequence> filterSequences(final PrimaryTag type, final EnumSet<SecondaryTag> tags,
|
||||
final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = new ArrayList<>();
|
||||
private static List<IndexedSequence> filterSequences(final PrimaryTag type, final EnumSet<SecondaryTag> tags,
|
||||
final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = new ArrayList<>();
|
||||
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
if (sequence.getPrimaryTags().contains(type) && (sequence.getSecondaryTags().containsAll(tags)
|
||||
&& tags.containsAll(sequence.getSecondaryTags()))) {
|
||||
filtered.add(new IndexedSequence(sequence, i));
|
||||
}
|
||||
}
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
if (sequence.getPrimaryTags().contains(type) && (sequence.getSecondaryTags().containsAll(tags)
|
||||
&& tags.containsAll(sequence.getSecondaryTags()))) {
|
||||
filtered.add(new IndexedSequence(sequence, i));
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public static IndexedSequence selectSequence(final String type, final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = filterSequences(type, sequences);
|
||||
public static IndexedSequence selectSequence(final String type, final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = filterSequences(type, sequences);
|
||||
|
||||
filtered.sort(STAND_SEQUENCE_COMPARATOR);
|
||||
filtered.sort(STAND_SEQUENCE_COMPARATOR);
|
||||
|
||||
int i = 0;
|
||||
final double randomRoll = Math.random() * 100;
|
||||
for (final int l = filtered.size(); i < l; i++) {
|
||||
final Sequence sequence = filtered.get(i).sequence;
|
||||
final float rarity = sequence.getRarity();
|
||||
int i = 0;
|
||||
final double randomRoll = Math.random() * 100;
|
||||
for (final int l = filtered.size(); i < l; i++) {
|
||||
final Sequence sequence = filtered.get(i).sequence;
|
||||
final float rarity = sequence.getRarity();
|
||||
|
||||
if (rarity == 0) {
|
||||
break;
|
||||
}
|
||||
if (rarity == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (randomRoll < (10 - rarity)) {
|
||||
return filtered.get(i);
|
||||
}
|
||||
}
|
||||
if (randomRoll < (10 - rarity)) {
|
||||
return filtered.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
final int sequencesLeft = filtered.size() - i;
|
||||
final int random = (int) (i + Math.floor(Math.random() * sequencesLeft));
|
||||
if (sequencesLeft <= 0) {
|
||||
return null; // new IndexedSequence(null, 0);
|
||||
}
|
||||
final IndexedSequence sequence = filtered.get(random);
|
||||
final int sequencesLeft = filtered.size() - i;
|
||||
final int random = (int) (i + Math.floor(Math.random() * sequencesLeft));
|
||||
if (sequencesLeft <= 0) {
|
||||
return null; // new IndexedSequence(null, 0);
|
||||
}
|
||||
final IndexedSequence sequence = filtered.get(random);
|
||||
|
||||
return sequence;
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public static IndexedSequence selectSequence(final AnimationTokens.PrimaryTag type,
|
||||
final EnumSet<AnimationTokens.SecondaryTag> tags, final List<Sequence> sequences,
|
||||
final boolean allowRarityVariations) {
|
||||
List<IndexedSequence> filtered = filterSequences(type, tags, sequences);
|
||||
Comparator<IndexedSequence> sequenceComparator = STAND_SEQUENCE_COMPARATOR;
|
||||
public static IndexedSequence selectSequence(final AnimationTokens.PrimaryTag type,
|
||||
final EnumSet<AnimationTokens.SecondaryTag> tags, final List<Sequence> sequences,
|
||||
final boolean allowRarityVariations) {
|
||||
List<IndexedSequence> filtered = filterSequences(type, tags, sequences);
|
||||
final Comparator<IndexedSequence> sequenceComparator = STAND_SEQUENCE_COMPARATOR;
|
||||
|
||||
if (filtered.isEmpty() && !tags.isEmpty()) {
|
||||
filtered = filterSequences(type, EMPTY, sequences);
|
||||
}
|
||||
if (filtered.isEmpty()) {
|
||||
// find tags
|
||||
EnumSet<SecondaryTag> fallbackTags = null;
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
if (sequence.getPrimaryTags().contains(type)) {
|
||||
if (fallbackTags == null || sequence.getSecondaryTags().size() < fallbackTags.size()
|
||||
|| (sequence.getSecondaryTags().size() == fallbackTags.size() && SecondaryTagSequenceComparator.getTagsOrdinal(sequence.getSecondaryTags(), tags)
|
||||
> SecondaryTagSequenceComparator.getTagsOrdinal(fallbackTags, tags))
|
||||
) {
|
||||
fallbackTags = sequence.getSecondaryTags();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fallbackTags != null) {
|
||||
filtered = filterSequences(type, fallbackTags, sequences);
|
||||
}
|
||||
}
|
||||
if (filtered.isEmpty() && !tags.isEmpty()) {
|
||||
filtered = filterSequences(type, EMPTY, sequences);
|
||||
}
|
||||
if (filtered.isEmpty()) {
|
||||
// find tags
|
||||
EnumSet<SecondaryTag> fallbackTags = null;
|
||||
for (int i = 0, l = sequences.size(); i < l; i++) {
|
||||
final Sequence sequence = sequences.get(i);
|
||||
if (sequence.getPrimaryTags().contains(type)) {
|
||||
if ((fallbackTags == null) || (sequence.getSecondaryTags().size() < fallbackTags.size())
|
||||
|| ((sequence.getSecondaryTags().size() == fallbackTags.size())
|
||||
&& (SecondaryTagSequenceComparator.getTagsOrdinal(sequence.getSecondaryTags(),
|
||||
tags) > SecondaryTagSequenceComparator.getTagsOrdinal(fallbackTags,
|
||||
tags)))) {
|
||||
fallbackTags = sequence.getSecondaryTags();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fallbackTags != null) {
|
||||
filtered = filterSequences(type, fallbackTags, sequences);
|
||||
}
|
||||
}
|
||||
|
||||
filtered.sort(sequenceComparator);
|
||||
filtered.sort(sequenceComparator);
|
||||
|
||||
int i = 0;
|
||||
final double randomRoll = Math.random() * 100;
|
||||
for (final int l = filtered.size(); i < l; i++) {
|
||||
final Sequence sequence = filtered.get(i).sequence;
|
||||
final float rarity = sequence.getRarity();
|
||||
int i = 0;
|
||||
final double randomRoll = Math.random() * 100;
|
||||
for (final int l = filtered.size(); i < l; i++) {
|
||||
final Sequence sequence = filtered.get(i).sequence;
|
||||
final float rarity = sequence.getRarity();
|
||||
|
||||
if (rarity == 0) {
|
||||
break;
|
||||
}
|
||||
if (rarity == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((randomRoll < (10 - rarity)) && allowRarityVariations) {
|
||||
return filtered.get(i);
|
||||
}
|
||||
}
|
||||
if ((randomRoll < (10 - rarity)) && allowRarityVariations) {
|
||||
return filtered.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
final int sequencesLeft = filtered.size() - i;
|
||||
final int random = (int) (i + Math.floor(Math.random() * sequencesLeft));
|
||||
if (sequencesLeft <= 0) {
|
||||
return null; // new IndexedSequence(null, 0);
|
||||
}
|
||||
final IndexedSequence sequence = filtered.get(random);
|
||||
final int sequencesLeft = filtered.size() - i;
|
||||
final int random = (int) (i + Math.floor(Math.random() * sequencesLeft));
|
||||
if (sequencesLeft <= 0) {
|
||||
return null; // new IndexedSequence(null, 0);
|
||||
}
|
||||
final IndexedSequence sequence = filtered.get(random);
|
||||
|
||||
return sequence;
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public static void randomStandSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("stand", sequences);
|
||||
public static void randomStandSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("stand", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomDeathSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("death", sequences);
|
||||
public static void randomDeathSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("death", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomWalkSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("walk", sequences);
|
||||
public static void randomWalkSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("walk", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomBirthSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("birth", sequences);
|
||||
public static void randomBirthSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("birth", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomPortraitSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("portrait", sequences);
|
||||
public static void randomPortraitSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("portrait", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomPortraitTalkSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("portrait talk", sequences);
|
||||
public static void randomPortraitTalkSequence(final MdxComplexInstance target) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence("portrait talk", sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
randomPortraitSequence(target);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
randomPortraitSequence(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void randomSequence(final MdxComplexInstance target, final String sequenceName) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(sequenceName, sequences);
|
||||
public static void randomSequence(final MdxComplexInstance target, final String sequenceName) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(sequenceName, sequences);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName,
|
||||
final boolean allowRarityVariations) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(animationName, null, sequences,
|
||||
allowRarityVariations);
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName,
|
||||
final boolean allowRarityVariations) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(animationName, null, sequences, allowRarityVariations);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
return sequence.sequence;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
return sequence.sequence;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName,
|
||||
final EnumSet<SecondaryTag> secondaryAnimationTags, final boolean allowRarityVariations) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(animationName, secondaryAnimationTags, sequences,
|
||||
allowRarityVariations);
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName,
|
||||
final EnumSet<SecondaryTag> secondaryAnimationTags, final boolean allowRarityVariations) {
|
||||
final MdxModel model = (MdxModel) target.model;
|
||||
final List<Sequence> sequences = model.getSequences();
|
||||
final IndexedSequence sequence = selectSequence(animationName, secondaryAnimationTags, sequences,
|
||||
allowRarityVariations);
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
return sequence.sequence;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
return sequence.sequence;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName) {
|
||||
return randomSequence(target, animationName, EMPTY, false);
|
||||
}
|
||||
public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName) {
|
||||
return randomSequence(target, animationName, EMPTY, false);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -60,7 +60,7 @@ public class Terrain {
|
||||
private static final Vector3 normalHeap2 = new Vector3();
|
||||
private static final float[] fourComponentHeap = new float[4];
|
||||
private static final Matrix4 tempMatrix = new Matrix4();
|
||||
private static final boolean WIREFRAME_TERRAIN = false;
|
||||
private static final boolean WIREFRAME_TERRAIN = true;
|
||||
|
||||
public ShaderProgram groundShader;
|
||||
public ShaderProgram waterShader;
|
||||
@ -411,7 +411,8 @@ public class Terrain {
|
||||
this.shaderMapBoundsRectangle = new Rectangle(this.shaderMapBounds[0], this.shaderMapBounds[1],
|
||||
this.shaderMapBounds[2] - this.shaderMapBounds[0], this.shaderMapBounds[3] - this.shaderMapBounds[1]);
|
||||
this.mapSize = w3eFile.getMapSize();
|
||||
this.entireMapRectangle = new Rectangle(centerOffset[0], centerOffset[1], (mapSize[0] * 128f) - 128, (mapSize[1] * 128f) - 128);
|
||||
this.entireMapRectangle = new Rectangle(this.centerOffset[0], this.centerOffset[1],
|
||||
(this.mapSize[0] * 128f) - 128, (this.mapSize[1] * 128f) - 128);
|
||||
this.softwareGroundMesh = new SoftwareGroundMesh(this.groundHeights, this.groundCornerHeights,
|
||||
this.centerOffset, width, height);
|
||||
|
||||
@ -1402,6 +1403,6 @@ public class Terrain {
|
||||
}
|
||||
|
||||
public Rectangle getEntireMap() {
|
||||
return entireMapRectangle;
|
||||
return this.entireMapRectangle;
|
||||
}
|
||||
}
|
||||
|
@ -137,10 +137,10 @@ public class RenderUnit {
|
||||
}
|
||||
|
||||
public void populateCommandCard(final CSimulation game, final CommandButtonListener commandButtonListener,
|
||||
final AbilityDataUI abilityDataUI) {
|
||||
final AbilityDataUI abilityDataUI, final int subMenuOrderId) {
|
||||
for (final CAbility ability : this.simulationUnit.getAbilities()) {
|
||||
ability.visit(CommandCardPopulatingAbilityVisitor.INSTANCE.reset(game, this.simulationUnit,
|
||||
commandButtonListener, abilityDataUI));
|
||||
commandButtonListener, abilityDataUI, subMenuOrderId));
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,15 +405,17 @@ public class RenderUnit {
|
||||
final boolean allowRarityVariations) {
|
||||
this.animationQueue.clear();
|
||||
if (force || (animationName != this.currentAnimation)) {
|
||||
this.currentAnimation = animationName;
|
||||
this.currentAnimationSecondaryTags = secondaryAnimationTags;
|
||||
this.currentSpeedRatio = speedRatio;
|
||||
this.currentlyAllowingRarityVariations = allowRarityVariations;
|
||||
this.recycleSet.clear();
|
||||
this.recycleSet.addAll(this.secondaryAnimationTags);
|
||||
this.recycleSet.addAll(secondaryAnimationTags);
|
||||
this.instance.setAnimationSpeed(speedRatio);
|
||||
SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, allowRarityVariations);
|
||||
if (SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet,
|
||||
allowRarityVariations) != null) {
|
||||
this.currentAnimation = animationName;
|
||||
this.currentAnimationSecondaryTags = secondaryAnimationTags;
|
||||
this.currentlyAllowingRarityVariations = allowRarityVariations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,15 +424,15 @@ public class RenderUnit {
|
||||
final boolean allowRarityVariations) {
|
||||
this.animationQueue.clear();
|
||||
if (force || (animationName != this.currentAnimation)) {
|
||||
this.currentAnimation = animationName;
|
||||
this.currentAnimationSecondaryTags = secondaryAnimationTags;
|
||||
this.currentlyAllowingRarityVariations = allowRarityVariations;
|
||||
this.recycleSet.clear();
|
||||
this.recycleSet.addAll(this.secondaryAnimationTags);
|
||||
this.recycleSet.addAll(secondaryAnimationTags);
|
||||
final Sequence sequence = SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet,
|
||||
allowRarityVariations);
|
||||
if (sequence != null) {
|
||||
this.currentAnimation = animationName;
|
||||
this.currentAnimationSecondaryTags = secondaryAnimationTags;
|
||||
this.currentlyAllowingRarityVariations = allowRarityVariations;
|
||||
this.currentSpeedRatio = ((sequence.getInterval()[1] - sequence.getInterval()[0]) / 1000.0f)
|
||||
/ duration;
|
||||
this.instance.setAnimationSpeed(this.currentSpeedRatio);
|
||||
|
@ -22,15 +22,27 @@ public class AbilityDataUI {
|
||||
private static final War3ID ICON_RESEARCH_X = War3ID.fromString("arpx");
|
||||
private static final War3ID ICON_RESEARCH_Y = War3ID.fromString("arpy");
|
||||
|
||||
private static final War3ID UNIT_ICON_NORMAL_X = War3ID.fromString("ubpx");
|
||||
private static final War3ID UNIT_ICON_NORMAL_Y = War3ID.fromString("ubpy");
|
||||
private static final War3ID UNIT_ICON_NORMAL = War3ID.fromString("uico");
|
||||
|
||||
private final Map<War3ID, AbilityIconUI> rawcodeToUI = new HashMap<>();
|
||||
private final Map<War3ID, IconUI> rawcodeToUnitUI = new HashMap<>();
|
||||
private final IconUI moveUI;
|
||||
private final IconUI stopUI;
|
||||
private final IconUI holdPosUI;
|
||||
private final IconUI patrolUI;
|
||||
private final IconUI attackUI;
|
||||
private final IconUI attackGroundUI;
|
||||
private final IconUI buildHumanUI;
|
||||
private final IconUI buildOrcUI;
|
||||
private final IconUI buildNightElfUI;
|
||||
private final IconUI buildUndeadUI;
|
||||
private final IconUI buildNeutralUI;
|
||||
private final IconUI buildNagaUI;
|
||||
private final IconUI cancelUI;
|
||||
|
||||
public AbilityDataUI(final MutableObjectData abilityData, final GameUI gameUI) {
|
||||
public AbilityDataUI(final MutableObjectData abilityData, final MutableObjectData unitData, final GameUI gameUI) {
|
||||
final String disabledPrefix = gameUI.getSkinField("CommandButtonDisabledArtPath");
|
||||
for (final War3ID alias : abilityData.keySet()) {
|
||||
final MutableGameObject abilityTypeData = abilityData.get(alias);
|
||||
@ -54,12 +66,28 @@ public class AbilityDataUI {
|
||||
new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY),
|
||||
new IconUI(iconTurnOff, iconTurnOffDisabled, iconTurnOffX, iconTurnOffY)));
|
||||
}
|
||||
for (final War3ID alias : unitData.keySet()) {
|
||||
final MutableGameObject abilityTypeData = unitData.get(alias);
|
||||
final String iconNormalPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(UNIT_ICON_NORMAL, 0));
|
||||
final int iconNormalX = abilityTypeData.getFieldAsInteger(UNIT_ICON_NORMAL_X, 0);
|
||||
final int iconNormalY = abilityTypeData.getFieldAsInteger(UNIT_ICON_NORMAL_Y, 0);
|
||||
final Texture iconNormal = gameUI.loadTexture(iconNormalPath);
|
||||
final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix));
|
||||
this.rawcodeToUnitUI.put(alias, new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY));
|
||||
}
|
||||
this.moveUI = createBuiltInIconUI(gameUI, "CmdMove", disabledPrefix);
|
||||
this.stopUI = createBuiltInIconUI(gameUI, "CmdStop", disabledPrefix);
|
||||
this.holdPosUI = createBuiltInIconUI(gameUI, "CmdHoldPos", disabledPrefix);
|
||||
this.patrolUI = createBuiltInIconUI(gameUI, "CmdPatrol", disabledPrefix);
|
||||
this.attackUI = createBuiltInIconUI(gameUI, "CmdAttack", disabledPrefix);
|
||||
this.buildHumanUI = createBuiltInIconUI(gameUI, "CmdBuildHuman", disabledPrefix);
|
||||
this.buildOrcUI = createBuiltInIconUI(gameUI, "CmdBuildOrc", disabledPrefix);
|
||||
this.buildNightElfUI = createBuiltInIconUI(gameUI, "CmdBuildNightElf", disabledPrefix);
|
||||
this.buildUndeadUI = createBuiltInIconUI(gameUI, "CmdBuildUndead", disabledPrefix);
|
||||
this.buildNagaUI = createBuiltInIconUI(gameUI, "CmdBuildNaga", disabledPrefix);
|
||||
this.buildNeutralUI = createBuiltInIconUI(gameUI, "CmdBuild", disabledPrefix);
|
||||
this.attackGroundUI = createBuiltInIconUI(gameUI, "CmdAttackGround", disabledPrefix);
|
||||
this.cancelUI = createBuiltInIconUI(gameUI, "CmdCancel", disabledPrefix);
|
||||
}
|
||||
|
||||
private IconUI createBuiltInIconUI(final GameUI gameUI, final String key, final String disabledPrefix) {
|
||||
@ -76,6 +104,10 @@ public class AbilityDataUI {
|
||||
return this.rawcodeToUI.get(rawcode);
|
||||
}
|
||||
|
||||
public IconUI getUnitUI(final War3ID rawcode) {
|
||||
return this.rawcodeToUnitUI.get(rawcode);
|
||||
}
|
||||
|
||||
private static String disable(final String path, final String disabledPrefix) {
|
||||
final int slashIndex = path.lastIndexOf('\\');
|
||||
String name = path;
|
||||
@ -109,4 +141,32 @@ public class AbilityDataUI {
|
||||
return this.attackGroundUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildHumanUI() {
|
||||
return this.buildHumanUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildNightElfUI() {
|
||||
return this.buildNightElfUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildOrcUI() {
|
||||
return this.buildOrcUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildUndeadUI() {
|
||||
return this.buildUndeadUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildNagaUI() {
|
||||
return this.buildNagaUI;
|
||||
}
|
||||
|
||||
public IconUI getBuildNeutralUI() {
|
||||
return this.buildNeutralUI;
|
||||
}
|
||||
|
||||
public IconUI getCancelUI() {
|
||||
return this.cancelUI;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,5 +35,5 @@ public interface CommandButtonListener {
|
||||
//
|
||||
// int getOrderId();
|
||||
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId,
|
||||
int autoCastOrderId, boolean active, boolean autoCastActive);
|
||||
int autoCastOrderId, boolean active, boolean autoCastActive, boolean menuButton);
|
||||
}
|
||||
|
@ -1,85 +1,158 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons;
|
||||
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.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.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.AbstractCAbilityBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void> {
|
||||
public static final CommandCardPopulatingAbilityVisitor INSTANCE = new CommandCardPopulatingAbilityVisitor();
|
||||
public static final CommandCardPopulatingAbilityVisitor INSTANCE = new CommandCardPopulatingAbilityVisitor();
|
||||
private CSimulation game;
|
||||
private CUnit unit;
|
||||
|
||||
private CSimulation game;
|
||||
private CUnit unit;
|
||||
private CommandButtonListener commandButtonListener;
|
||||
private AbilityDataUI abilityDataUI;
|
||||
private int menuBaseOrderId;
|
||||
private boolean hasStop;
|
||||
|
||||
private CommandButtonListener commandButtonListener;
|
||||
private AbilityDataUI abilityDataUI;
|
||||
private boolean hasStop;
|
||||
public CommandCardPopulatingAbilityVisitor reset(final CSimulation game, final CUnit unit,
|
||||
final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI,
|
||||
final int menuBaseOrderId) {
|
||||
this.game = game;
|
||||
this.unit = unit;
|
||||
this.commandButtonListener = commandButtonListener;
|
||||
this.abilityDataUI = abilityDataUI;
|
||||
this.menuBaseOrderId = menuBaseOrderId;
|
||||
this.hasStop = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandCardPopulatingAbilityVisitor reset(final CSimulation game, final CUnit unit,
|
||||
final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI) {
|
||||
this.game = game;
|
||||
this.unit = unit;
|
||||
this.commandButtonListener = commandButtonListener;
|
||||
this.abilityDataUI = abilityDataUI;
|
||||
this.hasStop = false;
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityAttack ability) {
|
||||
if (this.menuBaseOrderId == 0) {
|
||||
addCommandButton(ability, this.abilityDataUI.getAttackUI(), ability.getHandleId(), OrderIds.attack, 0,
|
||||
false, false);
|
||||
if (!this.hasStop) {
|
||||
this.hasStop = true;
|
||||
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false, false);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityAttack ability) {
|
||||
addCommandButton(ability, this.abilityDataUI.getAttackUI(), ability.getHandleId(), OrderIds.attack, 0, false);
|
||||
if (!this.hasStop) {
|
||||
this.hasStop = true;
|
||||
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityMove ability) {
|
||||
if (this.menuBaseOrderId == 0) {
|
||||
addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move, 0, false,
|
||||
false);
|
||||
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), ability.getHandleId(), OrderIds.holdposition,
|
||||
0, false, false);
|
||||
addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol, 0,
|
||||
false, false);
|
||||
if (!this.hasStop) {
|
||||
this.hasStop = true;
|
||||
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false, false);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityMove ability) {
|
||||
addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move, 0, false);
|
||||
addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), ability.getHandleId(), OrderIds.holdposition, 0,
|
||||
false);
|
||||
addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol, 0, false);
|
||||
if (!this.hasStop) {
|
||||
this.hasStop = true;
|
||||
addCommandButton(null, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityGeneric ability) {
|
||||
if (this.menuBaseOrderId == 0) {
|
||||
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(),
|
||||
ability.getHandleId(), 0, 0, false, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityGeneric ability) {
|
||||
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(), ability.getHandleId(),
|
||||
OrderIds.channel, 0, false);
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityColdArrows ability) {
|
||||
if (this.menuBaseOrderId == 0) {
|
||||
final boolean autoCastActive = ability.isAutoCastActive();
|
||||
int autoCastId;
|
||||
if (autoCastActive) {
|
||||
autoCastId = OrderIds.coldarrows;
|
||||
}
|
||||
else {
|
||||
autoCastId = OrderIds.uncoldarrows;
|
||||
}
|
||||
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(),
|
||||
ability.getHandleId(), OrderIds.coldarrowstarg, autoCastId, autoCastActive, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityColdArrows ability) {
|
||||
final boolean autoCastActive = ability.isAutoCastActive();
|
||||
int autoCastId;
|
||||
if (autoCastActive) {
|
||||
autoCastId = OrderIds.coldarrows;
|
||||
} else {
|
||||
autoCastId = OrderIds.uncoldarrows;
|
||||
}
|
||||
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(), ability.getHandleId(),
|
||||
OrderIds.coldarrowstarg, autoCastId, autoCastActive);
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityOrcBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildOrcUI());
|
||||
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 = (this.unit.getCurrentBehavior() != null && orderId == this.unit.getCurrentBehavior().getHighlightOrderId());
|
||||
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
||||
iconUI.getIcon(), handleId, orderId, autoCastOrderId, active, autoCastActive);
|
||||
}
|
||||
@Override
|
||||
public Void accept(final CAbilityHumanBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildHumanUI());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityNightElfBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildNightElfUI());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityUndeadBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildUndeadUI());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityNagaBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildNagaUI());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void accept(final CAbilityNeutralBuild ability) {
|
||||
handleBuildMenu(ability, this.abilityDataUI.getBuildNeutralUI());
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleBuildMenu(final AbstractCAbilityBuild ability, final IconUI buildUI) {
|
||||
if (this.menuBaseOrderId == ability.getBaseOrderId()) {
|
||||
for (final War3ID unitType : ability.getStructuresBuilt()) {
|
||||
final IconUI unitUI = this.abilityDataUI.getUnitUI(unitType);
|
||||
if (unitUI != null) {
|
||||
addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
addCommandButton(ability, buildUI, ability.getHandleId(), ability.getBaseOrderId(), 0, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
|
||||
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton) {
|
||||
final boolean active = ((this.unit.getCurrentBehavior() != null)
|
||||
&& (orderId == this.unit.getCurrentBehavior().getHighlightOrderId()));
|
||||
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
||||
iconUI.getIcon(), handleId, orderId, autoCastOrderId, active, autoCastActive, menuButton);
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ import java.awt.image.BufferedImage;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType;
|
||||
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.data.CUnitRace;
|
||||
|
||||
/**
|
||||
* The quick (symbol table instead of map) lookup for unit type values that we
|
||||
@ -35,13 +37,19 @@ public class CUnitType {
|
||||
private final EnumSet<CTargetType> targetedAs;
|
||||
private final float defaultAcquisitionRange;
|
||||
private final float minimumAttackRange;
|
||||
private final List<War3ID> structuresBuilt;
|
||||
private final CUnitRace unitRace;
|
||||
private final int goldCost;
|
||||
private final int lumberCost;
|
||||
private final int buildTime;
|
||||
|
||||
public CUnitType(final String name, final boolean isBldg, final MovementType movementType,
|
||||
final float defaultFlyingHeight, final float collisionSize,
|
||||
final EnumSet<CUnitClassification> classifications, final List<CUnitAttack> attacks, final String armorType,
|
||||
final boolean raise, final boolean decay, final CDefenseType defenseType, final float impactZ,
|
||||
final BufferedImage buildingPathingPixelMap, final float deathTime, final EnumSet<CTargetType> targetedAs,
|
||||
final float defaultAcquisitionRange, final float minimumAttackRange) {
|
||||
final float defaultAcquisitionRange, final float minimumAttackRange, final List<War3ID> structuresBuilt,
|
||||
final CUnitRace unitRace, final int goldCost, final int lumberCost, final int buildTime) {
|
||||
this.name = name;
|
||||
this.building = isBldg;
|
||||
this.movementType = movementType;
|
||||
@ -59,6 +67,11 @@ public class CUnitType {
|
||||
this.targetedAs = targetedAs;
|
||||
this.defaultAcquisitionRange = defaultAcquisitionRange;
|
||||
this.minimumAttackRange = minimumAttackRange;
|
||||
this.structuresBuilt = structuresBuilt;
|
||||
this.unitRace = unitRace;
|
||||
this.goldCost = goldCost;
|
||||
this.lumberCost = lumberCost;
|
||||
this.buildTime = buildTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -128,4 +141,24 @@ public class CUnitType {
|
||||
public float getMinimumAttackRange() {
|
||||
return this.minimumAttackRange;
|
||||
}
|
||||
|
||||
public List<War3ID> getStructuresBuilt() {
|
||||
return this.structuresBuilt;
|
||||
}
|
||||
|
||||
public CUnitRace getRace() {
|
||||
return this.unitRace;
|
||||
}
|
||||
|
||||
public int getGoldCost() {
|
||||
return this.goldCost;
|
||||
}
|
||||
|
||||
public int getLumberCost() {
|
||||
return this.lumberCost;
|
||||
}
|
||||
|
||||
public int getBuildTime() {
|
||||
return this.buildTime;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities;
|
||||
|
||||
public abstract class AbstractCAbility implements CAbility {
|
||||
private final int handleId;
|
||||
|
||||
public AbstractCAbility(final int handleId) {
|
||||
this.handleId = handleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getHandleId() {
|
||||
return this.handleId;
|
||||
}
|
||||
}
|
@ -1,5 +1,13 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
|
||||
|
||||
/**
|
||||
* A visitor for the lowest level inherent types of an ability. It's a bit of a
|
||||
* design clash to have the notion of an ability visitor pattern while also
|
||||
@ -13,7 +21,19 @@ public interface CAbilityVisitor<T> {
|
||||
|
||||
T accept(CAbilityMove ability);
|
||||
|
||||
T accept(CAbilityOrcBuild ability);
|
||||
|
||||
T accept(CAbilityHumanBuild ability);
|
||||
|
||||
T accept(CAbilityUndeadBuild ability);
|
||||
|
||||
T accept(CAbilityNightElfBuild ability);
|
||||
|
||||
T accept(CAbilityGeneric ability);
|
||||
|
||||
T accept(CAbilityColdArrows ability);
|
||||
|
||||
T accept(CAbilityNagaBuild ability);
|
||||
|
||||
T accept(CAbilityNeutralBuild ability);
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
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.CUnitType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.menu.CAbilityMenu;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer;
|
||||
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.ResourceType;
|
||||
|
||||
public abstract class AbstractCAbilityBuild extends AbstractCAbility implements CAbilityMenu {
|
||||
private final Set<War3ID> structuresBuilt;
|
||||
|
||||
public AbstractCAbilityBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId);
|
||||
this.structuresBuilt = new LinkedHashSet<>(structuresBuilt);
|
||||
}
|
||||
|
||||
public Collection<War3ID> getStructuresBuilt() {
|
||||
return this.structuresBuilt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCanUse(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityActivationReceiver receiver) {
|
||||
final CUnitType unitType = game.getUnitData().getUnitType(new War3ID(orderId));
|
||||
if (unitType != null) {
|
||||
final CPlayer player = game.getPlayer(unit.getPlayerIndex());
|
||||
if (player.getGold() >= unitType.getGoldCost()) {
|
||||
if (player.getLumber() >= unitType.getLumberCost()) {
|
||||
receiver.useOk();
|
||||
}
|
||||
else {
|
||||
receiver.notEnoughResources(ResourceType.LUMBER);
|
||||
}
|
||||
}
|
||||
else {
|
||||
receiver.notEnoughResources(ResourceType.GOLD);
|
||||
}
|
||||
}
|
||||
else {
|
||||
receiver.useOk();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target,
|
||||
final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final Vector2 target,
|
||||
final AbilityTargetCheckReceiver<Vector2> receiver) {
|
||||
if (this.structuresBuilt.contains(new War3ID(orderId))) {
|
||||
receiver.targetOk(target);
|
||||
}
|
||||
else {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||
final AbilityTargetCheckReceiver<Void> receiver) {
|
||||
receiver.orderIdNotAccepted();
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityHumanBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityHumanBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.humanbuild;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(final CAbilityVisitor<T> visitor) {
|
||||
return visitor.accept(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityNagaBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityNagaBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
}
|
||||
|
||||
@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) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.nagabuild;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityNeutralBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityNeutralBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
}
|
||||
|
||||
@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) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.buildmenu;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityNightElfBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityNightElfBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.nightelfbuild;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(final CAbilityVisitor<T> visitor) {
|
||||
return visitor.accept(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityOrcBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityOrcBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
}
|
||||
|
||||
@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) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
return caster.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.orcbuild;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.abilities.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityUndeadBuild extends AbstractCAbilityBuild {
|
||||
|
||||
public CAbilityUndeadBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBaseOrderId() {
|
||||
return OrderIds.undeadbuild;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(final CAbilityVisitor<T> visitor) {
|
||||
return visitor.accept(this);
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities;
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat;
|
||||
|
||||
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.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
|
||||
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;
|
@ -0,0 +1,8 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.menu;
|
||||
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
|
||||
public interface CAbilityMenu extends CAbility {
|
||||
// the base order ID of the menu
|
||||
int getBaseOrderId();
|
||||
}
|
@ -32,18 +32,18 @@ public class CBehaviorMove implements CBehavior {
|
||||
private CUnit followUnit;
|
||||
private CRangedBehavior rangedBehavior;
|
||||
|
||||
public CBehaviorMove reset(int highlightOrderId, final float targetX, final float targetY) {
|
||||
public CBehaviorMove reset(final int highlightOrderId, final float targetX, final float targetY) {
|
||||
internalResetMove(highlightOrderId, targetX, targetY);
|
||||
this.rangedBehavior = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void internalResetMove(int highlightOrderId, final float targetX, final float targetY) {
|
||||
private void internalResetMove(final int highlightOrderId, final float targetX, final float targetY) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
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(targetX, targetY);
|
||||
this.path = null;
|
||||
this.searchCycles = 0;
|
||||
@ -56,26 +56,19 @@ public class CBehaviorMove implements CBehavior {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CBehaviorMove reset(int highlightOrderId, final CUnit followUnit) {
|
||||
public CBehaviorMove reset(final int highlightOrderId, final CUnit followUnit) {
|
||||
internalResetMove(highlightOrderId, followUnit);
|
||||
this.rangedBehavior = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
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;
|
||||
this.target = new Point2D.Float(followUnit.getX(), followUnit.getY());
|
||||
this.path = null;
|
||||
this.searchCycles = 0;
|
||||
this.followUnit = followUnit;
|
||||
internalResetMove(rangedBehavior.getHighlightOrderId(), followUnit);
|
||||
this.rangedBehavior = rangedBehavior;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void internalResetMove(int highlightOrderId, CUnit followUnit) {
|
||||
private void internalResetMove(final int highlightOrderId, final CUnit followUnit) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
this.wasWithinPropWindow = false;
|
||||
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
||||
@ -89,7 +82,7 @@ public class CBehaviorMove implements CBehavior {
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return highlightOrderId;
|
||||
return this.highlightOrderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,8 +3,8 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data;
|
||||
import com.etheller.warsmash.units.manager.MutableObjectData;
|
||||
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;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows;
|
||||
|
||||
public class CAbilityData {
|
||||
private static final War3ID COLD_ARROWS = War3ID.fromString("ACcw");
|
||||
|
@ -18,6 +18,12 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.HandleIdAllocator;
|
||||
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.abilities.build.CAbilityHumanBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||
@ -32,410 +38,479 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUni
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
||||
|
||||
public class CUnitData {
|
||||
private static final War3ID MANA_INITIAL_AMOUNT = War3ID.fromString("umpi");
|
||||
private static final War3ID MANA_MAXIMUM = War3ID.fromString("umpm");
|
||||
private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("uhpm");
|
||||
private static final War3ID MOVEMENT_SPEED_BASE = War3ID.fromString("umvs");
|
||||
private static final War3ID PROPULSION_WINDOW = War3ID.fromString("uprw");
|
||||
private static final War3ID TURN_RATE = War3ID.fromString("umvr");
|
||||
private static final War3ID IS_BLDG = War3ID.fromString("ubdg");
|
||||
private static final War3ID NAME = War3ID.fromString("unam");
|
||||
private static final War3ID PROJECTILE_LAUNCH_X = War3ID.fromString("ulpx");
|
||||
private static final War3ID PROJECTILE_LAUNCH_Y = War3ID.fromString("ulpy");
|
||||
private static final War3ID PROJECTILE_LAUNCH_Z = War3ID.fromString("ulpz");
|
||||
private static final War3ID ATTACKS_ENABLED = War3ID.fromString("uaen");
|
||||
private static final War3ID ATTACK1_BACKSWING_POINT = War3ID.fromString("ubs1");
|
||||
private static final War3ID ATTACK1_DAMAGE_POINT = War3ID.fromString("udp1");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua1f");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua1h");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua1q");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua1p");
|
||||
private static final War3ID ATTACK1_ATTACK_TYPE = War3ID.fromString("ua1t");
|
||||
private static final War3ID ATTACK1_COOLDOWN = War3ID.fromString("ua1c");
|
||||
private static final War3ID ATTACK1_DMG_BASE = War3ID.fromString("ua1b");
|
||||
private static final War3ID ATTACK1_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd1");
|
||||
private static final War3ID ATTACK1_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd1");
|
||||
private static final War3ID ATTACK1_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl1");
|
||||
private static final War3ID ATTACK1_DMG_DICE = War3ID.fromString("ua1d");
|
||||
private static final War3ID ATTACK1_DMG_SIDES_PER_DIE = War3ID.fromString("ua1s");
|
||||
private static final War3ID ATTACK1_DMG_SPILL_DIST = War3ID.fromString("usd1");
|
||||
private static final War3ID ATTACK1_DMG_SPILL_RADIUS = War3ID.fromString("usr1");
|
||||
private static final War3ID ATTACK1_DMG_UPGRADE_AMT = War3ID.fromString("udu1");
|
||||
private static final War3ID ATTACK1_TARGET_COUNT = War3ID.fromString("utc1");
|
||||
private static final War3ID ATTACK1_PROJECTILE_ARC = War3ID.fromString("uma1");
|
||||
private static final War3ID ATTACK1_MISSILE_ART = War3ID.fromString("ua1m");
|
||||
private static final War3ID ATTACK1_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh1");
|
||||
private static final War3ID ATTACK1_PROJECTILE_SPEED = War3ID.fromString("ua1z");
|
||||
private static final War3ID ATTACK1_RANGE = War3ID.fromString("ua1r");
|
||||
private static final War3ID ATTACK1_RANGE_MOTION_BUFFER = War3ID.fromString("urb1");
|
||||
private static final War3ID ATTACK1_SHOW_UI = War3ID.fromString("uwu1");
|
||||
private static final War3ID ATTACK1_TARGETS_ALLOWED = War3ID.fromString("ua1g");
|
||||
private static final War3ID ATTACK1_WEAPON_SOUND = War3ID.fromString("ucs1");
|
||||
private static final War3ID ATTACK1_WEAPON_TYPE = War3ID.fromString("ua1w");
|
||||
private static final War3ID MANA_INITIAL_AMOUNT = War3ID.fromString("umpi");
|
||||
private static final War3ID MANA_MAXIMUM = War3ID.fromString("umpm");
|
||||
private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("uhpm");
|
||||
private static final War3ID MOVEMENT_SPEED_BASE = War3ID.fromString("umvs");
|
||||
private static final War3ID PROPULSION_WINDOW = War3ID.fromString("uprw");
|
||||
private static final War3ID TURN_RATE = War3ID.fromString("umvr");
|
||||
private static final War3ID IS_BLDG = War3ID.fromString("ubdg");
|
||||
private static final War3ID NAME = War3ID.fromString("unam");
|
||||
private static final War3ID PROJECTILE_LAUNCH_X = War3ID.fromString("ulpx");
|
||||
private static final War3ID PROJECTILE_LAUNCH_Y = War3ID.fromString("ulpy");
|
||||
private static final War3ID PROJECTILE_LAUNCH_Z = War3ID.fromString("ulpz");
|
||||
private static final War3ID ATTACKS_ENABLED = War3ID.fromString("uaen");
|
||||
private static final War3ID ATTACK1_BACKSWING_POINT = War3ID.fromString("ubs1");
|
||||
private static final War3ID ATTACK1_DAMAGE_POINT = War3ID.fromString("udp1");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua1f");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua1h");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua1q");
|
||||
private static final War3ID ATTACK1_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua1p");
|
||||
private static final War3ID ATTACK1_ATTACK_TYPE = War3ID.fromString("ua1t");
|
||||
private static final War3ID ATTACK1_COOLDOWN = War3ID.fromString("ua1c");
|
||||
private static final War3ID ATTACK1_DMG_BASE = War3ID.fromString("ua1b");
|
||||
private static final War3ID ATTACK1_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd1");
|
||||
private static final War3ID ATTACK1_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd1");
|
||||
private static final War3ID ATTACK1_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl1");
|
||||
private static final War3ID ATTACK1_DMG_DICE = War3ID.fromString("ua1d");
|
||||
private static final War3ID ATTACK1_DMG_SIDES_PER_DIE = War3ID.fromString("ua1s");
|
||||
private static final War3ID ATTACK1_DMG_SPILL_DIST = War3ID.fromString("usd1");
|
||||
private static final War3ID ATTACK1_DMG_SPILL_RADIUS = War3ID.fromString("usr1");
|
||||
private static final War3ID ATTACK1_DMG_UPGRADE_AMT = War3ID.fromString("udu1");
|
||||
private static final War3ID ATTACK1_TARGET_COUNT = War3ID.fromString("utc1");
|
||||
private static final War3ID ATTACK1_PROJECTILE_ARC = War3ID.fromString("uma1");
|
||||
private static final War3ID ATTACK1_MISSILE_ART = War3ID.fromString("ua1m");
|
||||
private static final War3ID ATTACK1_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh1");
|
||||
private static final War3ID ATTACK1_PROJECTILE_SPEED = War3ID.fromString("ua1z");
|
||||
private static final War3ID ATTACK1_RANGE = War3ID.fromString("ua1r");
|
||||
private static final War3ID ATTACK1_RANGE_MOTION_BUFFER = War3ID.fromString("urb1");
|
||||
private static final War3ID ATTACK1_SHOW_UI = War3ID.fromString("uwu1");
|
||||
private static final War3ID ATTACK1_TARGETS_ALLOWED = War3ID.fromString("ua1g");
|
||||
private static final War3ID ATTACK1_WEAPON_SOUND = War3ID.fromString("ucs1");
|
||||
private static final War3ID ATTACK1_WEAPON_TYPE = War3ID.fromString("ua1w");
|
||||
|
||||
private static final War3ID ATTACK2_BACKSWING_POINT = War3ID.fromString("ubs2");
|
||||
private static final War3ID ATTACK2_DAMAGE_POINT = War3ID.fromString("udp2");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua2f");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua2h");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua2q");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua2p");
|
||||
private static final War3ID ATTACK2_ATTACK_TYPE = War3ID.fromString("ua2t");
|
||||
private static final War3ID ATTACK2_COOLDOWN = War3ID.fromString("ua2c");
|
||||
private static final War3ID ATTACK2_DMG_BASE = War3ID.fromString("ua2b");
|
||||
private static final War3ID ATTACK2_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd2");
|
||||
private static final War3ID ATTACK2_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd2");
|
||||
private static final War3ID ATTACK2_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl2");
|
||||
private static final War3ID ATTACK2_DMG_DICE = War3ID.fromString("ua2d");
|
||||
private static final War3ID ATTACK2_DMG_SIDES_PER_DIE = War3ID.fromString("ua2s");
|
||||
private static final War3ID ATTACK2_DMG_SPILL_DIST = War3ID.fromString("usd2");
|
||||
private static final War3ID ATTACK2_DMG_SPILL_RADIUS = War3ID.fromString("usr2");
|
||||
private static final War3ID ATTACK2_DMG_UPGRADE_AMT = War3ID.fromString("udu2");
|
||||
private static final War3ID ATTACK2_TARGET_COUNT = War3ID.fromString("utc2");
|
||||
private static final War3ID ATTACK2_PROJECTILE_ARC = War3ID.fromString("uma2");
|
||||
private static final War3ID ATTACK2_MISSILE_ART = War3ID.fromString("ua2m");
|
||||
private static final War3ID ATTACK2_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh2");
|
||||
private static final War3ID ATTACK2_PROJECTILE_SPEED = War3ID.fromString("ua2z");
|
||||
private static final War3ID ATTACK2_RANGE = War3ID.fromString("ua2r");
|
||||
private static final War3ID ATTACK2_RANGE_MOTION_BUFFER = War3ID.fromString("urb2");
|
||||
private static final War3ID ATTACK2_SHOW_UI = War3ID.fromString("uwu2");
|
||||
private static final War3ID ATTACK2_TARGETS_ALLOWED = War3ID.fromString("ua2g");
|
||||
private static final War3ID ATTACK2_WEAPON_SOUND = War3ID.fromString("ucs2");
|
||||
private static final War3ID ATTACK2_WEAPON_TYPE = War3ID.fromString("ua2w");
|
||||
private static final War3ID ATTACK2_BACKSWING_POINT = War3ID.fromString("ubs2");
|
||||
private static final War3ID ATTACK2_DAMAGE_POINT = War3ID.fromString("udp2");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua2f");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua2h");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua2q");
|
||||
private static final War3ID ATTACK2_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua2p");
|
||||
private static final War3ID ATTACK2_ATTACK_TYPE = War3ID.fromString("ua2t");
|
||||
private static final War3ID ATTACK2_COOLDOWN = War3ID.fromString("ua2c");
|
||||
private static final War3ID ATTACK2_DMG_BASE = War3ID.fromString("ua2b");
|
||||
private static final War3ID ATTACK2_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd2");
|
||||
private static final War3ID ATTACK2_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd2");
|
||||
private static final War3ID ATTACK2_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl2");
|
||||
private static final War3ID ATTACK2_DMG_DICE = War3ID.fromString("ua2d");
|
||||
private static final War3ID ATTACK2_DMG_SIDES_PER_DIE = War3ID.fromString("ua2s");
|
||||
private static final War3ID ATTACK2_DMG_SPILL_DIST = War3ID.fromString("usd2");
|
||||
private static final War3ID ATTACK2_DMG_SPILL_RADIUS = War3ID.fromString("usr2");
|
||||
private static final War3ID ATTACK2_DMG_UPGRADE_AMT = War3ID.fromString("udu2");
|
||||
private static final War3ID ATTACK2_TARGET_COUNT = War3ID.fromString("utc2");
|
||||
private static final War3ID ATTACK2_PROJECTILE_ARC = War3ID.fromString("uma2");
|
||||
private static final War3ID ATTACK2_MISSILE_ART = War3ID.fromString("ua2m");
|
||||
private static final War3ID ATTACK2_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh2");
|
||||
private static final War3ID ATTACK2_PROJECTILE_SPEED = War3ID.fromString("ua2z");
|
||||
private static final War3ID ATTACK2_RANGE = War3ID.fromString("ua2r");
|
||||
private static final War3ID ATTACK2_RANGE_MOTION_BUFFER = War3ID.fromString("urb2");
|
||||
private static final War3ID ATTACK2_SHOW_UI = War3ID.fromString("uwu2");
|
||||
private static final War3ID ATTACK2_TARGETS_ALLOWED = War3ID.fromString("ua2g");
|
||||
private static final War3ID ATTACK2_WEAPON_SOUND = War3ID.fromString("ucs2");
|
||||
private static final War3ID ATTACK2_WEAPON_TYPE = War3ID.fromString("ua2w");
|
||||
|
||||
private static final War3ID ACQUISITION_RANGE = War3ID.fromString("uacq");
|
||||
private static final War3ID MINIMUM_ATTACK_RANGE = War3ID.fromString("uamn");
|
||||
private static final War3ID ACQUISITION_RANGE = War3ID.fromString("uacq");
|
||||
private static final War3ID MINIMUM_ATTACK_RANGE = War3ID.fromString("uamn");
|
||||
|
||||
private static final War3ID PROJECTILE_IMPACT_Z = War3ID.fromString("uimz");
|
||||
private static final War3ID PROJECTILE_IMPACT_Z = War3ID.fromString("uimz");
|
||||
|
||||
private static final War3ID DEATH_TYPE = War3ID.fromString("udea");
|
||||
private static final War3ID ARMOR_TYPE = War3ID.fromString("uarm");
|
||||
private static final War3ID DEATH_TYPE = War3ID.fromString("udea");
|
||||
private static final War3ID ARMOR_TYPE = War3ID.fromString("uarm");
|
||||
|
||||
private static final War3ID DEFENSE = War3ID.fromString("udef");
|
||||
private static final War3ID DEFENSE_TYPE = War3ID.fromString("udty");
|
||||
private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh");
|
||||
private static final War3ID MOVE_TYPE = War3ID.fromString("umvt");
|
||||
private static final War3ID COLLISION_SIZE = War3ID.fromString("ucol");
|
||||
private static final War3ID CLASSIFICATION = War3ID.fromString("utyp");
|
||||
private static final War3ID DEATH_TIME = War3ID.fromString("udtm");
|
||||
private static final War3ID TARGETED_AS = War3ID.fromString("utar");
|
||||
private static final War3ID DEFENSE = War3ID.fromString("udef");
|
||||
private static final War3ID DEFENSE_TYPE = War3ID.fromString("udty");
|
||||
private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh");
|
||||
private static final War3ID MOVE_TYPE = War3ID.fromString("umvt");
|
||||
private static final War3ID COLLISION_SIZE = War3ID.fromString("ucol");
|
||||
private static final War3ID CLASSIFICATION = War3ID.fromString("utyp");
|
||||
private static final War3ID DEATH_TIME = War3ID.fromString("udtm");
|
||||
private static final War3ID TARGETED_AS = War3ID.fromString("utar");
|
||||
|
||||
private static final War3ID ABILITIES_NORMAL = War3ID.fromString("uabi");
|
||||
private final MutableObjectData unitData;
|
||||
private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>();
|
||||
private final CAbilityData abilityData;
|
||||
private static final War3ID ABILITIES_NORMAL = War3ID.fromString("uabi");
|
||||
|
||||
public CUnitData(final MutableObjectData unitData, final CAbilityData abilityData) {
|
||||
this.unitData = unitData;
|
||||
this.abilityData = abilityData;
|
||||
}
|
||||
private static final War3ID STRUCTURES_BUILT = War3ID.fromString("ubui");
|
||||
private static final War3ID UNIT_RACE = War3ID.fromString("urac");
|
||||
|
||||
public CUnit create(final CSimulation simulation, final int playerIndex, final War3ID typeId, final float x,
|
||||
final float y, final float facing, final BufferedImage buildingPathingPixelMap,
|
||||
final SimulationRenderController simulationRenderController, final HandleIdAllocator handleIdAllocator) {
|
||||
final MutableGameObject unitType = this.unitData.get(typeId);
|
||||
final int handleId = handleIdAllocator.createId();
|
||||
final int life = unitType.getFieldAsInteger(HIT_POINT_MAXIMUM, 0);
|
||||
final int manaInitial = unitType.getFieldAsInteger(MANA_INITIAL_AMOUNT, 0);
|
||||
final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0);
|
||||
final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0);
|
||||
final int defense = unitType.getFieldAsInteger(DEFENSE, 0);
|
||||
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
|
||||
private static final War3ID GOLD_COST = War3ID.fromString("ugol");
|
||||
private static final War3ID LUMBER_COST = War3ID.fromString("ulum");
|
||||
private static final War3ID BUILD_TIME = War3ID.fromString("ubld");
|
||||
|
||||
final CUnitType unitTypeInstance = getUnitTypeInstance(typeId, buildingPathingPixelMap, unitType);
|
||||
private final MutableObjectData unitData;
|
||||
private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>();
|
||||
private final CAbilityData abilityData;
|
||||
private SimulationRenderController simulationRenderController;
|
||||
|
||||
final CUnit unit = new CUnit(handleId, playerIndex, x, y, life, typeId, facing, manaInitial, life, manaMaximum,
|
||||
speed, defense, unitTypeInstance);
|
||||
if (speed > 0) {
|
||||
unit.add(simulation, new CAbilityMove(handleIdAllocator.createId()));
|
||||
}
|
||||
if (!unitTypeInstance.getAttacks().isEmpty()) {
|
||||
unit.add(simulation, new CAbilityAttack(handleIdAllocator.createId()));
|
||||
}
|
||||
for (final String ability : abilityList.split(",")) {
|
||||
if (ability.length() > 0 && !"_".equals(ability)) {
|
||||
unit.add(simulation, this.abilityData.createAbility(ability, handleIdAllocator.createId()));
|
||||
}
|
||||
}
|
||||
return unit;
|
||||
}
|
||||
public CUnitData(final MutableObjectData unitData, final CAbilityData abilityData) {
|
||||
this.unitData = unitData;
|
||||
this.abilityData = abilityData;
|
||||
}
|
||||
|
||||
private CUnitType getUnitTypeInstance(final War3ID typeId, final BufferedImage buildingPathingPixelMap,
|
||||
final MutableGameObject unitType) {
|
||||
CUnitType unitTypeInstance = this.unitIdToUnitType.get(typeId);
|
||||
if (unitTypeInstance == null) {
|
||||
final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0);
|
||||
final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0);
|
||||
final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0);
|
||||
final boolean isBldg = unitType.getFieldAsBoolean(IS_BLDG, 0);
|
||||
final PathingGrid.MovementType movementType = PathingGrid.getMovementType(movetp);
|
||||
final String unitName = unitType.getFieldAsString(NAME, 0);
|
||||
final float acquisitionRange = unitType.getFieldAsFloat(ACQUISITION_RANGE, 0);
|
||||
final float minimumAttackRange = unitType.getFieldAsFloat(MINIMUM_ATTACK_RANGE, 0);
|
||||
final EnumSet<CTargetType> targetedAs = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(TARGETED_AS, 0));
|
||||
final String classificationString = unitType.getFieldAsString(CLASSIFICATION, 0);
|
||||
final EnumSet<CUnitClassification> classifications = EnumSet.noneOf(CUnitClassification.class);
|
||||
if (classificationString != null) {
|
||||
final String[] classificationValues = classificationString.split(",");
|
||||
for (final String unitEditorKey : classificationValues) {
|
||||
final CUnitClassification unitClassification = CUnitClassification
|
||||
.parseUnitClassification(unitEditorKey);
|
||||
if (unitClassification != null) {
|
||||
classifications.add(unitClassification);
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<CUnitAttack> attacks = new ArrayList<>();
|
||||
final int attacksEnabled = unitType.getFieldAsInteger(ATTACKS_ENABLED, 0);
|
||||
if ((attacksEnabled & 0x1) != 0) {
|
||||
try {
|
||||
// attack one
|
||||
final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK1_BACKSWING_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 areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_QUARTER_DMG,
|
||||
0);
|
||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_AREA_OF_EFFECT_TARGETS, 0));
|
||||
final CAttackType attackType = CAttackType
|
||||
.parseAttackType(unitType.getFieldAsString(ATTACK1_ATTACK_TYPE, 0));
|
||||
final float cooldownTime = unitType.getFieldAsFloat(ATTACK1_COOLDOWN, 0);
|
||||
final int damageBase = unitType.getFieldAsInteger(ATTACK1_DMG_BASE, 0);
|
||||
final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_HALF, 0);
|
||||
final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_QUARTER, 0);
|
||||
final float damageLossFactor = unitType.getFieldAsFloat(ATTACK1_DAMAGE_LOSS_FACTOR, 0);
|
||||
final int damageDice = unitType.getFieldAsInteger(ATTACK1_DMG_DICE, 0);
|
||||
final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0);
|
||||
final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_DIST, 0);
|
||||
final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_RADIUS, 0);
|
||||
final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK1_DMG_UPGRADE_AMT, 0);
|
||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK1_TARGET_COUNT, 0);
|
||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
||||
final String projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
||||
final boolean projectileHomingEnabled = unitType
|
||||
.getFieldAsBoolean(ATTACK1_PROJECTILE_HOMING_ENABLED, 0);
|
||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
||||
final int range = unitType.getFieldAsInteger(ATTACK1_RANGE, 0);
|
||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK1_RANGE_MOTION_BUFFER, 0);
|
||||
final boolean showUI = unitType.getFieldAsBoolean(ATTACK1_SHOW_UI, 0);
|
||||
final EnumSet<CTargetType> targetsAllowed = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_TARGETS_ALLOWED, 0));
|
||||
final String weaponSound = unitType.getFieldAsString(ATTACK1_WEAPON_SOUND, 0);
|
||||
final CWeaponType weaponType = CWeaponType
|
||||
.parseWeaponType(unitType.getFieldAsString(ATTACK1_WEAPON_TYPE, 0));
|
||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
} catch (final Exception exc) {
|
||||
System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
if ((attacksEnabled & 0x2) != 0) {
|
||||
try {
|
||||
// attack two
|
||||
final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK2_BACKSWING_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 areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_QUARTER_DMG,
|
||||
0);
|
||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_AREA_OF_EFFECT_TARGETS, 0));
|
||||
final CAttackType attackType = CAttackType
|
||||
.parseAttackType(unitType.getFieldAsString(ATTACK2_ATTACK_TYPE, 0));
|
||||
final float cooldownTime = unitType.getFieldAsFloat(ATTACK2_COOLDOWN, 0);
|
||||
final int damageBase = unitType.getFieldAsInteger(ATTACK2_DMG_BASE, 0);
|
||||
final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_HALF, 0);
|
||||
final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_QUARTER, 0);
|
||||
final float damageLossFactor = unitType.getFieldAsFloat(ATTACK2_DAMAGE_LOSS_FACTOR, 0);
|
||||
final int damageDice = unitType.getFieldAsInteger(ATTACK2_DMG_DICE, 0);
|
||||
final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0);
|
||||
final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_DIST, 0);
|
||||
final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_RADIUS, 0);
|
||||
final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK2_DMG_UPGRADE_AMT, 0);
|
||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK2_TARGET_COUNT, 0);
|
||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
||||
final String projectileArt = unitType.getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
||||
final boolean projectileHomingEnabled = unitType
|
||||
.getFieldAsBoolean(ATTACK2_PROJECTILE_HOMING_ENABLED, 0);
|
||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
||||
final int range = unitType.getFieldAsInteger(ATTACK2_RANGE, 0);
|
||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK2_RANGE_MOTION_BUFFER, 0);
|
||||
final boolean showUI = unitType.getFieldAsBoolean(ATTACK2_SHOW_UI, 0);
|
||||
final EnumSet<CTargetType> targetsAllowed = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_TARGETS_ALLOWED, 0));
|
||||
final String weaponSound = unitType.getFieldAsString(ATTACK2_WEAPON_SOUND, 0);
|
||||
final CWeaponType weaponType = CWeaponType
|
||||
.parseWeaponType(unitType.getFieldAsString(ATTACK2_WEAPON_TYPE, 0));
|
||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
} catch (final Exception exc) {
|
||||
System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
final int deathType = unitType.getFieldAsInteger(DEATH_TYPE, 0);
|
||||
final boolean raise = (deathType & 0x1) != 0;
|
||||
final boolean decay = (deathType & 0x2) != 0;
|
||||
final String armorType = unitType.getFieldAsString(ARMOR_TYPE, 0);
|
||||
final float impactZ = unitType.getFieldAsFloat(PROJECTILE_IMPACT_Z, 0);
|
||||
final CDefenseType defenseType = CDefenseType.parseDefenseType(unitType.getFieldAsString(DEFENSE_TYPE, 0));
|
||||
final float deathTime = unitType.getFieldAsFloat(DEATH_TIME, 0);
|
||||
unitTypeInstance = new CUnitType(unitName, isBldg, movementType, moveHeight, collisionSize, classifications,
|
||||
attacks, armorType, raise, decay, defenseType, impactZ, buildingPathingPixelMap, deathTime,
|
||||
targetedAs, acquisitionRange, minimumAttackRange);
|
||||
this.unitIdToUnitType.put(typeId, unitTypeInstance);
|
||||
}
|
||||
return unitTypeInstance;
|
||||
}
|
||||
public CUnit create(final CSimulation simulation, final int playerIndex, final War3ID typeId, final float x,
|
||||
final float y, final float facing, final BufferedImage buildingPathingPixelMap,
|
||||
final SimulationRenderController simulationRenderController, final HandleIdAllocator handleIdAllocator) {
|
||||
this.simulationRenderController = simulationRenderController;
|
||||
final MutableGameObject unitType = this.unitData.get(typeId);
|
||||
final int handleId = handleIdAllocator.createId();
|
||||
final int life = unitType.getFieldAsInteger(HIT_POINT_MAXIMUM, 0);
|
||||
final int manaInitial = unitType.getFieldAsInteger(MANA_INITIAL_AMOUNT, 0);
|
||||
final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0);
|
||||
final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0);
|
||||
final int defense = unitType.getFieldAsInteger(DEFENSE, 0);
|
||||
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
|
||||
|
||||
private CUnitAttack createAttack(final float animationBackswingPoint, final float animationDamagePoint,
|
||||
final int areaOfEffectFullDamage, final int areaOfEffectMediumDamage, final int areaOfEffectSmallDamage,
|
||||
final EnumSet<CTargetType> areaOfEffectTargets, final CAttackType attackType, final float cooldownTime,
|
||||
final int damageBase, final float damageFactorMedium, final float damageFactorSmall,
|
||||
final float damageLossFactor, final int damageDice, final int damageSidesPerDie,
|
||||
final float damageSpillDistance, final float damageSpillRadius, final int damageUpgradeAmount,
|
||||
final int maximumNumberOfTargets, final float projectileArc, final String projectileArt,
|
||||
final boolean projectileHomingEnabled, final int projectileSpeed, final int range,
|
||||
final float rangeMotionBuffer, final boolean showUI, final EnumSet<CTargetType> targetsAllowed,
|
||||
final String weaponSound, final CWeaponType weaponType) {
|
||||
final CUnitAttack attack;
|
||||
switch (weaponType) {
|
||||
case MISSILE:
|
||||
attack = new CUnitAttackMissile(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed);
|
||||
break;
|
||||
case MBOUNCE:
|
||||
attack = new CUnitAttackMissileBounce(animationBackswingPoint, animationDamagePoint, attackType,
|
||||
cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range,
|
||||
rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt,
|
||||
projectileHomingEnabled, projectileSpeed, damageLossFactor, maximumNumberOfTargets,
|
||||
areaOfEffectFullDamage, areaOfEffectTargets);
|
||||
break;
|
||||
case MSPLASH:
|
||||
case ARTILLERY:
|
||||
attack = new CUnitAttackMissileSplash(animationBackswingPoint, animationDamagePoint, attackType,
|
||||
cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range,
|
||||
rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt,
|
||||
projectileHomingEnabled, projectileSpeed, areaOfEffectFullDamage, areaOfEffectMediumDamage,
|
||||
areaOfEffectSmallDamage, areaOfEffectTargets, damageFactorMedium, damageFactorSmall);
|
||||
break;
|
||||
case MLINE:
|
||||
case ALINE:
|
||||
attack = new CUnitAttackMissileLine(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, damageSpillDistance, damageSpillRadius);
|
||||
break;
|
||||
case INSTANT:
|
||||
attack = new CUnitAttackInstant(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArt);
|
||||
break;
|
||||
default:
|
||||
case NORMAL:
|
||||
attack = new CUnitAttackNormal(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType);
|
||||
break;
|
||||
}
|
||||
return attack;
|
||||
}
|
||||
final CUnitType unitTypeInstance = getUnitTypeInstance(typeId, buildingPathingPixelMap, unitType);
|
||||
|
||||
public float getPropulsionWindow(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROPULSION_WINDOW, 0);
|
||||
}
|
||||
final CUnit unit = new CUnit(handleId, playerIndex, x, y, life, typeId, facing, manaInitial, life, manaMaximum,
|
||||
speed, defense, unitTypeInstance);
|
||||
if (speed > 0) {
|
||||
unit.add(simulation, new CAbilityMove(handleIdAllocator.createId()));
|
||||
}
|
||||
if (!unitTypeInstance.getAttacks().isEmpty()) {
|
||||
unit.add(simulation, new CAbilityAttack(handleIdAllocator.createId()));
|
||||
}
|
||||
final List<War3ID> structuresBuilt = unitTypeInstance.getStructuresBuilt();
|
||||
if (!structuresBuilt.isEmpty()) {
|
||||
switch (unitTypeInstance.getRace()) {
|
||||
case ORC:
|
||||
unit.add(simulation, new CAbilityOrcBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
case HUMAN:
|
||||
unit.add(simulation, new CAbilityHumanBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
case UNDEAD:
|
||||
unit.add(simulation, new CAbilityUndeadBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
case NIGHTELF:
|
||||
unit.add(simulation, new CAbilityNightElfBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
case NAGA:
|
||||
unit.add(simulation, new CAbilityNagaBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
case CREEPS:
|
||||
case CRITTERS:
|
||||
case DEMON:
|
||||
case OTHER:
|
||||
unit.add(simulation, new CAbilityNeutralBuild(handleIdAllocator.createId(), structuresBuilt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (final String ability : abilityList.split(",")) {
|
||||
if ((ability.length() > 0) && !"_".equals(ability)) {
|
||||
unit.add(simulation, this.abilityData.createAbility(ability, handleIdAllocator.createId()));
|
||||
}
|
||||
}
|
||||
return unit;
|
||||
}
|
||||
|
||||
public float getTurnRate(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(TURN_RATE, 0);
|
||||
}
|
||||
private CUnitType getUnitTypeInstance(final War3ID typeId, final BufferedImage buildingPathingPixelMap,
|
||||
final MutableGameObject unitType) {
|
||||
CUnitType unitTypeInstance = this.unitIdToUnitType.get(typeId);
|
||||
if (unitTypeInstance == null) {
|
||||
final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0);
|
||||
final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0);
|
||||
final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0);
|
||||
final boolean isBldg = unitType.getFieldAsBoolean(IS_BLDG, 0);
|
||||
final PathingGrid.MovementType movementType = PathingGrid.getMovementType(movetp);
|
||||
final String unitName = unitType.getFieldAsString(NAME, 0);
|
||||
final float acquisitionRange = unitType.getFieldAsFloat(ACQUISITION_RANGE, 0);
|
||||
final float minimumAttackRange = unitType.getFieldAsFloat(MINIMUM_ATTACK_RANGE, 0);
|
||||
final EnumSet<CTargetType> targetedAs = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(TARGETED_AS, 0));
|
||||
final String classificationString = unitType.getFieldAsString(CLASSIFICATION, 0);
|
||||
final EnumSet<CUnitClassification> classifications = EnumSet.noneOf(CUnitClassification.class);
|
||||
if (classificationString != null) {
|
||||
final String[] classificationValues = classificationString.split(",");
|
||||
for (final String unitEditorKey : classificationValues) {
|
||||
final CUnitClassification unitClassification = CUnitClassification
|
||||
.parseUnitClassification(unitEditorKey);
|
||||
if (unitClassification != null) {
|
||||
classifications.add(unitClassification);
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<CUnitAttack> attacks = new ArrayList<>();
|
||||
final int attacksEnabled = unitType.getFieldAsInteger(ATTACKS_ENABLED, 0);
|
||||
if ((attacksEnabled & 0x1) != 0) {
|
||||
try {
|
||||
// attack one
|
||||
final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK1_BACKSWING_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 areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_QUARTER_DMG,
|
||||
0);
|
||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_AREA_OF_EFFECT_TARGETS, 0));
|
||||
final CAttackType attackType = CAttackType
|
||||
.parseAttackType(unitType.getFieldAsString(ATTACK1_ATTACK_TYPE, 0));
|
||||
final float cooldownTime = unitType.getFieldAsFloat(ATTACK1_COOLDOWN, 0);
|
||||
final int damageBase = unitType.getFieldAsInteger(ATTACK1_DMG_BASE, 0);
|
||||
final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_HALF, 0);
|
||||
final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_QUARTER, 0);
|
||||
final float damageLossFactor = unitType.getFieldAsFloat(ATTACK1_DAMAGE_LOSS_FACTOR, 0);
|
||||
final int damageDice = unitType.getFieldAsInteger(ATTACK1_DMG_DICE, 0);
|
||||
final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0);
|
||||
final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_DIST, 0);
|
||||
final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_RADIUS, 0);
|
||||
final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK1_DMG_UPGRADE_AMT, 0);
|
||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK1_TARGET_COUNT, 0);
|
||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
||||
final String projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
||||
final boolean projectileHomingEnabled = unitType
|
||||
.getFieldAsBoolean(ATTACK1_PROJECTILE_HOMING_ENABLED, 0);
|
||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
||||
final int range = unitType.getFieldAsInteger(ATTACK1_RANGE, 0);
|
||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK1_RANGE_MOTION_BUFFER, 0);
|
||||
final boolean showUI = unitType.getFieldAsBoolean(ATTACK1_SHOW_UI, 0);
|
||||
final EnumSet<CTargetType> targetsAllowed = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_TARGETS_ALLOWED, 0));
|
||||
final String weaponSound = unitType.getFieldAsString(ATTACK1_WEAPON_SOUND, 0);
|
||||
final CWeaponType weaponType = CWeaponType
|
||||
.parseWeaponType(unitType.getFieldAsString(ATTACK1_WEAPON_TYPE, 0));
|
||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
if ((attacksEnabled & 0x2) != 0) {
|
||||
try {
|
||||
// attack two
|
||||
final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK2_BACKSWING_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 areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_HALF_DMG, 0);
|
||||
final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_QUARTER_DMG,
|
||||
0);
|
||||
final EnumSet<CTargetType> areaOfEffectTargets = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_AREA_OF_EFFECT_TARGETS, 0));
|
||||
final CAttackType attackType = CAttackType
|
||||
.parseAttackType(unitType.getFieldAsString(ATTACK2_ATTACK_TYPE, 0));
|
||||
final float cooldownTime = unitType.getFieldAsFloat(ATTACK2_COOLDOWN, 0);
|
||||
final int damageBase = unitType.getFieldAsInteger(ATTACK2_DMG_BASE, 0);
|
||||
final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_HALF, 0);
|
||||
final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_QUARTER, 0);
|
||||
final float damageLossFactor = unitType.getFieldAsFloat(ATTACK2_DAMAGE_LOSS_FACTOR, 0);
|
||||
final int damageDice = unitType.getFieldAsInteger(ATTACK2_DMG_DICE, 0);
|
||||
final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0);
|
||||
final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_DIST, 0);
|
||||
final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_RADIUS, 0);
|
||||
final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK2_DMG_UPGRADE_AMT, 0);
|
||||
final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK2_TARGET_COUNT, 0);
|
||||
final float projectileArc = unitType.getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
||||
final String projectileArt = unitType.getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
||||
final boolean projectileHomingEnabled = unitType
|
||||
.getFieldAsBoolean(ATTACK2_PROJECTILE_HOMING_ENABLED, 0);
|
||||
final int projectileSpeed = unitType.getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
||||
final int range = unitType.getFieldAsInteger(ATTACK2_RANGE, 0);
|
||||
final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK2_RANGE_MOTION_BUFFER, 0);
|
||||
final boolean showUI = unitType.getFieldAsBoolean(ATTACK2_SHOW_UI, 0);
|
||||
final EnumSet<CTargetType> targetsAllowed = CTargetType
|
||||
.parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_TARGETS_ALLOWED, 0));
|
||||
final String weaponSound = unitType.getFieldAsString(ATTACK2_WEAPON_SOUND, 0);
|
||||
final CWeaponType weaponType = CWeaponType
|
||||
.parseWeaponType(unitType.getFieldAsString(ATTACK2_WEAPON_TYPE, 0));
|
||||
attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage,
|
||||
areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType,
|
||||
cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor,
|
||||
damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount,
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
final int deathType = unitType.getFieldAsInteger(DEATH_TYPE, 0);
|
||||
final boolean raise = (deathType & 0x1) != 0;
|
||||
final boolean decay = (deathType & 0x2) != 0;
|
||||
final String armorType = unitType.getFieldAsString(ARMOR_TYPE, 0);
|
||||
final float impactZ = unitType.getFieldAsFloat(PROJECTILE_IMPACT_Z, 0);
|
||||
final CDefenseType defenseType = CDefenseType.parseDefenseType(unitType.getFieldAsString(DEFENSE_TYPE, 0));
|
||||
final float deathTime = unitType.getFieldAsFloat(DEATH_TIME, 0);
|
||||
final int goldCost = unitType.getFieldAsInteger(GOLD_COST, 0);
|
||||
final int lumberCost = unitType.getFieldAsInteger(LUMBER_COST, 0);
|
||||
final int buildTime = unitType.getFieldAsInteger(BUILD_TIME, 0);
|
||||
|
||||
public boolean isBuilding(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsBoolean(IS_BLDG, 0);
|
||||
}
|
||||
final String structuresBuiltString = unitType.getFieldAsString(STRUCTURES_BUILT, 0);
|
||||
final String[] structuresBuiltStringItems = structuresBuiltString.split(",");
|
||||
final List<War3ID> structuresBuilt = new ArrayList<>();
|
||||
for (final String structuresBuiltStringItem : structuresBuiltStringItems) {
|
||||
if (structuresBuiltStringItem.length() == 4) {
|
||||
structuresBuilt.add(War3ID.fromString(structuresBuiltStringItem));
|
||||
}
|
||||
}
|
||||
|
||||
public String getName(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getName();
|
||||
}
|
||||
final String raceString = unitType.getFieldAsString(UNIT_RACE, 0);
|
||||
final CUnitRace unitRace = CUnitRace.parseRace(raceString);
|
||||
|
||||
public int getA1MinDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0)
|
||||
+ this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0);
|
||||
}
|
||||
unitTypeInstance = new CUnitType(unitName, isBldg, movementType, moveHeight, collisionSize, classifications,
|
||||
attacks, armorType, raise, decay, defenseType, impactZ, buildingPathingPixelMap, deathTime,
|
||||
targetedAs, acquisitionRange, minimumAttackRange, structuresBuilt, unitRace, goldCost, lumberCost,
|
||||
buildTime);
|
||||
this.unitIdToUnitType.put(typeId, unitTypeInstance);
|
||||
}
|
||||
return unitTypeInstance;
|
||||
}
|
||||
|
||||
public int getA1MaxDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0)
|
||||
+ (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0)
|
||||
* this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0));
|
||||
}
|
||||
private CUnitAttack createAttack(final float animationBackswingPoint, final float animationDamagePoint,
|
||||
final int areaOfEffectFullDamage, final int areaOfEffectMediumDamage, final int areaOfEffectSmallDamage,
|
||||
final EnumSet<CTargetType> areaOfEffectTargets, final CAttackType attackType, final float cooldownTime,
|
||||
final int damageBase, final float damageFactorMedium, final float damageFactorSmall,
|
||||
final float damageLossFactor, final int damageDice, final int damageSidesPerDie,
|
||||
final float damageSpillDistance, final float damageSpillRadius, final int damageUpgradeAmount,
|
||||
final int maximumNumberOfTargets, final float projectileArc, final String projectileArt,
|
||||
final boolean projectileHomingEnabled, final int projectileSpeed, final int range,
|
||||
final float rangeMotionBuffer, final boolean showUI, final EnumSet<CTargetType> targetsAllowed,
|
||||
final String weaponSound, final CWeaponType weaponType) {
|
||||
final CUnitAttack attack;
|
||||
switch (weaponType) {
|
||||
case MISSILE:
|
||||
attack = new CUnitAttackMissile(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed);
|
||||
break;
|
||||
case MBOUNCE:
|
||||
attack = new CUnitAttackMissileBounce(animationBackswingPoint, animationDamagePoint, attackType,
|
||||
cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range,
|
||||
rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt,
|
||||
projectileHomingEnabled, projectileSpeed, damageLossFactor, maximumNumberOfTargets,
|
||||
areaOfEffectFullDamage, areaOfEffectTargets);
|
||||
break;
|
||||
case MSPLASH:
|
||||
case ARTILLERY:
|
||||
attack = new CUnitAttackMissileSplash(animationBackswingPoint, animationDamagePoint, attackType,
|
||||
cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range,
|
||||
rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt,
|
||||
projectileHomingEnabled, projectileSpeed, areaOfEffectFullDamage, areaOfEffectMediumDamage,
|
||||
areaOfEffectSmallDamage, areaOfEffectTargets, damageFactorMedium, damageFactorSmall);
|
||||
break;
|
||||
case MLINE:
|
||||
case ALINE:
|
||||
attack = new CUnitAttackMissileLine(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, damageSpillDistance, damageSpillRadius);
|
||||
break;
|
||||
case INSTANT:
|
||||
attack = new CUnitAttackInstant(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType, projectileArt);
|
||||
break;
|
||||
default:
|
||||
case NORMAL:
|
||||
attack = new CUnitAttackNormal(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime,
|
||||
damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI,
|
||||
targetsAllowed, weaponSound, weaponType);
|
||||
break;
|
||||
}
|
||||
return attack;
|
||||
}
|
||||
|
||||
public int getA2MinDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0)
|
||||
+ this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0);
|
||||
}
|
||||
public float getPropulsionWindow(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROPULSION_WINDOW, 0);
|
||||
}
|
||||
|
||||
public int getA2MaxDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0)
|
||||
+ (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0)
|
||||
* this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0));
|
||||
}
|
||||
public float getTurnRate(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(TURN_RATE, 0);
|
||||
}
|
||||
|
||||
public int getDefense(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(DEFENSE, 0);
|
||||
}
|
||||
public boolean isBuilding(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsBoolean(IS_BLDG, 0);
|
||||
}
|
||||
|
||||
public int getA1ProjectileSpeed(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
||||
}
|
||||
public String getName(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getName();
|
||||
}
|
||||
|
||||
public float getA1ProjectileArc(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
||||
}
|
||||
public int getA1MinDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0)
|
||||
+ this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0);
|
||||
}
|
||||
|
||||
public int getA2ProjectileSpeed(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
||||
}
|
||||
public int getA1MaxDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0)
|
||||
+ (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0)
|
||||
* this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0));
|
||||
}
|
||||
|
||||
public float getA2ProjectileArc(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
||||
}
|
||||
public int getA2MinDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0)
|
||||
+ this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0);
|
||||
}
|
||||
|
||||
public String getA1MissileArt(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
||||
}
|
||||
public int getA2MaxDamage(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0)
|
||||
+ (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0)
|
||||
* this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0));
|
||||
}
|
||||
|
||||
public String getA2MissileArt(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
||||
}
|
||||
public int getDefense(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(DEFENSE, 0);
|
||||
}
|
||||
|
||||
public float getA1Cooldown(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_COOLDOWN, 0);
|
||||
}
|
||||
public int getA1ProjectileSpeed(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0);
|
||||
}
|
||||
|
||||
public float getA2Cooldown(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_COOLDOWN, 0);
|
||||
}
|
||||
public float getA1ProjectileArc(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchX(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_X, 0);
|
||||
}
|
||||
public int getA2ProjectileSpeed(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchY(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Y, 0);
|
||||
}
|
||||
public float getA2ProjectileArc(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchZ(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Z, 0);
|
||||
}
|
||||
public String getA1MissileArt(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsString(ATTACK1_MISSILE_ART, 0);
|
||||
}
|
||||
|
||||
public String getA2MissileArt(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsString(ATTACK2_MISSILE_ART, 0);
|
||||
}
|
||||
|
||||
public float getA1Cooldown(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_COOLDOWN, 0);
|
||||
}
|
||||
|
||||
public float getA2Cooldown(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_COOLDOWN, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchX(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_X, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchY(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Y, 0);
|
||||
}
|
||||
|
||||
public float getProjectileLaunchZ(final War3ID unitTypeId) {
|
||||
return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Z, 0);
|
||||
}
|
||||
|
||||
public CUnitType getUnitType(final War3ID rawcode) {
|
||||
final CUnitType unitTypeInstance = this.unitIdToUnitType.get(rawcode);
|
||||
if (unitTypeInstance != null) {
|
||||
return unitTypeInstance;
|
||||
}
|
||||
final MutableGameObject unitType = this.unitData.get(rawcode);
|
||||
if (unitType == null) {
|
||||
return null;
|
||||
}
|
||||
final BufferedImage buildingPathingPixelMap = this.simulationRenderController
|
||||
.getBuildingPathingPixelMap(rawcode);
|
||||
return getUnitTypeInstance(rawcode, buildingPathingPixelMap, unitType);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum CUnitRace {
|
||||
HUMAN,
|
||||
ORC,
|
||||
UNDEAD,
|
||||
NIGHTELF,
|
||||
NAGA,
|
||||
CREEPS,
|
||||
DEMON,
|
||||
CRITTERS,
|
||||
OTHER;
|
||||
|
||||
private static Map<String, CUnitRace> keyToRace = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (final CUnitRace race : CUnitRace.values()) {
|
||||
keyToRace.put(race.name(), race);
|
||||
}
|
||||
}
|
||||
|
||||
public static CUnitRace parseRace(final String raceString) {
|
||||
final CUnitRace race = keyToRace.get(raceString.toUpperCase());
|
||||
if (race == null) {
|
||||
return OTHER;
|
||||
}
|
||||
return race;
|
||||
}
|
||||
}
|
@ -27,6 +27,10 @@ public class COrderNoTarget implements COrder {
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster) {
|
||||
final CAbility ability = game.getAbility(this.abilityHandleId);
|
||||
if ((ability == null) && (this.orderId == OrderIds.stop)) {
|
||||
// stop
|
||||
return caster.getStopBehavior();
|
||||
}
|
||||
return ability.beginNoTarget(game, caster, this.orderId);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||
public interface AbilityActivationReceiver {
|
||||
void useOk();
|
||||
|
||||
void notEnoughResources(ResourceType resource, int amount);
|
||||
void notEnoughResources(ResourceType resource);
|
||||
|
||||
void notAnActiveAbility();
|
||||
|
||||
|
@ -10,7 +10,7 @@ public class BooleanAbilityActivationReceiver implements AbilityActivationReceiv
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notEnoughResources(final ResourceType resource, final int amount) {
|
||||
public void notEnoughResources(final ResourceType resource) {
|
||||
this.ok = false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
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;
|
||||
@ -16,4 +19,6 @@ public interface SimulationRenderController {
|
||||
void spawnUnitDamageSound(CUnit damagedUnit, final String weaponSound, String armorType);
|
||||
|
||||
void removeUnit(CUnit unit);
|
||||
|
||||
BufferedImage getBuildingPathingPixelMap(War3ID rawcode);
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ public class StringMsgAbilityActivationReceiver implements AbilityActivationRece
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notEnoughResources(final ResourceType resource, final int amount) {
|
||||
this.message = "NOTEXTERN: Requires " + amount + " " + resource.name().toLowerCase() + ".";
|
||||
public void notEnoughResources(final ResourceType resource) {
|
||||
this.message = "NOTEXTERN: Requires more " + resource.name().toLowerCase() + ".";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.AbstractRenderableFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.TextureFrame;
|
||||
@ -26,6 +27,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
private int autoCastOrderId;
|
||||
private boolean autoCastActive;
|
||||
private final CommandCardCommandListener commandCardCommandListener;
|
||||
private boolean menuButton;
|
||||
|
||||
public CommandCardIcon(final String name, final UIFrame parent,
|
||||
final CommandCardCommandListener commandCardCommandListener) {
|
||||
@ -70,7 +72,8 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
}
|
||||
|
||||
public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId,
|
||||
final int autoCastOrderId, final boolean active, final boolean autoCastActive) {
|
||||
final int autoCastOrderId, final boolean active, final boolean autoCastActive, final boolean menuButton) {
|
||||
this.menuButton = menuButton;
|
||||
this.iconFrame.setVisible(true);
|
||||
this.activeHighlightFrame.setVisible(active);
|
||||
this.cooldownFrame.setVisible(false);
|
||||
@ -111,14 +114,46 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
@Override
|
||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||
if (this.renderBounds.contains(screenX, screenY)) {
|
||||
if (button == Input.Buttons.LEFT) {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
||||
}
|
||||
else if (button == Input.Buttons.RIGHT) {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.autoCastOrderId);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
if (this.renderBounds.contains(screenX, screenY)) {
|
||||
return this;
|
||||
}
|
||||
return super.touchUp(screenX, screenY, button);
|
||||
}
|
||||
|
||||
public boolean isMenuButton() {
|
||||
return this.menuButton;
|
||||
}
|
||||
|
||||
public void onClick(final int button) {
|
||||
if (button == Input.Buttons.LEFT) {
|
||||
if (this.menuButton) {
|
||||
this.commandCardCommandListener.openMenu(this.orderId);
|
||||
}
|
||||
else {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
||||
}
|
||||
}
|
||||
else if (button == Input.Buttons.RIGHT) {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.autoCastOrderId);
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseDown(final Viewport uiViewport) {
|
||||
this.iconFrame.setWidth(GameUI.convertX(uiViewport, MeleeUI.DEFAULT_COMMAND_CARD_ICON_PRESSED_WIDTH));
|
||||
this.iconFrame.setHeight(GameUI.convertY(uiViewport, MeleeUI.DEFAULT_COMMAND_CARD_ICON_PRESSED_WIDTH));
|
||||
positionBounds(uiViewport);
|
||||
}
|
||||
|
||||
public void mouseUp(final Viewport uiViewport) {
|
||||
this.iconFrame.setWidth(GameUI.convertX(uiViewport, MeleeUI.DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
this.iconFrame.setHeight(GameUI.convertY(uiViewport, MeleeUI.DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
positionBounds(uiViewport);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@ -38,6 +39,7 @@ import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.ReplaceableIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
||||
import com.etheller.warsmash.viewer5.handlers.tga.TgaFile;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||
@ -46,6 +48,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.GameCameraManager;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButtonListener;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
|
||||
@ -69,6 +73,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbili
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandCardCommandListener;
|
||||
|
||||
public class MeleeUI implements CUnitStateListener, CommandButtonListener, CommandCardCommandListener {
|
||||
public static final float DEFAULT_COMMAND_CARD_ICON_WIDTH = 0.039f;
|
||||
public static final float DEFAULT_COMMAND_CARD_ICON_PRESSED_WIDTH = 0.037f;
|
||||
private static final int COMMAND_CARD_WIDTH = 4;
|
||||
private static final int COMMAND_CARD_HEIGHT = 3;
|
||||
|
||||
@ -120,6 +126,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
private final CommandCardIcon[][] commandCard = new CommandCardIcon[COMMAND_CARD_HEIGHT][COMMAND_CARD_WIDTH];
|
||||
|
||||
private RenderUnit selectedUnit;
|
||||
private final List<Integer> subMenuOrderIdStack = new ArrayList<>();
|
||||
|
||||
// TODO remove this & replace with FDF
|
||||
private final Texture activeButtonTexture;
|
||||
@ -140,6 +147,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
// probably remove them later
|
||||
private final float widthRatioCorrection;
|
||||
private final float heightRatioCorrection;
|
||||
private CommandCardIcon mouseDownUIFrame;
|
||||
|
||||
public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport,
|
||||
final FreeTypeFontGenerator fontGenerator, final Scene uiScene, final Scene portraitScene,
|
||||
@ -325,25 +333,25 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
commandCardIcon.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT,
|
||||
GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)),
|
||||
GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j))));
|
||||
commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||
commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||
commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
iconFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||
iconFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||
iconFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||
iconFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
iconFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
iconFrame.setTexture(ImageUtils.DEFAULT_ICON_PATH, this.rootFrame);
|
||||
activeHighlightFrame
|
||||
.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||
activeHighlightFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||
activeHighlightFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||
activeHighlightFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
activeHighlightFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
activeHighlightFrame.setTexture("CommandButtonActiveHighlight", this.rootFrame);
|
||||
cooldownFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||
this.rootFrame.setSpriteFrameModel(cooldownFrame, this.rootFrame.getSkinField("CommandButtonCooldown"));
|
||||
cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||
cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||
cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
autocastFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||
this.rootFrame.setSpriteFrameModel(autocastFrame, this.rootFrame.getSkinField("CommandButtonAutocast"));
|
||||
autocastFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||
autocastFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||
autocastFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
autocastFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
|
||||
commandCardIcon.set(iconFrame, activeHighlightFrame, cooldownFrame, autocastFrame);
|
||||
this.commandCard[j][i] = commandCardIcon;
|
||||
commandCardIcon.setCommandButton(null);
|
||||
@ -395,9 +403,20 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.activeCommand = abilityToUse;
|
||||
this.activeCommandOrderId = orderId;
|
||||
this.activeCommandUnit = this.selectedUnit;
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(),
|
||||
abilityHandleId, orderId, isShiftDown());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openMenu(final int orderId) {
|
||||
this.subMenuOrderIdStack.add(orderId);
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
|
||||
public void showCommandError(final String message) {
|
||||
@ -515,12 +534,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.portraitCameraManager.updateCamera();
|
||||
if ((this.modelInstance != null)
|
||||
&& (this.modelInstance.sequenceEnded || (this.modelInstance.sequence == -1))) {
|
||||
SequenceUtils.randomPortraitSequence(this.modelInstance);
|
||||
SequenceUtils.randomSequence(this.modelInstance, PrimaryTag.PORTRAIT, SequenceUtils.EMPTY, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void talk() {
|
||||
SequenceUtils.randomPortraitTalkSequence(this.modelInstance);
|
||||
SequenceUtils.randomSequence(this.modelInstance, PrimaryTag.PORTRAIT, SequenceUtils.TALK, true);
|
||||
}
|
||||
|
||||
public void setSelectedUnit(final RenderUnit unit) {
|
||||
@ -539,7 +558,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
this.modelInstance = (MdxComplexInstance) portraitModel.addInstance();
|
||||
this.portraitCameraManager.setModelInstance(this.modelInstance, portraitModel);
|
||||
this.modelInstance.setSequenceLoopMode(SequenceLoopMode.MODEL_LOOP);
|
||||
this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP);
|
||||
this.modelInstance.setScene(this.portraitScene);
|
||||
this.modelInstance.setVertexColor(unit.instance.vertexColor);
|
||||
this.modelInstance.setTeamColor(unit.playerIndex);
|
||||
@ -549,6 +568,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
|
||||
public void selectUnit(RenderUnit unit) {
|
||||
this.subMenuOrderIdStack.clear();
|
||||
if ((unit != null) && unit.getSimulationUnit().isDead()) {
|
||||
unit = null;
|
||||
}
|
||||
@ -645,7 +665,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
localArmorIconBackdrop.setTexture(defenseTexture);
|
||||
localArmorInfoPanelIconValue.setText(Integer.toString(unit.getSimulationUnit().getDefense()));
|
||||
unit.populateCommandCard(this.war3MapViewer.simulation, this, this.war3MapViewer.getAbilityDataUI());
|
||||
unit.populateCommandCard(this.war3MapViewer.simulation, this, this.war3MapViewer.getAbilityDataUI(),
|
||||
getSubMenuOrderId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -660,10 +681,11 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
@Override
|
||||
public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon,
|
||||
final int abilityHandleId, final int orderId, final int autoCastId, final boolean active,
|
||||
final boolean autoCastActive) {
|
||||
final boolean autoCastActive, final boolean menuButton) {
|
||||
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));
|
||||
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active, autoCastActive);
|
||||
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active, autoCastActive,
|
||||
menuButton);
|
||||
}
|
||||
|
||||
public void resize(final Rectangle viewport) {
|
||||
@ -755,9 +777,34 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
|
||||
@Override
|
||||
public void ordersChanged(final int abilityHandleId, final int orderId) {
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
|
||||
private void clearAndRepopulateCommandCard() {
|
||||
clearCommandCard();
|
||||
this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this,
|
||||
this.war3MapViewer.getAbilityDataUI());
|
||||
final AbilityDataUI abilityDataUI = this.war3MapViewer.getAbilityDataUI();
|
||||
final int menuOrderId = getSubMenuOrderId();
|
||||
if (this.activeCommand != null) {
|
||||
final IconUI cancelUI = abilityDataUI.getCancelUI();
|
||||
this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0,
|
||||
menuOrderId, 0, false, false, true);
|
||||
}
|
||||
else {
|
||||
if (menuOrderId != 0) {
|
||||
final int exitOrderId = this.subMenuOrderIdStack.size() > 1
|
||||
? this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 2)
|
||||
: 0;
|
||||
final IconUI cancelUI = abilityDataUI.getCancelUI();
|
||||
this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0,
|
||||
exitOrderId, 0, false, false, true);
|
||||
}
|
||||
this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this, abilityDataUI, menuOrderId);
|
||||
}
|
||||
}
|
||||
|
||||
private int getSubMenuOrderId() {
|
||||
return this.subMenuOrderIdStack.isEmpty() ? 0
|
||||
: this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 1);
|
||||
}
|
||||
|
||||
public RenderUnit getSelectedUnit() {
|
||||
@ -794,6 +841,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.activeCommandUnit = null;
|
||||
this.activeCommand = null;
|
||||
this.activeCommandOrderId = -1;
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
else {
|
||||
final RenderUnit rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY,
|
||||
@ -813,6 +861,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.activeCommandUnit = null;
|
||||
this.activeCommand = null;
|
||||
this.activeCommandOrderId = -1;
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -843,6 +892,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.activeCommandUnit = null;
|
||||
this.activeCommand = null;
|
||||
this.activeCommandOrderId = -1;
|
||||
clearAndRepopulateCommandCard();
|
||||
}
|
||||
|
||||
}
|
||||
@ -957,6 +1007,27 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (clickedUIFrame instanceof CommandCardIcon) {
|
||||
this.mouseDownUIFrame = (CommandCardIcon) clickedUIFrame;
|
||||
this.mouseDownUIFrame.mouseDown(this.uiViewport);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean touchUp(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
||||
screenCoordsVector.set(screenX, screenY);
|
||||
this.uiViewport.unproject(screenCoordsVector);
|
||||
final UIFrame clickedUIFrame = this.rootFrame.touchUp(screenCoordsVector.x, screenCoordsVector.y, button);
|
||||
if (this.mouseDownUIFrame != null) {
|
||||
if (clickedUIFrame == this.mouseDownUIFrame) {
|
||||
this.mouseDownUIFrame.onClick(button);
|
||||
this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0);
|
||||
}
|
||||
this.mouseDownUIFrame.mouseUp(this.uiViewport);
|
||||
}
|
||||
this.mouseDownUIFrame = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2,4 +2,6 @@ package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
||||
|
||||
public interface CommandCardCommandListener {
|
||||
void startUsingAbility(int abilityHandleId, int orderId);
|
||||
|
||||
void openMenu(int orderId);
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui.sound;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.etheller.warsmash.datasources.DataSource;
|
||||
import com.etheller.warsmash.units.DataTable;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound;
|
||||
|
||||
public class KeyedSounds {
|
||||
private final DataTable uiSoundsTable;
|
||||
private final DataSource dataSource;
|
||||
private final Map<String, UnitSound> keyToSound;
|
||||
|
||||
public KeyedSounds(final DataTable uiSoundsTable, final DataSource dataSource) {
|
||||
this.uiSoundsTable = uiSoundsTable;
|
||||
this.dataSource = dataSource;
|
||||
this.keyToSound = new HashMap<>();
|
||||
}
|
||||
|
||||
public UnitSound getSound(final String key) {
|
||||
UnitSound sound = this.keyToSound.get(key);
|
||||
if (sound == null) {
|
||||
sound = UnitSound.create(this.dataSource, this.uiSoundsTable, key, "");
|
||||
this.keyToSound.put(key, sound);
|
||||
}
|
||||
return sound;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user