mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
TestUI and FDFTest as well as small jass updates
This commit is contained in:
parent
38f67af599
commit
f54b74ba0f
@ -0,0 +1,868 @@
|
||||
package com.etheller.warsmash;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.GL30;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.math.Matrix4;
|
||||
import com.badlogic.gdx.math.Quaternion;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import com.etheller.warsmash.datasources.DataSource;
|
||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
|
||||
import com.etheller.warsmash.units.DataTable;
|
||||
import com.etheller.warsmash.util.DataSourceFileHandle;
|
||||
import com.etheller.warsmash.util.ImageUtils;
|
||||
import com.etheller.warsmash.util.StringBundle;
|
||||
import com.etheller.warsmash.util.WarsmashConstants;
|
||||
import com.etheller.warsmash.viewer5.Camera;
|
||||
import com.etheller.warsmash.viewer5.CanvasProvider;
|
||||
import com.etheller.warsmash.viewer5.Model;
|
||||
import com.etheller.warsmash.viewer5.ModelInstance;
|
||||
import com.etheller.warsmash.viewer5.ModelViewer;
|
||||
import com.etheller.warsmash.viewer5.PathSolver;
|
||||
import com.etheller.warsmash.viewer5.RenderBatch;
|
||||
import com.etheller.warsmash.viewer5.Scene;
|
||||
import com.etheller.warsmash.viewer5.SolvedPath;
|
||||
import com.etheller.warsmash.viewer5.TextureMapper;
|
||||
import com.etheller.warsmash.viewer5.handlers.ModelHandler;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.Sequence;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.TestUI;
|
||||
|
||||
public class WarsmashGdxFDFTestRenderScreen implements InputProcessor, Screen, SingleModelScreen {
|
||||
private static final boolean ENABLE_AUDIO = true;
|
||||
private DataSource codebase;
|
||||
private MdxViewer viewer;
|
||||
private MdxModel model;
|
||||
private CameraManager cameraManager;
|
||||
private final Rectangle tempRect = new Rectangle();
|
||||
|
||||
// libGDX stuff
|
||||
private OrthographicCamera uiCamera;
|
||||
private SpriteBatch batch;
|
||||
private Viewport uiViewport;
|
||||
private GlyphLayout glyphLayout;
|
||||
|
||||
private final DataTable warsmashIni;
|
||||
private Scene uiScene;
|
||||
private Texture solidGreenTexture;
|
||||
private TestUI menuUI;
|
||||
private final WarsmashGdxMultiScreenGame game;
|
||||
private Music currentMusic;
|
||||
private boolean hasPlayedStandHack = false;
|
||||
private boolean loaded = false;
|
||||
private final String finalFileToLoad;
|
||||
|
||||
public WarsmashGdxFDFTestRenderScreen(final DataTable warsmashIni, final WarsmashGdxMultiScreenGame game,
|
||||
final String finalFileToLoad) {
|
||||
this.warsmashIni = warsmashIni;
|
||||
this.game = game;
|
||||
this.finalFileToLoad = finalFileToLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
if (!this.loaded) {
|
||||
this.loaded = true;
|
||||
final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4);
|
||||
tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
final IntBuffer temp = tempByteBuffer.asIntBuffer();
|
||||
//
|
||||
Gdx.gl30.glGenVertexArrays(1, temp);
|
||||
WarsmashGdxGame.VAO = temp.get(0);
|
||||
|
||||
Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO);
|
||||
|
||||
final String renderer = Gdx.gl.glGetString(GL20.GL_RENDERER);
|
||||
System.err.println("Renderer: " + renderer);
|
||||
|
||||
this.codebase = WarsmashGdxMapScreen.parseDataSources(this.warsmashIni);
|
||||
this.viewer = new MdxViewer(this.codebase, this.game, Vector3.Zero);
|
||||
|
||||
this.viewer.addHandler(new MdxHandler());
|
||||
this.viewer.enableAudio();
|
||||
|
||||
this.scene = this.viewer.addSimpleScene();
|
||||
this.scene.enableAudio();
|
||||
|
||||
this.uiScene = this.viewer.addSimpleScene();
|
||||
this.uiScene.alpha = true;
|
||||
if (ENABLE_AUDIO) {
|
||||
this.uiScene.enableAudio();
|
||||
}
|
||||
final int width = Gdx.graphics.getWidth();
|
||||
final int height = Gdx.graphics.getHeight();
|
||||
|
||||
this.glyphLayout = new GlyphLayout();
|
||||
|
||||
// Constructs a new OrthographicCamera, using the given viewport width and
|
||||
// height
|
||||
// Height is multiplied by aspect ratio.
|
||||
this.uiCamera = new OrthographicCamera();
|
||||
int aspect3By4Width;
|
||||
int aspect3By4Height;
|
||||
if (width < ((height * 4) / 3)) {
|
||||
aspect3By4Width = width;
|
||||
aspect3By4Height = (width * 3) / 4;
|
||||
}
|
||||
else {
|
||||
aspect3By4Width = (height * 4) / 3;
|
||||
aspect3By4Height = height;
|
||||
}
|
||||
this.uiViewport = new FitViewport(aspect3By4Width, aspect3By4Height, this.uiCamera);
|
||||
this.uiViewport.update(width, height);
|
||||
|
||||
this.uiCamera.position.set(this.getMinWorldWidth() / 2, this.getMinWorldHeight() / 2, 0);
|
||||
this.uiCamera.update();
|
||||
|
||||
this.batch = new SpriteBatch();
|
||||
|
||||
this.solidGreenTexture = ImageUtils.getAnyExtensionTexture(this.viewer.dataSource,
|
||||
"ReplaceableTextures\\TeamColor\\TeamColor06.blp");
|
||||
|
||||
this.cameraManager = new CameraManager();
|
||||
this.cameraManager.setupCamera(this.scene);
|
||||
|
||||
System.out.println("Loaded");
|
||||
Gdx.gl30.glClearColor(0.0f, 0.0f, 0.0f, 1);
|
||||
final DataTable musicSLK = new DataTable(StringBundle.EMPTY);
|
||||
final String musicSLKPath = "UI\\SoundInfo\\Music.SLK";
|
||||
if (this.viewer.dataSource.has(musicSLKPath)) {
|
||||
try (InputStream miscDataTxtStream = this.viewer.dataSource.getResourceAsStream(musicSLKPath)) {
|
||||
musicSLK.readSLK(miscDataTxtStream);
|
||||
}
|
||||
catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
this.menuUI = new TestUI(this.viewer.dataSource, this.uiViewport, this.uiScene, this.viewer, this.game,
|
||||
this, this.warsmashIni, new RootFrameListener() {
|
||||
@Override
|
||||
public void onCreate(final GameUI rootFrame) {
|
||||
// WarsmashGdxMapGame.this.viewer.setGameUI(rootFrame);
|
||||
|
||||
if (WarsmashConstants.ENABLE_MUSIC) {
|
||||
final String musicField = rootFrame
|
||||
.getSkinField("GlueMusic_V" + WarsmashConstants.GAME_VERSION);
|
||||
final String[] musics = musicField.split(";");
|
||||
String musicPath = musics[(int) (Math.random() * musics.length)];
|
||||
if (musicSLK.get(musicPath) != null) {
|
||||
musicPath = musicSLK.get(musicPath).getField("FileNames");
|
||||
}
|
||||
final String[] moreSplitMusics = musicPath.split(",");
|
||||
final String finalMusicPath = moreSplitMusics[(int) (Math.random()
|
||||
* moreSplitMusics.length)];
|
||||
final Music music = Gdx.audio.newMusic(new DataSourceFileHandle(
|
||||
WarsmashGdxFDFTestRenderScreen.this.viewer.dataSource, finalMusicPath));
|
||||
// music.setVolume(0.2f);
|
||||
music.setLooping(true);
|
||||
music.play();
|
||||
WarsmashGdxFDFTestRenderScreen.this.currentMusic = music;
|
||||
}
|
||||
|
||||
WarsmashGdxFDFTestRenderScreen.this
|
||||
.singleModelScene(WarsmashGdxFDFTestRenderScreen.this.scene,
|
||||
War3MapViewer.mdx(rootFrame.getSkinField(
|
||||
"GlueSpriteLayerBackground_V" + WarsmashConstants.GAME_VERSION)),
|
||||
"Stand");
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera = WarsmashGdxFDFTestRenderScreen.this.mainModel.cameras
|
||||
.get(0);
|
||||
}
|
||||
}, this.finalFileToLoad);
|
||||
|
||||
final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "",
|
||||
PathSolver.DEFAULT, "").addInstance();
|
||||
libgdxContentInstance.setLocation(0f, 0f, -0.5f);
|
||||
libgdxContentInstance.setScene(this.uiScene);
|
||||
this.menuUI.main();
|
||||
|
||||
this.updateUIScene();
|
||||
|
||||
this.resize(width, height);
|
||||
}
|
||||
|
||||
Gdx.input.setInputProcessor(this);
|
||||
if (this.currentMusic != null) {
|
||||
this.currentMusic.play();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private float getMinWorldWidth() {
|
||||
if (this.uiViewport instanceof ExtendViewport) {
|
||||
return ((ExtendViewport) this.uiViewport).getMinWorldWidth();
|
||||
}
|
||||
return this.uiViewport.getWorldWidth();
|
||||
}
|
||||
|
||||
private float getMinWorldHeight() {
|
||||
if (this.uiViewport instanceof ExtendViewport) {
|
||||
return ((ExtendViewport) this.uiViewport).getMinWorldHeight();
|
||||
}
|
||||
return this.uiViewport.getWorldHeight();
|
||||
}
|
||||
|
||||
private void updateUIScene() {
|
||||
this.tempRect.x = this.uiViewport.getScreenX();
|
||||
this.tempRect.y = this.uiViewport.getScreenY();
|
||||
this.tempRect.width = this.uiViewport.getScreenWidth();
|
||||
this.tempRect.height = this.uiViewport.getScreenHeight();
|
||||
this.uiScene.camera.viewport(this.tempRect);
|
||||
final float worldWidth = this.uiViewport.getWorldWidth();
|
||||
final float worldHeight = this.uiViewport.getWorldHeight();
|
||||
final float xScale = worldWidth / this.getMinWorldWidth();
|
||||
final float yScale = worldHeight / this.getMinWorldHeight();
|
||||
final float uiSceneWidth = 0.8f * xScale;
|
||||
final float uiSceneHeight = 0.6f * yScale;
|
||||
final float uiSceneX = (0.8f - uiSceneWidth) / 2;
|
||||
final float uiSceneY = (0.6f - uiSceneHeight) / 2;
|
||||
this.uiScene.camera.ortho(uiSceneX, uiSceneWidth + uiSceneX, uiSceneY, uiSceneHeight + uiSceneY, -1024f, 1024);
|
||||
}
|
||||
|
||||
private void makeDruidSquare(final Scene scene) {
|
||||
final MdxModel model2 = (MdxModel) this.viewer.load("units\\nightelf\\druidoftheclaw\\druidoftheclaw.mdx",
|
||||
new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
this.makePerfectSquare(scene, model2, 15);
|
||||
}
|
||||
|
||||
private void singleAcolyteScene(final Scene scene) {
|
||||
final MdxModel model2 = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
|
||||
final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0);
|
||||
|
||||
instance3.setScene(scene);
|
||||
|
||||
int animIndex = 0;
|
||||
for (final Sequence s : model2.getSequences()) {
|
||||
if (s.getName().toLowerCase().startsWith("stand work")) {
|
||||
animIndex = model2.getSequences().indexOf(s);
|
||||
}
|
||||
}
|
||||
instance3.setSequence(animIndex);
|
||||
|
||||
instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
}
|
||||
|
||||
private void singleModelScene(final Scene scene, final String path, final String animName) {
|
||||
final MdxModel model2 = (MdxModel) this.viewer.load(path, new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
|
||||
final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0);
|
||||
|
||||
instance3.setScene(scene);
|
||||
|
||||
int animIndex = 0;
|
||||
for (final Sequence s : model2.getSequences()) {
|
||||
if (s.getName().toLowerCase().startsWith(animName)) {
|
||||
animIndex = model2.getSequences().indexOf(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
instance3.setSequence(animIndex);
|
||||
|
||||
instance3.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP);
|
||||
this.mainInstance = instance3;
|
||||
this.mainModel = model2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModel(final String path) {
|
||||
if (this.mainInstance != null) {
|
||||
this.mainInstance.detach();
|
||||
}
|
||||
if (path == null) {
|
||||
this.modelCamera = null;
|
||||
this.mainInstance = null;
|
||||
this.mainModel = null;
|
||||
}
|
||||
else {
|
||||
this.singleModelScene(this.scene, War3MapViewer.mdx(path), "birth");
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera = WarsmashGdxFDFTestRenderScreen.this.mainModel.cameras
|
||||
.get(0);
|
||||
// this hack is because we only have the queued animation system in RenderWidget
|
||||
// which is stupid and back and needs to get moved to the model instance
|
||||
// itself... our model instance class is a
|
||||
// hacky replica of a model viewer tool with a bunch of irrelevant loop type
|
||||
// settings instead of what it should be
|
||||
this.hasPlayedStandHack = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void acolytesHarvestingScene(final Scene scene) {
|
||||
|
||||
final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx",
|
||||
new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
final MdxModel mineEffectModel = (MdxModel) this.viewer
|
||||
.load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0);
|
||||
|
||||
acolyteInstance.setScene(scene);
|
||||
|
||||
int animIndex = i % acolyteModel.getSequences().size();
|
||||
for (final Sequence s : acolyteModel.getSequences()) {
|
||||
if (s.getName().toLowerCase().startsWith("stand work")) {
|
||||
animIndex = acolyteModel.getSequences().indexOf(s);
|
||||
}
|
||||
}
|
||||
acolyteInstance.setSequence(animIndex);
|
||||
|
||||
acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
|
||||
final double angle = ((Math.PI * 2) / 5) * i;
|
||||
acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256;
|
||||
acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256;
|
||||
acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI));
|
||||
|
||||
final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0);
|
||||
|
||||
effectInstance.setScene(scene);
|
||||
|
||||
effectInstance.setSequence(1);
|
||||
|
||||
effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
effectInstance.localLocation.x = (float) Math.cos(angle) * 256;
|
||||
effectInstance.localLocation.y = (float) Math.sin(angle) * 256;
|
||||
effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) angle);
|
||||
|
||||
}
|
||||
final MdxModel mineModel = (MdxModel) this.viewer.load("buildings\\undead\\hauntedmine\\hauntedmine.mdx",
|
||||
new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0);
|
||||
|
||||
mineInstance.setScene(scene);
|
||||
|
||||
mineInstance.setSequence(2);
|
||||
|
||||
mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
}
|
||||
|
||||
private void acolytesHarvestingSceneJoke2(final Scene scene) {
|
||||
|
||||
final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx",
|
||||
new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
final MdxModel mineEffectModel = (MdxModel) this.viewer
|
||||
.load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0);
|
||||
|
||||
acolyteInstance.setScene(scene);
|
||||
|
||||
int animIndex = i % acolyteModel.getSequences().size();
|
||||
for (final Sequence s : acolyteModel.getSequences()) {
|
||||
if (s.getName().toLowerCase().startsWith("stand work")) {
|
||||
animIndex = acolyteModel.getSequences().indexOf(s);
|
||||
}
|
||||
}
|
||||
acolyteInstance.setSequence(animIndex);
|
||||
|
||||
acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
|
||||
final double angle = ((Math.PI * 2) / 5) * i;
|
||||
acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256;
|
||||
acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256;
|
||||
acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI));
|
||||
|
||||
final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0);
|
||||
|
||||
effectInstance.setScene(scene);
|
||||
|
||||
effectInstance.setSequence(1);
|
||||
|
||||
effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
effectInstance.localLocation.x = (float) Math.cos(angle) * 256;
|
||||
effectInstance.localLocation.y = (float) Math.sin(angle) * 256;
|
||||
effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) angle);
|
||||
|
||||
}
|
||||
final MdxModel mineModel = (MdxModel) this.viewer.load("units\\orc\\spiritwolf\\spiritwolf.mdx",
|
||||
new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0);
|
||||
|
||||
mineInstance.setScene(scene);
|
||||
|
||||
mineInstance.setSequence(0);
|
||||
mineInstance.localScale.x = 2;
|
||||
mineInstance.localScale.y = 2;
|
||||
mineInstance.localScale.z = 2;
|
||||
|
||||
mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
final MdxModel mineModel2 = (MdxModel) this.viewer
|
||||
.load("abilities\\spells\\undead\\unsummon\\unsummontarget.mdx", new PathSolver() {
|
||||
@Override
|
||||
public SolvedPath solve(final String src, final Object solverParams) {
|
||||
return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true);
|
||||
}
|
||||
}, null);
|
||||
final MdxComplexInstance mineInstance2 = (MdxComplexInstance) mineModel2.addInstance(0);
|
||||
|
||||
mineInstance2.setScene(scene);
|
||||
|
||||
mineInstance2.setSequence(0);
|
||||
|
||||
mineInstance2.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
}
|
||||
|
||||
private void makeFourHundred(final Scene scene, final MdxModel model2) {
|
||||
for (int i = 0; i < 400; i++) {
|
||||
final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0);
|
||||
instance3.localLocation.x = ((i % 20) - 10) * 128;
|
||||
instance3.localLocation.y = ((i / 20) - 10) * 128;
|
||||
|
||||
instance3.setScene(scene);
|
||||
|
||||
final int animIndex = i % model2.getSequences().size();
|
||||
instance3.setSequence(animIndex);
|
||||
|
||||
instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
}
|
||||
}
|
||||
|
||||
private void makePerfectSquare(final Scene scene, final MdxModel model2, final int n) {
|
||||
final int n2 = n * n;
|
||||
for (int i = 0; i < n2; i++) {
|
||||
final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0);
|
||||
instance3.localLocation.x = ((i % n) - (n / 2)) * 128;
|
||||
instance3.localLocation.y = ((i / n) - (n / 2)) * 128;
|
||||
|
||||
instance3.setScene(scene);
|
||||
|
||||
final int animIndex = i % model2.getSequences().size();
|
||||
instance3.setSequence(animIndex);
|
||||
|
||||
instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindDefaultVertexArray() {
|
||||
Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO);
|
||||
}
|
||||
|
||||
private final int frame = 0;
|
||||
private MdxComplexInstance mainInstance;
|
||||
private MdxModel mainModel;
|
||||
private com.etheller.warsmash.viewer5.handlers.mdx.Camera modelCamera;
|
||||
private final float[] cameraPositionTemp = new float[3];
|
||||
private final float[] cameraTargetTemp = new float[3];
|
||||
private final boolean firstFrame = true;
|
||||
private Scene scene;
|
||||
|
||||
@Override
|
||||
public void render(final float delta) {
|
||||
|
||||
Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST);
|
||||
final float deltaTime = Gdx.graphics.getDeltaTime();
|
||||
Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO);
|
||||
this.cameraManager.updateCamera();
|
||||
this.menuUI.update(deltaTime);
|
||||
if ((this.mainInstance != null) && this.mainInstance.sequenceEnded
|
||||
&& (((this.mainModel.getSequences().get(this.mainInstance.sequence).getFlags() & 0x1) == 0)
|
||||
|| !this.hasPlayedStandHack)) {
|
||||
SequenceUtils.randomStandSequence(this.mainInstance);
|
||||
this.hasPlayedStandHack = true;
|
||||
}
|
||||
this.viewer.updateAndRender();
|
||||
|
||||
Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST);
|
||||
|
||||
Gdx.gl30.glDisable(GL30.GL_CULL_FACE);
|
||||
|
||||
this.viewer.webGL.useShaderProgram(null);
|
||||
|
||||
Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
this.menuUI.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(final int width, final int height) {
|
||||
this.tempRect.width = width;
|
||||
this.tempRect.height = height;
|
||||
final float fourThirdsHeight = (this.tempRect.height * 4) / 3;
|
||||
if (fourThirdsHeight < this.tempRect.width) {
|
||||
final float dx = this.tempRect.width - fourThirdsHeight;
|
||||
this.tempRect.width = fourThirdsHeight;
|
||||
this.tempRect.x = dx / 2;
|
||||
}
|
||||
else {
|
||||
final float threeFourthsWidth = (this.tempRect.width * 3) / 4;
|
||||
if (threeFourthsWidth < this.tempRect.height) {
|
||||
final float dy = this.tempRect.height - threeFourthsWidth;
|
||||
this.tempRect.height = threeFourthsWidth;
|
||||
this.tempRect.y = dy;
|
||||
}
|
||||
}
|
||||
this.cameraManager.camera.viewport(this.tempRect);
|
||||
|
||||
// super.resize(width, height);
|
||||
|
||||
this.uiViewport.update(width, height);
|
||||
this.uiCamera.position.set(this.getMinWorldWidth() / 2, this.getMinWorldHeight() / 2, 0);
|
||||
|
||||
this.menuUI.resize();
|
||||
this.updateUIScene();
|
||||
|
||||
}
|
||||
|
||||
class CameraManager {
|
||||
private CanvasProvider canvas;
|
||||
private Camera camera;
|
||||
private float moveSpeed;
|
||||
private float rotationSpeed;
|
||||
private float zoomFactor;
|
||||
private float horizontalAngle;
|
||||
private float verticalAngle;
|
||||
private float distance;
|
||||
private Vector3 position;
|
||||
private Vector3 target;
|
||||
private Vector3 worldUp;
|
||||
private Vector3 vecHeap;
|
||||
private Vector3 vecHeap2;
|
||||
private Quaternion quatHeap;
|
||||
private Quaternion quatHeap2;
|
||||
|
||||
// An orbit camera setup example.
|
||||
// Left mouse button controls the orbit itself.
|
||||
// The right mouse button allows to move the camera and the point it's looking
|
||||
// at on the XY plane.
|
||||
// Scrolling zooms in and out.
|
||||
private void setupCamera(final Scene scene) {
|
||||
this.canvas = scene.viewer.canvas;
|
||||
this.camera = scene.camera;
|
||||
this.moveSpeed = 2;
|
||||
this.rotationSpeed = (float) (Math.PI / 180);
|
||||
this.zoomFactor = 0.1f;
|
||||
this.horizontalAngle = (float) (Math.PI / 2);
|
||||
this.verticalAngle = (float) (Math.PI / 4);
|
||||
this.distance = 500;
|
||||
this.position = new Vector3();
|
||||
this.target = new Vector3(0, 0, 50);
|
||||
this.worldUp = new Vector3(0, 0, 1);
|
||||
this.vecHeap = new Vector3();
|
||||
this.vecHeap2 = new Vector3();
|
||||
this.quatHeap = new Quaternion();
|
||||
this.quatHeap2 = new Quaternion();
|
||||
|
||||
this.updateCamera();
|
||||
|
||||
// cameraUpdate();
|
||||
}
|
||||
|
||||
private void updateCamera() {
|
||||
// Limit the vertical angle so it doesn't flip.
|
||||
// Since the camera uses a quaternion, flips don't matter to it, but this feels
|
||||
// better.
|
||||
this.verticalAngle = (float) Math.min(Math.max(0.01, this.verticalAngle), Math.PI - 0.01);
|
||||
|
||||
this.quatHeap.idt();
|
||||
this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle);
|
||||
this.quatHeap2.idt();
|
||||
this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle);
|
||||
this.quatHeap.mul(this.quatHeap2);
|
||||
|
||||
this.position.set(0, 0, 1);
|
||||
this.quatHeap.transform(this.position);
|
||||
this.position.scl(this.distance);
|
||||
this.position = this.position.add(this.target);
|
||||
if (WarsmashGdxFDFTestRenderScreen.this.modelCamera != null) {
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera.getPositionTranslation(
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraPositionTemp,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.sequence,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.frame,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.counter);
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera.getTargetTranslation(
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraTargetTemp,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.sequence,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.frame,
|
||||
WarsmashGdxFDFTestRenderScreen.this.mainInstance.counter);
|
||||
|
||||
this.position.set(WarsmashGdxFDFTestRenderScreen.this.modelCamera.position);
|
||||
this.target.set(WarsmashGdxFDFTestRenderScreen.this.modelCamera.targetPosition);
|
||||
// this.vecHeap2.set(this.target);
|
||||
// this.vecHeap2.sub(this.position);
|
||||
// this.vecHeap.set(this.vecHeap2);
|
||||
// this.vecHeap.crs(this.worldUp);
|
||||
// this.vecHeap.crs(this.vecHeap2);
|
||||
// this.vecHeap.nor();
|
||||
// this.vecHeap.scl(this.camera.rect.height / 2f);
|
||||
// this.position.add(this.vecHeap);
|
||||
|
||||
this.position.add(WarsmashGdxFDFTestRenderScreen.this.cameraPositionTemp[0],
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraPositionTemp[1],
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraPositionTemp[2]);
|
||||
this.target.add(WarsmashGdxFDFTestRenderScreen.this.cameraTargetTemp[0],
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraTargetTemp[1],
|
||||
WarsmashGdxFDFTestRenderScreen.this.cameraTargetTemp[2]);
|
||||
this.camera.perspective(WarsmashGdxFDFTestRenderScreen.this.modelCamera.fieldOfView * 0.6f,
|
||||
this.camera.rect.width / this.camera.rect.height,
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera.nearClippingPlane,
|
||||
WarsmashGdxFDFTestRenderScreen.this.modelCamera.farClippingPlane);
|
||||
}
|
||||
else {
|
||||
this.camera.perspective(70, this.camera.getAspect(), 100, 5000);
|
||||
}
|
||||
|
||||
this.camera.moveToAndFace(this.position, this.target, this.worldUp);
|
||||
}
|
||||
|
||||
// private void cameraUpdate() {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
public DataSource getCodebase() {
|
||||
return this.codebase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(final int keycode) {
|
||||
return this.menuUI.keyDown(keycode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(final int keycode) {
|
||||
return this.menuUI.keyUp(keycode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(final char character) {
|
||||
return this.menuUI.keyTyped(character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) {
|
||||
final float worldScreenY = this.game.getHeight() - screenY;
|
||||
|
||||
if (this.menuUI.touchDown(screenX, screenY, worldScreenY, button)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchUp(final int screenX, final int screenY, final int pointer, final int button) {
|
||||
final float worldScreenY = this.game.getHeight() - screenY;
|
||||
|
||||
if (this.menuUI.touchUp(screenX, screenY, worldScreenY, button)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDragged(final int screenX, final int screenY, final int pointer) {
|
||||
final float worldScreenY = this.game.getHeight() - screenY;
|
||||
if (this.menuUI.touchDragged(screenX, screenY, worldScreenY, pointer)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(final int screenX, final int screenY) {
|
||||
final float worldScreenY = this.game.getHeight() - screenY;
|
||||
if (this.menuUI.mouseMoved(screenX, screenY, worldScreenY)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrolled(final int amount) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private void renderLibGDXContent() {
|
||||
|
||||
Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST);
|
||||
|
||||
Gdx.gl30.glDisable(GL30.GL_CULL_FACE);
|
||||
|
||||
this.viewer.webGL.useShaderProgram(null);
|
||||
|
||||
Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0);
|
||||
|
||||
this.uiViewport.apply();
|
||||
this.batch.setProjectionMatrix(this.uiCamera.combined);
|
||||
this.batch.begin();
|
||||
this.menuUI.render(this.batch, this.glyphLayout);
|
||||
this.batch.end();
|
||||
|
||||
Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST);
|
||||
Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO);
|
||||
}
|
||||
|
||||
private class LibGDXContentLayerModelInstance extends ModelInstance {
|
||||
|
||||
public LibGDXContentLayerModelInstance(final Model model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAnimations(final float dt) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEmittedObjects() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateLights(final Scene scene2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderOpaque(final Matrix4 mvp) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTranslucent() {
|
||||
WarsmashGdxFDFTestRenderScreen.this.renderLibGDXContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RenderBatch getBatch(final TextureMapper textureMapper2) {
|
||||
throw new UnsupportedOperationException("NOT API");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReplaceableTexture(final int replaceableTextureId, final String replaceableTextureFile) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBatched() {
|
||||
return super.isBatched();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeLights(final Scene scene2) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class LibGDXContentLayerModel extends Model {
|
||||
|
||||
public LibGDXContentLayerModel(final ModelHandler handler, final ModelViewer viewer, final String extension,
|
||||
final PathSolver pathSolver, final String fetchUrl) {
|
||||
super(handler, viewer, extension, pathSolver, fetchUrl);
|
||||
this.ok = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelInstance createInstance(final int type) {
|
||||
return new LibGDXContentLayerModelInstance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void lateLoad() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(final InputStream src, final Object options) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void error(final Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
if (this.currentMusic != null) {
|
||||
this.currentMusic.stop();
|
||||
}
|
||||
this.menuUI.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
}
|
||||
}
|
@ -1,206 +1,35 @@
|
||||
package com.etheller.warsmash.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxAttachment;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxBone;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxExtent;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxLight;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxLight.Type;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxMaterial;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxModel;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture;
|
||||
import com.hiveworkshop.rms.parsers.mdlx.util.MdxUtils;
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(final String[] args) {
|
||||
final Pattern pattern = Pattern.compile("^\\[(.+?)\\]");
|
||||
final Matcher matcher = pattern.matcher("[boat] // ocean");
|
||||
if (matcher.matches()) {
|
||||
final String name = matcher.group(1).trim().toLowerCase();
|
||||
System.out.println(name);
|
||||
final File mdxFile = new File("C:\\Users\\micro\\Downloads\\DrunkSnake\\NagaTridentyr.mdx");
|
||||
final File mdlFile = new File("C:\\Users\\micro\\Downloads\\DrunkSnake\\NagaTridentyr.mdl");
|
||||
try (FileInputStream stream = new FileInputStream(mdxFile)) {
|
||||
final MdlxModel mdlx = MdxUtils.loadMdlx(stream);
|
||||
final ByteBuffer mdl = mdlx.saveMdl();
|
||||
try (FileChannel outChannel = FileChannel.open(mdlFile.toPath(), StandardOpenOption.CREATE,
|
||||
StandardOpenOption.WRITE)) {
|
||||
outChannel.write(mdl);
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println("no match");
|
||||
}
|
||||
|
||||
// Quadtree<String> myQT = new Quadtree<>(new Rectangle(-, y, width, height))
|
||||
|
||||
final MdlxModel model = new MdlxModel();
|
||||
upExtent(model.extent);
|
||||
MdlxSequence sequence = new MdlxSequence();
|
||||
sequence.name = "Stand";
|
||||
sequence.interval = new long[] { 333, 332 };
|
||||
upExtent(sequence.extent);
|
||||
model.sequences.add(sequence);
|
||||
sequence = new MdlxSequence();
|
||||
sequence.name = "Stand";
|
||||
sequence.interval = new long[] { 333, 332 };
|
||||
upExtent(sequence.extent);
|
||||
model.sequences.add(sequence);
|
||||
sequence.name = "Stand";
|
||||
sequence.interval = new long[] { 334, 333 };
|
||||
upExtent(sequence.extent);
|
||||
model.sequences.add(sequence);
|
||||
sequence.name = "Stand";
|
||||
sequence.interval = new long[] { 331, 330 };
|
||||
upExtent(sequence.extent);
|
||||
model.sequences.add(sequence);
|
||||
|
||||
MdlxGeoset mdlxGeoset = new MdlxGeoset();
|
||||
upExtent(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.vertices = new float[] { -128f, -128f, 0f, 128f, -128f, 0f, 128f, 128f, 0f, -128f, 128f, 0f };
|
||||
mdlxGeoset.vertexGroups = new short[] { 0, 0, 0, 0 };
|
||||
mdlxGeoset.normals = new float[] { 0, 0, 1, 0, 128f, 1, 0, 0, Float.NaN, 0, 0, 1 };
|
||||
mdlxGeoset.faceTypeGroups = new long[] { 1, 0 };
|
||||
mdlxGeoset.faces = new int[] { 0, 1, 2, 3 };
|
||||
mdlxGeoset.faceGroups = new long[] { 2, 2 };
|
||||
mdlxGeoset.materialId = 0;
|
||||
mdlxGeoset.matrixGroups = new long[] { 3 };
|
||||
mdlxGeoset.matrixIndices = new long[] { 0, 1, 2 };
|
||||
mdlxGeoset.uvSets = new float[][] { { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f } };
|
||||
model.geosets.add(mdlxGeoset);
|
||||
|
||||
final int n = 3600;
|
||||
mdlxGeoset = new MdlxGeoset();
|
||||
upExtent(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent);
|
||||
mdlxGeoset.vertices = new float[(n + 1) * 3];
|
||||
for (int i = 1; i <= n; i++) {
|
||||
final float distance = 4000;
|
||||
final float down = (float) ((((((i / 360) % 10) + 1) / 10f) * Math.PI) / 2);
|
||||
final float around = (float) (((i % 360) / 360f) * Math.PI * 2);
|
||||
final float xyRad = (float) (Math.sin(down) * distance);
|
||||
final float z = (float) (Math.cos(down) * distance);
|
||||
mdlxGeoset.vertices[i * 3] = (float) (Math.cos(around) * xyRad);
|
||||
mdlxGeoset.vertices[(i * 3) + 1] = (float) (Math.sin(around) * xyRad);
|
||||
mdlxGeoset.vertices[(i * 3) + 2] = z;
|
||||
}
|
||||
mdlxGeoset.vertexGroups = new short[(n + 1)];
|
||||
mdlxGeoset.normals = new float[(n + 1) * 3];
|
||||
mdlxGeoset.faceTypeGroups = new long[n];
|
||||
Arrays.fill(mdlxGeoset.faceTypeGroups, 1);
|
||||
mdlxGeoset.faces = new int[n * 2];
|
||||
for (int i = 0; i < n; i++) {
|
||||
mdlxGeoset.faces[(i * 2) + 1] = i + 1;
|
||||
}
|
||||
mdlxGeoset.faceGroups = new long[n];
|
||||
Arrays.fill(mdlxGeoset.faceGroups, 2);
|
||||
mdlxGeoset.materialId = 0;
|
||||
mdlxGeoset.matrixGroups = new long[] { 3 };
|
||||
mdlxGeoset.matrixIndices = new long[] { 0, 1, 2 };
|
||||
mdlxGeoset.uvSets = new float[][] { { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f } };
|
||||
model.geosets.add(mdlxGeoset);
|
||||
|
||||
final MdlxTexture texture = new MdlxTexture();
|
||||
texture.setPath("Textures\\white.blp");
|
||||
model.textures.add(texture);
|
||||
|
||||
final MdlxMaterial material = new MdlxMaterial();
|
||||
final MdlxLayer layer = new MdlxLayer();
|
||||
layer.alpha = 1.0f;
|
||||
layer.textureId = 0;
|
||||
layer.filterMode = FilterMode.NONE;
|
||||
material.layers.add(layer);
|
||||
model.materials.add(material);
|
||||
|
||||
final MdlxBone stupid1 = makeStupidBone("Bone_A");
|
||||
stupid1.setObjectId(0);
|
||||
stupid1.setParentId(-1);
|
||||
model.bones.add(stupid1);
|
||||
final MdlxBone stupid2 = makeStupidBone("Bone_B");
|
||||
stupid2.setObjectId(1);
|
||||
stupid1.setParentId(-1);
|
||||
model.bones.add(stupid2);
|
||||
final MdlxBone stupid3 = makeStupidBone("Bone_C");
|
||||
stupid2.setObjectId(2);
|
||||
stupid1.setParentId(-1);
|
||||
model.bones.add(stupid3);
|
||||
|
||||
final MdlxLight light = new MdlxLight();
|
||||
light.ambientColor[0] = -5;
|
||||
light.ambientColor[1] = 0;
|
||||
light.ambientColor[2] = Float.MAX_VALUE;
|
||||
light.ambientIntensity = Float.MAX_VALUE;
|
||||
light.intensity = Float.MAX_VALUE;
|
||||
light.attenuation[0] = Float.MAX_VALUE;
|
||||
light.attenuation[1] = Float.MAX_VALUE;
|
||||
light.color[0] = -5;
|
||||
light.color[1] = -5;
|
||||
light.color[2] = Float.MAX_VALUE;
|
||||
light.type = Type.OMNIDIRECTIONAL;
|
||||
light.name = "#!@$!@#$";
|
||||
light.objectId = 3;
|
||||
light.parentId = -1;
|
||||
model.lights.add(light);
|
||||
|
||||
final MdlxAttachment attachment = new MdlxAttachment();
|
||||
attachment.setObjectId(4);
|
||||
attachment.setParentId(-1);
|
||||
attachment.setName("!@#$");
|
||||
// attachment.setPath("war3mapImport\\stupidFan.mdl");
|
||||
model.attachments.add(attachment);
|
||||
|
||||
final MdlxParticleEmitter mdlxParticleEmitter = new MdlxParticleEmitter();
|
||||
mdlxParticleEmitter.emissionRate = 99999;
|
||||
mdlxParticleEmitter.flags |= 0x8000;
|
||||
mdlxParticleEmitter.lifeSpan = 99999;
|
||||
mdlxParticleEmitter.name = "ATCH";
|
||||
mdlxParticleEmitter.objectId = 5;
|
||||
mdlxParticleEmitter.parentId = -1;
|
||||
mdlxParticleEmitter.path = "Doodads\\Cinematic\\ArthasIllidanFight\\ArthasIllidanFight.mdl";
|
||||
model.particleEmitters.add(mdlxParticleEmitter);
|
||||
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
model.pivotPoints.add(new float[] { 0, 0, 0 });
|
||||
|
||||
final ByteBuffer mdxBuffer = model.saveMdx();
|
||||
try {
|
||||
Files.write(mdxBuffer.array(), new File("C:\\Temp\\doomball.mdx"));
|
||||
catch (final FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void upExtent(final MdlxExtent extent) {
|
||||
extent.boundsRadius = Float.MAX_VALUE;
|
||||
extent.max[0] = Float.MAX_VALUE;
|
||||
extent.max[1] = Float.MAX_VALUE;
|
||||
extent.max[2] = Float.MAX_VALUE;
|
||||
extent.min[0] = -Float.MAX_VALUE;
|
||||
extent.min[1] = -Float.MAX_VALUE;
|
||||
extent.min[2] = -Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
private static MdlxBone makeStupidBone(final String name) {
|
||||
final MdlxBone stupid1 = new MdlxBone();
|
||||
stupid1.setName(name);
|
||||
stupid1.setGeosetId(-1);
|
||||
stupid1.setGeosetAnimationId(-1);
|
||||
return stupid1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
computedRotation = rotationHeap;
|
||||
|
||||
computedRotation.set(this.parent.inverseWorldRotation);
|
||||
if(scene!=null) {
|
||||
if (scene != null) {
|
||||
// TODO null scene is stupid, and happens rarely
|
||||
computedRotation.mul(scene.camera.inverseRotation);
|
||||
}
|
||||
@ -194,6 +194,9 @@ public abstract class SkeletalNode extends GenericNode {
|
||||
|
||||
RenderMathUtils.mul(computedRotation, computedRotation, rotationHeap2);
|
||||
}
|
||||
else if (this.dontInheritRotation) {
|
||||
RenderMathUtils.mul(computedRotation, this.parent.inverseWorldRotation, computedRotation);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) {
|
||||
|
@ -56,8 +56,8 @@ public class GenericObject extends AnimatedObject implements GenericIndexed {
|
||||
final int flags = object.getFlags();
|
||||
|
||||
this.dontInheritTranslation = flags & 0x1;
|
||||
this.dontInheritRotation = flags & 0x2;
|
||||
this.dontInheritScaling = flags & 0x4;
|
||||
this.dontInheritScaling = flags & 0x2;
|
||||
this.dontInheritRotation = flags & 0x4;
|
||||
this.billboarded = flags & 0x8;
|
||||
this.billboardedX = flags & 0x10;
|
||||
this.billboardedY = flags & 0x20;
|
||||
|
@ -234,7 +234,7 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
}
|
||||
|
||||
private void initNode(final MdxNode[] nodes, final SkeletalNode node, final GenericObject genericObject) {
|
||||
initNode(nodes, node, genericObject, null);
|
||||
this.initNode(nodes, node, genericObject, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,7 +251,10 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
node.parent = nodes[genericObject.parentId];
|
||||
}
|
||||
|
||||
/// TODO: single-axis billboarding
|
||||
node.dontInheritTranslation = genericObject.dontInheritTranslation > 0;
|
||||
node.dontInheritScaling = genericObject.dontInheritScaling > 0;
|
||||
node.dontInheritRotation = genericObject.dontInheritRotation > 0;
|
||||
|
||||
if (genericObject.billboarded != 0) {
|
||||
node.billboarded = true;
|
||||
}
|
||||
@ -573,11 +576,13 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
|
||||
final long animEnd = interval[1] - 1;
|
||||
if (this.floatingFrame >= animEnd) {
|
||||
boolean sequenceRestarted = false;
|
||||
if ((this.sequenceLoopMode == SequenceLoopMode.ALWAYS_LOOP)
|
||||
|| ((this.sequenceLoopMode == SequenceLoopMode.MODEL_LOOP) && (sequence.getFlags() == 0))) {
|
||||
this.floatingFrame = this.frame = (int) interval[0]; // TODO not cast
|
||||
|
||||
this.resetEventEmitters();
|
||||
sequenceRestarted = true;
|
||||
}
|
||||
else if (this.sequenceLoopMode == SequenceLoopMode.LOOP_TO_NEXT_ANIMATION) { // faux queued animation
|
||||
// mode
|
||||
@ -590,6 +595,7 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
this.sequenceEnded = false;
|
||||
this.resetEventEmitters();
|
||||
this.forced = true;
|
||||
sequenceRestarted = true;
|
||||
}
|
||||
else {
|
||||
this.floatingFrame = this.frame = (int) animEnd; // TODO not cast
|
||||
@ -597,10 +603,10 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
this.allowParticleSpawn = false;
|
||||
}
|
||||
if (this.sequenceLoopMode == SequenceLoopMode.NEVER_LOOP_AND_HIDE_WHEN_DONE) {
|
||||
hide();
|
||||
this.hide();
|
||||
}
|
||||
|
||||
this.sequenceEnded = true;
|
||||
this.sequenceEnded = !sequenceRestarted;
|
||||
}
|
||||
else {
|
||||
this.sequenceEnded = false;
|
||||
@ -800,7 +806,7 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
}
|
||||
|
||||
public boolean intersectRayBounds(final Ray ray, final Vector3 intersection) {
|
||||
return CollisionShape.intersectRayBounds(getBounds(), this.worldMatrix, ray, intersection);
|
||||
return CollisionShape.intersectRayBounds(this.getBounds(), this.worldMatrix, ray, intersection);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -824,7 +830,7 @@ public class MdxComplexInstance extends ModelInstance {
|
||||
intersected = true;
|
||||
}
|
||||
}
|
||||
return intersected || (!this.hasAnyUnselectableMesh && intersectRayBounds(ray, intersection));
|
||||
return intersected || (!this.hasAnyUnselectableMesh && this.intersectRayBounds(ray, intersection));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -384,9 +384,9 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
this.selectionCircleScaleFactor = selectionCircleData.getFieldFloatValue("ScaleFactor");
|
||||
this.imageWalkableZOffset = selectionCircleData.getFieldValue("ImageWalkableZOffset");
|
||||
this.selectionCircleColorFriend = parseColor(selectionCircleData, "ColorFriend");
|
||||
this.selectionCircleColorNeutral = parseColor(selectionCircleData, "ColorNeutral");
|
||||
this.selectionCircleColorEnemy = parseColor(selectionCircleData, "ColorEnemy");
|
||||
this.selectionCircleColorFriend = this.parseColor(selectionCircleData, "ColorFriend");
|
||||
this.selectionCircleColorNeutral = this.parseColor(selectionCircleData, "ColorNeutral");
|
||||
this.selectionCircleColorEnemy = this.parseColor(selectionCircleData, "ColorEnemy");
|
||||
|
||||
this.uiSoundsTable = new DataTable(worldEditStrings);
|
||||
try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) {
|
||||
@ -410,10 +410,10 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
public GenericResource loadMapGeneric(final String path, final FetchDataTypeName dataType,
|
||||
final LoadGenericCallback callback) {
|
||||
if (this.mapMpq == null) {
|
||||
return loadGeneric(path, dataType, callback);
|
||||
return this.loadGeneric(path, dataType, callback);
|
||||
}
|
||||
else {
|
||||
return loadGeneric(path, dataType, callback, this.dataSource);
|
||||
return this.loadGeneric(path, dataType, callback, this.dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,9 +506,9 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
catch (final MPQException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
setDataSource(tilesetSource);
|
||||
this.setDataSource(tilesetSource);
|
||||
this.worldEditStrings = new WorldEditStrings(this.dataSource);
|
||||
loadSLKs(this.worldEditStrings);
|
||||
this.loadSLKs(this.worldEditStrings);
|
||||
|
||||
this.solverParams.tileset = Character.toLowerCase(tileset);
|
||||
|
||||
@ -530,7 +530,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
this.worldScene.grid = new Grid(centerOffset[0], centerOffset[1], (mapSize[0] * 128) - 128,
|
||||
(mapSize[1] * 128) - 128, 16 * 128, 16 * 128);
|
||||
|
||||
final MdxModel confirmation = (MdxModel) load("UI\\Feedback\\Confirmation\\Confirmation.mdx",
|
||||
final MdxModel confirmation = (MdxModel) this.load("UI\\Feedback\\Confirmation\\Confirmation.mdx",
|
||||
PathSolver.DEFAULT, null);
|
||||
this.confirmationInstance = (MdxComplexInstance) confirmation.addInstance();
|
||||
this.confirmationInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP_AND_HIDE_WHEN_DONE);
|
||||
@ -573,8 +573,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final CAttackProjectile simulationAttackProjectile = new CAttackProjectile(x, y,
|
||||
projectileSpeed, target, source, damage, unitAttack, bounceIndex, attackListener);
|
||||
|
||||
final MdxModel model = (MdxModel) load(missileArt, War3MapViewer.this.mapPathSolver,
|
||||
War3MapViewer.this.solverParams);
|
||||
final MdxModel model = (MdxModel) War3MapViewer.this.load(missileArt,
|
||||
War3MapViewer.this.mapPathSolver, War3MapViewer.this.solverParams);
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance();
|
||||
modelInstance.setTeamColor(source.getPlayerIndex());
|
||||
modelInstance.setScene(War3MapViewer.this.worldScene);
|
||||
@ -619,8 +619,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final float height = War3MapViewer.this.terrain.getGroundHeight(targetX, targetY)
|
||||
+ target.getFlyHeight() + target.getImpactZ();
|
||||
|
||||
final MdxModel model = (MdxModel) load(missileArt, War3MapViewer.this.mapPathSolver,
|
||||
War3MapViewer.this.solverParams);
|
||||
final MdxModel model = (MdxModel) War3MapViewer.this.load(missileArt,
|
||||
War3MapViewer.this.mapPathSolver, War3MapViewer.this.solverParams);
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance();
|
||||
modelInstance.setTeamColor(source.getPlayerIndex());
|
||||
SequenceUtils.randomBirthSequence(modelInstance);
|
||||
@ -633,7 +633,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
@Override
|
||||
public void spawnDamageSound(final CWidget damagedDestructable, final String weaponSound,
|
||||
final String armorType) {
|
||||
final RenderWidget damagedWidget = getRenderPeer(damagedDestructable);
|
||||
final RenderWidget damagedWidget = War3MapViewer.this.getRenderPeer(damagedDestructable);
|
||||
if (damagedWidget == null) {
|
||||
return;
|
||||
}
|
||||
@ -711,15 +711,18 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
@Override
|
||||
public CUnit createUnit(final CSimulation simulation, final War3ID typeId, final int playerIndex,
|
||||
final float x, final float y, final float facing) {
|
||||
return (CUnit) createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y, playerIndex,
|
||||
playerIndex, (float) Math.toRadians(facing));
|
||||
return (CUnit) War3MapViewer.this.createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y,
|
||||
playerIndex, playerIndex, (float) Math.toRadians(facing));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CDestructable createDestructable(final War3ID typeId, final float x, final float y,
|
||||
final float facing, final float scale, final int variation) {
|
||||
return createDestructableZ(typeId, x, y, Math.max(getWalkableRenderHeight(x, y),
|
||||
War3MapViewer.this.terrain.getGroundHeight(x, y)), facing, scale, variation);
|
||||
return this
|
||||
.createDestructableZ(typeId, x, y,
|
||||
Math.max(War3MapViewer.this.getWalkableRenderHeight(x, y),
|
||||
War3MapViewer.this.terrain.getGroundHeight(x, y)),
|
||||
facing, scale, variation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -728,16 +731,16 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final MutableGameObject row = War3MapViewer.this.allObjectData.getDestructibles().get(typeId);
|
||||
final float[] location3d = { x, y, z };
|
||||
final float[] scale3d = { scale, scale, scale };
|
||||
final RenderDestructable newDestructable = createNewDestructable(typeId, row, variation,
|
||||
location3d, (float) Math.toRadians(facing), (short) 100, scale3d);
|
||||
final RenderDestructable newDestructable = War3MapViewer.this.createNewDestructable(typeId, row,
|
||||
variation, location3d, (float) Math.toRadians(facing), (short) 100, scale3d);
|
||||
return newDestructable.getSimulationDestructable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CItem createItem(final CSimulation simulation, final War3ID typeId, final float x,
|
||||
final float y) {
|
||||
return (CItem) createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y, -1, -1,
|
||||
(float) Math.toRadians(
|
||||
return (CItem) War3MapViewer.this.createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y,
|
||||
-1, -1, (float) Math.toRadians(
|
||||
War3MapViewer.this.simulation.getGameplayConstants().getBuildingAngle()));
|
||||
}
|
||||
|
||||
@ -762,7 +765,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final AbilityUI heroUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_HERO_RAWCODE);
|
||||
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source);
|
||||
final String heroLevelUpArt = heroUI.getCasterArt(0);
|
||||
spawnFxOnOrigin(renderUnit, heroLevelUpArt);
|
||||
War3MapViewer.this.spawnFxOnOrigin(renderUnit, heroLevelUpArt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -773,7 +776,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
renderUnit.instance.setVertexAlpha(1.0f);
|
||||
final CPlayer player = War3MapViewer.this.simulation.getPlayer(source.getPlayerIndex());
|
||||
final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal());
|
||||
spawnFxOnOrigin(renderUnit, heroReviveArt);
|
||||
War3MapViewer.this.spawnFxOnOrigin(renderUnit, heroReviveArt);
|
||||
final MutableGameObject row = War3MapViewer.this.allObjectData.getUnits()
|
||||
.get(source.getTypeId());
|
||||
|
||||
@ -815,7 +818,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
@Override
|
||||
public void spawnEffectOnUnit(final CUnit unit, final String effectPath) {
|
||||
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(unit);
|
||||
final MdxModel spawnedEffectModel = (MdxModel) load(mdx(effectPath), PathSolver.DEFAULT, null);
|
||||
final MdxModel spawnedEffectModel = (MdxModel) War3MapViewer.this.load(mdx(effectPath),
|
||||
PathSolver.DEFAULT, null);
|
||||
if (spawnedEffectModel != null) {
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) spawnedEffectModel
|
||||
.addInstance();
|
||||
@ -834,7 +838,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
@Override
|
||||
public void spawnSpellEffectOnUnit(final CUnit unit, final War3ID alias) {
|
||||
final AbilityUI abilityUI = War3MapViewer.this.abilityDataUI.getUI(alias);
|
||||
spawnEffectOnUnit(unit, abilityUI.getTargetArt(0));
|
||||
this.spawnEffectOnUnit(unit, abilityUI.getTargetArt(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -916,13 +920,13 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
throw new IllegalStateException("transcription of JS has not loaded a map and has no JS async promises");
|
||||
}
|
||||
|
||||
loadSounds();
|
||||
this.loadSounds();
|
||||
|
||||
this.terrain.createWaves();
|
||||
}
|
||||
|
||||
public void spawnFxOnOrigin(final RenderUnit renderUnit, final String heroLevelUpArt) {
|
||||
final MdxModel heroLevelUpModel = loadModel(heroLevelUpArt);
|
||||
final MdxModel heroLevelUpModel = this.loadModel(heroLevelUpArt);
|
||||
if (heroLevelUpModel != null) {
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) heroLevelUpModel.addInstance();
|
||||
modelInstance.setTeamColor(renderUnit.playerIndex);
|
||||
@ -952,11 +956,11 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
|
||||
protected BufferedImage getDestructablePathingPixelMap(final MutableGameObject row) {
|
||||
return loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING, 0));
|
||||
return this.loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING, 0));
|
||||
}
|
||||
|
||||
protected BufferedImage getDestructablePathingDeathPixelMap(final MutableGameObject row) {
|
||||
return loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING_DEATH, 0));
|
||||
return this.loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING_DEATH, 0));
|
||||
}
|
||||
|
||||
private void loadSounds() {
|
||||
@ -1003,8 +1007,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final float facingRadians = doodad.getAngle();
|
||||
final short lifePercent = doodad.getLife();
|
||||
final float[] scale = doodad.getScale();
|
||||
createDestructableOrDoodad(doodadId, modifications, doodadVariation, location, facingRadians, lifePercent,
|
||||
scale);
|
||||
this.createDestructableOrDoodad(doodadId, modifications, doodadVariation, location, facingRadians,
|
||||
lifePercent, scale);
|
||||
}
|
||||
|
||||
// Cliff/Terrain doodads.
|
||||
@ -1072,7 +1076,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
|
||||
private void createDoodad(final MutableGameObject row, final int doodadVariation, final float[] location,
|
||||
final float facingRadians, final float[] scale) {
|
||||
final MdxModel model = getDoodadModel(doodadVariation, row);
|
||||
final MdxModel model = this.getDoodadModel(doodadVariation, row);
|
||||
final float maxPitch = row.readSLKTagFloat("maxPitch");
|
||||
final float maxRoll = row.readSLKTagFloat("maxRoll");
|
||||
final float defScale = row.readSLKTagFloat("defScale");
|
||||
@ -1088,7 +1092,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
BuildingShadow destructableShadow = null;
|
||||
RemovablePathingMapInstance destructablePathing = null;
|
||||
RemovablePathingMapInstance destructablePathingDeath = null;
|
||||
final MdxModel model = getDoodadModel(doodadVariation, row);
|
||||
final MdxModel model = this.getDoodadModel(doodadVariation, row);
|
||||
|
||||
final float maxPitch = row.readSLKTagFloat("maxPitch");
|
||||
final float maxRoll = row.readSLKTagFloat("maxRoll");
|
||||
@ -1097,7 +1101,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
destructableShadow = this.terrain.addShadow(shadowString, location[0], location[1]);
|
||||
}
|
||||
|
||||
final BufferedImage destructablePathingPixelMap = getDestructablePathingPixelMap(row);
|
||||
final BufferedImage destructablePathingPixelMap = this.getDestructablePathingPixelMap(row);
|
||||
if (destructablePathingPixelMap != null) {
|
||||
destructablePathing = this.terrain.pathingGrid.createRemovablePathingOverlayTexture(location[0],
|
||||
location[1], (int) Math.toDegrees(facingRadians), destructablePathingPixelMap);
|
||||
@ -1105,7 +1109,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
destructablePathing.add();
|
||||
}
|
||||
}
|
||||
final BufferedImage destructablePathingDeathPixelMap = getDestructablePathingDeathPixelMap(row);
|
||||
final BufferedImage destructablePathingDeathPixelMap = this.getDestructablePathingDeathPixelMap(row);
|
||||
if (destructablePathingDeathPixelMap != null) {
|
||||
destructablePathingDeath = this.terrain.pathingGrid.createRemovablePathingOverlayTexture(location[0],
|
||||
location[1], (int) Math.toDegrees(facingRadians), destructablePathingDeathPixelMap);
|
||||
@ -1127,7 +1131,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
if (row.readSLKTagBoolean("walkable")) {
|
||||
final float angle = facingRadians;
|
||||
final BoundingBox boundingBox = model.bounds.getBoundingBox();
|
||||
final Rectangle renderDestructableBounds = getRotatedBoundingBox(x, y, angle, boundingBox);
|
||||
final Rectangle renderDestructableBounds = this.getRotatedBoundingBox(x, y, angle, boundingBox);
|
||||
this.walkableObjectsTree.add((MdxComplexInstance) renderDestructable.instance, renderDestructableBounds);
|
||||
renderDestructable.walkableBounds = renderDestructableBounds;
|
||||
}
|
||||
@ -1143,11 +1147,11 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
if (row == null) {
|
||||
row = modifications.getDestructibles().get(doodadId);
|
||||
if (row != null) {
|
||||
createNewDestructable(doodadId, row, doodadVariation, location, facingRadians, lifePercent, scale);
|
||||
this.createNewDestructable(doodadId, row, doodadVariation, location, facingRadians, lifePercent, scale);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createDoodad(row, doodadVariation, location, facingRadians, scale);
|
||||
this.createDoodad(row, doodadVariation, location, facingRadians, scale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1249,7 +1253,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final float unitAngle = unit.getAngle();
|
||||
final int editorConfigHitPointPercent = unit.getHitpoints();
|
||||
|
||||
final CWidget widgetCreated = createNewUnit(modifications, unitId, unitX, unitY, playerIndex,
|
||||
final CWidget widgetCreated = this.createNewUnit(modifications, unitId, unitX, unitY, playerIndex,
|
||||
customTeamColor, unitAngle);
|
||||
if (widgetCreated instanceof CUnit) {
|
||||
final CUnit unitCreated = (CUnit) widgetCreated;
|
||||
@ -1338,9 +1342,9 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
else {
|
||||
type = WorldEditorDataType.UNITS;
|
||||
path = getUnitModelPath(row);
|
||||
path = this.getUnitModelPath(row);
|
||||
|
||||
buildingPathingPixelMap = getBuildingPathingPixelMap(row);
|
||||
buildingPathingPixelMap = this.getBuildingPathingPixelMap(row);
|
||||
if (buildingPathingPixelMap != null) {
|
||||
unitX = (float) Math.floor(unitX / 64f) * 64f;
|
||||
unitY = (float) Math.floor(unitY / 64f) * 64f;
|
||||
@ -1426,7 +1430,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
if (path != null) {
|
||||
final String unitSpecialArtPath = row.getFieldAsString(UNIT_SPECIAL, 0);
|
||||
MdxModel specialArtModel;
|
||||
if (unitSpecialArtPath != null) {
|
||||
if ((unitSpecialArtPath != null) && !unitSpecialArtPath.isEmpty()) {
|
||||
try {
|
||||
specialArtModel = (MdxModel) this.load(mdx(unitSpecialArtPath), this.mapPathSolver,
|
||||
this.solverParams);
|
||||
@ -1452,7 +1456,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final float angle = (float) Math.toDegrees(unitAngle);
|
||||
final CUnit simulationUnit = this.simulation.internalCreateUnit(row.getAlias(), playerIndex, unitX,
|
||||
unitY, angle, buildingPathingPixelMap, pathingInstance);
|
||||
final RenderUnitTypeData typeData = getUnitTypeData(unitId, row);
|
||||
final RenderUnitTypeData typeData = this.getUnitTypeData(unitId, row);
|
||||
if (!typeData.isAllowCustomTeamColor() || (customTeamColor == -1)) {
|
||||
if (typeData.getTeamColor() != -1) {
|
||||
customTeamColor = typeData.getTeamColor();
|
||||
@ -1461,7 +1465,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
customTeamColor = playerIndex;
|
||||
}
|
||||
}
|
||||
final float unitZ = Math.max(getWalkableRenderHeight(unitX, unitY),
|
||||
final float unitZ = Math.max(this.getWalkableRenderHeight(unitX, unitY),
|
||||
War3MapViewer.this.terrain.getGroundHeight(unitX, unitY)) + simulationUnit.getFlyHeight();
|
||||
final RenderUnit renderUnit = new RenderUnit(this, model, row, unitX, unitY, unitZ, customTeamColor,
|
||||
soundset, portraitModel, simulationUnit, typeData, specialArtModel, buildingShadowInstance,
|
||||
@ -1498,7 +1502,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
else {
|
||||
|
||||
final CItem simulationItem = this.simulation.internalCreateItem(row.getAlias(), unitX, unitY);
|
||||
final float unitZ = Math.max(getWalkableRenderHeight(unitX, unitY),
|
||||
final float unitZ = Math.max(this.getWalkableRenderHeight(unitX, unitY),
|
||||
War3MapViewer.this.terrain.getGroundHeight(unitX, unitY));
|
||||
final RenderItem renderItem = new RenderItem(this, model, row, unitX, unitY, unitZ, unitAngle, soundset,
|
||||
portraitModel, simulationItem);
|
||||
@ -1542,7 +1546,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
|
||||
private BufferedImage getBuildingPathingPixelMap(final MutableGameObject row) {
|
||||
final String pathingTexture = row.getFieldAsString(UNIT_PATHING, 0);
|
||||
final BufferedImage buildingPathingPixelMap = loadPathingTexture(pathingTexture);
|
||||
final BufferedImage buildingPathingPixelMap = this.loadPathingTexture(pathingTexture);
|
||||
return buildingPathingPixelMap;
|
||||
}
|
||||
|
||||
@ -1663,7 +1667,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
if (this.anyReady) {
|
||||
final Scene worldScene = this.worldScene;
|
||||
|
||||
startFrame();
|
||||
this.startFrame();
|
||||
worldScene.startFrame();
|
||||
if (DEBUG_DEPTH > 0) {
|
||||
worldScene.renderOpaque(this.dynamicShadowManager, this.webGL);
|
||||
@ -1728,7 +1732,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
|
||||
public void doSelectUnit(final List<RenderWidget> units) {
|
||||
deselect();
|
||||
this.deselect();
|
||||
if (units.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -1798,7 +1802,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final String filePath = path.substring(2);
|
||||
final String allyKey = path.substring(0, 2);
|
||||
final Splat locations = entry.getValue();
|
||||
final SplatModel model = new SplatModel(Gdx.gl30, (Texture) load(filePath, PathSolver.DEFAULT, null),
|
||||
final SplatModel model = new SplatModel(Gdx.gl30, (Texture) this.load(filePath, PathSolver.DEFAULT, null),
|
||||
locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true);
|
||||
switch (allyKey) {
|
||||
case "e:":
|
||||
@ -1905,7 +1909,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final String filePath = path.substring(2);
|
||||
final String allyKey = path.substring(0, 2);
|
||||
final Splat locations = entry.getValue();
|
||||
final SplatModel model = new SplatModel(Gdx.gl30, (Texture) load(filePath, PathSolver.DEFAULT, null),
|
||||
final SplatModel model = new SplatModel(Gdx.gl30, (Texture) this.load(filePath, PathSolver.DEFAULT, null),
|
||||
locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true);
|
||||
switch (allyKey) {
|
||||
case "e:":
|
||||
@ -1947,7 +1951,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
out.set(this.walkablesIntersectionFinder.intersection);
|
||||
}
|
||||
else {
|
||||
out.z = Math.max(getWalkableRenderHeight(out.x, out.y), this.terrain.getGroundHeight(out.x, out.y));
|
||||
out.z = Math.max(this.getWalkableRenderHeight(out.x, out.y), this.terrain.getGroundHeight(out.x, out.y));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1962,7 +1966,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
|
||||
public RenderWidget rayPickUnit(final float x, final float y) {
|
||||
return rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL);
|
||||
return this.rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL);
|
||||
}
|
||||
|
||||
public RenderWidget rayPickUnit(final float x, final float y, final CWidgetFilterFunction filter) {
|
||||
@ -2113,15 +2117,15 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
|
||||
public void setDayNightModels(final String terrainDNCFile, final String unitDNCFile) {
|
||||
final MdxModel terrainDNCModel = (MdxModel) load(mdx(terrainDNCFile), PathSolver.DEFAULT, null);
|
||||
final MdxModel terrainDNCModel = (MdxModel) this.load(mdx(terrainDNCFile), PathSolver.DEFAULT, null);
|
||||
this.dncTerrain = (MdxComplexInstance) terrainDNCModel.addInstance();
|
||||
this.dncTerrain.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
this.dncTerrain.setSequence(0);
|
||||
final MdxModel unitDNCModel = (MdxModel) load(mdx(unitDNCFile), PathSolver.DEFAULT, null);
|
||||
final MdxModel unitDNCModel = (MdxModel) this.load(mdx(unitDNCFile), PathSolver.DEFAULT, null);
|
||||
this.dncUnit = (MdxComplexInstance) unitDNCModel.addInstance();
|
||||
this.dncUnit.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP);
|
||||
this.dncUnit.setSequence(0);
|
||||
final MdxModel targetDNCModel = (MdxModel) load(
|
||||
final MdxModel targetDNCModel = (MdxModel) this.load(
|
||||
mdx("Environment\\DNC\\DNCLordaeron\\DNCLordaeronTarget\\DNCLordaeronTarget.mdl"), PathSolver.DEFAULT,
|
||||
null);
|
||||
this.dncTarget = (MdxComplexInstance) targetDNCModel.addInstance();
|
||||
@ -2161,7 +2165,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
}
|
||||
|
||||
public MdxModel loadModel(final String path) {
|
||||
return (MdxModel) load(mdx(path), PathSolver.DEFAULT, null);
|
||||
return (MdxModel) this.load(mdx(path), PathSolver.DEFAULT, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2332,11 +2336,31 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
||||
final String attachPointName) {
|
||||
if (targetWidget instanceof CUnit) {
|
||||
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(targetWidget);
|
||||
final MdxModel spawnedEffectModel = (MdxModel) load(mdx(modelName), PathSolver.DEFAULT, null);
|
||||
final MdxModel spawnedEffectModel = (MdxModel) this.load(mdx(modelName), PathSolver.DEFAULT, null);
|
||||
if (spawnedEffectModel != null) {
|
||||
final MdxComplexInstance modelInstance = (MdxComplexInstance) spawnedEffectModel.addInstance();
|
||||
modelInstance.setTeamColor(renderUnit.playerIndex);
|
||||
modelInstance.setLocation(renderUnit.location);
|
||||
{
|
||||
final MdxModel model = (MdxModel) renderUnit.instance.model;
|
||||
int index = -1;
|
||||
for (int i = 0; i < model.attachments.size(); i++) {
|
||||
final Attachment attachment = model.attachments.get(i);
|
||||
if (attachment.getName().startsWith(attachPointName)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index != -1) {
|
||||
modelInstance.detach();
|
||||
final MdxNode attachment = renderUnit.instance.getAttachment(index);
|
||||
modelInstance.setParent(attachment);
|
||||
modelInstance.setLocation(0, 0, 0);
|
||||
}
|
||||
else {
|
||||
// TODO This is not consistent with War3, is it? Should look nice though.
|
||||
modelInstance.setLocation(renderUnit.location);
|
||||
}
|
||||
}
|
||||
modelInstance.setScene(War3MapViewer.this.worldScene);
|
||||
final RenderSpellEffect renderAttackInstant = new RenderSpellEffect(modelInstance, War3MapViewer.this,
|
||||
(float) Math.toRadians(renderUnit.getSimulationUnit().getFacing()),
|
||||
|
@ -24,17 +24,20 @@ public class RenderSpellEffect implements RenderEffect {
|
||||
this.animationQueue = animationQueue;
|
||||
final MdxModel model = (MdxModel) this.modelInstance.model;
|
||||
this.sequences = model.getSequences();
|
||||
this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP);
|
||||
this.modelInstance.setSequenceLoopMode(SequenceLoopMode.MODEL_LOOP);
|
||||
this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, yaw);
|
||||
this.modelInstance.sequenceEnded = true;
|
||||
playNextAnimation();
|
||||
this.playNextAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateAnimations(final War3MapViewer war3MapViewer, final float deltaTime) {
|
||||
playNextAnimation();
|
||||
this.playNextAnimation();
|
||||
final boolean everythingDone = this.animationQueueIndex >= this.animationQueue.length;
|
||||
if (everythingDone) {
|
||||
if (this.modelInstance.parent != null) {
|
||||
this.modelInstance.setParent(null);
|
||||
}
|
||||
war3MapViewer.worldScene.removeInstance(this.modelInstance);
|
||||
}
|
||||
return everythingDone;
|
||||
|
@ -0,0 +1,315 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
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.math.Vector2;
|
||||
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||
import com.etheller.warsmash.SingleModelScreen;
|
||||
import com.etheller.warsmash.WarsmashGdxMultiScreenGame;
|
||||
import com.etheller.warsmash.datasources.DataSource;
|
||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.UIFrame;
|
||||
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
|
||||
import com.etheller.warsmash.units.DataTable;
|
||||
import com.etheller.warsmash.units.custom.WTS;
|
||||
import com.etheller.warsmash.util.WarsmashConstants;
|
||||
import com.etheller.warsmash.util.WorldEditStrings;
|
||||
import com.etheller.warsmash.viewer5.Scene;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.FocusableFrame;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.sound.KeyedSounds;
|
||||
|
||||
public class TestUI {
|
||||
private static final Vector2 screenCoordsVector = new Vector2();
|
||||
private static boolean ENABLE_NOT_YET_IMPLEMENTED_BUTTONS = false;
|
||||
|
||||
private final DataSource dataSource;
|
||||
private final Scene uiScene;
|
||||
private final Viewport uiViewport;
|
||||
private final MdxViewer viewer;
|
||||
private final RootFrameListener rootFrameListener;
|
||||
private final float widthRatioCorrection;
|
||||
private final float heightRatioCorrection;
|
||||
private GameUI rootFrame;
|
||||
private SpriteFrame cursorFrame;
|
||||
|
||||
private ClickableFrame mouseDownUIFrame;
|
||||
private ClickableFrame mouseOverUIFrame;
|
||||
private FocusableFrame focusUIFrame;
|
||||
|
||||
private WorldEditStrings worldEditStrings;
|
||||
|
||||
private DataTable uiSoundsTable;
|
||||
|
||||
private KeyedSounds uiSounds;
|
||||
|
||||
private final WarsmashGdxMultiScreenGame screenManager;
|
||||
|
||||
private final DataTable warsmashIni;
|
||||
|
||||
private final SingleModelScreen menuScreen;
|
||||
private UIFrame main;
|
||||
private final String customTOC;
|
||||
|
||||
public TestUI(final DataSource dataSource, final Viewport uiViewport, final Scene uiScene, final MdxViewer viewer,
|
||||
final WarsmashGdxMultiScreenGame screenManager, final SingleModelScreen menuScreen,
|
||||
final DataTable warsmashIni, final RootFrameListener rootFrameListener, final String customTOC) {
|
||||
this.dataSource = dataSource;
|
||||
this.uiViewport = uiViewport;
|
||||
this.uiScene = uiScene;
|
||||
this.viewer = viewer;
|
||||
this.screenManager = screenManager;
|
||||
this.menuScreen = menuScreen;
|
||||
this.warsmashIni = warsmashIni;
|
||||
this.rootFrameListener = rootFrameListener;
|
||||
this.customTOC = customTOC;
|
||||
|
||||
this.widthRatioCorrection = this.getMinWorldWidth() / 1600f;
|
||||
this.heightRatioCorrection = this.getMinWorldHeight() / 1200f;
|
||||
}
|
||||
|
||||
public float getHeightRatioCorrection() {
|
||||
return this.heightRatioCorrection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called "main" because this was originally written in JASS so that maps could
|
||||
* override it, and I may convert it back to the JASS at some point.
|
||||
*/
|
||||
public void main() {
|
||||
// =================================
|
||||
// Load skins and templates
|
||||
// =================================
|
||||
this.rootFrame = new GameUI(this.dataSource, GameUI.loadSkin(this.dataSource, WarsmashConstants.GAME_VERSION),
|
||||
this.uiViewport, this.uiScene, this.viewer, 0, WTS.DO_NOTHING);
|
||||
|
||||
this.rootFrameListener.onCreate(this.rootFrame);
|
||||
try {
|
||||
this.rootFrame.loadTOCFile(this.customTOC);
|
||||
}
|
||||
catch (final IOException exc) {
|
||||
throw new IllegalStateException(this.customTOC);
|
||||
}
|
||||
|
||||
// Create main menu
|
||||
this.main = this.rootFrame.createFrame("Main", this.rootFrame, 0, 0);
|
||||
|
||||
this.cursorFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", "SmashCursorFrame", this.rootFrame,
|
||||
"", 0);
|
||||
this.rootFrame.setSpriteFrameModel(this.cursorFrame, this.rootFrame.getSkinField("Cursor"));
|
||||
this.cursorFrame.setSequence("Normal");
|
||||
this.cursorFrame.setZDepth(-1.0f);
|
||||
if (WarsmashConstants.CATCH_CURSOR) {
|
||||
Gdx.input.setCursorCatched(true);
|
||||
}
|
||||
|
||||
// position all
|
||||
this.rootFrame.positionBounds(this.rootFrame, this.uiViewport);
|
||||
|
||||
this.loadSounds();
|
||||
}
|
||||
|
||||
private static String getStringWithWTS(final WTS wts, String string) {
|
||||
if (string.startsWith("TRIGSTR_")) {
|
||||
string = wts.get(Integer.parseInt(string.substring(8)));
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public void resize() {
|
||||
|
||||
}
|
||||
|
||||
public void render(final SpriteBatch batch, final GlyphLayout glyphLayout) {
|
||||
final BitmapFont font = this.rootFrame.getFont();
|
||||
final BitmapFont font20 = this.rootFrame.getFont20();
|
||||
font.setColor(Color.YELLOW);
|
||||
final String fpsString = "FPS: " + Gdx.graphics.getFramesPerSecond();
|
||||
glyphLayout.setText(font, fpsString);
|
||||
font.draw(batch, fpsString, (this.getMinWorldWidth() - glyphLayout.width) / 2,
|
||||
1100 * this.heightRatioCorrection);
|
||||
this.rootFrame.render(batch, font20, glyphLayout);
|
||||
}
|
||||
|
||||
private float getMinWorldWidth() {
|
||||
if (this.uiViewport instanceof ExtendViewport) {
|
||||
return ((ExtendViewport) this.uiViewport).getMinWorldWidth();
|
||||
}
|
||||
return this.uiViewport.getWorldWidth();
|
||||
}
|
||||
|
||||
private float getMinWorldHeight() {
|
||||
if (this.uiViewport instanceof ExtendViewport) {
|
||||
return ((ExtendViewport) this.uiViewport).getMinWorldHeight();
|
||||
}
|
||||
return this.uiViewport.getWorldHeight();
|
||||
}
|
||||
|
||||
public void update(final float deltaTime) {
|
||||
if ((this.focusUIFrame != null) && !this.focusUIFrame.isVisibleOnScreen()) {
|
||||
this.setFocusFrame(this.getNextFocusFrame());
|
||||
}
|
||||
|
||||
final int baseMouseX = Gdx.input.getX();
|
||||
int mouseX = baseMouseX;
|
||||
final int baseMouseY = Gdx.input.getY();
|
||||
int mouseY = baseMouseY;
|
||||
final int minX = this.uiViewport.getScreenX();
|
||||
final int maxX = minX + this.uiViewport.getScreenWidth();
|
||||
final int minY = this.uiViewport.getScreenY();
|
||||
final int maxY = minY + this.uiViewport.getScreenHeight();
|
||||
|
||||
mouseX = Math.max(minX, Math.min(maxX, mouseX));
|
||||
mouseY = Math.max(minY, Math.min(maxY, mouseY));
|
||||
if (Gdx.input.isCursorCatched()) {
|
||||
if (WarsmashConstants.CATCH_CURSOR) {
|
||||
Gdx.input.setCursorPosition(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
screenCoordsVector.set(mouseX, mouseY);
|
||||
this.uiViewport.unproject(screenCoordsVector);
|
||||
this.cursorFrame.setFramePointX(FramePoint.LEFT, screenCoordsVector.x);
|
||||
this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y);
|
||||
this.cursorFrame.setSequence("Normal");
|
||||
|
||||
}
|
||||
|
||||
private FocusableFrame getNextFocusFrame() {
|
||||
return this.rootFrame.getNextFocusFrame();
|
||||
}
|
||||
|
||||
public boolean touchDown(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.touchDown(screenCoordsVector.x, screenCoordsVector.y, button);
|
||||
if (clickedUIFrame != null) {
|
||||
if (clickedUIFrame instanceof ClickableFrame) {
|
||||
this.mouseDownUIFrame = (ClickableFrame) clickedUIFrame;
|
||||
this.mouseDownUIFrame.mouseDown(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
if (clickedUIFrame instanceof FocusableFrame) {
|
||||
final FocusableFrame clickedFocusableFrame = (FocusableFrame) clickedUIFrame;
|
||||
if (clickedFocusableFrame.isFocusable()) {
|
||||
this.setFocusFrame(clickedFocusableFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setFocusFrame(final FocusableFrame clickedFocusableFrame) {
|
||||
if (this.focusUIFrame != null) {
|
||||
this.focusUIFrame.onFocusLost();
|
||||
}
|
||||
this.focusUIFrame = clickedFocusableFrame;
|
||||
if (this.focusUIFrame != null) {
|
||||
this.focusUIFrame.onFocusGained();
|
||||
}
|
||||
}
|
||||
|
||||
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.uiSounds.getSound("GlueScreenClick").play(this.uiScene.audioContext, 0, 0, 0);
|
||||
}
|
||||
this.mouseDownUIFrame.mouseUp(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
this.mouseDownUIFrame = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean touchDragged(final int screenX, final int screenY, final float worldScreenY, final int pointer) {
|
||||
this.mouseMoved(screenX, screenY, worldScreenY);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mouseMoved(final int screenX, final int screenY, final float worldScreenY) {
|
||||
screenCoordsVector.set(screenX, screenY);
|
||||
this.uiViewport.unproject(screenCoordsVector);
|
||||
final UIFrame mousedUIFrame = this.rootFrame.getFrameChildUnderMouse(screenCoordsVector.x,
|
||||
screenCoordsVector.y);
|
||||
if (mousedUIFrame != this.mouseOverUIFrame) {
|
||||
if (this.mouseOverUIFrame != null) {
|
||||
this.mouseOverUIFrame.mouseExit(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
if (mousedUIFrame instanceof ClickableFrame) {
|
||||
this.mouseOverUIFrame = (ClickableFrame) mousedUIFrame;
|
||||
if (this.mouseOverUIFrame != null) {
|
||||
this.mouseOverUIFrame.mouseEnter(this.rootFrame, this.uiViewport);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.mouseOverUIFrame = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void loadSounds() {
|
||||
this.worldEditStrings = new WorldEditStrings(this.dataSource);
|
||||
this.uiSoundsTable = new DataTable(this.worldEditStrings);
|
||||
try {
|
||||
try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) {
|
||||
this.uiSoundsTable.readSLK(miscDataTxtStream);
|
||||
}
|
||||
try (InputStream miscDataTxtStream = this.dataSource
|
||||
.getResourceAsStream("UI\\SoundInfo\\AmbienceSounds.slk")) {
|
||||
this.uiSoundsTable.readSLK(miscDataTxtStream);
|
||||
}
|
||||
}
|
||||
catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.uiSounds = new KeyedSounds(this.uiSoundsTable, this.dataSource);
|
||||
}
|
||||
|
||||
public KeyedSounds getUiSounds() {
|
||||
return this.uiSounds;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (this.rootFrame != null) {
|
||||
this.rootFrame.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean keyDown(final int keycode) {
|
||||
if (this.focusUIFrame != null) {
|
||||
this.focusUIFrame.keyDown(keycode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean keyUp(final int keycode) {
|
||||
if (this.focusUIFrame != null) {
|
||||
this.focusUIFrame.keyUp(keycode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean keyTyped(final char character) {
|
||||
if (this.focusUIFrame != null) {
|
||||
this.focusUIFrame.keyTyped(character);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -37,19 +37,19 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
this.parentId = reader.readInt32();
|
||||
this.flags = reader.readInt32();
|
||||
|
||||
readTimelines(reader, size - 96);
|
||||
this.readTimelines(reader, size - 96);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeMdx(final BinaryWriter writer, final int version) {
|
||||
writer.writeUInt32(getGenericByteLength(version));
|
||||
writer.writeUInt32(this.getGenericByteLength(version));
|
||||
writer.writeWithNulls(this.name, 80);
|
||||
writer.writeInt32(this.objectId);
|
||||
writer.writeInt32(this.parentId);
|
||||
writer.writeInt32(this.flags);
|
||||
|
||||
for (final MdlxTimeline<?> timeline : this.timelines) {
|
||||
if (isGeneric(timeline)) {
|
||||
if (this.isGeneric(timeline)) {
|
||||
timeline.writeMdx(writer);
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
|
||||
public void writeNonGenericAnimationChunks(final BinaryWriter writer) {
|
||||
for (final MdlxTimeline<?> timeline : this.timelines) {
|
||||
if (!isGeneric(timeline)) {
|
||||
if (!this.isGeneric(timeline)) {
|
||||
timeline.writeMdx(writer);
|
||||
}
|
||||
}
|
||||
@ -65,7 +65,7 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
|
||||
protected final Iterable<String> readMdlGeneric(final MdlTokenInputStream stream) {
|
||||
this.name = stream.read();
|
||||
return () -> new WrappedMdlTokenIterator(readAnimatedBlock(stream), MdlxGenericObject.this, stream);
|
||||
return () -> new WrappedMdlTokenIterator(this.readAnimatedBlock(stream), MdlxGenericObject.this, stream);
|
||||
}
|
||||
|
||||
public void writeGenericHeader(final MdlTokenOutputStream stream) {
|
||||
@ -95,7 +95,7 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
stream.writeFlag(MdlUtils.TOKEN_CAMERA_ANCHORED);
|
||||
}
|
||||
|
||||
if ((this.flags & 0x2) != 0) {
|
||||
if ((this.flags & 0x4) != 0) {
|
||||
stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_ROTATION + " }");
|
||||
}
|
||||
|
||||
@ -103,22 +103,22 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_TRANSLATION + " }");
|
||||
}
|
||||
|
||||
if ((this.flags & 0x4) != 0) {
|
||||
if ((this.flags & 0x2) != 0) {
|
||||
stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_SCALING + " }");
|
||||
}
|
||||
}
|
||||
|
||||
public void writeGenericTimelines(final MdlTokenOutputStream stream) {
|
||||
writeTimeline(stream, AnimationMap.KGTR);
|
||||
writeTimeline(stream, AnimationMap.KGRT);
|
||||
writeTimeline(stream, AnimationMap.KGSC);
|
||||
this.writeTimeline(stream, AnimationMap.KGTR);
|
||||
this.writeTimeline(stream, AnimationMap.KGRT);
|
||||
this.writeTimeline(stream, AnimationMap.KGSC);
|
||||
}
|
||||
|
||||
public long getGenericByteLength(final int version) {
|
||||
long size = 96;
|
||||
|
||||
for (final MdlxTimeline<?> timeline : this.timelines) {
|
||||
if (isGeneric(timeline)) {
|
||||
if (this.isGeneric(timeline)) {
|
||||
size += timeline.getByteLength();
|
||||
}
|
||||
}
|
||||
@ -186,7 +186,7 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (this.delegate.hasNext()) {
|
||||
this.next = read();
|
||||
this.next = this.read();
|
||||
this.hasLoaded = true;
|
||||
return this.next != null;
|
||||
}
|
||||
@ -196,7 +196,7 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
@Override
|
||||
public String next() {
|
||||
if (!this.hasLoaded) {
|
||||
this.next = read();
|
||||
this.next = this.read();
|
||||
}
|
||||
this.hasLoaded = false;
|
||||
return this.next;
|
||||
@ -242,13 +242,13 @@ public abstract class MdlxGenericObject extends MdlxAnimatedObject {
|
||||
for (final String subToken : this.stream.readBlock()) {
|
||||
switch (subToken) {
|
||||
case MdlUtils.TOKEN_ROTATION:
|
||||
this.updatingObject.flags |= 0x2;
|
||||
this.updatingObject.flags |= 0x4;
|
||||
break;
|
||||
case MdlUtils.TOKEN_TRANSLATION:
|
||||
this.updatingObject.flags |= 0x1;
|
||||
break;
|
||||
case MdlUtils.TOKEN_SCALING:
|
||||
this.updatingObject.flags |= 0x0;
|
||||
this.updatingObject.flags |= 0x2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import java.io.PrintStream;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL31;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
@ -24,6 +25,7 @@ import com.badlogic.gdx.audio.Sound;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglNativesLoader;
|
||||
import com.etheller.warsmash.WarsmashGdxFDFTestRenderScreen;
|
||||
import com.etheller.warsmash.WarsmashGdxMenuScreen;
|
||||
import com.etheller.warsmash.WarsmashGdxMultiScreenGame;
|
||||
import com.etheller.warsmash.audio.OpenALSound;
|
||||
@ -104,11 +106,17 @@ public class DesktopLauncher {
|
||||
Gdx.app.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final WarsmashGdxMenuScreen menuScreen = new WarsmashGdxMenuScreen(warsmashIni,
|
||||
warsmashGdxMultiScreenGame);
|
||||
warsmashGdxMultiScreenGame.setScreen(menuScreen);
|
||||
if (finalFileToLoad != null) {
|
||||
menuScreen.startMap(finalFileToLoad);
|
||||
if ((finalFileToLoad != null) && finalFileToLoad.toLowerCase().endsWith(".toc")) {
|
||||
warsmashGdxMultiScreenGame.setScreen(new WarsmashGdxFDFTestRenderScreen(warsmashIni,
|
||||
warsmashGdxMultiScreenGame, finalFileToLoad));
|
||||
}
|
||||
else {
|
||||
final WarsmashGdxMenuScreen menuScreen = new WarsmashGdxMenuScreen(warsmashIni,
|
||||
warsmashGdxMultiScreenGame);
|
||||
warsmashGdxMultiScreenGame.setScreen(menuScreen);
|
||||
if (finalFileToLoad != null) {
|
||||
menuScreen.startMap(finalFileToLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -188,7 +196,7 @@ public class DesktopLauncher {
|
||||
@Override
|
||||
public AudioContext createContext(final boolean world) {
|
||||
Listener listener;
|
||||
if (world) {
|
||||
if (world && AL.isCreated()) {
|
||||
listener = new Listener() {
|
||||
private float x;
|
||||
private float y;
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.etheller.interpreter.ast;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.BaseErrorListener;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
@ -8,6 +11,11 @@ import org.antlr.v4.runtime.Recognizer;
|
||||
|
||||
import com.etheller.interpreter.JassLexer;
|
||||
import com.etheller.interpreter.JassParser;
|
||||
import com.etheller.interpreter.ast.function.JassFunction;
|
||||
import com.etheller.interpreter.ast.scope.GlobalScope;
|
||||
import com.etheller.interpreter.ast.scope.TriggerExecutionScope;
|
||||
import com.etheller.interpreter.ast.value.JassValue;
|
||||
import com.etheller.interpreter.ast.value.visitor.StringJassValueVisitor;
|
||||
import com.etheller.interpreter.ast.visitors.JassProgramVisitor;
|
||||
|
||||
public class JassRunner {
|
||||
@ -19,8 +27,19 @@ public class JassRunner {
|
||||
return;
|
||||
}
|
||||
final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor();
|
||||
jassProgramVisitor.getJassNativeManager().createNative("BJDebugMsg", new JassFunction() {
|
||||
@Override
|
||||
public JassValue call(final List<JassValue> arguments, final GlobalScope globalScope,
|
||||
final TriggerExecutionScope triggerScope) {
|
||||
for (final JassValue argument : arguments) {
|
||||
System.out.println(argument.visit(StringJassValueVisitor.getInstance()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
for (final String arg : args) {
|
||||
try {
|
||||
jassProgramVisitor.setCurrentFileName(arg);
|
||||
final JassLexer lexer = new JassLexer(CharStreams.fromFileName(arg));
|
||||
final JassParser parser = new JassParser(new CommonTokenStream(lexer));
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@ -41,10 +60,13 @@ public class JassRunner {
|
||||
}
|
||||
});
|
||||
jassProgramVisitor.visit(parser.program());
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
jassProgramVisitor.getGlobals().getFunctionByName("main").call(Collections.emptyList(),
|
||||
jassProgramVisitor.getGlobals(), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.etheller.interpreter.ast.expression;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.etheller.interpreter.ast.debug.JassException;
|
||||
import com.etheller.interpreter.ast.function.JassFunction;
|
||||
import com.etheller.interpreter.ast.scope.GlobalScope;
|
||||
import com.etheller.interpreter.ast.scope.LocalScope;
|
||||
@ -23,7 +24,7 @@ public class FunctionCallJassExpression implements JassExpression {
|
||||
final TriggerExecutionScope triggerScope) {
|
||||
final JassFunction functionByName = globalScope.getFunctionByName(this.functionName);
|
||||
if (functionByName == null) {
|
||||
throw new RuntimeException("Undefined function: " + this.functionName);
|
||||
throw new JassException(globalScope, "Undefined function: " + this.functionName, new RuntimeException());
|
||||
}
|
||||
final List<JassValue> evaluatedExpressions = new ArrayList<>();
|
||||
for (final JassExpression expr : this.arguments) {
|
||||
@ -34,7 +35,7 @@ public class FunctionCallJassExpression implements JassExpression {
|
||||
return functionByName.call(evaluatedExpressions, globalScope, triggerScope);
|
||||
}
|
||||
catch (final Exception exc) {
|
||||
throw new RuntimeException("Function call by name failed for name: " + this.functionName, exc);
|
||||
throw new JassException(globalScope, "Function call by name failed for name: " + this.functionName, exc);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user