mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Highlight proper movement icons, improve sequence filter
This commit is contained in:
parent
fa94450d54
commit
238015f21d
@ -0,0 +1,41 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class SecondaryTagSequenceComparator implements Comparator<IndexedSequence> {
|
||||
private final StandSequenceComparator standSequenceComparator;
|
||||
private EnumSet<AnimationTokens.SecondaryTag> ignoredTags;
|
||||
|
||||
public SecondaryTagSequenceComparator(StandSequenceComparator standSequenceComparator) {
|
||||
this.standSequenceComparator = standSequenceComparator;
|
||||
}
|
||||
|
||||
public SecondaryTagSequenceComparator reset(EnumSet<AnimationTokens.SecondaryTag> ignoredTags) {
|
||||
this.ignoredTags = ignoredTags;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(final IndexedSequence a, final IndexedSequence b) {
|
||||
EnumSet<AnimationTokens.SecondaryTag> secondaryTagsA = a.sequence.getSecondaryTags();
|
||||
EnumSet<AnimationTokens.SecondaryTag> secondaryTagsB = b.sequence.getSecondaryTags();
|
||||
int secondaryTagsAOrdinal = getTagsOrdinal(secondaryTagsA, ignoredTags);
|
||||
int secondaryTagsBOrdinal = getTagsOrdinal(secondaryTagsB, ignoredTags);
|
||||
if (secondaryTagsAOrdinal != secondaryTagsBOrdinal) {
|
||||
return secondaryTagsBOrdinal - secondaryTagsAOrdinal;
|
||||
}
|
||||
return standSequenceComparator.compare(a, b);
|
||||
}
|
||||
|
||||
public static int getTagsOrdinal(EnumSet<AnimationTokens.SecondaryTag> secondaryTagsA, EnumSet<AnimationTokens.SecondaryTag> ignoredTags) {
|
||||
int secondaryTagsBOrdinal = Integer.MAX_VALUE;
|
||||
for (AnimationTokens.SecondaryTag secondaryTag : secondaryTagsA) {
|
||||
if (secondaryTag.ordinal() < secondaryTagsBOrdinal && !ignoredTags.contains(secondaryTag)) {
|
||||
secondaryTagsBOrdinal = secondaryTag.ordinal();
|
||||
}
|
||||
}
|
||||
return secondaryTagsBOrdinal;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
@ -17,6 +18,7 @@ public class SequenceUtils {
|
||||
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);
|
||||
|
||||
public static List<IndexedSequence> filterSequences(final String type, final List<Sequence> sequences) {
|
||||
final List<IndexedSequence> filtered = new ArrayList<>();
|
||||
@ -39,24 +41,11 @@ public class SequenceUtils {
|
||||
|
||||
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())) {
|
||||
for (final AnimationTokens.SecondaryTag secondaryTag : sequence.getSecondaryTags()) {
|
||||
if (tags.contains(secondaryTag)) {
|
||||
if (sequence.getPrimaryTags().contains(type) && (sequence.getSecondaryTags().containsAll(tags)
|
||||
&& tags.containsAll(sequence.getSecondaryTags()))) {
|
||||
filtered.add(new IndexedSequence(sequence, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filtered.isEmpty()) {
|
||||
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;
|
||||
}
|
||||
@ -94,9 +83,32 @@ public class SequenceUtils {
|
||||
public static IndexedSequence selectSequence(final AnimationTokens.PrimaryTag type,
|
||||
final EnumSet<AnimationTokens.SecondaryTag> tags, final List<Sequence> sequences,
|
||||
final boolean allowRarityVariations) {
|
||||
final List<IndexedSequence> filtered = filterSequences(type, tags, sequences);
|
||||
List<IndexedSequence> filtered = filterSequences(type, tags, sequences);
|
||||
Comparator<IndexedSequence> sequenceComparator = STAND_SEQUENCE_COMPARATOR;
|
||||
|
||||
filtered.sort(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);
|
||||
}
|
||||
}
|
||||
|
||||
filtered.sort(sequenceComparator);
|
||||
|
||||
int i = 0;
|
||||
final double randomRoll = Math.random() * 100;
|
||||
@ -130,8 +142,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
@ -143,8 +154,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
target.setSequence(0);
|
||||
}
|
||||
}
|
||||
@ -156,8 +166,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
@ -169,8 +178,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
@ -182,8 +190,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
randomStandSequence(target);
|
||||
}
|
||||
}
|
||||
@ -195,8 +202,7 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
randomPortraitSequence(target);
|
||||
}
|
||||
}
|
||||
@ -208,12 +214,26 @@ public class SequenceUtils {
|
||||
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
}
|
||||
else {
|
||||
} 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);
|
||||
|
||||
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;
|
||||
@ -224,11 +244,7 @@ public class SequenceUtils {
|
||||
if (sequence != null) {
|
||||
target.setSequence(sequence.index);
|
||||
return sequence.sequence;
|
||||
}
|
||||
else {
|
||||
if (!secondaryAnimationTags.isEmpty()) {
|
||||
return randomSequence(target, animationName, EMPTY, allowRarityVariations);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -314,8 +314,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
final LoadGenericCallback callback) {
|
||||
if (this.mapMpq == null) {
|
||||
return loadGeneric(path, dataType, callback);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return loadGeneric(path, dataType, callback, this.dataSource);
|
||||
}
|
||||
}
|
||||
@ -346,22 +345,19 @@ public class War3MapViewer extends ModelViewer {
|
||||
tilesetSource = new CompoundDataSource(Arrays.asList(compoundDataSource,
|
||||
new SubdirDataSource(compoundDataSource, tileset + ".mpq/"),
|
||||
new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/")));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final byte[] mapData = IOUtils.toByteArray(mapStream);
|
||||
sbc = new SeekableInMemoryByteChannel(mapData);
|
||||
final DataSource internalMpqContentsDataSource = new MpqDataSource(new MPQArchive(sbc), sbc);
|
||||
tilesetSource = new CompoundDataSource(
|
||||
Arrays.asList(compoundDataSource, internalMpqContentsDataSource));
|
||||
}
|
||||
}
|
||||
catch (final IOException exc) {
|
||||
} catch (final IOException exc) {
|
||||
tilesetSource = new CompoundDataSource(
|
||||
Arrays.asList(compoundDataSource, new SubdirDataSource(compoundDataSource, tileset + ".mpq/"),
|
||||
new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/")));
|
||||
}
|
||||
}
|
||||
catch (final MPQException e) {
|
||||
} catch (final MPQException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
setDataSource(tilesetSource);
|
||||
@ -435,8 +431,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
modelInstance.setScene(War3MapViewer.this.worldScene);
|
||||
if (bounceIndex == 0) {
|
||||
SequenceUtils.randomBirthSequence(modelInstance);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SequenceUtils.randomStandSequence(modelInstance);
|
||||
}
|
||||
modelInstance.setLocation(x, y, height);
|
||||
@ -510,8 +505,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
this.walkableObjectsTree = new Quadtree<>(this.terrain.getEntireMap());
|
||||
if (this.doodadsAndDestructiblesLoaded) {
|
||||
this.loadDoodadsAndDestructibles(this.allObjectData);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw new IllegalStateException("transcription of JS has not loaded a map and has no JS async promises");
|
||||
}
|
||||
|
||||
@ -532,8 +526,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
public void loadAfterUI() throws IOException {
|
||||
if (this.unitsAndItemsLoaded) {
|
||||
this.loadUnitsAndItems(this.allObjectData);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw new IllegalStateException("transcription of JS has not loaded a map and has no JS async promises");
|
||||
}
|
||||
|
||||
@ -603,8 +596,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
bufferedImage = TgaFile.readTGA(pathingTexture,
|
||||
this.mapMpq.getResourceAsStream(pathingTexture));
|
||||
this.filePathToPathingMap.put(pathingTexture.toLowerCase(), bufferedImage);
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
} catch (final Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -622,15 +614,13 @@ public class War3MapViewer extends ModelViewer {
|
||||
String path;
|
||||
if (this.mapMpq.has(fileVar)) {
|
||||
path = fileVar;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
path = file;
|
||||
}
|
||||
MdxModel model;
|
||||
if (this.mapMpq.has(path)) {
|
||||
model = (MdxModel) this.load(path, this.mapPathSolver, this.solverParams);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
model = (MdxModel) this.load(fileVar, this.mapPathSolver, this.solverParams);
|
||||
}
|
||||
|
||||
@ -649,8 +639,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
renderDestructableBounds);
|
||||
}
|
||||
this.doodads.add(renderDestructable);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.doodads.add(new RenderDoodad(this, model, row, doodad, type, maxPitch, maxRoll));
|
||||
}
|
||||
}
|
||||
@ -683,14 +672,12 @@ public class War3MapViewer extends ModelViewer {
|
||||
pathingTextureImage = TgaFile.readTGA(pathingTexture,
|
||||
this.mapMpq.getResourceAsStream(pathingTexture));
|
||||
this.filePathToPathingMap.put(pathingTexture.toLowerCase(), pathingTextureImage);
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
} catch (final Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pathingTextureImage = null;
|
||||
}
|
||||
if (pathingTextureImage != null) {
|
||||
@ -748,8 +735,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
// path = "Objects\\StartLocation\\StartLocation.mdx";
|
||||
type = null; /// ??????
|
||||
this.startLocations[unit.getPlayer()] = new Vector2(unit.getLocation()[0], unit.getLocation()[1]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
row = modifications.getUnits().get(unit.getId());
|
||||
if (row == null) {
|
||||
row = modifications.getItems().get(unit.getId());
|
||||
@ -782,8 +768,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
|
||||
path += ".mdx";
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
type = WorldEditorDataType.UNITS;
|
||||
path = row.getFieldAsString(UNIT_FILE, 0);
|
||||
|
||||
@ -845,8 +830,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
if (pathingTexture.toLowerCase().endsWith(".tga")) {
|
||||
buildingPathingPixelMap = TgaFile.readTGA(pathingTexture,
|
||||
this.mapMpq.getResourceAsStream(pathingTexture));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
try (InputStream stream = this.mapMpq.getResourceAsStream(pathingTexture)) {
|
||||
buildingPathingPixelMap = ImageIO.read(stream);
|
||||
System.out.println("LOADING BLP PATHING: " + pathingTexture);
|
||||
@ -875,8 +859,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
final String portraitPath = path.substring(0, path.length() - 4) + "_portrait.mdx";
|
||||
if (this.dataSource.has(portraitPath)) {
|
||||
portraitModel = (MdxModel) this.load(portraitPath, this.mapPathSolver, this.solverParams);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
portraitModel = model;
|
||||
}
|
||||
if (type == WorldEditorDataType.UNITS) {
|
||||
@ -896,8 +879,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.items.add(new RenderItem(this, model, row, unit, soundset, portraitModel)); // TODO store
|
||||
// somewhere
|
||||
if (unitShadowSplat != null) {
|
||||
@ -909,8 +891,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
System.err.println("Unknown unit ID: " + unit.getId());
|
||||
}
|
||||
}
|
||||
@ -960,13 +941,14 @@ public class War3MapViewer extends ModelViewer {
|
||||
final ModelInstance instance = item.instance;
|
||||
if (instance instanceof MdxComplexInstance) {
|
||||
final MdxComplexInstance mdxComplexInstance = (MdxComplexInstance) instance;
|
||||
if ((mdxComplexInstance.sequence == -1)
|
||||
|| (mdxComplexInstance.sequenceEnded/*
|
||||
* && (((MdxModel) mdxComplexInstance.model).sequences
|
||||
* .get(mdxComplexInstance.sequence).getFlags() == 0)
|
||||
*/)) {
|
||||
if (mdxComplexInstance.sequence == -1 ||
|
||||
(mdxComplexInstance.sequenceEnded && (item.getAnimation() != AnimationTokens.PrimaryTag.DEATH ||
|
||||
(((MdxModel) mdxComplexInstance.model).sequences
|
||||
.get(mdxComplexInstance.sequence).getFlags() == 0)
|
||||
))) {
|
||||
SequenceUtils.randomSequence(mdxComplexInstance, item.getAnimation(), SequenceUtils.EMPTY,
|
||||
true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1100,8 +1082,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
this.walkableObjectsTree.intersect(rectangleHeap, this.walkablesIntersectionFinder.reset(gdxRayHeap));
|
||||
if (this.walkablesIntersectionFinder.found) {
|
||||
out.set(this.walkablesIntersectionFinder.intersection);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
out.z = Math.max(getWalkableRenderHeight(out.x, out.y), this.terrain.getGroundHeight(out.x, out.y));
|
||||
}
|
||||
}
|
||||
@ -1143,16 +1124,13 @@ public class War3MapViewer extends ModelViewer {
|
||||
final int idx = sel.indexOf(entity);
|
||||
if (idx >= 0) {
|
||||
sel.remove(idx);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sel.add(entity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sel = Arrays.asList(entity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sel = Collections.emptyList();
|
||||
}
|
||||
this.doSelectUnit(sel);
|
||||
@ -1195,11 +1173,9 @@ public class War3MapViewer extends ModelViewer {
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
catch (final UnsupportedEncodingException e) {
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new MappedData(stringBuilder.toString());
|
||||
@ -1219,11 +1195,9 @@ public class War3MapViewer extends ModelViewer {
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
catch (final UnsupportedEncodingException e) {
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
@ -1319,8 +1293,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
public SceneLightManager createLightManager(final boolean simple) {
|
||||
if (simple) {
|
||||
return new W3xScenePortraitLightManager(this, this.lightDirection);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new W3xSceneWorldLightManager(this);
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class TerrainShaders {
|
||||
" vec3 terrain_normal = normalize(vNormal);//vec3(hL - hR, hD - hU, 2.0)+vNormal);\r\n" + //
|
||||
"\r\n" + //
|
||||
" Normal = terrain_normal;\r\n" + //
|
||||
Shaders.lightSystem("Normal", "myposition.xyz", "lightTexture", "lightTextureHeight", "lightCount",
|
||||
Shaders.lightSystem("terrain_normal", "myposition.xyz", "lightTexture", "lightTextureHeight", "lightCount",
|
||||
true)
|
||||
+ "\r\n" + //
|
||||
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||
|
@ -194,9 +194,6 @@ public class RenderUnit {
|
||||
}
|
||||
else {
|
||||
currentWalkableUnder = map.getHighestWalkableUnder(x, y);
|
||||
if (currentWalkableUnder != null) {
|
||||
System.out.println("WALKABLE UNDER");
|
||||
}
|
||||
War3MapViewer.gdxRayHeap.set(x, y, 4096, 0, 0, -8192);
|
||||
if ((currentWalkableUnder != null)
|
||||
&& currentWalkableUnder.intersectRayWithCollision(War3MapViewer.gdxRayHeap,
|
||||
|
@ -68,8 +68,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
|
||||
int autoCastId;
|
||||
if (autoCastActive) {
|
||||
autoCastId = OrderIds.coldarrows;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
autoCastId = OrderIds.uncoldarrows;
|
||||
}
|
||||
addCommandButton(ability, this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(), ability.getHandleId(),
|
||||
@ -79,8 +78,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
|
||||
|
||||
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
|
||||
final int autoCastOrderId, final boolean autoCastActive) {
|
||||
final boolean active = ((handleId == this.unit.getCurrentAbilityHandleId())
|
||||
&& (orderId == this.unit.getCurrentOrderId()));
|
||||
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);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
@ -200,7 +201,11 @@ public class CUnit extends CWidget {
|
||||
}
|
||||
}
|
||||
else if (this.currentBehavior != null) {
|
||||
CBehavior lastBehavior = this.currentBehavior;
|
||||
this.currentBehavior = this.currentBehavior.update(game);
|
||||
if(this.currentBehavior.getHighlightOrderId() != lastBehavior.getHighlightOrderId()) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// check to auto acquire targets
|
||||
@ -243,15 +248,15 @@ public class CUnit extends CWidget {
|
||||
else {
|
||||
this.currentBehavior = beginOrder(game, order);
|
||||
this.orderQueue.clear();
|
||||
final boolean omitNotify = (this.currentOrder == null) && (order == null);
|
||||
if (!omitNotify) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CBehavior beginOrder(final CSimulation game, final COrder order) {
|
||||
final boolean omitNotify = (this.currentOrder == null) && (order == null);
|
||||
this.currentOrder = order;
|
||||
if (!omitNotify) {
|
||||
this.stateNotifier.ordersChanged(getCurrentAbilityHandleId(), getCurrentOrderId());
|
||||
}
|
||||
CBehavior nextBehavior;
|
||||
if (order != null) {
|
||||
nextBehavior = order.begin(game, this);
|
||||
@ -426,7 +431,7 @@ public class CUnit extends CWidget {
|
||||
CAllianceType.PASSIVE)) {
|
||||
for (final CUnitAttack attack : this.unitType.getAttacks()) {
|
||||
if (source.canBeTargetedBy(simulation, this, attack.getTargetsAllowed())) {
|
||||
this.currentBehavior = getAttackBehavior().reset(attack, source);
|
||||
this.currentBehavior = getAttackBehavior().reset(OrderIds.attack, attack, source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -590,7 +595,7 @@ public class CUnit extends CWidget {
|
||||
if (this.source.canReach(unit, this.source.acquisitionRange)
|
||||
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
|
||||
&& (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) {
|
||||
this.source.currentBehavior = this.source.getAttackBehavior().reset(attack, unit);
|
||||
this.source.currentBehavior = this.source.getAttackBehavior().reset(OrderIds.attack, attack, unit);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -109,12 +109,12 @@ public class CAbilityAttack implements CAbility {
|
||||
CBehavior behavior = null;
|
||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||
behavior = caster.getAttackBehavior().reset(attack, target);
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.attack, attack, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (behavior == null) {
|
||||
behavior = caster.getMoveBehavior().reset(target.getX(), target.getY());
|
||||
behavior = caster.getMoveBehavior().reset(OrderIds.attack, target.getX(), target.getY());
|
||||
}
|
||||
return behavior;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public class CAbilityColdArrows implements CAbility {
|
||||
CBehavior behavior = null;
|
||||
for (final CUnitAttack attack : caster.getUnitType().getAttacks()) {
|
||||
if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) {
|
||||
behavior = caster.getAttackBehavior().reset(attack, target);
|
||||
behavior = caster.getAttackBehavior().reset(OrderIds.coldarrowstarg, attack, target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ public class CAbilityMove implements CAbility {
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||
return caster.getFollowBehavior().reset((CUnit) target);
|
||||
return caster.getFollowBehavior().reset(OrderIds.move, (CUnit) target);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,7 +96,7 @@ public class CAbilityMove implements CAbility {
|
||||
return caster.getPatrolBehavior().reset(point);
|
||||
}
|
||||
else {
|
||||
return caster.getMoveBehavior().reset(point.x, point.y);
|
||||
return caster.getMoveBehavior().reset(OrderIds.move, point.x, point.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,4 +10,6 @@ public interface CBehavior {
|
||||
* @return
|
||||
*/
|
||||
CBehavior update(CSimulation game);
|
||||
|
||||
int getHighlightOrderId();
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUni
|
||||
|
||||
public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||
|
||||
private int highlightOrderId;
|
||||
|
||||
public CBehaviorAttack(final CUnit unit) {
|
||||
super(unit);
|
||||
}
|
||||
@ -19,7 +21,8 @@ public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||
private int backSwingTime;
|
||||
private int thisOrderCooldownEndTime;
|
||||
|
||||
public CBehaviorAttack reset(final CUnitAttack unitAttack, final CWidget target) {
|
||||
public CBehaviorAttack reset(int highlightOrderId, final CUnitAttack unitAttack, final CWidget target) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
super.innerReset(target);
|
||||
this.unitAttack = unitAttack;
|
||||
this.damagePointLaunchTime = 0;
|
||||
@ -28,6 +31,11 @@ public class CBehaviorAttack extends CAbstractRangedBehavior {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return highlightOrderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRange(final CSimulation simulation) {
|
||||
float range = this.unitAttack.getRange();
|
||||
|
@ -7,14 +7,22 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
|
||||
public class CBehaviorFollow extends CAbstractRangedBehavior {
|
||||
|
||||
private int higlightOrderId;
|
||||
|
||||
public CBehaviorFollow(final CUnit unit) {
|
||||
super(unit);
|
||||
}
|
||||
|
||||
public CBehavior reset(final CUnit target) {
|
||||
public CBehavior reset(int higlightOrderId, final CUnit target) {
|
||||
this.higlightOrderId = higlightOrderId;
|
||||
return innerReset(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return higlightOrderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRange(final CSimulation simulation) {
|
||||
return this.unit.canReach(this.target, this.unit.getAcquisitionRange());
|
||||
|
@ -18,6 +18,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CPathfindin
|
||||
public class CBehaviorMove implements CBehavior {
|
||||
private static final Rectangle tempRect = new Rectangle();
|
||||
private final CUnit unit;
|
||||
private int highlightOrderId;
|
||||
|
||||
public CBehaviorMove(final CUnit unit) {
|
||||
this.unit = unit;
|
||||
@ -31,11 +32,14 @@ public class CBehaviorMove implements CBehavior {
|
||||
private CUnit followUnit;
|
||||
private CRangedBehavior rangedBehavior;
|
||||
|
||||
public CBehaviorMove reset(final float targetX, final float targetY) {
|
||||
return reset(targetX, targetY, null);
|
||||
public CBehaviorMove reset(int highlightOrderId, final float targetX, final float targetY) {
|
||||
internalResetMove(highlightOrderId, targetX, targetY);
|
||||
this.rangedBehavior = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CBehaviorMove reset(final float targetX, final float targetY, final CRangedBehavior rangedBehavior) {
|
||||
private void internalResetMove(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
|
||||
@ -44,12 +48,18 @@ public class CBehaviorMove implements CBehavior {
|
||||
this.path = null;
|
||||
this.searchCycles = 0;
|
||||
this.followUnit = null;
|
||||
}
|
||||
|
||||
public CBehaviorMove reset(final float targetX, final float targetY, final CRangedBehavior rangedBehavior) {
|
||||
internalResetMove(rangedBehavior.getHighlightOrderId(), targetX, targetY);
|
||||
this.rangedBehavior = rangedBehavior;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CBehaviorMove reset(final CUnit followUnit) {
|
||||
return reset(followUnit, null);
|
||||
public CBehaviorMove reset(int highlightOrderId, final CUnit followUnit) {
|
||||
internalResetMove(highlightOrderId, followUnit);
|
||||
this.rangedBehavior = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CBehaviorMove reset(final CUnit followUnit, final CRangedBehavior rangedBehavior) {
|
||||
@ -65,6 +75,23 @@ public class CBehaviorMove implements CBehavior {
|
||||
return this;
|
||||
}
|
||||
|
||||
private void internalResetMove(int highlightOrderId, CUnit followUnit) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
this.wasWithinPropWindow = false;
|
||||
this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners(
|
||||
this.unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS
|
||||
: CPathfindingProcessor.GridMapping.CELLS;
|
||||
this.target = new Float(followUnit.getX(), followUnit.getY());
|
||||
this.path = null;
|
||||
this.searchCycles = 0;
|
||||
this.followUnit = followUnit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return highlightOrderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior update(final CSimulation simulation) {
|
||||
if ((this.rangedBehavior != null) && this.rangedBehavior.isWithinRange(simulation)) {
|
||||
|
@ -3,6 +3,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CBehaviorPatrol implements CRangedBehavior {
|
||||
|
||||
@ -20,6 +21,11 @@ public class CBehaviorPatrol implements CRangedBehavior {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return OrderIds.patrol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRange(final CSimulation simulation) {
|
||||
return this.unit.distance(this.target.x, this.target.y) <= simulation.getGameplayConstants()
|
||||
|
@ -4,6 +4,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CBehaviorStop implements CBehavior {
|
||||
|
||||
@ -13,8 +14,14 @@ public class CBehaviorStop implements CBehavior {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return OrderIds.stop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CBehavior update(final CSimulation game) {
|
||||
this.unit.autoAcquireAttackTargets(game);
|
||||
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true);
|
||||
return this.unit.pollNextOrderBehavior(game);
|
||||
}
|
||||
|
@ -152,8 +152,10 @@ public class CUnitData {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -229,8 +231,7 @@ public class CUnitData {
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
} catch (final Exception exc) {
|
||||
System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
@ -278,8 +279,7 @@ public class CUnitData {
|
||||
maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled,
|
||||
projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound,
|
||||
weaponType));
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
} catch (final Exception exc) {
|
||||
System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user