mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Update with simple status bar
This commit is contained in:
parent
632576323c
commit
2b3e5bdf4a
@ -130,7 +130,7 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
||||
this.viewer.enableAudio();
|
||||
}
|
||||
try {
|
||||
this.viewer.loadMap(this.warsmashIni.get("Map").getField("FilePath"));
|
||||
this.viewer.loadMap(this.warsmashIni.get("Map").getField("FilePath"), 0);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -222,7 +222,7 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
||||
cameraRatesElement.getFieldFloatValue("FOV"), cameraRatesElement.getFieldFloatValue("Rotation"),
|
||||
cameraRatesElement.getFieldFloatValue("Distance"), cameraRatesElement.getFieldFloatValue("Forward"),
|
||||
cameraRatesElement.getFieldFloatValue("Strafe"));
|
||||
this.meleeUI = new MeleeUI(this.codebase, this.uiViewport, fontGenerator, this.uiScene, portraitScene,
|
||||
this.meleeUI = new MeleeUI(this.viewer.mapMpq, this.uiViewport, fontGenerator, this.uiScene, portraitScene,
|
||||
cameraPresets, cameraRates, this.viewer, new RootFrameListener() {
|
||||
@Override
|
||||
public void onCreate(final GameUI rootFrame) {
|
||||
|
@ -30,6 +30,7 @@ import com.etheller.warsmash.parsers.fdf.frames.AbstractUIFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.FilterModeTextureFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SetPoint;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SimpleStatusBarFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.StringFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.TextureFrame;
|
||||
@ -104,16 +105,31 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// TODO eliminate duplicate read of skin TXT!!
|
||||
if (dataSource.has("war3mapSkin.txt")) {
|
||||
try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("war3mapSkin.txt")) {
|
||||
skinsTable.readTXT(miscDataTxtStream, true);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
// final Element main = skinsTable.get("Main");
|
||||
// final String skinsField = main.getField("Skins");
|
||||
// final String[] skins = skinsField.split(",");
|
||||
final Element defaultSkin = skinsTable.get("Default");
|
||||
final Element userSkin = skinsTable.get(skin);
|
||||
final Element customSkin = skinsTable.get("CustomSkin");
|
||||
for (final String key : defaultSkin.keySet()) {
|
||||
if (!userSkin.hasField(key)) {
|
||||
userSkin.setField(key, defaultSkin.getField(key));
|
||||
}
|
||||
}
|
||||
if (customSkin != null) {
|
||||
for (final String key : customSkin.keySet()) {
|
||||
userSkin.setField(key, customSkin.getField(key));
|
||||
}
|
||||
}
|
||||
return userSkin;
|
||||
}
|
||||
|
||||
@ -125,16 +141,31 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// TODO eliminate duplicate read of skin TXT!!
|
||||
if (dataSource.has("war3mapSkin.txt")) {
|
||||
try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("war3mapSkin.txt")) {
|
||||
skinsTable.readTXT(miscDataTxtStream, true);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
final Element main = skinsTable.get("Main");
|
||||
final String skinsField = main.getField("Skins");
|
||||
final String[] skins = skinsField.split(",");
|
||||
final Element defaultSkin = skinsTable.get("Default");
|
||||
final Element userSkin = skinsTable.get(skins[skinIndex]);
|
||||
final Element customSkin = skinsTable.get("CustomSkin");
|
||||
for (final String key : defaultSkin.keySet()) {
|
||||
if (!userSkin.hasField(key)) {
|
||||
userSkin.setField(key, defaultSkin.getField(key));
|
||||
}
|
||||
}
|
||||
if (customSkin != null) {
|
||||
for (final String key : customSkin.keySet()) {
|
||||
userSkin.setField(key, customSkin.getField(key));
|
||||
}
|
||||
}
|
||||
return userSkin;
|
||||
}
|
||||
|
||||
@ -252,6 +283,17 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
||||
}
|
||||
inflatedFrame = simpleFrame;
|
||||
}
|
||||
else if ("SIMPLESTATUSBAR".equals(frameDefinition.getFrameType())) {
|
||||
final boolean decorateFileNames = frameDefinition.has("DecorateFileNames")
|
||||
|| ((parentDefinitionIfAvailable != null)
|
||||
&& parentDefinitionIfAvailable.has("DecorateFileNames"));
|
||||
final SimpleStatusBarFrame simpleStatusBarFrame = new SimpleStatusBarFrame(frameDefinition.getName(),
|
||||
parent, decorateFileNames);
|
||||
for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) {
|
||||
simpleStatusBarFrame.add(inflate(childDefinition, simpleStatusBarFrame, frameDefinition));
|
||||
}
|
||||
inflatedFrame = simpleStatusBarFrame;
|
||||
}
|
||||
else if ("SPRITE".equals(frameDefinition.getFrameType())) {
|
||||
final SpriteFrame spriteFrame = new SpriteFrame(frameDefinition.getName(), parent, this.uiScene,
|
||||
viewport2);
|
||||
@ -448,6 +490,10 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
||||
}
|
||||
|
||||
public Scene getUiScene() {
|
||||
return uiScene;
|
||||
return this.uiScene;
|
||||
}
|
||||
|
||||
public FrameTemplateEnvironment getTemplates() {
|
||||
return this.templates;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.etheller.warsmash.parsers.fdf.frames;
|
||||
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition;
|
||||
|
||||
public class SimpleStatusBarFrame extends AbstractUIFrame {
|
||||
private final boolean decorateFileNames;
|
||||
private final TextureFrame barFrame;
|
||||
private final TextureFrame borderFrame;
|
||||
|
||||
public SimpleStatusBarFrame(final String name, final UIFrame parent, final boolean decorateFileNames) {
|
||||
super(name, parent);
|
||||
this.decorateFileNames = decorateFileNames;
|
||||
this.barFrame = new TextureFrame(name + "Bar", this, decorateFileNames, new Vector4Definition(0, 1, 0, 1));
|
||||
this.borderFrame = new TextureFrame(name + "Border", this, decorateFileNames,
|
||||
new Vector4Definition(0, 1, 0, 1));
|
||||
this.borderFrame.setSetAllPoints(true);
|
||||
this.barFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, 0, 0));
|
||||
this.barFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this, FramePoint.BOTTOMLEFT, 0, 0));
|
||||
add(this.barFrame);
|
||||
add(this.borderFrame);
|
||||
}
|
||||
|
||||
public boolean isDecorateFileNames() {
|
||||
return this.decorateFileNames;
|
||||
}
|
||||
|
||||
public void setValue(final float value) {
|
||||
this.barFrame.setWidth(this.renderBounds.width * value);
|
||||
}
|
||||
|
||||
public TextureFrame getBarFrame() {
|
||||
return this.barFrame;
|
||||
}
|
||||
|
||||
public TextureFrame getBorderFrame() {
|
||||
return this.borderFrame;
|
||||
}
|
||||
}
|
@ -9,9 +9,9 @@ public class AudioBufferSource {
|
||||
|
||||
}
|
||||
|
||||
public void start(final int value) {
|
||||
public void start(final int value, final float volume, final float pitch) {
|
||||
if (this.buffer != null) {
|
||||
this.buffer.play(1);
|
||||
this.buffer.play(volume, pitch, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,328 +22,348 @@ import com.etheller.warsmash.viewer5.Texture;
|
||||
import com.etheller.warsmash.viewer5.handlers.EmitterObject;
|
||||
|
||||
public class EventObjectEmitterObject extends GenericObject implements EmitterObject {
|
||||
private static final class LoadGenericSoundCallback implements LoadGenericCallback {
|
||||
private final String filename;
|
||||
private static final class LoadGenericSoundCallback implements LoadGenericCallback {
|
||||
private final String filename;
|
||||
|
||||
public LoadGenericSoundCallback(final String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
public LoadGenericSoundCallback(final String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call(final InputStream data) {
|
||||
final FileHandle temp = new FileHandle(this.filename) {
|
||||
@Override
|
||||
public InputStream read() {
|
||||
return data;
|
||||
}
|
||||
@Override
|
||||
public Object call(final InputStream data) {
|
||||
final FileHandle temp = new FileHandle(this.filename) {
|
||||
@Override
|
||||
public InputStream read() {
|
||||
return data;
|
||||
}
|
||||
|
||||
;
|
||||
};
|
||||
if (data != null) {
|
||||
return Gdx.audio.newSound(temp);
|
||||
} else {
|
||||
System.err.println("Warning: missing sound file: " + this.filename);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
};
|
||||
if (data != null) {
|
||||
return Gdx.audio.newSound(temp);
|
||||
}
|
||||
else {
|
||||
System.err.println("Warning: missing sound file: " + this.filename);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final LoadGenericCallback mappedDataCallback = new LoadGenericCallback() {
|
||||
private static final LoadGenericCallback mappedDataCallback = new LoadGenericCallback() {
|
||||
|
||||
@Override
|
||||
public Object call(final InputStream data) {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(data, "utf-8"))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new MappedData(stringBuilder.toString());
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public Object call(final InputStream data) {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(data, "utf-8"))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
catch (final UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new MappedData(stringBuilder.toString());
|
||||
}
|
||||
};
|
||||
|
||||
private int geometryEmitterType = -1;
|
||||
public final String type;
|
||||
private final String id;
|
||||
public final long[] keyFrames;
|
||||
private long globalSequence = -1;
|
||||
private final long[] defval = {1};
|
||||
public MdxModel internalModel;
|
||||
public Texture internalTexture;
|
||||
public float[][] colors;
|
||||
public float[] intervalTimes;
|
||||
public float scale;
|
||||
public int columns;
|
||||
public int rows;
|
||||
public float lifeSpan;
|
||||
public int blendSrc;
|
||||
public int blendDst;
|
||||
public float[][] intervals;
|
||||
public float distanceCutoff;
|
||||
private float maxDistance;
|
||||
public float minDistance;
|
||||
private float pitch;
|
||||
private float pitchVariance;
|
||||
private float volume;
|
||||
public List<Sound> decodedBuffers = new ArrayList<>();
|
||||
/**
|
||||
* If this is an SPL/UBR emitter object, ok will be set to true if the tables
|
||||
* are loaded.
|
||||
* <p>
|
||||
* This is because, like the other geometry emitters, it is fine to use them
|
||||
* even if the textures don't load.
|
||||
* <p>
|
||||
* The particles will simply be black.
|
||||
*/
|
||||
private boolean ok = false;
|
||||
private int geometryEmitterType = -1;
|
||||
public final String type;
|
||||
private final String id;
|
||||
public final long[] keyFrames;
|
||||
private long globalSequence = -1;
|
||||
private final long[] defval = { 1 };
|
||||
public MdxModel internalModel;
|
||||
public Texture internalTexture;
|
||||
public float[][] colors;
|
||||
public float[] intervalTimes;
|
||||
public float scale;
|
||||
public int columns;
|
||||
public int rows;
|
||||
public float lifeSpan;
|
||||
public int blendSrc;
|
||||
public int blendDst;
|
||||
public float[][] intervals;
|
||||
public float distanceCutoff;
|
||||
private float maxDistance;
|
||||
public float minDistance;
|
||||
public float pitch;
|
||||
public float pitchVariance;
|
||||
public float volume;
|
||||
public List<Sound> decodedBuffers = new ArrayList<>();
|
||||
/**
|
||||
* If this is an SPL/UBR emitter object, ok will be set to true if the tables
|
||||
* are loaded.
|
||||
* <p>
|
||||
* This is because, like the other geometry emitters, it is fine to use them
|
||||
* even if the textures don't load.
|
||||
* <p>
|
||||
* The particles will simply be black.
|
||||
*/
|
||||
private boolean ok = false;
|
||||
|
||||
public EventObjectEmitterObject(final MdxModel model,
|
||||
final com.etheller.warsmash.parsers.mdlx.EventObject eventObject, final int index) {
|
||||
super(model, eventObject, index);
|
||||
public EventObjectEmitterObject(final MdxModel model,
|
||||
final com.etheller.warsmash.parsers.mdlx.EventObject eventObject, final int index) {
|
||||
super(model, eventObject, index);
|
||||
|
||||
final ModelViewer viewer = model.viewer;
|
||||
final String name = eventObject.getName();
|
||||
String type = name.substring(0, 3);
|
||||
final String id = name.substring(4);
|
||||
final ModelViewer viewer = model.viewer;
|
||||
final String name = eventObject.getName();
|
||||
String type = name.substring(0, 3);
|
||||
final String id = name.substring(4);
|
||||
|
||||
// Same thing
|
||||
if ("FPT".equals(type)) {
|
||||
type = "SPL";
|
||||
}
|
||||
// Same thing
|
||||
if ("FPT".equals(type)) {
|
||||
type = "SPL";
|
||||
}
|
||||
|
||||
if ("SPL".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPLAT;
|
||||
} else if ("UBR".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_UBERSPLAT;
|
||||
} else if ("SPN".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPN;
|
||||
}
|
||||
if ("SPL".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPLAT;
|
||||
}
|
||||
else if ("UBR".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_UBERSPLAT;
|
||||
}
|
||||
else if ("SPN".equals(type)) {
|
||||
this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPN;
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.keyFrames = eventObject.getKeyFrames();
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.keyFrames = eventObject.getKeyFrames();
|
||||
|
||||
final int globalSequenceId = eventObject.getGlobalSequenceId();
|
||||
if (globalSequenceId != -1) {
|
||||
this.globalSequence = model.getGlobalSequences().get(globalSequenceId);
|
||||
}
|
||||
final int globalSequenceId = eventObject.getGlobalSequenceId();
|
||||
if (globalSequenceId != -1) {
|
||||
this.globalSequence = model.getGlobalSequences().get(globalSequenceId);
|
||||
}
|
||||
|
||||
final List<GenericResource> tables = new ArrayList<>();
|
||||
final PathSolver pathSolver = model.pathSolver;
|
||||
final Object solverParams = model.solverParams;
|
||||
final List<GenericResource> tables = new ArrayList<>();
|
||||
final PathSolver pathSolver = model.pathSolver;
|
||||
final Object solverParams = model.solverParams;
|
||||
|
||||
if ("SPN".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SpawnData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
} else if ("SPL".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SplatData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
} else if ("UBR".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\UberSplatData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
} else if ("SND".equals(type)) {
|
||||
if (!model.reforged) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimLookups.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimSounds.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
} else {
|
||||
// Units\Critters\BlackStagMale\BlackStagMale.mdx has an event object named
|
||||
// "Point01".
|
||||
return;
|
||||
}
|
||||
if ("SPN".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SpawnData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
else if ("SPL".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SplatData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
else if ("UBR".equals(type)) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\UberSplatData.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
else if ("SND".equals(type)) {
|
||||
if (!model.reforged) {
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimLookups.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimSounds.slk", solverParams).finalSrc,
|
||||
FetchDataTypeName.SLK, mappedDataCallback));
|
||||
}
|
||||
else {
|
||||
// Units\Critters\BlackStagMale\BlackStagMale.mdx has an event object named
|
||||
// "Point01".
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO I am scrapping some async stuff with promises here from the JS and
|
||||
// calling load
|
||||
this.load(tables);
|
||||
}
|
||||
// TODO I am scrapping some async stuff with promises here from the JS and
|
||||
// calling load
|
||||
this.load(tables);
|
||||
}
|
||||
|
||||
private float getFloat(final MappedDataRow row, final String name) {
|
||||
final Float x = (Float) row.get(name);
|
||||
if (x == null) {
|
||||
return Float.NaN;
|
||||
} else {
|
||||
return x.floatValue();
|
||||
}
|
||||
}
|
||||
private float getFloat(final MappedDataRow row, final String name) {
|
||||
final Float x = (Float) row.get(name);
|
||||
if (x == null) {
|
||||
return Float.NaN;
|
||||
}
|
||||
else {
|
||||
return x.floatValue();
|
||||
}
|
||||
}
|
||||
|
||||
private int getInt(final MappedDataRow row, final String name) {
|
||||
return getInt(row, name, Integer.MIN_VALUE);
|
||||
}
|
||||
private int getInt(final MappedDataRow row, final String name) {
|
||||
return getInt(row, name, Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
private int getInt(final MappedDataRow row, final String name, final int defaultValue) {
|
||||
final Number x = (Number) row.get(name);
|
||||
if (x == null) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return x.intValue();
|
||||
}
|
||||
}
|
||||
private int getInt(final MappedDataRow row, final String name, final int defaultValue) {
|
||||
final Number x = (Number) row.get(name);
|
||||
if (x == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
else {
|
||||
return x.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
private void load(final List<GenericResource> tables) {
|
||||
final MappedData firstTable = (MappedData) tables.get(0).data;
|
||||
if (firstTable == null) {
|
||||
return;
|
||||
}
|
||||
final MappedDataRow row = firstTable.getRow(this.id.trim());
|
||||
private void load(final List<GenericResource> tables) {
|
||||
final MappedData firstTable = (MappedData) tables.get(0).data;
|
||||
if (firstTable == null) {
|
||||
return;
|
||||
}
|
||||
final MappedDataRow row = firstTable.getRow(this.id.trim());
|
||||
|
||||
if (row != null) {
|
||||
final MdxModel model = this.model;
|
||||
final ModelViewer viewer = model.viewer;
|
||||
final PathSolver pathSolver = model.pathSolver;
|
||||
if (row != null) {
|
||||
final MdxModel model = this.model;
|
||||
final ModelViewer viewer = model.viewer;
|
||||
final PathSolver pathSolver = model.pathSolver;
|
||||
|
||||
if ("SPN".equals(this.type)) {
|
||||
this.internalModel = (MdxModel) viewer.load(((String) row.get("Model")).replace(".mdl", ".mdx"),
|
||||
pathSolver, model.solverParams);
|
||||
if ("SPN".equals(this.type)) {
|
||||
this.internalModel = (MdxModel) viewer.load(((String) row.get("Model")).replace(".mdl", ".mdx"),
|
||||
pathSolver, model.solverParams);
|
||||
|
||||
if (this.internalModel != null) {
|
||||
// TODO javascript async code removed here
|
||||
if (this.internalModel != null) {
|
||||
// TODO javascript async code removed here
|
||||
// this.internalModel.whenLoaded((model) => this.ok = model.ok)
|
||||
this.ok = this.internalModel.ok;
|
||||
}
|
||||
} else if ("SPL".equals(this.type) || "UBR".equals(this.type)) {
|
||||
final String texturesExt = model.reforged ? ".dds" : ".blp";
|
||||
this.ok = this.internalModel.ok;
|
||||
}
|
||||
}
|
||||
else if ("SPL".equals(this.type) || "UBR".equals(this.type)) {
|
||||
final String texturesExt = model.reforged ? ".dds" : ".blp";
|
||||
|
||||
this.internalTexture = (Texture) viewer.load(
|
||||
"ReplaceableTextures\\Splats\\" + row.get("file") + texturesExt, pathSolver,
|
||||
model.solverParams);
|
||||
this.internalTexture = (Texture) viewer.load(
|
||||
"ReplaceableTextures\\Splats\\" + row.get("file") + texturesExt, pathSolver,
|
||||
model.solverParams);
|
||||
|
||||
this.scale = getFloat(row, "Scale");
|
||||
this.colors = new float[][]{
|
||||
{getFloat(row, "StartR"), getFloat(row, "StartG"), getFloat(row, "StartB"),
|
||||
getFloat(row, "StartA")},
|
||||
{getFloat(row, "MiddleR"), getFloat(row, "MiddleG"), getFloat(row, "MiddleB"),
|
||||
getFloat(row, "MiddleA")},
|
||||
{getFloat(row, "EndR"), getFloat(row, "EndG"), getFloat(row, "EndB"),
|
||||
getFloat(row, "EndA")}};
|
||||
this.scale = getFloat(row, "Scale");
|
||||
this.colors = new float[][] {
|
||||
{ getFloat(row, "StartR"), getFloat(row, "StartG"), getFloat(row, "StartB"),
|
||||
getFloat(row, "StartA") },
|
||||
{ getFloat(row, "MiddleR"), getFloat(row, "MiddleG"), getFloat(row, "MiddleB"),
|
||||
getFloat(row, "MiddleA") },
|
||||
{ getFloat(row, "EndR"), getFloat(row, "EndG"), getFloat(row, "EndB"),
|
||||
getFloat(row, "EndA") } };
|
||||
|
||||
if ("SPL".equals(this.type)) {
|
||||
this.columns = getInt(row, "Columns");
|
||||
this.rows = getInt(row, "Rows");
|
||||
this.lifeSpan = getFloat(row, "Lifespan") + getFloat(row, "Decay");
|
||||
this.intervalTimes = new float[]{getFloat(row, "Lifespan"), getFloat(row, "Decay")};
|
||||
this.intervals = new float[][]{
|
||||
{getFloat(row, "UVLifespanStart"), getFloat(row, "UVLifespanEnd"),
|
||||
getFloat(row, "LifespanRepeat")},
|
||||
{getFloat(row, "UVDecayStart"), getFloat(row, "UVDecayEnd"),
|
||||
getFloat(row, "DecayRepeat")},};
|
||||
} else {
|
||||
this.columns = 1;
|
||||
this.rows = 1;
|
||||
this.lifeSpan = getFloat(row, "BirthTime") + getFloat(row, "PauseTime") + getFloat(row, "Decay");
|
||||
this.intervalTimes = new float[]{getFloat(row, "BirthTime"), getFloat(row, "PauseTime"),
|
||||
getFloat(row, "Decay")};
|
||||
}
|
||||
if ("SPL".equals(this.type)) {
|
||||
this.columns = getInt(row, "Columns");
|
||||
this.rows = getInt(row, "Rows");
|
||||
this.lifeSpan = getFloat(row, "Lifespan") + getFloat(row, "Decay");
|
||||
this.intervalTimes = new float[] { getFloat(row, "Lifespan"), getFloat(row, "Decay") };
|
||||
this.intervals = new float[][] {
|
||||
{ getFloat(row, "UVLifespanStart"), getFloat(row, "UVLifespanEnd"),
|
||||
getFloat(row, "LifespanRepeat") },
|
||||
{ getFloat(row, "UVDecayStart"), getFloat(row, "UVDecayEnd"),
|
||||
getFloat(row, "DecayRepeat") }, };
|
||||
}
|
||||
else {
|
||||
this.columns = 1;
|
||||
this.rows = 1;
|
||||
this.lifeSpan = getFloat(row, "BirthTime") + getFloat(row, "PauseTime") + getFloat(row, "Decay");
|
||||
this.intervalTimes = new float[] { getFloat(row, "BirthTime"), getFloat(row, "PauseTime"),
|
||||
getFloat(row, "Decay") };
|
||||
}
|
||||
|
||||
final int[] blendModes = FilterMode
|
||||
.emitterFilterMode(com.etheller.warsmash.parsers.mdlx.ParticleEmitter2.FilterMode
|
||||
.fromId(getInt(row, "BlendMode")));
|
||||
final int[] blendModes = FilterMode
|
||||
.emitterFilterMode(com.etheller.warsmash.parsers.mdlx.ParticleEmitter2.FilterMode
|
||||
.fromId(getInt(row, "BlendMode")));
|
||||
|
||||
this.blendSrc = blendModes[0];
|
||||
this.blendDst = blendModes[1];
|
||||
this.blendSrc = blendModes[0];
|
||||
this.blendDst = blendModes[1];
|
||||
|
||||
this.ok = true;
|
||||
} else if ("SND".equals(this.type)) {
|
||||
// Only load sounds if audio is enabled.
|
||||
// This is mostly to save on bandwidth and loading time, especially when loading
|
||||
// full maps.
|
||||
if (viewer.audioEnabled) {
|
||||
final MappedData animSounds = (MappedData) tables.get(1).data;
|
||||
this.ok = true;
|
||||
}
|
||||
else if ("SND".equals(this.type)) {
|
||||
// Only load sounds if audio is enabled.
|
||||
// This is mostly to save on bandwidth and loading time, especially when loading
|
||||
// full maps.
|
||||
if (viewer.audioEnabled) {
|
||||
final MappedData animSounds = (MappedData) tables.get(1).data;
|
||||
|
||||
final MappedDataRow animSoundsRow = animSounds.getRow((String) row.get("SoundLabel"));
|
||||
final MappedDataRow animSoundsRow = animSounds.getRow((String) row.get("SoundLabel"));
|
||||
|
||||
if (animSoundsRow != null) {
|
||||
this.distanceCutoff = getFloat(animSoundsRow, "DistanceCutoff");
|
||||
this.maxDistance = getFloat(animSoundsRow, "MaxDistance");
|
||||
this.minDistance = getFloat(animSoundsRow, "MinDistance");
|
||||
this.pitch = getFloat(animSoundsRow, "Pitch");
|
||||
this.pitchVariance = getFloat(animSoundsRow, "PitchVariance");
|
||||
this.volume = getFloat(animSoundsRow, "Volume");
|
||||
if (animSoundsRow != null) {
|
||||
this.distanceCutoff = getFloat(animSoundsRow, "DistanceCutoff");
|
||||
this.maxDistance = getFloat(animSoundsRow, "MaxDistance");
|
||||
this.minDistance = getFloat(animSoundsRow, "MinDistance");
|
||||
this.pitch = getFloat(animSoundsRow, "Pitch");
|
||||
this.pitchVariance = getFloat(animSoundsRow, "PitchVariance");
|
||||
this.volume = getFloat(animSoundsRow, "Volume") / 127f;
|
||||
|
||||
final String[] fileNames = ((String) animSoundsRow.get("FileNames")).split(",");
|
||||
final GenericResource[] resources = new GenericResource[fileNames.length];
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
final String path = ((String) animSoundsRow.get("DirectoryBase")) + fileNames[i];
|
||||
try {
|
||||
final String pathString = pathSolver.solve(path, model.solverParams).finalSrc;
|
||||
final GenericResource genericResource = viewer.loadGeneric(pathString,
|
||||
FetchDataTypeName.ARRAY_BUFFER, new LoadGenericSoundCallback(pathString));
|
||||
if (genericResource == null) {
|
||||
System.err.println("Null sound: " + fileNames[i]);
|
||||
}
|
||||
resources[i] = genericResource;
|
||||
} catch (final Exception exc) {
|
||||
System.err.println("Failed to load sound: " + path);
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
final String[] fileNames = ((String) animSoundsRow.get("FileNames")).split(",");
|
||||
final GenericResource[] resources = new GenericResource[fileNames.length];
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
final String path = ((String) animSoundsRow.get("DirectoryBase")) + fileNames[i];
|
||||
try {
|
||||
final String pathString = pathSolver.solve(path, model.solverParams).finalSrc;
|
||||
final GenericResource genericResource = viewer.loadGeneric(pathString,
|
||||
FetchDataTypeName.ARRAY_BUFFER, new LoadGenericSoundCallback(pathString));
|
||||
if (genericResource == null) {
|
||||
System.err.println("Null sound: " + fileNames[i]);
|
||||
}
|
||||
resources[i] = genericResource;
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
System.err.println("Failed to load sound: " + path);
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO JS async removed
|
||||
for (final GenericResource resource : resources) {
|
||||
if (resource != null) {
|
||||
this.decodedBuffers.add((Sound) resource.data);
|
||||
}
|
||||
}
|
||||
this.ok = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.err.println("Unknown event object type: " + this.type + this.id);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Unknown event object ID: " + this.type + this.id);
|
||||
}
|
||||
}
|
||||
// TODO JS async removed
|
||||
for (final GenericResource resource : resources) {
|
||||
if (resource != null) {
|
||||
this.decodedBuffers.add((Sound) resource.data);
|
||||
}
|
||||
}
|
||||
this.ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.err.println("Unknown event object type: " + this.type + this.id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.err.println("Unknown event object ID: " + this.type + this.id);
|
||||
}
|
||||
}
|
||||
|
||||
public int getValue(final long[] out, final MdxComplexInstance instance) {
|
||||
if (this.globalSequence != -1) {
|
||||
public int getValue(final long[] out, final MdxComplexInstance instance) {
|
||||
if (this.globalSequence != -1) {
|
||||
|
||||
return this.getValueAtTime(out, instance.counter % this.globalSequence, 0, this.globalSequence);
|
||||
} else if (instance.sequence != -1) {
|
||||
final long[] interval = this.model.getSequences().get(instance.sequence).getInterval();
|
||||
return this.getValueAtTime(out, instance.counter % this.globalSequence, 0, this.globalSequence);
|
||||
}
|
||||
else if (instance.sequence != -1) {
|
||||
final long[] interval = this.model.getSequences().get(instance.sequence).getInterval();
|
||||
|
||||
return this.getValueAtTime(out, instance.frame, interval[0], interval[1]);
|
||||
} else {
|
||||
out[0] = this.defval[0];
|
||||
return this.getValueAtTime(out, instance.frame, interval[0], interval[1]);
|
||||
}
|
||||
else {
|
||||
out[0] = this.defval[0];
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getValueAtTime(final long[] out, final long frame, final long start, final long end) {
|
||||
if ((frame >= start) && (frame <= end)) {
|
||||
for (int i = this.keyFrames.length - 1; i > -1; i--) {
|
||||
if (this.keyFrames[i] < start) {
|
||||
out[0] = 0;
|
||||
public int getValueAtTime(final long[] out, final long frame, final long start, final long end) {
|
||||
if ((frame >= start) && (frame <= end)) {
|
||||
for (int i = this.keyFrames.length - 1; i > -1; i--) {
|
||||
if (this.keyFrames[i] < start) {
|
||||
out[0] = 0;
|
||||
|
||||
return i;
|
||||
} else if (this.keyFrames[i] <= frame) {
|
||||
out[0] = 1;
|
||||
return i;
|
||||
}
|
||||
else if (this.keyFrames[i] <= frame) {
|
||||
out[0] = 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out[0] = 0;
|
||||
out[0] = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ok() {
|
||||
return this.ok;
|
||||
}
|
||||
@Override
|
||||
public boolean ok() {
|
||||
return this.ok;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGeometryEmitterType() {
|
||||
return this.geometryEmitterType;
|
||||
}
|
||||
@Override
|
||||
public int getGeometryEmitterType() {
|
||||
return this.geometryEmitterType;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,9 @@ public class EventObjectSnd extends EmittedObject<MdxComplexInstance, EventObjec
|
||||
source.connect(panner);
|
||||
|
||||
// Make a sound.
|
||||
source.start(0);
|
||||
source.start(0, emitterObject.volume,
|
||||
(emitterObject.pitch + ((float) Math.random() * emitterObject.pitchVariance * 2))
|
||||
- emitterObject.pitchVariance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,15 @@ public final class UnitAckSound {
|
||||
private final List<Sound> sounds = new ArrayList<>();
|
||||
private final float volume;
|
||||
private final float pitch;
|
||||
private final float pitchVariation;
|
||||
private final float pitchVariance;
|
||||
private final float minDistance;
|
||||
private final float maxDistance;
|
||||
private final float distanceCutoff;
|
||||
|
||||
private Sound lastPlayedSound;
|
||||
|
||||
public static UnitAckSound create(final DataSource dataSource, final DataTable unitAckSounds, final String soundName,
|
||||
final String soundType) {
|
||||
public static UnitAckSound create(final DataSource dataSource, final DataTable unitAckSounds,
|
||||
final String soundName, final String soundType) {
|
||||
final Element row = unitAckSounds.get(soundName + soundType);
|
||||
if (row == null) {
|
||||
return SILENT;
|
||||
@ -40,13 +40,17 @@ public final class UnitAckSound {
|
||||
if ((directoryBase.length() > 1) && !directoryBase.endsWith("\\")) {
|
||||
directoryBase += "\\";
|
||||
}
|
||||
final float volume = row.getFieldFloatValue("Volume");
|
||||
final float volume = row.getFieldFloatValue("Volume") / 127f;
|
||||
final float pitch = row.getFieldFloatValue("Pitch");
|
||||
final float pitchVariation = row.getFieldFloatValue("PitchVariance");
|
||||
float pitchVariance = row.getFieldFloatValue("PitchVariance");
|
||||
if (pitchVariance == 1.0f) {
|
||||
pitchVariance = 0.0f;
|
||||
}
|
||||
final float minDistance = row.getFieldFloatValue("MinDistance");
|
||||
final float maxDistance = row.getFieldFloatValue("MaxDistance");
|
||||
final float distanceCutoff = row.getFieldFloatValue("DistanceCutoff");
|
||||
final UnitAckSound sound = new UnitAckSound(volume, pitch, pitchVariation, minDistance, maxDistance, distanceCutoff);
|
||||
final UnitAckSound sound = new UnitAckSound(volume, pitch, pitchVariance, minDistance, maxDistance,
|
||||
distanceCutoff);
|
||||
for (final String fileName : fileNames.split(",")) {
|
||||
String filePath = directoryBase + fileName;
|
||||
if (!filePath.toLowerCase().endsWith(".wav")) {
|
||||
@ -63,7 +67,7 @@ public final class UnitAckSound {
|
||||
final float maxDistance, final float distanceCutoff) {
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
this.pitchVariation = pitchVariation;
|
||||
this.pitchVariance = pitchVariation;
|
||||
this.minDistance = minDistance;
|
||||
this.maxDistance = maxDistance;
|
||||
this.distanceCutoff = distanceCutoff;
|
||||
@ -96,7 +100,8 @@ public final class UnitAckSound {
|
||||
source.connect(panner);
|
||||
|
||||
// Make a sound.
|
||||
source.start(0);
|
||||
source.start(0, this.volume,
|
||||
(this.pitch + ((float) Math.random() * this.pitchVariance * 2)) - this.pitchVariance);
|
||||
this.lastPlayedSound = source.buffer;
|
||||
final float duration = Extensions.soundLengthExtension.getDuration(this.lastPlayedSound);
|
||||
unit.lastUnitResponseEndTimeMillis = millisTime + (long) (1000 * duration);
|
||||
|
@ -22,7 +22,7 @@ public final class UnitSound {
|
||||
private final List<Sound> sounds = new ArrayList<>();
|
||||
private final float volume;
|
||||
private final float pitch;
|
||||
private final float pitchVariation;
|
||||
private final float pitchVariance;
|
||||
private final float minDistance;
|
||||
private final float maxDistance;
|
||||
private final float distanceCutoff;
|
||||
@ -40,13 +40,16 @@ public final class UnitSound {
|
||||
if ((directoryBase.length() > 1) && !directoryBase.endsWith("\\")) {
|
||||
directoryBase += "\\";
|
||||
}
|
||||
final float volume = row.getFieldFloatValue("Volume");
|
||||
final float volume = row.getFieldFloatValue("Volume") / 127f;
|
||||
final float pitch = row.getFieldFloatValue("Pitch");
|
||||
final float pitchVariation = row.getFieldFloatValue("PitchVariance");
|
||||
float pitchVariance = row.getFieldFloatValue("PitchVariance");
|
||||
if (pitchVariance == 1.0f) {
|
||||
pitchVariance = 0.0f;
|
||||
}
|
||||
final float minDistance = row.getFieldFloatValue("MinDistance");
|
||||
final float maxDistance = row.getFieldFloatValue("MaxDistance");
|
||||
final float distanceCutoff = row.getFieldFloatValue("DistanceCutoff");
|
||||
final UnitSound sound = new UnitSound(volume, pitch, pitchVariation, minDistance, maxDistance, distanceCutoff);
|
||||
final UnitSound sound = new UnitSound(volume, pitch, pitchVariance, minDistance, maxDistance, distanceCutoff);
|
||||
for (final String fileName : fileNames.split(",")) {
|
||||
String filePath = directoryBase + fileName;
|
||||
if (!filePath.toLowerCase().endsWith(".wav")) {
|
||||
@ -63,7 +66,7 @@ public final class UnitSound {
|
||||
final float maxDistance, final float distanceCutoff) {
|
||||
this.volume = volume;
|
||||
this.pitch = pitch;
|
||||
this.pitchVariation = pitchVariation;
|
||||
this.pitchVariance = pitchVariation;
|
||||
this.minDistance = minDistance;
|
||||
this.maxDistance = maxDistance;
|
||||
this.distanceCutoff = distanceCutoff;
|
||||
@ -112,7 +115,8 @@ public final class UnitSound {
|
||||
source.connect(panner);
|
||||
|
||||
// Make a sound.
|
||||
source.start(0);
|
||||
source.start(0, this.volume,
|
||||
(this.pitch + ((float) Math.random() * this.pitchVariance * 2)) - this.pitchVariance);
|
||||
this.lastPlayedSound = source.buffer;
|
||||
return true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,13 @@ import com.etheller.warsmash.util.RenderMathUtils;
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.*;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.UnitSoundset;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||
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.rendersim.ability.AbilityDataUI;
|
||||
@ -64,7 +67,6 @@ public class RenderUnit {
|
||||
private boolean corpse;
|
||||
private boolean boneCorpse;
|
||||
private final RenderUnitTypeData typeData;
|
||||
public UnitSound buildSound;
|
||||
|
||||
public RenderUnit(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x,
|
||||
final float y, final float z, final int playerIndex, final UnitSoundset soundset,
|
||||
@ -127,7 +129,6 @@ public class RenderUnit {
|
||||
|
||||
final float blendTime = row.getFieldAsFloat(BLEND_TIME, 0);
|
||||
instance.setBlendTime(blendTime * 1000.0f);
|
||||
buildSound = map.getUiSounds().getSound(row.getFieldAsString(BUILD_SOUND_LABEL, 0));
|
||||
}
|
||||
|
||||
this.instance = instance;
|
||||
@ -350,8 +351,9 @@ public class RenderUnit {
|
||||
this.selectionCircle.move(dx, dy, map.terrain.centerOffset);
|
||||
}
|
||||
this.unitAnimationListenerImpl.update();
|
||||
if(!dead && simulationUnit.isConstructing()) {
|
||||
instance.setFrameByRatio(simulationUnit.getConstructionProgress() / simulationUnit.getUnitType().getBuildTime());
|
||||
if (!dead && this.simulationUnit.isConstructing()) {
|
||||
this.instance.setFrameByRatio(
|
||||
this.simulationUnit.getConstructionProgress() / this.simulationUnit.getUnitType().getBuildTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
this.activeHighlightFrame.setVisible(false);
|
||||
this.cooldownFrame.setVisible(false);
|
||||
this.autocastFrame.setVisible(false);
|
||||
setVisible(false);
|
||||
}
|
||||
else {
|
||||
if (commandButton.isEnabled()) {
|
||||
@ -74,6 +75,7 @@ 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 boolean menuButton) {
|
||||
this.menuButton = menuButton;
|
||||
setVisible(true);
|
||||
this.iconFrame.setVisible(true);
|
||||
this.activeHighlightFrame.setVisible(active);
|
||||
this.cooldownFrame.setVisible(false);
|
||||
@ -113,7 +115,7 @@ 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 (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
return this;
|
||||
}
|
||||
return super.touchDown(screenX, screenY, button);
|
||||
@ -121,7 +123,7 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
|
||||
@Override
|
||||
public UIFrame touchUp(final float screenX, final float screenY, final int button) {
|
||||
if (this.renderBounds.contains(screenX, screenY)) {
|
||||
if (isVisible() && this.renderBounds.contains(screenX, screenY)) {
|
||||
return this;
|
||||
}
|
||||
return super.touchUp(screenX, screenY, button);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user