mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Invulnerable ability, first draft of multi select, colored selection circles
This commit is contained in:
parent
46ac4ade21
commit
24590f7783
@ -53,7 +53,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.ui.MeleeUI;
|
|||||||
|
|
||||||
public class WarsmashGdxMapScreen implements InputProcessor, Screen {
|
public class WarsmashGdxMapScreen implements InputProcessor, Screen {
|
||||||
public static final boolean ENABLE_AUDIO = true;
|
public static final boolean ENABLE_AUDIO = true;
|
||||||
private static final boolean ENABLE_MUSIC = true;
|
private static final boolean ENABLE_MUSIC = false;
|
||||||
private final War3MapViewer viewer;
|
private final War3MapViewer viewer;
|
||||||
private final Rectangle tempRect = new Rectangle();
|
private final Rectangle tempRect = new Rectangle();
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSkinField(String file) {
|
public boolean hasSkinField(final String file) {
|
||||||
return (file != null) && this.skin.hasField(file);
|
return (file != null) && this.skin.hasField(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
|||||||
|| ((parentDefinitionIfAvailable != null)
|
|| ((parentDefinitionIfAvailable != null)
|
||||||
&& parentDefinitionIfAvailable.has("DecorateFileNames"));
|
&& parentDefinitionIfAvailable.has("DecorateFileNames"));
|
||||||
final SimpleStatusBarFrame simpleStatusBarFrame = new SimpleStatusBarFrame(frameDefinition.getName(),
|
final SimpleStatusBarFrame simpleStatusBarFrame = new SimpleStatusBarFrame(frameDefinition.getName(),
|
||||||
parent, decorateFileNames);
|
parent, decorateFileNames, false, 0.0f);
|
||||||
for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) {
|
for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) {
|
||||||
simpleStatusBarFrame.add(inflate(childDefinition, simpleStatusBarFrame, frameDefinition,
|
simpleStatusBarFrame.add(inflate(childDefinition, simpleStatusBarFrame, frameDefinition,
|
||||||
inDecorateFileNames || childDefinition.has("DecorateFileNames")));
|
inDecorateFileNames || childDefinition.has("DecorateFileNames")));
|
||||||
|
@ -7,20 +7,29 @@ public class SimpleStatusBarFrame extends AbstractUIFrame {
|
|||||||
private final boolean decorateFileNames;
|
private final boolean decorateFileNames;
|
||||||
private final TextureFrame barFrame;
|
private final TextureFrame barFrame;
|
||||||
private final TextureFrame borderFrame;
|
private final TextureFrame borderFrame;
|
||||||
|
private final float barInset;
|
||||||
|
|
||||||
public SimpleStatusBarFrame(final String name, final UIFrame parent, final boolean decorateFileNames) {
|
public SimpleStatusBarFrame(final String name, final UIFrame parent, final boolean decorateFileNames,
|
||||||
|
final boolean borderBelow, final float barInset) {
|
||||||
super(name, parent);
|
super(name, parent);
|
||||||
this.decorateFileNames = decorateFileNames;
|
this.decorateFileNames = decorateFileNames;
|
||||||
|
this.barInset = barInset;
|
||||||
this.barFrame = new TextureFrame(name + "Bar", this, decorateFileNames, new Vector4Definition(0, 1, 0, 1));
|
this.barFrame = new TextureFrame(name + "Bar", this, decorateFileNames, new Vector4Definition(0, 1, 0, 1));
|
||||||
this.borderFrame = new TextureFrame(name + "Border", this, decorateFileNames,
|
this.borderFrame = new TextureFrame(name + "Border", this, decorateFileNames,
|
||||||
new Vector4Definition(0, 1, 0, 1));
|
new Vector4Definition(0, 1, 0, 1));
|
||||||
this.borderFrame.setSetAllPoints(true);
|
this.borderFrame.setSetAllPoints(true);
|
||||||
this.barFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, 0, 0));
|
this.barFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, barInset, -barInset));
|
||||||
this.barFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this, FramePoint.BOTTOMLEFT, 0, 0));
|
this.barFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this, FramePoint.BOTTOMLEFT, barInset, barInset));
|
||||||
this.barFrame.setSetAllPoints(true);
|
this.barFrame.setSetAllPoints(true, barInset);
|
||||||
|
if (borderBelow) {
|
||||||
|
add(this.borderFrame);
|
||||||
|
add(this.barFrame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
add(this.barFrame);
|
add(this.barFrame);
|
||||||
add(this.borderFrame);
|
add(this.borderFrame);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDecorateFileNames() {
|
public boolean isDecorateFileNames() {
|
||||||
return this.decorateFileNames;
|
return this.decorateFileNames;
|
||||||
@ -28,7 +37,7 @@ public class SimpleStatusBarFrame extends AbstractUIFrame {
|
|||||||
|
|
||||||
public void setValue(final float value) {
|
public void setValue(final float value) {
|
||||||
this.barFrame.setTexCoord(0, value, 0, 1);
|
this.barFrame.setTexCoord(0, value, 0, 1);
|
||||||
this.barFrame.setWidth(this.renderBounds.width * value);
|
this.barFrame.setWidth(((this.renderBounds.width - (this.barInset * 2)) * value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureFrame getBarFrame() {
|
public TextureFrame getBarFrame() {
|
||||||
|
@ -46,6 +46,17 @@ public class TextureFrame extends AbstractRenderableFrame {
|
|||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setColor(final float r, final float g, final float b, final float a) {
|
||||||
|
if (this.color == null) {
|
||||||
|
this.color = new Color();
|
||||||
|
}
|
||||||
|
this.color.r = r;
|
||||||
|
this.color.g = g;
|
||||||
|
this.color.b = b;
|
||||||
|
this.color.a = a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void setTexture(String file, final GameUI gameUI) {
|
public void setTexture(String file, final GameUI gameUI) {
|
||||||
if (this.decorateFileNames) {
|
if (this.decorateFileNames) {
|
||||||
file = gameUI.trySkinField(file);
|
file = gameUI.trySkinField(file);
|
||||||
|
@ -9,7 +9,6 @@ public class WarsmashConstants {
|
|||||||
public static int GAME_VERSION = 1;
|
public static int GAME_VERSION = 1;
|
||||||
public static final int REPLACEABLE_TEXTURE_LIMIT = 64;
|
public static final int REPLACEABLE_TEXTURE_LIMIT = 64;
|
||||||
public static final float SIMULATION_STEP_TIME = 1 / 20f;
|
public static final float SIMULATION_STEP_TIME = 1 / 20f;
|
||||||
public static final float PLAYER_UNIT_MOUSE_HIGHLIGHT_UPDATE_STEP_TIME = 1 / 20f;
|
|
||||||
public static final int PORT_NUMBER = 6115;
|
public static final int PORT_NUMBER = 6115;
|
||||||
public static final float BUILDING_CONSTRUCT_START_LIFE = 0.1f;
|
public static final float BUILDING_CONSTRUCT_START_LIFE = 0.1f;
|
||||||
public static final int BUILD_QUEUE_SIZE = 7;
|
public static final int BUILD_QUEUE_SIZE = 7;
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package com.etheller.warsmash.viewer5;
|
package com.etheller.warsmash.viewer5;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType;
|
||||||
|
|
||||||
public class Shaders {
|
public class Shaders {
|
||||||
public static final String boneTexture = ""//
|
public static final String boneTexture = ""//
|
||||||
+ " uniform sampler2D u_boneMap;\r\n" + //
|
+ " uniform sampler2D u_boneMap;\r\n" + //
|
||||||
@ -58,6 +61,7 @@ public class Shaders {
|
|||||||
|
|
||||||
public static String lightSystem(final String normalName, final String positionName, final String lightTexture,
|
public static String lightSystem(final String normalName, final String positionName, final String lightTexture,
|
||||||
final String lightTextureHeight, final String lightCount, final boolean terrain) {
|
final String lightTextureHeight, final String lightCount, final boolean terrain) {
|
||||||
|
new RuntimeException("lightSystem").printStackTrace();
|
||||||
return " vec3 lightFactor = vec3(0.0,0.0,0.0);\r\n" + //
|
return " vec3 lightFactor = vec3(0.0,0.0,0.0);\r\n" + //
|
||||||
" for(float lightIndex = 0.5; lightIndex < " + lightCount + "; lightIndex += 1.0) {\r\n" + //
|
" for(float lightIndex = 0.5; lightIndex < " + lightCount + "; lightIndex += 1.0) {\r\n" + //
|
||||||
" float rowPos = (lightIndex) / " + lightTextureHeight + ";\r\n" + //
|
" float rowPos = (lightIndex) / " + lightTextureHeight + ";\r\n" + //
|
||||||
@ -103,13 +107,14 @@ public class Shaders {
|
|||||||
" lightFactor += lightFactorContribution + (lightAmbColor.a/(pow(dist, 2.0))) * lightAmbColor.rgb;\r\n"
|
" lightFactor += lightFactorContribution + (lightAmbColor.a/(pow(dist, 2.0))) * lightAmbColor.rgb;\r\n"
|
||||||
+ //
|
+ //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" }\r\n";// + //
|
" }\r\n" + //
|
||||||
|
(MdxHandler.CURRENT_SHADER_TYPE == ShaderEnvironmentType.MENU
|
||||||
// " vec4 sRGB = vec4(lightFactor, 1.0);" + //
|
? " vec4 sRGB = vec4(lightFactor, 1.0);" + //
|
||||||
// " bvec4 cutoff = lessThan(sRGB, vec4(0.04045));" + //
|
" bvec4 cutoff = lessThan(sRGB, vec4(0.04045));" + //
|
||||||
// " vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4));" + //
|
" vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4));" + //
|
||||||
// " vec4 lower = sRGB/vec4(12.92);" + //
|
" vec4 lower = sRGB/vec4(12.92);" + //
|
||||||
// "" + //
|
"" + //
|
||||||
// " lightFactor = (higher * (vec4(1.0) - vec4(cutoff)) + lower * vec4(cutoff)).xyz;";
|
" lightFactor = (higher * (vec4(1.0) - vec4(cutoff)) + lower * vec4(cutoff)).xyz;"
|
||||||
|
: "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,18 +41,18 @@ public class BatchGroup extends GenericGroup {
|
|||||||
|
|
||||||
if (isExtended) {
|
if (isExtended) {
|
||||||
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
||||||
shader = MdxHandler.Shaders.extendedShadowMap;
|
shader = handler.shaders.extendedShadowMap;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shader = MdxHandler.Shaders.extended;
|
shader = handler.shaders.extended;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
if (DynamicShadowManager.IS_SHADOW_MAPPING) {
|
||||||
shader = MdxHandler.Shaders.complexShadowMap;
|
shader = handler.shaders.complexShadowMap;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shader = MdxHandler.Shaders.complex;
|
shader = handler.shaders.complex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,10 @@ public class CollisionShape extends GenericObject {
|
|||||||
public boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection) {
|
public boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection) {
|
||||||
intersectHeap.set(this.center);
|
intersectHeap.set(this.center);
|
||||||
intersectHeap.prj(mdxNode.worldMatrix);
|
intersectHeap.prj(mdxNode.worldMatrix);
|
||||||
return Intersector.intersectRaySphere(ray, intersectHeap, this.radius, intersection);
|
if (Intersector.intersectRaySphere(ray, intersectHeap, this.radius, intersection)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +123,10 @@ public class CollisionShape extends GenericObject {
|
|||||||
intersectHeap2.prj(intersectMatrixHeap);
|
intersectHeap2.prj(intersectMatrixHeap);
|
||||||
intersectHeap2.sub(intersectHeap);
|
intersectHeap2.sub(intersectHeap);
|
||||||
intersectRayHeap.set(intersectHeap, intersectHeap2);
|
intersectRayHeap.set(intersectHeap, intersectHeap2);
|
||||||
return bounds.intersectRay(intersectRayHeap, intersection);
|
if (bounds.intersectRay(intersectRayHeap, intersection)) {
|
||||||
|
intersection.prj(worldMatrix);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class EmitterGroup extends GenericGroup {
|
|||||||
final ModelViewer viewer = model.viewer;
|
final ModelViewer viewer = model.viewer;
|
||||||
final GL20 gl = viewer.gl;
|
final GL20 gl = viewer.gl;
|
||||||
final ANGLEInstancedArrays instancedArrays = viewer.webGL.instancedArrays;
|
final ANGLEInstancedArrays instancedArrays = viewer.webGL.instancedArrays;
|
||||||
final ShaderProgram shader = MdxHandler.Shaders.particles;
|
final ShaderProgram shader = ((MdxModel) model).handler.shaders.particles;
|
||||||
|
|
||||||
gl.glDepthMask(false);
|
gl.glDepthMask(false);
|
||||||
gl.glEnable(GL20.GL_BLEND);
|
gl.glEnable(GL20.GL_BLEND);
|
||||||
|
@ -15,7 +15,9 @@ import com.etheller.warsmash.viewer5.Texture;
|
|||||||
import com.etheller.warsmash.viewer5.TextureMapper;
|
import com.etheller.warsmash.viewer5.TextureMapper;
|
||||||
import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays;
|
import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays;
|
||||||
import com.etheller.warsmash.viewer5.gl.ClientBuffer;
|
import com.etheller.warsmash.viewer5.gl.ClientBuffer;
|
||||||
|
import com.etheller.warsmash.viewer5.gl.DataTexture;
|
||||||
import com.etheller.warsmash.viewer5.handlers.EmitterObject;
|
import com.etheller.warsmash.viewer5.handlers.EmitterObject;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.W3xSceneLightManager;
|
||||||
|
|
||||||
//The total storage that emitted objects can use.
|
//The total storage that emitted objects can use.
|
||||||
//This is enough to support all of the MDX geometry emitters.
|
//This is enough to support all of the MDX geometry emitters.
|
||||||
@ -191,6 +193,15 @@ public class GeometryEmitterFuncs {
|
|||||||
shader.setUniformf("u_columns", emitterObject.columns);
|
shader.setUniformf("u_columns", emitterObject.columns);
|
||||||
shader.setUniformf("u_rows", emitterObject.rows);
|
shader.setUniformf("u_rows", emitterObject.rows);
|
||||||
shader.setUniformf("u_teamColored", emitterObject.teamColored);
|
shader.setUniformf("u_teamColored", emitterObject.teamColored);
|
||||||
|
shader.setUniformi("u_unshaded", emitterObject.emitterUsesMdlOrUnshaded != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
final W3xSceneLightManager lightManager = (W3xSceneLightManager) scene.getLightManager();
|
||||||
|
final DataTexture unitLightsTexture = lightManager.getUnitLightsTexture();
|
||||||
|
|
||||||
|
unitLightsTexture.bind(14);
|
||||||
|
shader.setUniformi("u_lightTexture", 14);
|
||||||
|
shader.setUniformf("u_lightCount", lightManager.getUnitLightCount());
|
||||||
|
shader.setUniformf("u_lightTextureHeight", unitLightsTexture.getHeight());
|
||||||
|
|
||||||
shader.setUniform3fv("u_intervals[0]", intervals[0], 0, 3);
|
shader.setUniform3fv("u_intervals[0]", intervals[0], 0, 3);
|
||||||
shader.setUniform3fv("u_intervals[1]", intervals[1], 0, 3);
|
shader.setUniform3fv("u_intervals[1]", intervals[1], 0, 3);
|
||||||
@ -210,10 +221,8 @@ public class GeometryEmitterFuncs {
|
|||||||
shader.setUniform3fv("u_vertices[3]", asFloatArray(vectors[3]), 0, 3);
|
shader.setUniform3fv("u_vertices[3]", asFloatArray(vectors[3]), 0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emitterObject.tail) {
|
|
||||||
shader.setUniform3fv("u_cameraZ", asFloatArray(camera.billboardedVectors[6]), 0, 3);
|
shader.setUniform3fv("u_cameraZ", asFloatArray(camera.billboardedVectors[6]), 0, 3);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static void bindRibbonEmitterBuffer(final RibbonEmitter emitter, final ClientBuffer buffer) {
|
public static void bindRibbonEmitterBuffer(final RibbonEmitter emitter, final ClientBuffer buffer) {
|
||||||
Ribbon object = emitter.first;
|
Ribbon object = emitter.first;
|
||||||
|
@ -36,6 +36,7 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
private static final float[] colorHeap = new float[3];
|
private static final float[] colorHeap = new float[3];
|
||||||
private static final float[] alphaHeap = new float[1];
|
private static final float[] alphaHeap = new float[1];
|
||||||
private static final long[] textureIdHeap = new long[1];
|
private static final long[] textureIdHeap = new long[1];
|
||||||
|
private static final Vector3 intersectionHeap = new Vector3();
|
||||||
|
|
||||||
public List<LightInstance> lights = new ArrayList<>();
|
public List<LightInstance> lights = new ArrayList<>();
|
||||||
public List<AttachmentInstance> attachments = new ArrayList<>();
|
public List<AttachmentInstance> attachments = new ArrayList<>();
|
||||||
@ -778,13 +779,18 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
public boolean intersectRayWithCollisionSimple(final Ray ray, final Vector3 intersection) {
|
public boolean intersectRayWithCollisionSimple(final Ray ray, final Vector3 intersection) {
|
||||||
final MdxModel mdxModel = (MdxModel) this.model;
|
final MdxModel mdxModel = (MdxModel) this.model;
|
||||||
final List<CollisionShape> collisionShapes = mdxModel.collisionShapes;
|
final List<CollisionShape> collisionShapes = mdxModel.collisionShapes;
|
||||||
|
boolean intersected = false;
|
||||||
|
ray.getEndPoint(intersection, 99999);
|
||||||
for (final CollisionShape collisionShape : collisionShapes) {
|
for (final CollisionShape collisionShape : collisionShapes) {
|
||||||
final MdxNode mdxNode = this.nodes[collisionShape.index];
|
final MdxNode mdxNode = this.nodes[collisionShape.index];
|
||||||
if (collisionShape.checkIntersect(ray, mdxNode, intersection)) {
|
if (collisionShape.checkIntersect(ray, mdxNode, intersectionHeap)) {
|
||||||
return true;
|
if (intersectionHeap.dst2(ray.origin) < intersection.dst2(ray.origin)) {
|
||||||
|
intersection.set(intersectionHeap);
|
||||||
|
}
|
||||||
|
intersected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return intersectRayBounds(ray, intersection);
|
return intersected || intersectRayBounds(ray, intersection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -796,19 +802,24 @@ public class MdxComplexInstance extends ModelInstance {
|
|||||||
*/
|
*/
|
||||||
public boolean intersectRayWithMeshSlow(final Ray ray, final Vector3 intersection) {
|
public boolean intersectRayWithMeshSlow(final Ray ray, final Vector3 intersection) {
|
||||||
final MdxModel mdxModel = (MdxModel) this.model;
|
final MdxModel mdxModel = (MdxModel) this.model;
|
||||||
|
boolean intersected = false;
|
||||||
|
ray.getEndPoint(intersection, 99999);
|
||||||
for (final Geoset geoset : mdxModel.geosets) {
|
for (final Geoset geoset : mdxModel.geosets) {
|
||||||
if (!geoset.unselectable) {
|
if (!geoset.unselectable) {
|
||||||
geoset.getAlpha(alphaHeap, this.sequence, this.frame, this.counter);
|
geoset.getAlpha(alphaHeap, this.sequence, this.frame, this.counter);
|
||||||
if (alphaHeap[0] > 0) {
|
if (alphaHeap[0] > 0) {
|
||||||
final MdlxGeoset mdlxGeoset = geoset.mdlxGeoset;
|
final MdlxGeoset mdlxGeoset = geoset.mdlxGeoset;
|
||||||
if (CollisionShape.intersectRayTriangles(ray, this, mdlxGeoset.getVertices(), mdlxGeoset.getFaces(),
|
if (CollisionShape.intersectRayTriangles(ray, this, mdlxGeoset.getVertices(), mdlxGeoset.getFaces(),
|
||||||
3, intersection)) {
|
3, intersectionHeap)) {
|
||||||
return true;
|
if (intersectionHeap.dst2(ray.origin) < intersection.dst2(ray.origin)) {
|
||||||
|
intersection.set(intersectionHeap);
|
||||||
|
}
|
||||||
|
intersected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return intersected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,14 @@ import com.etheller.warsmash.viewer5.handlers.blp.DdsHandler;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.tga.TgaHandler;
|
import com.etheller.warsmash.viewer5.handlers.tga.TgaHandler;
|
||||||
|
|
||||||
public class MdxHandler extends ModelHandler {
|
public class MdxHandler extends ModelHandler {
|
||||||
|
public final Shaders shaders = new Shaders();
|
||||||
|
|
||||||
|
public static enum ShaderEnvironmentType {
|
||||||
|
MENU,
|
||||||
|
GAME
|
||||||
|
};
|
||||||
|
|
||||||
|
public static ShaderEnvironmentType CURRENT_SHADER_TYPE;
|
||||||
|
|
||||||
public MdxHandler() {
|
public MdxHandler() {
|
||||||
this.extensions = new ArrayList<>();
|
this.extensions = new ArrayList<>();
|
||||||
@ -26,14 +34,14 @@ public class MdxHandler extends ModelHandler {
|
|||||||
viewer.addHandler(new DdsHandler());
|
viewer.addHandler(new DdsHandler());
|
||||||
viewer.addHandler(new TgaHandler());
|
viewer.addHandler(new TgaHandler());
|
||||||
|
|
||||||
Shaders.complex = viewer.webGL.createShaderProgram(MdxShaders.vsComplex, MdxShaders.fsComplex);
|
this.shaders.complex = viewer.webGL.createShaderProgram(MdxShaders.vsComplex(), MdxShaders.fsComplex);
|
||||||
Shaders.extended = viewer.webGL.createShaderProgram("#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex,
|
this.shaders.extended = viewer.webGL.createShaderProgram("#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex(),
|
||||||
MdxShaders.fsComplex);
|
MdxShaders.fsComplex);
|
||||||
Shaders.complexShadowMap = viewer.webGL.createShaderProgram(MdxShaders.vsComplex,
|
this.shaders.complexShadowMap = viewer.webGL.createShaderProgram(MdxShaders.vsComplex(),
|
||||||
MdxShaders.fsComplexShadowMap);
|
MdxShaders.fsComplexShadowMap);
|
||||||
Shaders.extendedShadowMap = viewer.webGL.createShaderProgram(
|
this.shaders.extendedShadowMap = viewer.webGL.createShaderProgram(
|
||||||
"#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex, MdxShaders.fsComplexShadowMap);
|
"#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex(), MdxShaders.fsComplexShadowMap);
|
||||||
Shaders.particles = viewer.webGL.createShaderProgram(MdxShaders.vsParticles, MdxShaders.fsParticles);
|
this.shaders.particles = viewer.webGL.createShaderProgram(MdxShaders.vsParticles(), MdxShaders.fsParticles);
|
||||||
// Shaders.simple = viewer.webGL.createShaderProgram(MdxShaders.vsSimple,
|
// Shaders.simple = viewer.webGL.createShaderProgram(MdxShaders.vsSimple,
|
||||||
// MdxShaders.fsSimple);
|
// MdxShaders.fsSimple);
|
||||||
// Shaders.hd = viewer.webGL.createShaderProgram(MdxShaders.vsHd, MdxShaders.fsHd);
|
// Shaders.hd = viewer.webGL.createShaderProgram(MdxShaders.vsHd, MdxShaders.fsHd);
|
||||||
@ -41,7 +49,8 @@ public class MdxHandler extends ModelHandler {
|
|||||||
|
|
||||||
// If a shader failed to compile, don't allow the handler to be registered, and
|
// If a shader failed to compile, don't allow the handler to be registered, and
|
||||||
// send an error instead.
|
// send an error instead.
|
||||||
return Shaders.complex.isCompiled() && Shaders.extended.isCompiled() && Shaders.particles.isCompiled()
|
return this.shaders.complex.isCompiled() && this.shaders.extended.isCompiled()
|
||||||
|
&& this.shaders.particles.isCompiled()
|
||||||
/* && Shaders.simple.isCompiled() && Shaders.hd.isCompiled() */;
|
/* && Shaders.simple.isCompiled() && Shaders.hd.isCompiled() */;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,12 +65,12 @@ public class MdxHandler extends ModelHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShaderProgram complex;
|
public ShaderProgram complex;
|
||||||
public static ShaderProgram complexShadowMap;
|
public ShaderProgram complexShadowMap;
|
||||||
public static ShaderProgram extended;
|
public ShaderProgram extended;
|
||||||
public static ShaderProgram extendedShadowMap;
|
public ShaderProgram extendedShadowMap;
|
||||||
public static ShaderProgram simple;
|
public ShaderProgram simple;
|
||||||
public static ShaderProgram particles;
|
public ShaderProgram particles;
|
||||||
public static ShaderProgram hd;
|
public ShaderProgram hd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class MdxRenderBatch extends RenderBatch {
|
|||||||
final GL20 gl = viewer.gl;
|
final GL20 gl = viewer.gl;
|
||||||
final WebGL webGL = viewer.webGL;
|
final WebGL webGL = viewer.webGL;
|
||||||
final ANGLEInstancedArrays instancedArrays = webGL.instancedArrays;
|
final ANGLEInstancedArrays instancedArrays = webGL.instancedArrays;
|
||||||
final ShaderProgram shader = MdxHandler.Shaders.simple;
|
final ShaderProgram shader = model.handler.shaders.simple;
|
||||||
final int m0 = shader.getAttributeLocation("a_m0");
|
final int m0 = shader.getAttributeLocation("a_m0");
|
||||||
final int m1 = shader.getAttributeLocation("a_m1");
|
final int m1 = shader.getAttributeLocation("a_m1");
|
||||||
final int m2 = shader.getAttributeLocation("a_m2");
|
final int m2 = shader.getAttributeLocation("a_m2");
|
||||||
|
@ -83,7 +83,8 @@ public class MdxShaders {
|
|||||||
" gl_FragColor = color;\r\n" + //
|
" gl_FragColor = color;\r\n" + //
|
||||||
" }\r\n";
|
" }\r\n";
|
||||||
|
|
||||||
public static final String vsComplex = "\r\n" + //
|
public static final String vsComplex() {
|
||||||
|
return "\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
" uniform mat4 u_mvp;\r\n" + //
|
" uniform mat4 u_mvp;\r\n" + //
|
||||||
" uniform vec4 u_vertexColor;\r\n" + //
|
" uniform vec4 u_vertexColor;\r\n" + //
|
||||||
@ -153,11 +154,13 @@ public class MdxShaders {
|
|||||||
" v_uvScale = u_uvScale;\r\n" + //
|
" v_uvScale = u_uvScale;\r\n" + //
|
||||||
" gl_Position = u_mvp * vec4(position, 1.0);\r\n" + //
|
" gl_Position = u_mvp * vec4(position, 1.0);\r\n" + //
|
||||||
" if(!u_unshaded) {\r\n" + //
|
" if(!u_unshaded) {\r\n" + //
|
||||||
Shaders.lightSystem("normal", "position", "u_lightTexture", "u_lightTextureHeight", "u_lightCount", false)
|
Shaders.lightSystem("normal", "position", "u_lightTexture", "u_lightTextureHeight", "u_lightCount",
|
||||||
|
false)
|
||||||
+ "\r\n" + //
|
+ "\r\n" + //
|
||||||
" v_color.xyz *= clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
" v_color.xyz *= clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" }";
|
" }";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String fsComplex = Shaders.quatTransform + "\r\n\r\n" + //
|
public static final String fsComplex = Shaders.quatTransform + "\r\n\r\n" + //
|
||||||
" uniform sampler2D u_texture;\r\n" + //
|
" uniform sampler2D u_texture;\r\n" + //
|
||||||
@ -219,7 +222,8 @@ public class MdxShaders {
|
|||||||
" gl_FragColor = vec4(0.0, 0, 0, 1.0);//gl_FragCoord.z;\r\n" + //
|
" gl_FragColor = vec4(0.0, 0, 0, 1.0);//gl_FragCoord.z;\r\n" + //
|
||||||
" }";
|
" }";
|
||||||
|
|
||||||
public static final String vsParticles = "\r\n" + //
|
public static final String vsParticles() {
|
||||||
|
return "\r\n" + //
|
||||||
" #define EMITTER_PARTICLE2 0.0\r\n" + //
|
" #define EMITTER_PARTICLE2 0.0\r\n" + //
|
||||||
" #define EMITTER_RIBBON 1.0\r\n" + //
|
" #define EMITTER_RIBBON 1.0\r\n" + //
|
||||||
" #define EMITTER_SPLAT 2.0\r\n" + //
|
" #define EMITTER_SPLAT 2.0\r\n" + //
|
||||||
@ -239,6 +243,10 @@ public class MdxShaders {
|
|||||||
" uniform vec3 u_cameraZ;\r\n" + //
|
" uniform vec3 u_cameraZ;\r\n" + //
|
||||||
" uniform float u_timeMiddle;\r\n" + //
|
" uniform float u_timeMiddle;\r\n" + //
|
||||||
" uniform bool u_teamColored;\r\n" + //
|
" uniform bool u_teamColored;\r\n" + //
|
||||||
|
" uniform bool u_unshaded;\r\n" + //
|
||||||
|
" uniform sampler2D u_lightTexture;\r\n" + //
|
||||||
|
" uniform float u_lightCount;\r\n" + //
|
||||||
|
" uniform float u_lightTextureHeight;\r\n" + //
|
||||||
" // Splat and Uber.\r\n" + //
|
" // Splat and Uber.\r\n" + //
|
||||||
" uniform vec3 u_intervalTimes;\r\n" + //
|
" uniform vec3 u_intervalTimes;\r\n" + //
|
||||||
" // Vertices\r\n" + //
|
" // Vertices\r\n" + //
|
||||||
@ -314,9 +322,12 @@ public class MdxShaders {
|
|||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" v_color = color;\r\n" + //
|
" v_color = color;\r\n" + //
|
||||||
" \r\n" + //
|
" \r\n" + //
|
||||||
|
" vec3 lightingNormal;\r\n" + //
|
||||||
|
" vec3 position;\r\n" + //
|
||||||
" if (a_tail == HEAD) {\r\n" + //
|
" if (a_tail == HEAD) {\r\n" + //
|
||||||
" vec3 vertices[4];\r\n" + //
|
" vec3 vertices[4];\r\n" + //
|
||||||
" if(a_p1[0] != 0.0 || a_p1[1] != 0.0) {\r\n" + //
|
" if(a_p1[0] != 0.0 || a_p1[1] != 0.0) {\r\n" + //
|
||||||
|
" lightingNormal = vec3(0.0, 0.0, 1.0);\r\n" + //
|
||||||
" vec3 vx;\r\n" + //
|
" vec3 vx;\r\n" + //
|
||||||
" vx[0] = a_p1[0];\r\n" + //
|
" vx[0] = a_p1[0];\r\n" + //
|
||||||
" vx[1] = a_p1[1];\r\n" + //
|
" vx[1] = a_p1[1];\r\n" + //
|
||||||
@ -331,18 +342,19 @@ public class MdxShaders {
|
|||||||
" vertices[0] = -vertices[2];\r\n" + //
|
" vertices[0] = -vertices[2];\r\n" + //
|
||||||
" vertices[3] = -vertices[1];\r\n" + //
|
" vertices[3] = -vertices[1];\r\n" + //
|
||||||
" } else {\r\n" + //
|
" } else {\r\n" + //
|
||||||
|
" lightingNormal = normalize(u_cameraZ);\r\n" + //
|
||||||
" vertices[0] = u_vertices[0];\r\n" + //
|
" vertices[0] = u_vertices[0];\r\n" + //
|
||||||
" vertices[1] = u_vertices[1];\r\n" + //
|
" vertices[1] = u_vertices[1];\r\n" + //
|
||||||
" vertices[2] = u_vertices[2];\r\n" + //
|
" vertices[2] = u_vertices[2];\r\n" + //
|
||||||
" vertices[3] = u_vertices[3];\r\n" + //
|
" vertices[3] = u_vertices[3];\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" gl_Position = u_mvp * vec4(a_p0 + (vertices[int(a_position)] * scale), 1.0);\r\n" + //
|
" position = a_p0 + (vertices[int(a_position)] * scale);\r\n" + //
|
||||||
|
" gl_Position = u_mvp * vec4(position, 1.0);\r\n" + //
|
||||||
" } else {\r\n" + //
|
" } else {\r\n" + //
|
||||||
" // Get the normal to the tail in camera space.\r\n" + //
|
" // Get the normal to the tail in camera space.\r\n" + //
|
||||||
" // This allows to build a 2D rectangle around the 3D tail.\r\n" + //
|
" // This allows to build a 2D rectangle around the 3D tail.\r\n" + //
|
||||||
" vec3 normal = cross(u_cameraZ, normalize(a_p1 - a_p0));\r\n" + //
|
" vec3 normal = cross(u_cameraZ, normalize(a_p1 - a_p0));\r\n" + //
|
||||||
" vec3 boundary = normal * scale * a_p2[0];\r\n" + //
|
" vec3 boundary = normal * scale * a_p2[0];\r\n" + //
|
||||||
" vec3 position;\r\n" + //
|
|
||||||
" if (a_position == 0.0) {\r\n" + //
|
" if (a_position == 0.0) {\r\n" + //
|
||||||
" position = a_p0 - boundary;\r\n" + //
|
" position = a_p0 - boundary;\r\n" + //
|
||||||
" } else if (a_position == 1.0) {\r\n" + //
|
" } else if (a_position == 1.0) {\r\n" + //
|
||||||
@ -353,6 +365,13 @@ public class MdxShaders {
|
|||||||
" position = a_p0 + boundary;\r\n" + //
|
" position = a_p0 + boundary;\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" gl_Position = u_mvp * vec4(position, 1.0);\r\n" + //
|
" gl_Position = u_mvp * vec4(position, 1.0);\r\n" + //
|
||||||
|
" lightingNormal = normalize(u_cameraZ);\r\n" + //
|
||||||
|
" }\r\n" + //
|
||||||
|
" if(!u_unshaded) {\r\n" + //
|
||||||
|
Shaders.lightSystem("lightingNormal", "position", "u_lightTexture", "u_lightTextureHeight",
|
||||||
|
"u_lightCount", false)
|
||||||
|
+ "\r\n" + //
|
||||||
|
" v_color.xyz *= clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" void ribbon() {\r\n" + //
|
" void ribbon() {\r\n" + //
|
||||||
@ -452,6 +471,7 @@ public class MdxShaders {
|
|||||||
" ubersplat();\r\n" + //
|
" ubersplat();\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" }";
|
" }";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String fsParticles = "\r\n" + //
|
public static final String fsParticles = "\r\n" + //
|
||||||
" #define EMITTER_RIBBON 1.0\r\n" + //
|
" #define EMITTER_RIBBON 1.0\r\n" + //
|
||||||
|
@ -7,6 +7,7 @@ import com.etheller.warsmash.util.WorldEditStrings;
|
|||||||
import com.etheller.warsmash.viewer5.CanvasProvider;
|
import com.etheller.warsmash.viewer5.CanvasProvider;
|
||||||
import com.etheller.warsmash.viewer5.SceneLightManager;
|
import com.etheller.warsmash.viewer5.SceneLightManager;
|
||||||
import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer;
|
import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.W3xScenePortraitLightManager;
|
import com.etheller.warsmash.viewer5.handlers.w3x.W3xScenePortraitLightManager;
|
||||||
|
|
||||||
public class MdxViewer extends AbstractMdxModelViewer {
|
public class MdxViewer extends AbstractMdxModelViewer {
|
||||||
@ -16,6 +17,7 @@ public class MdxViewer extends AbstractMdxModelViewer {
|
|||||||
|
|
||||||
public MdxViewer(final DataSource dataSource, final CanvasProvider canvas, final Vector3 defaultLighting) {
|
public MdxViewer(final DataSource dataSource, final CanvasProvider canvas, final Vector3 defaultLighting) {
|
||||||
super(dataSource, canvas);
|
super(dataSource, canvas);
|
||||||
|
MdxHandler.CURRENT_SHADER_TYPE = ShaderEnvironmentType.MENU;
|
||||||
this.defaultLighting = defaultLighting;
|
this.defaultLighting = defaultLighting;
|
||||||
this.worldEditStrings = new WorldEditStrings(this.dataSource);
|
this.worldEditStrings = new WorldEditStrings(this.dataSource);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ public class W3xShaders {
|
|||||||
private UberSplat() {
|
private UberSplat() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String vert = "\r\n" + //
|
public static final String vert() {
|
||||||
|
return "\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
" uniform mat4 u_mvp;\r\n" + //
|
" uniform mat4 u_mvp;\r\n" + //
|
||||||
" uniform sampler2D u_heightMap;\r\n" + //
|
" uniform sampler2D u_heightMap;\r\n" + //
|
||||||
@ -37,10 +38,14 @@ public class W3xShaders {
|
|||||||
" float hU;\r\n" + //
|
" float hU;\r\n" + //
|
||||||
" if (a_absoluteHeight < -256.0) {\r\n" + //
|
" if (a_absoluteHeight < -256.0) {\r\n" + //
|
||||||
" height = texture2D(u_heightMap, base * u_pixel + halfPixel).r * 128.0;\r\n" + //
|
" height = texture2D(u_heightMap, base * u_pixel + halfPixel).r * 128.0;\r\n" + //
|
||||||
" hL = texture2D(u_heightMap, vec2(base - vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n" + //
|
" hL = texture2D(u_heightMap, vec2(base - vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n"
|
||||||
" hR = texture2D(u_heightMap, vec2(base + vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n" + //
|
+ //
|
||||||
" hD = texture2D(u_heightMap, vec2(base - vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n" + //
|
" hR = texture2D(u_heightMap, vec2(base + vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n"
|
||||||
" hU = texture2D(u_heightMap, vec2(base + vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n" + //
|
+ //
|
||||||
|
" hD = texture2D(u_heightMap, vec2(base - vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n"
|
||||||
|
+ //
|
||||||
|
" hU = texture2D(u_heightMap, vec2(base + vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n"
|
||||||
|
+ //
|
||||||
" } else {\r\n" + //
|
" } else {\r\n" + //
|
||||||
" height = a_absoluteHeight;\r\n" + //
|
" height = a_absoluteHeight;\r\n" + //
|
||||||
" hL = a_absoluteHeight;\r\n" + //
|
" hL = a_absoluteHeight;\r\n" + //
|
||||||
@ -54,12 +59,13 @@ public class W3xShaders {
|
|||||||
" vec3 myposition = vec3(a_position.xy, height + a_position.z);\r\n" + //
|
" vec3 myposition = vec3(a_position.xy, height + a_position.z);\r\n" + //
|
||||||
" gl_Position = u_mvp * vec4(myposition.xyz, 1.0);\r\n" + //
|
" gl_Position = u_mvp * vec4(myposition.xyz, 1.0);\r\n" + //
|
||||||
" a_positionHeight = a_position.z;\r\n" + //
|
" a_positionHeight = a_position.z;\r\n" + //
|
||||||
Shaders.lightSystem("v_normal", "myposition", "u_lightTexture", "u_lightTextureHeight", "u_lightCount",
|
Shaders.lightSystem("v_normal", "myposition", "u_lightTexture", "u_lightTextureHeight",
|
||||||
true)
|
"u_lightCount", true)
|
||||||
+ "\r\n" + //
|
+ "\r\n" + //
|
||||||
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
" }\r\n" + //
|
" }\r\n" + //
|
||||||
" ";
|
" ";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String frag = "\r\n" + //
|
public static final String frag = "\r\n" + //
|
||||||
" uniform sampler2D u_texture;\r\n" + //
|
" uniform sampler2D u_texture;\r\n" + //
|
||||||
|
@ -11,10 +11,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@ -73,6 +75,7 @@ import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.mdx.Attachment;
|
import com.etheller.warsmash.viewer5.handlers.mdx.Attachment;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler;
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxNode;
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxNode;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
||||||
@ -188,6 +191,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
|
|
||||||
public List<SplatModel> selModels = new ArrayList<>();
|
public List<SplatModel> selModels = new ArrayList<>();
|
||||||
public List<RenderWidget> selected = new ArrayList<>();
|
public List<RenderWidget> selected = new ArrayList<>();
|
||||||
|
private final Set<String> mouseHighlightSplatModelKeys = new HashSet<>();
|
||||||
|
private final List<RenderWidget> mouseHighlightWidgets = new ArrayList<>();
|
||||||
private DataTable unitAckSoundsTable;
|
private DataTable unitAckSoundsTable;
|
||||||
private DataTable unitCombatSoundsTable;
|
private DataTable unitCombatSoundsTable;
|
||||||
public DataTable miscData;
|
public DataTable miscData;
|
||||||
@ -234,6 +239,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
|
|
||||||
public War3MapViewer(final DataSource dataSource, final CanvasProvider canvas, final War3MapConfig mapConfig) {
|
public War3MapViewer(final DataSource dataSource, final CanvasProvider canvas, final War3MapConfig mapConfig) {
|
||||||
super(dataSource, canvas);
|
super(dataSource, canvas);
|
||||||
|
MdxHandler.CURRENT_SHADER_TYPE = ShaderEnvironmentType.GAME;
|
||||||
this.gameDataSource = dataSource;
|
this.gameDataSource = dataSource;
|
||||||
|
|
||||||
final WebGL webGL = this.webGL;
|
final WebGL webGL = this.webGL;
|
||||||
@ -369,6 +375,9 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
}
|
}
|
||||||
this.selectionCircleScaleFactor = selectionCircleData.getFieldFloatValue("ScaleFactor");
|
this.selectionCircleScaleFactor = selectionCircleData.getFieldFloatValue("ScaleFactor");
|
||||||
this.imageWalkableZOffset = selectionCircleData.getFieldValue("ImageWalkableZOffset");
|
this.imageWalkableZOffset = selectionCircleData.getFieldValue("ImageWalkableZOffset");
|
||||||
|
this.selectionCircleColorFriend = parseColor(selectionCircleData, "ColorFriend");
|
||||||
|
this.selectionCircleColorNeutral = parseColor(selectionCircleData, "ColorNeutral");
|
||||||
|
this.selectionCircleColorEnemy = parseColor(selectionCircleData, "ColorEnemy");
|
||||||
|
|
||||||
this.uiSoundsTable = new DataTable(worldEditStrings);
|
this.uiSoundsTable = new DataTable(worldEditStrings);
|
||||||
try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) {
|
try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) {
|
||||||
@ -379,6 +388,13 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color parseColor(final Element selectionCircleData, final String field) {
|
||||||
|
return new Color(selectionCircleData.getFieldFloatValue(field, 1) / 255f,
|
||||||
|
selectionCircleData.getFieldFloatValue(field, 2) / 255f,
|
||||||
|
selectionCircleData.getFieldFloatValue(field, 3) / 255f,
|
||||||
|
selectionCircleData.getFieldFloatValue(field, 0) / 255f);
|
||||||
|
}
|
||||||
|
|
||||||
public GenericResource loadMapGeneric(final String path, final FetchDataTypeName dataType,
|
public GenericResource loadMapGeneric(final String path, final FetchDataTypeName dataType,
|
||||||
final LoadGenericCallback callback) {
|
final LoadGenericCallback callback) {
|
||||||
if (this.mapMpq == null) {
|
if (this.mapMpq == null) {
|
||||||
@ -1583,22 +1599,22 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true);
|
locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true);
|
||||||
switch (allyKey) {
|
switch (allyKey) {
|
||||||
case "e:":
|
case "e:":
|
||||||
model.color[0] = 1;
|
model.color[0] = this.selectionCircleColorEnemy.r;
|
||||||
model.color[1] = 0;
|
model.color[1] = this.selectionCircleColorEnemy.g;
|
||||||
model.color[2] = 0;
|
model.color[2] = this.selectionCircleColorEnemy.b;
|
||||||
model.color[3] = 1;
|
model.color[3] = this.selectionCircleColorEnemy.a;
|
||||||
break;
|
break;
|
||||||
case "f:":
|
case "f:":
|
||||||
model.color[0] = 0;
|
model.color[0] = this.selectionCircleColorFriend.r;
|
||||||
model.color[1] = 1;
|
model.color[1] = this.selectionCircleColorFriend.g;
|
||||||
model.color[2] = 0;
|
model.color[2] = this.selectionCircleColorFriend.b;
|
||||||
model.color[3] = 1;
|
model.color[3] = this.selectionCircleColorFriend.a;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
model.color[0] = 1;
|
model.color[0] = this.selectionCircleColorNeutral.r;
|
||||||
model.color[1] = 1;
|
model.color[1] = this.selectionCircleColorNeutral.g;
|
||||||
model.color[2] = 0;
|
model.color[2] = this.selectionCircleColorNeutral.b;
|
||||||
model.color[3] = 1;
|
model.color[3] = this.selectionCircleColorNeutral.a;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.selModels.add(model);
|
this.selModels.add(model);
|
||||||
@ -1606,6 +1622,113 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearUnitMouseOverHighlight(final RenderWidget unit) {
|
||||||
|
this.mouseHighlightWidgets.remove(unit);
|
||||||
|
unit.getSelectionPreviewHighlight().destroy(Gdx.gl30, this.terrain.centerOffset);
|
||||||
|
unit.unassignSelectionPreviewHighlight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearUnitMouseOverHighlight() {
|
||||||
|
for (final String modelKey : this.mouseHighlightSplatModelKeys) {
|
||||||
|
this.terrain.removeSplatBatchModel(modelKey);
|
||||||
|
}
|
||||||
|
for (final RenderWidget widget : this.mouseHighlightWidgets) {
|
||||||
|
widget.unassignSelectionPreviewHighlight();
|
||||||
|
}
|
||||||
|
this.mouseHighlightSplatModelKeys.clear();
|
||||||
|
this.mouseHighlightWidgets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showUnitMouseOverHighlight(final RenderWidget unit) {
|
||||||
|
final Map<String, Terrain.Splat> splats = new HashMap<String, Terrain.Splat>();
|
||||||
|
if (unit.getSelectionScale() > 0) {
|
||||||
|
String allyKey = "n:";
|
||||||
|
final float selectionSize = unit.getSelectionScale();
|
||||||
|
String path = null;
|
||||||
|
for (int i = 0; i < this.selectionCircleSizes.size(); i++) {
|
||||||
|
final SelectionCircleSize selectionCircleSize = this.selectionCircleSizes.get(i);
|
||||||
|
if ((selectionSize < selectionCircleSize.size) || (i == (this.selectionCircleSizes.size() - 1))) {
|
||||||
|
path = selectionCircleSize.texture;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!path.toLowerCase().endsWith(".blp")) {
|
||||||
|
path += ".blp";
|
||||||
|
}
|
||||||
|
if (unit instanceof RenderUnit) {
|
||||||
|
final int selectedUnitPlayerIndex = ((RenderUnit) unit).getSimulationUnit().getPlayerIndex();
|
||||||
|
final CPlayer localPlayer = this.simulation.getPlayer(this.localPlayerIndex);
|
||||||
|
if (!localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.PASSIVE)) {
|
||||||
|
allyKey = "e:";
|
||||||
|
}
|
||||||
|
else if (localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.HELP_REQUEST)) {
|
||||||
|
allyKey = "f:";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path = allyKey + path;
|
||||||
|
final SplatModel splatModel = this.terrain.getSplatModel("mouseover:" + path);
|
||||||
|
if (splatModel != null) {
|
||||||
|
final float x = unit.getX();
|
||||||
|
final float y = unit.getY();
|
||||||
|
final SplatMover splatInstance = splatModel.add(x - (selectionSize / 2), y - (selectionSize / 2),
|
||||||
|
x + (selectionSize / 2), y + (selectionSize / 2), 4, this.terrain.centerOffset);
|
||||||
|
unit.assignSelectionPreviewHighlight(splatInstance);
|
||||||
|
if (unit.getInstance().hidden()) {
|
||||||
|
splatInstance.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!splats.containsKey(path)) {
|
||||||
|
splats.put(path, new Splat());
|
||||||
|
}
|
||||||
|
final float x = unit.getX();
|
||||||
|
final float y = unit.getY();
|
||||||
|
splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2),
|
||||||
|
x + (selectionSize / 2), y + (selectionSize / 2), 4 });
|
||||||
|
splats.get(path).unitMapping.add(new Consumer<SplatModel.SplatMover>() {
|
||||||
|
@Override
|
||||||
|
public void accept(final SplatMover t) {
|
||||||
|
unit.assignSelectionPreviewHighlight(t);
|
||||||
|
if (unit.getInstance().hidden()) {
|
||||||
|
t.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mouseHighlightWidgets.add(unit);
|
||||||
|
for (final Map.Entry<String, Terrain.Splat> entry : splats.entrySet()) {
|
||||||
|
final String path = entry.getKey();
|
||||||
|
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),
|
||||||
|
locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true);
|
||||||
|
switch (allyKey) {
|
||||||
|
case "e:":
|
||||||
|
model.color[0] = this.selectionCircleColorEnemy.r;
|
||||||
|
model.color[1] = this.selectionCircleColorEnemy.g;
|
||||||
|
model.color[2] = this.selectionCircleColorEnemy.b;
|
||||||
|
model.color[3] = this.selectionCircleColorEnemy.a * 0.5f;
|
||||||
|
break;
|
||||||
|
case "f:":
|
||||||
|
model.color[0] = this.selectionCircleColorFriend.r;
|
||||||
|
model.color[1] = this.selectionCircleColorFriend.g;
|
||||||
|
model.color[2] = this.selectionCircleColorFriend.b;
|
||||||
|
model.color[3] = this.selectionCircleColorFriend.a * 0.5f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
model.color[0] = this.selectionCircleColorNeutral.r;
|
||||||
|
model.color[1] = this.selectionCircleColorNeutral.g;
|
||||||
|
model.color[2] = this.selectionCircleColorNeutral.b;
|
||||||
|
model.color[3] = this.selectionCircleColorNeutral.a * 0.5f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.mouseHighlightSplatModelKeys.add("mouseover:" + path);
|
||||||
|
this.terrain.addSplatBatchModel("mouseover:" + path, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void getClickLocation(final Vector3 out, final int screenX, final int screenY) {
|
public void getClickLocation(final Vector3 out, final int screenX, final int screenY) {
|
||||||
final float[] ray = rayHeap;
|
final float[] ray = rayHeap;
|
||||||
mousePosHeap.set(screenX, screenY);
|
mousePosHeap.set(screenX, screenY);
|
||||||
@ -1678,15 +1801,16 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
final MdxComplexInstance instance = unit.getInstance();
|
final MdxComplexInstance instance = unit.getInstance();
|
||||||
if (instance.shown() && instance.isVisible(this.worldScene.camera)
|
if (instance.shown() && instance.isVisible(this.worldScene.camera)
|
||||||
&& instance.intersectRayWithCollisionSimple(gdxRayHeap, intersectionHeap)) {
|
&& instance.intersectRayWithCollisionSimple(gdxRayHeap, intersectionHeap)) {
|
||||||
if (filter.call(unit.getSimulationWidget()) && (intersectionHeap.z > this.terrain
|
if (filter.call(unit.getSimulationWidget())) {
|
||||||
.getGroundHeight(intersectionHeap.x, intersectionHeap.y))) {
|
final float groundHeight = this.terrain.getGroundHeight(intersectionHeap.x, intersectionHeap.y);
|
||||||
|
if (intersectionHeap.z > groundHeight) {
|
||||||
if (((entity == null) && !unit.isIntersectedOnMeshAlways())) {
|
if (((entity == null) && !unit.isIntersectedOnMeshAlways())) {
|
||||||
entity = unit;
|
entity = unit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (instance.intersectRayWithMeshSlow(gdxRayHeap, intersectionHeap)
|
if (instance.intersectRayWithMeshSlow(gdxRayHeap, intersectionHeap)) {
|
||||||
&& (intersectionHeap.z > this.terrain.getGroundHeight(intersectionHeap.x,
|
if (intersectionHeap.z > this.terrain.getGroundHeight(intersectionHeap.x,
|
||||||
intersectionHeap.y))) {
|
intersectionHeap.y)) {
|
||||||
this.worldScene.camera.worldToCamera(intersectionHeap, intersectionHeap);
|
this.worldScene.camera.worldToCamera(intersectionHeap, intersectionHeap);
|
||||||
if ((entity == null) || (intersectionHeap.z > intersectionHeap2.z)) {
|
if ((entity == null) || (intersectionHeap.z > intersectionHeap2.z)) {
|
||||||
entity = unit;
|
entity = unit;
|
||||||
@ -1697,6 +1821,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1773,6 +1899,12 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
public int imageWalkableZOffset;
|
public int imageWalkableZOffset;
|
||||||
private WTS preloadedWTS;
|
private WTS preloadedWTS;
|
||||||
|
|
||||||
|
private Color selectionCircleColorFriend;
|
||||||
|
|
||||||
|
private Color selectionCircleColorNeutral;
|
||||||
|
|
||||||
|
private Color selectionCircleColorEnemy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a power of two size for the given target capacity.
|
* Returns a power of two size for the given target capacity.
|
||||||
*/
|
*/
|
||||||
@ -1921,7 +2053,7 @@ public class War3MapViewer extends AbstractMdxModelViewer {
|
|||||||
return this.itemToRenderPeer.get(item);
|
return this.itemToRenderPeer.get(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RenderWidget getRenderPeer(final CWidget damagedDestructable) {
|
public RenderWidget getRenderPeer(final CWidget damagedDestructable) {
|
||||||
RenderWidget damagedWidget = War3MapViewer.this.unitToRenderPeer.get(damagedDestructable);
|
RenderWidget damagedWidget = War3MapViewer.this.unitToRenderPeer.get(damagedDestructable);
|
||||||
if (damagedWidget == null) {
|
if (damagedWidget == null) {
|
||||||
damagedWidget = War3MapViewer.this.destructableToRenderPeer.get(damagedDestructable);
|
damagedWidget = War3MapViewer.this.destructableToRenderPeer.get(damagedDestructable);
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.camera;
|
package com.etheller.warsmash.viewer5.handlers.w3x.camera;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Input;
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
|
|
||||||
public final class GameCameraManager extends CameraManager {
|
public final class GameCameraManager extends CameraManager {
|
||||||
|
private static final CameraRates INFINITE_CAMERA_RATES = new CameraRates(Float.POSITIVE_INFINITY,
|
||||||
|
Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY,
|
||||||
|
Float.POSITIVE_INFINITY);
|
||||||
private final CameraPreset[] presets;
|
private final CameraPreset[] presets;
|
||||||
private final CameraRates cameraRates;
|
private final CameraRates cameraRates;
|
||||||
public final CameraPanControls cameraPanControls;
|
public final CameraPanControls cameraPanControls;
|
||||||
private int currentPreset = 0;
|
private int currentPreset = 0;
|
||||||
|
private float fov;
|
||||||
|
|
||||||
public GameCameraManager(final CameraPreset[] presets, final CameraRates cameraRates) {
|
public GameCameraManager(final CameraPreset[] presets, final CameraRates cameraRates) {
|
||||||
this.presets = presets;
|
this.presets = presets;
|
||||||
@ -17,14 +22,22 @@ public final class GameCameraManager extends CameraManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateCamera() {
|
public void updateCamera() {
|
||||||
this.quatHeap2.idt();
|
|
||||||
final CameraPreset cameraPreset = this.presets[this.currentPreset];
|
final CameraPreset cameraPreset = this.presets[this.currentPreset];
|
||||||
|
final CameraRates cameraRate = this.cameraRates;
|
||||||
|
updateCamera(cameraPreset, cameraRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCamera(final CameraPreset cameraPreset, final CameraRates cameraRate) {
|
||||||
|
this.quatHeap2.idt();
|
||||||
this.quatHeap.idt();
|
this.quatHeap.idt();
|
||||||
this.horizontalAngle = (float) Math.toRadians(
|
this.horizontalAngle = applyAtRate(this.horizontalAngle, (float) Math.toRadians(
|
||||||
cameraPreset.getRotation(this.cameraPanControls.insertDown, this.cameraPanControls.deleteDown) - 90);
|
cameraPreset.getRotation(this.cameraPanControls.insertDown, this.cameraPanControls.deleteDown) - 90),
|
||||||
|
(float) Math.toRadians(cameraRate.rotation * 3));
|
||||||
this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle);
|
this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle);
|
||||||
this.distance = Math.max(1200, cameraPreset.getDistance());
|
this.distance = applyAtRate(this.distance, Math.max(1200, cameraPreset.getDistance()), cameraRate.distance);
|
||||||
this.verticalAngle = (float) Math.toRadians(Math.min(335, cameraPreset.getAoa()) - 270);
|
this.verticalAngle = applyAtRate(this.verticalAngle,
|
||||||
|
(float) Math.toRadians(Math.min(335, cameraPreset.getAoa()) - 270),
|
||||||
|
(float) Math.toRadians(cameraRate.aoa));
|
||||||
this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle);
|
this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle);
|
||||||
this.quatHeap.mul(this.quatHeap2);
|
this.quatHeap.mul(this.quatHeap2);
|
||||||
|
|
||||||
@ -33,12 +46,24 @@ public final class GameCameraManager extends CameraManager {
|
|||||||
this.position.nor();
|
this.position.nor();
|
||||||
this.position.scl(this.distance);
|
this.position.scl(this.distance);
|
||||||
this.position = this.position.add(this.target);
|
this.position = this.position.add(this.target);
|
||||||
this.camera.perspective((float) Math.toRadians(cameraPreset.getFov() / 2), this.camera.getAspect(),
|
this.fov = applyAtRate(this.fov, (float) Math.toRadians(cameraPreset.getFov() / 2),
|
||||||
cameraPreset.getNearZ(), cameraPreset.getFarZ());
|
(float) Math.toRadians(cameraRate.fov));
|
||||||
|
this.camera.perspective(this.fov, this.camera.getAspect(), cameraPreset.getNearZ(), cameraPreset.getFarZ());
|
||||||
|
|
||||||
this.camera.moveToAndFace(this.position, this.target, this.worldUp);
|
this.camera.moveToAndFace(this.position, this.target, this.worldUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float applyAtRate(final float oldValue, final float newValue, float rate) {
|
||||||
|
rate *= Gdx.graphics.getDeltaTime();
|
||||||
|
final float deltaDistance = newValue - oldValue;
|
||||||
|
if (Math.abs(deltaDistance) < rate) {
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return oldValue + (Math.signum(deltaDistance) * rate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void resize(final Rectangle viewport) {
|
public void resize(final Rectangle viewport) {
|
||||||
this.camera.viewport(viewport);
|
this.camera.viewport(viewport);
|
||||||
}
|
}
|
||||||
|
@ -391,11 +391,11 @@ public class Terrain {
|
|||||||
|
|
||||||
updateGroundHeights(new Rectangle(0, 0, width - 1, height - 1));
|
updateGroundHeights(new Rectangle(0, 0, width - 1, height - 1));
|
||||||
|
|
||||||
this.groundShader = webGL.createShaderProgram(TerrainShaders.Terrain.vert, TerrainShaders.Terrain.frag);
|
this.groundShader = webGL.createShaderProgram(TerrainShaders.Terrain.vert(), TerrainShaders.Terrain.frag);
|
||||||
this.cliffShader = webGL.createShaderProgram(TerrainShaders.Cliffs.vert, TerrainShaders.Cliffs.frag);
|
this.cliffShader = webGL.createShaderProgram(TerrainShaders.Cliffs.vert(), TerrainShaders.Cliffs.frag);
|
||||||
this.waterShader = webGL.createShaderProgram(TerrainShaders.Water.vert, TerrainShaders.Water.frag);
|
this.waterShader = webGL.createShaderProgram(TerrainShaders.Water.vert(), TerrainShaders.Water.frag);
|
||||||
|
|
||||||
this.uberSplatShader = webGL.createShaderProgram(W3xShaders.UberSplat.vert, W3xShaders.UberSplat.frag);
|
this.uberSplatShader = webGL.createShaderProgram(W3xShaders.UberSplat.vert(), W3xShaders.UberSplat.frag);
|
||||||
|
|
||||||
// TODO collision bodies (?)
|
// TODO collision bodies (?)
|
||||||
|
|
||||||
@ -1443,6 +1443,10 @@ public class Terrain {
|
|||||||
Collections.sort(this.uberSplatModelsList);
|
Collections.sort(this.uberSplatModelsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SplatModel getSplatModel(final String pathKey) {
|
||||||
|
return this.uberSplatModels.get(pathKey);
|
||||||
|
}
|
||||||
|
|
||||||
public SplatMover addUberSplat(final String path, final float x, final float y, final float z, final float scale,
|
public SplatMover addUberSplat(final String path, final float x, final float y, final float z, final float scale,
|
||||||
final boolean unshaded, final boolean noDepthTest, final boolean highPriority) {
|
final boolean unshaded, final boolean noDepthTest, final boolean highPriority) {
|
||||||
SplatModel splatModel = this.uberSplatModels.get(path);
|
SplatModel splatModel = this.uberSplatModels.get(path);
|
||||||
|
@ -10,7 +10,8 @@ public class TerrainShaders {
|
|||||||
private Cliffs() {
|
private Cliffs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String vert = "#version 330 core\r\n" + //
|
public static final String vert() {
|
||||||
|
return "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
"in vec3 vPosition;\r\n" + //
|
"in vec3 vPosition;\r\n" + //
|
||||||
"in vec2 vUV;\r\n" + //
|
"in vec2 vUV;\r\n" + //
|
||||||
@ -80,6 +81,7 @@ public class TerrainShaders {
|
|||||||
+ "\r\n" + //
|
+ "\r\n" + //
|
||||||
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
"}";
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String frag = "#version 330 core\r\n" + //
|
public static final String frag = "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
@ -113,7 +115,8 @@ public class TerrainShaders {
|
|||||||
private Terrain() {
|
private Terrain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String vert = "#version 330 core\r\n" + //
|
public static final String vert() {
|
||||||
|
return "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
"in vec2 vPosition;\r\n" + //
|
"in vec2 vPosition;\r\n" + //
|
||||||
"uniform mat4 MVP;\r\n" + //
|
"uniform mat4 MVP;\r\n" + //
|
||||||
@ -165,10 +168,12 @@ public class TerrainShaders {
|
|||||||
" v_suv = (vPosition + pos) / size;\r\n" + //
|
" v_suv = (vPosition + pos) / size;\r\n" + //
|
||||||
" position.x = (position.x - centerOffsetX) / (size.x * 128.0);\r\n" + //
|
" position.x = (position.x - centerOffsetX) / (size.x * 128.0);\r\n" + //
|
||||||
" position.y = (position.y - centerOffsetY) / (size.y * 128.0);\r\n" + //
|
" position.y = (position.y - centerOffsetY) / (size.y * 128.0);\r\n" + //
|
||||||
Shaders.lightSystem("normal", "positionWorld", "lightTexture", "lightTextureHeight", "lightCount", true)
|
Shaders.lightSystem("normal", "positionWorld", "lightTexture", "lightTextureHeight", "lightCount",
|
||||||
|
true)
|
||||||
+ "\r\n" + //
|
+ "\r\n" + //
|
||||||
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
"}";
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String frag = "#version 330 core\r\n" + //
|
public static final String frag = "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
@ -291,7 +296,8 @@ public class TerrainShaders {
|
|||||||
private Water() {
|
private Water() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String vert = "#version 330 core\r\n" + //
|
public static final String vert() {
|
||||||
|
return "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
"in vec2 vPosition;\r\n" + //
|
"in vec2 vPosition;\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
@ -353,6 +359,7 @@ public class TerrainShaders {
|
|||||||
+ "\r\n" + //
|
+ "\r\n" + //
|
||||||
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
" shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + //
|
||||||
" }";
|
" }";
|
||||||
|
}
|
||||||
|
|
||||||
public static final String frag = "#version 330 core\r\n" + //
|
public static final String frag = "#version 330 core\r\n" + //
|
||||||
"\r\n" + //
|
"\r\n" + //
|
||||||
|
@ -24,9 +24,11 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
|
|||||||
public Rectangle walkableBounds;
|
public Rectangle walkableBounds;
|
||||||
private final CDestructable simulationDestructable;
|
private final CDestructable simulationDestructable;
|
||||||
private SplatMover selectionCircle;
|
private SplatMover selectionCircle;
|
||||||
|
private SplatMover selectionPreviewHighlight;
|
||||||
private final UnitAnimationListenerImpl unitAnimationListenerImpl;
|
private final UnitAnimationListenerImpl unitAnimationListenerImpl;
|
||||||
private boolean dead;
|
private boolean dead;
|
||||||
private BuildingShadow destructableShadow;
|
private BuildingShadow destructableShadow;
|
||||||
|
private final boolean selectable;
|
||||||
|
|
||||||
public RenderDestructable(final War3MapViewer map, final MdxModel model, final MutableGameObject row,
|
public RenderDestructable(final War3MapViewer map, final MdxModel model, final MutableGameObject row,
|
||||||
final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type,
|
final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type,
|
||||||
@ -50,6 +52,7 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
|
|||||||
this.unitAnimationListenerImpl = new UnitAnimationListenerImpl((MdxComplexInstance) this.instance);
|
this.unitAnimationListenerImpl = new UnitAnimationListenerImpl((MdxComplexInstance) this.instance);
|
||||||
simulationDestructable.setUnitAnimationListener(this.unitAnimationListenerImpl);
|
simulationDestructable.setUnitAnimationListener(this.unitAnimationListenerImpl);
|
||||||
this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true);
|
this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true);
|
||||||
|
this.selectable = row.readSLKTagBoolean("selectable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -86,6 +89,10 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
|
|||||||
this.selectionCircle.destroy(Gdx.gl30, war3MapViewer.terrain.centerOffset);
|
this.selectionCircle.destroy(Gdx.gl30, war3MapViewer.terrain.centerOffset);
|
||||||
this.selectionCircle = null;
|
this.selectionCircle = null;
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.destroy(Gdx.gl30, war3MapViewer.terrain.centerOffset);
|
||||||
|
this.selectionPreviewHighlight = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!dead) {
|
else if (!dead) {
|
||||||
if (this.dead) {
|
if (this.dead) {
|
||||||
@ -140,6 +147,25 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
|
|||||||
@Override
|
@Override
|
||||||
public void assignSelectionCircle(final SplatMover selectionCircle) {
|
public void assignSelectionCircle(final SplatMover selectionCircle) {
|
||||||
this.selectionCircle = selectionCircle;
|
this.selectionCircle = selectionCircle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unassignSelectionPreviewHighlight() {
|
||||||
|
this.selectionPreviewHighlight = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assignSelectionPreviewHighlight(final SplatMover t) {
|
||||||
|
this.selectionPreviewHighlight = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return this.selectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SplatMover getSelectionPreviewHighlight() {
|
||||||
|
return this.selectionPreviewHighlight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ public class RenderItem implements RenderWidget {
|
|||||||
public final MdxModel portraitModel;
|
public final MdxModel portraitModel;
|
||||||
public SplatMover shadow;
|
public SplatMover shadow;
|
||||||
public SplatMover selectionCircle;
|
public SplatMover selectionCircle;
|
||||||
|
public SplatMover selectionPreviewHighlight;
|
||||||
private boolean hidden;
|
private boolean hidden;
|
||||||
private boolean dead;
|
private boolean dead;
|
||||||
|
|
||||||
@ -176,4 +177,24 @@ public class RenderItem implements RenderWidget {
|
|||||||
public void assignSelectionCircle(final SplatMover t) {
|
public void assignSelectionCircle(final SplatMover t) {
|
||||||
this.selectionCircle = t;
|
this.selectionCircle = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unassignSelectionPreviewHighlight() {
|
||||||
|
this.selectionPreviewHighlight = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assignSelectionPreviewHighlight(final SplatMover t) {
|
||||||
|
this.selectionPreviewHighlight = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SplatMover getSelectionPreviewHighlight() {
|
||||||
|
return this.selectionPreviewHighlight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ public class RenderUnit implements RenderWidget {
|
|||||||
public SplatMover shadow;
|
public SplatMover shadow;
|
||||||
private BuildingShadow buildingShadowInstance;
|
private BuildingShadow buildingShadowInstance;
|
||||||
public SplatMover selectionCircle;
|
public SplatMover selectionCircle;
|
||||||
|
public SplatMover selectionPreviewHighlight;
|
||||||
|
|
||||||
private float facing;
|
private float facing;
|
||||||
|
|
||||||
@ -161,6 +162,9 @@ public class RenderUnit implements RenderWidget {
|
|||||||
if (this.selectionCircle != null) {
|
if (this.selectionCircle != null) {
|
||||||
this.selectionCircle.hide();
|
this.selectionCircle.hide();
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.hide();
|
||||||
|
}
|
||||||
if (this.shadow != null) {
|
if (this.shadow != null) {
|
||||||
this.shadow.hide();
|
this.shadow.hide();
|
||||||
}
|
}
|
||||||
@ -174,6 +178,9 @@ public class RenderUnit implements RenderWidget {
|
|||||||
if (this.selectionCircle != null) {
|
if (this.selectionCircle != null) {
|
||||||
this.selectionCircle.show(map.terrain.centerOffset);
|
this.selectionCircle.show(map.terrain.centerOffset);
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.show(map.terrain.centerOffset);
|
||||||
|
}
|
||||||
if (this.shadow != null) {
|
if (this.shadow != null) {
|
||||||
this.shadow.show(map.terrain.centerOffset);
|
this.shadow.show(map.terrain.centerOffset);
|
||||||
}
|
}
|
||||||
@ -276,6 +283,10 @@ public class RenderUnit implements RenderWidget {
|
|||||||
this.selectionCircle.destroy(Gdx.gl30, map.terrain.centerOffset);
|
this.selectionCircle.destroy(Gdx.gl30, map.terrain.centerOffset);
|
||||||
this.selectionCircle = null;
|
this.selectionCircle = null;
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.destroy(Gdx.gl30, map.terrain.centerOffset);
|
||||||
|
this.selectionPreviewHighlight = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (boneCorpse && !this.boneCorpse) {
|
if (boneCorpse && !this.boneCorpse) {
|
||||||
this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE,
|
this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE,
|
||||||
@ -404,6 +415,13 @@ public class RenderUnit implements RenderWidget {
|
|||||||
|| ((movementType == MovementType.FLY) || (movementType == MovementType.HOVER)),
|
|| ((movementType == MovementType.FLY) || (movementType == MovementType.HOVER)),
|
||||||
selectionCircleHeight + map.imageWalkableZOffset);
|
selectionCircleHeight + map.imageWalkableZOffset);
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.move(dx, dy, map.terrain.centerOffset);
|
||||||
|
this.selectionPreviewHighlight.setHeightAbsolute(
|
||||||
|
(currentWalkableUnder != null)
|
||||||
|
|| ((movementType == MovementType.FLY) || (movementType == MovementType.HOVER)),
|
||||||
|
selectionCircleHeight + map.imageWalkableZOffset);
|
||||||
|
}
|
||||||
this.unitAnimationListenerImpl.update();
|
this.unitAnimationListenerImpl.update();
|
||||||
if (!dead && this.simulationUnit.isConstructing()) {
|
if (!dead && this.simulationUnit.isConstructing()) {
|
||||||
this.instance.setFrameByRatio(
|
this.instance.setFrameByRatio(
|
||||||
@ -447,6 +465,9 @@ public class RenderUnit implements RenderWidget {
|
|||||||
if (this.selectionCircle != null) {
|
if (this.selectionCircle != null) {
|
||||||
this.selectionCircle.move(dx, dy, map.terrain.centerOffset);
|
this.selectionCircle.move(dx, dy, map.terrain.centerOffset);
|
||||||
}
|
}
|
||||||
|
if (this.selectionPreviewHighlight != null) {
|
||||||
|
this.selectionPreviewHighlight.move(dx, dy, map.terrain.centerOffset);
|
||||||
|
}
|
||||||
this.location[0] = this.simulationUnit.getX();
|
this.location[0] = this.simulationUnit.getX();
|
||||||
this.location[1] = this.simulationUnit.getY();
|
this.location[1] = this.simulationUnit.getY();
|
||||||
}
|
}
|
||||||
@ -463,7 +484,7 @@ public class RenderUnit implements RenderWidget {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isIntersectedOnMeshAlways() {
|
public boolean isIntersectedOnMeshAlways() {
|
||||||
return this.simulationUnit.getUnitType().isBuilding();
|
return this.simulationUnit.isBuilding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -495,4 +516,24 @@ public class RenderUnit implements RenderWidget {
|
|||||||
public void assignSelectionCircle(final SplatMover t) {
|
public void assignSelectionCircle(final SplatMover t) {
|
||||||
this.selectionCircle = t;
|
this.selectionCircle = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unassignSelectionPreviewHighlight() {
|
||||||
|
this.selectionPreviewHighlight = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assignSelectionPreviewHighlight(final SplatMover t) {
|
||||||
|
this.selectionPreviewHighlight = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return true; // later needs locust
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SplatMover getSelectionPreviewHighlight() {
|
||||||
|
return this.selectionPreviewHighlight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,12 @@ public interface RenderWidget {
|
|||||||
|
|
||||||
void assignSelectionCircle(SplatMover t);
|
void assignSelectionCircle(SplatMover t);
|
||||||
|
|
||||||
|
void unassignSelectionPreviewHighlight();
|
||||||
|
|
||||||
|
void assignSelectionPreviewHighlight(SplatMover t);
|
||||||
|
|
||||||
|
boolean isSelectable();
|
||||||
|
|
||||||
public static final class UnitAnimationListenerImpl implements CUnitAnimationListener {
|
public static final class UnitAnimationListenerImpl implements CUnitAnimationListener {
|
||||||
private final MdxComplexInstance instance;
|
private final MdxComplexInstance instance;
|
||||||
protected final EnumSet<AnimationTokens.SecondaryTag> secondaryAnimationTags = EnumSet
|
protected final EnumSet<AnimationTokens.SecondaryTag> secondaryAnimationTags = EnumSet
|
||||||
@ -159,4 +165,6 @@ public interface RenderWidget {
|
|||||||
this.allowRarityVariations = allowRarityVariations;
|
this.allowRarityVariations = allowRarityVariations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SplatMover getSelectionPreviewHighlight();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ public class CDestructable extends CWidget {
|
|||||||
private final RemovablePathingMapInstance pathingInstance;
|
private final RemovablePathingMapInstance pathingInstance;
|
||||||
private final RemovablePathingMapInstance pathingInstanceDeath;
|
private final RemovablePathingMapInstance pathingInstanceDeath;
|
||||||
private UnitAnimationListenerImpl unitAnimationListenerImpl;
|
private UnitAnimationListenerImpl unitAnimationListenerImpl;
|
||||||
|
private boolean invulnerable;
|
||||||
|
|
||||||
public CDestructable(final int handleId, final float x, final float y, final float life,
|
public CDestructable(final int handleId, final float x, final float y, final float life,
|
||||||
final CDestructableType destTypeInstance, final RemovablePathingMapInstance pathingInstance,
|
final CDestructableType destTypeInstance, final RemovablePathingMapInstance pathingInstance,
|
||||||
@ -80,4 +81,18 @@ public class CDestructable extends CWidget {
|
|||||||
public void setUnitAnimationListener(final UnitAnimationListenerImpl unitAnimationListenerImpl) {
|
public void setUnitAnimationListener(final UnitAnimationListenerImpl unitAnimationListenerImpl) {
|
||||||
this.unitAnimationListenerImpl = unitAnimationListenerImpl;
|
this.unitAnimationListenerImpl = unitAnimationListenerImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMaxLife() {
|
||||||
|
return this.destType.getLife();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvulnerable(final boolean invulnerable) {
|
||||||
|
this.invulnerable = invulnerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerable() {
|
||||||
|
return this.invulnerable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,11 @@ public class CItem extends CWidget {
|
|||||||
return this.hidden;
|
return this.hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMaxLife() {
|
||||||
|
return this.itemType.getHitPoints();
|
||||||
|
}
|
||||||
|
|
||||||
public void setPointAndCheckUnstuck(final float newX, final float newY, final CSimulation game) {
|
public void setPointAndCheckUnstuck(final float newX, final float newY, final CSimulation game) {
|
||||||
final CWorldCollision collision = game.getWorldCollision();
|
final CWorldCollision collision = game.getWorldCollision();
|
||||||
final PathingGrid pathingGrid = game.getPathingGrid();
|
final PathingGrid pathingGrid = game.getPathingGrid();
|
||||||
@ -100,4 +105,9 @@ public class CItem extends CWidget {
|
|||||||
setY(outputY);
|
setY(outputY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -201,14 +201,14 @@ public class CUnit extends CWidget {
|
|||||||
return this.mana;
|
return this.mana;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaximumLife() {
|
|
||||||
return this.maximumLife;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaximumMana() {
|
public int getMaximumMana() {
|
||||||
return this.maximumMana;
|
return this.maximumMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMaximumLife() {
|
||||||
|
return this.maximumLife;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTypeId(final War3ID typeId) {
|
public void setTypeId(final War3ID typeId) {
|
||||||
this.typeId = typeId;
|
this.typeId = typeId;
|
||||||
}
|
}
|
||||||
@ -430,7 +430,7 @@ public class CUnit extends CWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float getEndingDecayTime(final CSimulation game) {
|
public float getEndingDecayTime(final CSimulation game) {
|
||||||
if (this.unitType.isBuilding()) {
|
if (this.isBuilding()) {
|
||||||
return game.getGameplayConstants().getStructureDecayTime();
|
return game.getGameplayConstants().getStructureDecayTime();
|
||||||
}
|
}
|
||||||
return game.getGameplayConstants().getBoneDecayTime();
|
return game.getGameplayConstants().getBoneDecayTime();
|
||||||
@ -630,7 +630,7 @@ public class CUnit extends CWidget {
|
|||||||
|
|
||||||
public void setX(final float newX, final CWorldCollision collision, final CRegionManager regionManager) {
|
public void setX(final float newX, final CWorldCollision collision, final CRegionManager regionManager) {
|
||||||
final float prevX = getX();
|
final float prevX = getX();
|
||||||
if (!this.unitType.isBuilding()) {
|
if (!this.isBuilding()) {
|
||||||
setX(newX);
|
setX(newX);
|
||||||
collision.translate(this, newX - prevX, 0);
|
collision.translate(this, newX - prevX, 0);
|
||||||
}
|
}
|
||||||
@ -639,7 +639,7 @@ public class CUnit extends CWidget {
|
|||||||
|
|
||||||
public void setY(final float newY, final CWorldCollision collision, final CRegionManager regionManager) {
|
public void setY(final float newY, final CWorldCollision collision, final CRegionManager regionManager) {
|
||||||
final float prevY = getY();
|
final float prevY = getY();
|
||||||
if (!this.unitType.isBuilding()) {
|
if (!this.isBuilding()) {
|
||||||
setY(newY);
|
setY(newY);
|
||||||
collision.translate(this, 0, newY - prevY);
|
collision.translate(this, 0, newY - prevY);
|
||||||
}
|
}
|
||||||
@ -692,7 +692,7 @@ public class CUnit extends CWidget {
|
|||||||
final float prevY = getY();
|
final float prevY = getY();
|
||||||
setX(newX);
|
setX(newX);
|
||||||
setY(newY);
|
setY(newY);
|
||||||
if (!this.unitType.isBuilding()) {
|
if (!this.isBuilding()) {
|
||||||
collision.translate(this, newX - prevX, newY - prevY);
|
collision.translate(this, newX - prevX, newY - prevY);
|
||||||
}
|
}
|
||||||
checkRegionEvents(regionManager);
|
checkRegionEvents(regionManager);
|
||||||
@ -867,7 +867,7 @@ public class CUnit extends CWidget {
|
|||||||
final CPlayer sourcePlayer = simulation.getPlayer(source.getPlayerIndex());
|
final CPlayer sourcePlayer = simulation.getPlayer(source.getPlayerIndex());
|
||||||
if (!sourcePlayer.hasAlliance(this.playerIndex, CAllianceType.PASSIVE)) {
|
if (!sourcePlayer.hasAlliance(this.playerIndex, CAllianceType.PASSIVE)) {
|
||||||
final CGameplayConstants gameplayConstants = simulation.getGameplayConstants();
|
final CGameplayConstants gameplayConstants = simulation.getGameplayConstants();
|
||||||
if (gameplayConstants.isBuildingKillsGiveExp() || !source.getUnitType().isBuilding()) {
|
if (gameplayConstants.isBuildingKillsGiveExp() || !source.isBuilding()) {
|
||||||
final CUnit killedUnit = this;
|
final CUnit killedUnit = this;
|
||||||
final CAbilityHero killedUnitHeroData = getHeroData();
|
final CAbilityHero killedUnitHeroData = getHeroData();
|
||||||
final boolean killedUnitIsAHero = killedUnitHeroData != null;
|
final boolean killedUnitIsAHero = killedUnitHeroData != null;
|
||||||
@ -917,7 +917,7 @@ public class CUnit extends CWidget {
|
|||||||
if (target instanceof CUnit) {
|
if (target instanceof CUnit) {
|
||||||
final CUnit targetUnit = (CUnit) target;
|
final CUnit targetUnit = (CUnit) target;
|
||||||
final CUnitType targetUnitType = targetUnit.getUnitType();
|
final CUnitType targetUnitType = targetUnit.getUnitType();
|
||||||
if (targetUnitType.isBuilding() && (targetUnitType.getBuildingPathingPixelMap() != null)) {
|
if (targetUnit.isBuilding() && (targetUnitType.getBuildingPathingPixelMap() != null)) {
|
||||||
final BufferedImage buildingPathingPixelMap = targetUnitType.getBuildingPathingPixelMap();
|
final BufferedImage buildingPathingPixelMap = targetUnitType.getBuildingPathingPixelMap();
|
||||||
final float targetX = target.getX();
|
final float targetX = target.getX();
|
||||||
final float targetY = target.getY();
|
final float targetY = target.getY();
|
||||||
@ -1061,7 +1061,7 @@ public class CUnit extends CWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMovementDisabled() {
|
public boolean isMovementDisabled() {
|
||||||
return this.unitType.isBuilding();
|
return this.isBuilding();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAcquisitionRange() {
|
public float getAcquisitionRange() {
|
||||||
@ -1205,6 +1205,7 @@ public class CUnit extends CWidget {
|
|||||||
this.invulnerable = invulnerable;
|
this.invulnerable = invulnerable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isInvulnerable() {
|
public boolean isInvulnerable() {
|
||||||
return this.invulnerable;
|
return this.invulnerable;
|
||||||
}
|
}
|
||||||
@ -1537,6 +1538,11 @@ public class CUnit extends CWidget {
|
|||||||
return this.containingRegions.contains(region);
|
return this.containingRegions.contains(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMaxLife() {
|
||||||
|
return this.maximumLife;
|
||||||
|
}
|
||||||
|
|
||||||
private static final class RegionCheckerImpl implements CRegionEnumFunction {
|
private static final class RegionCheckerImpl implements CRegionEnumFunction {
|
||||||
private CUnit unit;
|
private CUnit unit;
|
||||||
|
|
||||||
@ -1556,4 +1562,8 @@ public class CUnit extends CWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBuilding() {
|
||||||
|
return this.unitType.isBuilding();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ public class CUnitType {
|
|||||||
private final List<String> heroProperNames;
|
private final List<String> heroProperNames;
|
||||||
private final int properNamesCount;
|
private final int properNamesCount;
|
||||||
private final boolean canFlee;
|
private final boolean canFlee;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
public CUnitType(final String name, final String legacyName, final War3ID typeId, final int life,
|
public CUnitType(final String name, final String legacyName, final War3ID typeId, final int life,
|
||||||
final int manaInitial, final int manaMaximum, final int speed, final int defense, final String abilityList,
|
final int manaInitial, final int manaMaximum, final int speed, final int defense, final String abilityList,
|
||||||
@ -91,7 +92,7 @@ public class CUnitType {
|
|||||||
final float strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence,
|
final float strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence,
|
||||||
final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute,
|
final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute,
|
||||||
final List<War3ID> heroAbilityList, final List<String> heroProperNames, final int properNamesCount,
|
final List<War3ID> heroAbilityList, final List<String> heroProperNames, final int properNamesCount,
|
||||||
final boolean canFlee) {
|
final boolean canFlee, final int priority) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.legacyName = legacyName;
|
this.legacyName = legacyName;
|
||||||
this.typeId = typeId;
|
this.typeId = typeId;
|
||||||
@ -144,6 +145,7 @@ public class CUnitType {
|
|||||||
this.heroProperNames = heroProperNames;
|
this.heroProperNames = heroProperNames;
|
||||||
this.properNamesCount = properNamesCount;
|
this.properNamesCount = properNamesCount;
|
||||||
this.canFlee = canFlee;
|
this.canFlee = canFlee;
|
||||||
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -353,4 +355,8 @@ public class CUnitType {
|
|||||||
public boolean isCanFlee() {
|
public boolean isCanFlee() {
|
||||||
return this.canFlee;
|
return this.canFlee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return this.priority;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ public abstract class CWidget implements AbilityTarget {
|
|||||||
return this.life;
|
return this.life;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract float getMaxLife();
|
||||||
|
|
||||||
protected void setX(final float x) {
|
protected void setX(final float x) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
@ -70,4 +72,6 @@ public abstract class CWidget implements AbilityTarget {
|
|||||||
final double dy = Math.abs(target.getY() - getY());
|
final double dy = Math.abs(target.getY() - getY());
|
||||||
return (dx * dx) + (dy * dy);
|
return (dx * dx) + (dy * dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract boolean isInvulnerable();
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class CWorldCollision {
|
|||||||
collisionSize * 2);
|
collisionSize * 2);
|
||||||
unit.setCollisionRectangle(bounds);
|
unit.setCollisionRectangle(bounds);
|
||||||
}
|
}
|
||||||
if (unit.getUnitType().isBuilding()) {
|
if (unit.isBuilding()) {
|
||||||
// buildings are here so that we can include them when enumerating all units in
|
// buildings are here so that we can include them when enumerating all units in
|
||||||
// a rect, but they don't really move dynamically, this is kind of pointless
|
// a rect, but they don't really move dynamically, this is kind of pointless
|
||||||
this.buildingUnitCollision.add(unit, bounds);
|
this.buildingUnitCollision.add(unit, bounds);
|
||||||
@ -73,7 +73,7 @@ public class CWorldCollision {
|
|||||||
public void removeUnit(final CUnit unit) {
|
public void removeUnit(final CUnit unit) {
|
||||||
final Rectangle bounds = unit.getCollisionRectangle();
|
final Rectangle bounds = unit.getCollisionRectangle();
|
||||||
if (bounds != null) {
|
if (bounds != null) {
|
||||||
if (unit.getUnitType().isBuilding()) {
|
if (unit.isBuilding()) {
|
||||||
this.buildingUnitCollision.remove(unit, bounds);
|
this.buildingUnitCollision.remove(unit, bounds);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -154,7 +154,7 @@ public class CWorldCollision {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void translate(final CUnit unit, final float xShift, final float yShift) {
|
public void translate(final CUnit unit, final float xShift, final float yShift) {
|
||||||
if (unit.getUnitType().isBuilding()) {
|
if (unit.isBuilding()) {
|
||||||
throw new IllegalArgumentException("Cannot add building to the CWorldCollision");
|
throw new IllegalArgumentException("Cannot add building to the CWorldCollision");
|
||||||
}
|
}
|
||||||
final MovementType movementType = unit.getUnitType().getMovementType();
|
final MovementType movementType = unit.getUnitType().getMovementType();
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||||
|
|
||||||
|
public class CAbilityInvulnerable extends AbstractGenericNoIconAbility {
|
||||||
|
|
||||||
|
public CAbilityInvulnerable(final int handleId, final War3ID alias) {
|
||||||
|
super(handleId, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||||
|
unit.setInvulnerable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(final CSimulation game, final CUnit unit) {
|
||||||
|
unit.setInvulnerable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick(final CSimulation game, final CUnit unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId,
|
||||||
|
final AbilityPointTarget point) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target,
|
||||||
|
final AbilityTargetCheckReceiver<CWidget> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityTargetCheckReceiver<Void> receiver) {
|
||||||
|
receiver.orderIdNotAccepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
|
||||||
|
final AbilityActivationReceiver receiver) {
|
||||||
|
receiver.notAnActiveAbility();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -78,7 +78,8 @@ public class CAbilityHero extends AbstractCAbility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) {
|
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
|
||||||
|
final AbilityTarget target) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
|
||||||
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeInvulnerable;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
|
||||||
|
|
||||||
|
public class CAbilityTypeDefinitionInvulnerable extends AbstractCAbilityTypeDefinition<CAbilityTypeLevelData>
|
||||||
|
implements CAbilityTypeDefinition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CAbilityTypeLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) {
|
||||||
|
final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level);
|
||||||
|
final EnumSet<CTargetType> targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString);
|
||||||
|
return new CAbilityTypeLevelData(targetsAllowedAtLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CAbilityType<?> innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData,
|
||||||
|
final List<CAbilityTypeLevelData> levelData) {
|
||||||
|
return new CAbilityTypeInvulnerable(alias, abilityEditorData.getCode(), levelData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityInvulnerable;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData;
|
||||||
|
|
||||||
|
public class CAbilityTypeInvulnerable extends CAbilityType<CAbilityTypeLevelData> {
|
||||||
|
|
||||||
|
public CAbilityTypeInvulnerable(final War3ID alias, final War3ID code,
|
||||||
|
final List<CAbilityTypeLevelData> levelData) {
|
||||||
|
super(alias, code, levelData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CAbility createAbility(final int handleId) {
|
||||||
|
final CAbilityTypeLevelData levelData = getLevelData(0);
|
||||||
|
return new CAbilityInvulnerable(handleId, getAlias());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -108,8 +108,11 @@ public class CUnitAttackMissileSplash extends CUnitAttackMissile {
|
|||||||
final CUnitAttackListener attackListener) {
|
final CUnitAttackListener attackListener) {
|
||||||
SplashDamageConsumer.INSTANCE.doDamage(cSimulation, source, target, this, x, y, damage, attackListener);
|
SplashDamageConsumer.INSTANCE.doDamage(cSimulation, source, target, this, x, y, damage, attackListener);
|
||||||
if ((getWeaponType() != CWeaponType.ARTILLERY) && !SplashDamageConsumer.INSTANCE.hitTarget) {
|
if ((getWeaponType() != CWeaponType.ARTILLERY) && !SplashDamageConsumer.INSTANCE.hitTarget) {
|
||||||
super.doDamage(cSimulation, source, target, damage * this.damageFactorSmall, x, y, bounceIndex,
|
float originalTargetDamage = damage;
|
||||||
attackListener);
|
if (Math.abs(this.damageFactorSmall) > 0.0001) {
|
||||||
|
originalTargetDamage *= this.damageFactorSmall;
|
||||||
|
}
|
||||||
|
super.doDamage(cSimulation, source, target, originalTargetDamage, x, y, bounceIndex, attackListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.def
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionGoldMine;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionGoldMine;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInventory;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInventory;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionReturnResources;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionReturnResources;
|
||||||
|
|
||||||
public class CAbilityData {
|
public class CAbilityData {
|
||||||
@ -36,6 +37,7 @@ public class CAbilityData {
|
|||||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest());
|
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest());
|
||||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("ANcl"), new CAbilityTypeDefinitionChannelTest());
|
this.codeToAbilityTypeDefinition.put(War3ID.fromString("ANcl"), new CAbilityTypeDefinitionChannelTest());
|
||||||
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory());
|
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory());
|
||||||
|
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Avul"), new CAbilityTypeDefinitionInvulnerable());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CAbilityType<?> getAbilityType(final War3ID alias) {
|
public CAbilityType<?> getAbilityType(final War3ID alias) {
|
||||||
|
@ -168,6 +168,7 @@ public class CUnitData {
|
|||||||
private static final War3ID PRIMARY_ATTRIBUTE = War3ID.fromString("upra");
|
private static final War3ID PRIMARY_ATTRIBUTE = War3ID.fromString("upra");
|
||||||
|
|
||||||
private static final War3ID CAN_FLEE = War3ID.fromString("ufle");
|
private static final War3ID CAN_FLEE = War3ID.fromString("ufle");
|
||||||
|
private static final War3ID PRIORITY = War3ID.fromString("upri");
|
||||||
|
|
||||||
private final CGameplayConstants gameplayConstants;
|
private final CGameplayConstants gameplayConstants;
|
||||||
private final MutableObjectData unitData;
|
private final MutableObjectData unitData;
|
||||||
@ -275,6 +276,7 @@ public class CUnitData {
|
|||||||
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
|
final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0);
|
||||||
final String heroAbilityListString = unitType.getFieldAsString(ABILITIES_HERO, 0);
|
final String heroAbilityListString = unitType.getFieldAsString(ABILITIES_HERO, 0);
|
||||||
final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0);
|
final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0);
|
||||||
|
final int priority = unitType.getFieldAsInteger(PRIORITY, 0);
|
||||||
|
|
||||||
final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0);
|
final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0);
|
||||||
final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0);
|
final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0);
|
||||||
@ -536,7 +538,7 @@ public class CUnitData {
|
|||||||
goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes,
|
goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes,
|
||||||
propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus,
|
propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus,
|
||||||
intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount,
|
intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount,
|
||||||
canFlee);
|
canFlee, priority);
|
||||||
this.unitIdToUnitType.put(typeId, unitTypeInstance);
|
this.unitIdToUnitType.put(typeId, unitTypeInstance);
|
||||||
this.jassLegacyNameToUnitId.put(legacyName, typeId);
|
this.jassLegacyNameToUnitId.put(legacyName, typeId);
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,10 @@ public class CPathfindingProcessor {
|
|||||||
}
|
}
|
||||||
workIterations++;
|
workIterations++;
|
||||||
this.totalIterations++;
|
this.totalIterations++;
|
||||||
if (workIterations >= 7500) {
|
if (this.totalIterations > 20000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (workIterations >= 500) {
|
||||||
// breaking jobs loop will implicitly exit without calling pathFound() below
|
// breaking jobs loop will implicitly exit without calling pathFound() below
|
||||||
break JobsLoop;
|
break JobsLoop;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,13 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
@ -23,9 +26,12 @@ import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
||||||
import com.badlogic.gdx.graphics.glutils.PixmapTextureData;
|
import com.badlogic.gdx.graphics.glutils.PixmapTextureData;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
|
import com.badlogic.gdx.math.collision.BoundingBox;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
||||||
import com.etheller.warsmash.datasources.DataSource;
|
import com.etheller.warsmash.datasources.DataSource;
|
||||||
@ -53,6 +59,7 @@ import com.etheller.warsmash.util.ImageUtils;
|
|||||||
import com.etheller.warsmash.util.RenderMathUtils;
|
import com.etheller.warsmash.util.RenderMathUtils;
|
||||||
import com.etheller.warsmash.util.War3ID;
|
import com.etheller.warsmash.util.War3ID;
|
||||||
import com.etheller.warsmash.util.WarsmashConstants;
|
import com.etheller.warsmash.util.WarsmashConstants;
|
||||||
|
import com.etheller.warsmash.viewer5.Bounds;
|
||||||
import com.etheller.warsmash.viewer5.Scene;
|
import com.etheller.warsmash.viewer5.Scene;
|
||||||
import com.etheller.warsmash.viewer5.ViewerTextureRenderable;
|
import com.etheller.warsmash.viewer5.ViewerTextureRenderable;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.Attachment;
|
import com.etheller.warsmash.viewer5.handlers.mdx.Attachment;
|
||||||
@ -91,6 +98,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListene
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit.QueueItemType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit.QueueItemType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
@ -245,6 +253,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
private long lastErrorMessageExpireTime;
|
private long lastErrorMessageExpireTime;
|
||||||
private long lastErrorMessageFadeTime;
|
private long lastErrorMessageFadeTime;
|
||||||
|
|
||||||
|
private MenuCursorState cursorState;
|
||||||
private CAbilityView activeCommand;
|
private CAbilityView activeCommand;
|
||||||
private int activeCommandOrderId;
|
private int activeCommandOrderId;
|
||||||
private RenderUnit activeCommandUnit;
|
private RenderUnit activeCommandUnit;
|
||||||
@ -278,6 +287,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
private MdxModel waypointModel;
|
private MdxModel waypointModel;
|
||||||
private final List<MdxComplexInstance> waypointModelInstances = new ArrayList<>();
|
private final List<MdxComplexInstance> waypointModelInstances = new ArrayList<>();
|
||||||
private List<RenderUnit> selectedUnits;
|
private List<RenderUnit> selectedUnits;
|
||||||
|
private Set<RenderUnit> dragSelectPreviewUnits = new HashSet<>();
|
||||||
|
private Set<RenderUnit> dragSelectPreviewUnitsUpcoming = new HashSet<>();
|
||||||
private BitmapFont textTagFont;
|
private BitmapFont textTagFont;
|
||||||
private SetPoint uberTipNoResourcesSetPoint;
|
private SetPoint uberTipNoResourcesSetPoint;
|
||||||
private SetPoint uberTipWithResourcesSetPoint;
|
private SetPoint uberTipWithResourcesSetPoint;
|
||||||
@ -296,6 +307,15 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
private SimpleButtonFrame chatButton;
|
private SimpleButtonFrame chatButton;
|
||||||
private final Runnable exitGameRunnable;
|
private final Runnable exitGameRunnable;
|
||||||
private SimpleFrame smashEscMenu;
|
private SimpleFrame smashEscMenu;
|
||||||
|
private RenderWidget mouseOverUnit;
|
||||||
|
private final Vector3 lastMouseDragStart = new Vector3();
|
||||||
|
private final Vector3 lastMouseClickLocation = new Vector3();
|
||||||
|
|
||||||
|
private final List<SimpleStatusBarFrame> hpBarFrames = new ArrayList<>();
|
||||||
|
private int hpBarFrameIndex = 0;
|
||||||
|
private boolean allowDrag;
|
||||||
|
private int currentlyDraggingPointer;
|
||||||
|
private final ShapeRenderer shapeRenderer = new ShapeRenderer();
|
||||||
|
|
||||||
public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport, final Scene uiScene,
|
public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport, final Scene uiScene,
|
||||||
final Scene portraitScene, final CameraPreset[] cameraPresets, final CameraRates cameraRates,
|
final Scene portraitScene, final CameraPreset[] cameraPresets, final CameraRates cameraRates,
|
||||||
@ -939,13 +959,13 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(final int abilityHandleId, final int orderId, final boolean rightClick) {
|
public void onClick(final int abilityHandleId, final int orderId, final boolean rightClick) {
|
||||||
// TODO not O(N)
|
|
||||||
if (this.selectedUnit == null) {
|
if (this.selectedUnit == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (orderId == 0) {
|
if (orderId == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// TODO not O(N)
|
||||||
CAbilityView abilityToUse = null;
|
CAbilityView abilityToUse = null;
|
||||||
for (final CAbility ability : this.selectedUnit.getSimulationUnit().getAbilities()) {
|
for (final CAbility ability : this.selectedUnit.getSimulationUnit().getAbilities()) {
|
||||||
if (ability.getHandleId() == abilityHandleId) {
|
if (ability.getHandleId() == abilityHandleId) {
|
||||||
@ -1050,6 +1070,53 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
if (Gdx.input.isCursorCatched()) {
|
if (Gdx.input.isCursorCatched()) {
|
||||||
Gdx.input.setCursorPosition(mouseX, mouseY);
|
Gdx.input.setCursorPosition(mouseX, mouseY);
|
||||||
}
|
}
|
||||||
|
this.hpBarFrameIndex = 0;
|
||||||
|
if (this.currentlyDraggingPointer == -1) {
|
||||||
|
if ((this.mouseOverUnit != null) && !this.mouseOverUnit.getSimulationWidget().isInvulnerable()) {
|
||||||
|
final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar();
|
||||||
|
positionHealthBar(simpleStatusBarFrame, this.mouseOverUnit, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (this.currentlyDraggingPointer == Input.Buttons.LEFT) {
|
||||||
|
final float minDragX = Math.min(this.lastMouseClickLocation.x, this.lastMouseDragStart.x);
|
||||||
|
final float minDragY = Math.min(this.lastMouseClickLocation.y, this.lastMouseDragStart.y);
|
||||||
|
final float maxDragX = Math.max(this.lastMouseClickLocation.x, this.lastMouseDragStart.x);
|
||||||
|
final float maxDragY = Math.max(this.lastMouseClickLocation.y, this.lastMouseDragStart.y);
|
||||||
|
this.tempRect.set(minDragX, minDragY, maxDragX - minDragX, maxDragY - minDragY);
|
||||||
|
this.dragSelectPreviewUnitsUpcoming.clear();
|
||||||
|
this.war3MapViewer.simulation.getWorldCollision().enumUnitsInRect(this.tempRect, new CUnitEnumFunction() {
|
||||||
|
@Override
|
||||||
|
public boolean call(final CUnit unit) {
|
||||||
|
final RenderUnit renderUnit = MeleeUI.this.war3MapViewer.getRenderPeer(unit);
|
||||||
|
if (!unit.isInvulnerable() && !unit.isDead() && renderUnit.isSelectable()
|
||||||
|
&& MeleeUI.this.dragSelectPreviewUnitsUpcoming.add(renderUnit)) {
|
||||||
|
final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar();
|
||||||
|
positionHealthBar(simpleStatusBarFrame, renderUnit, 1.0f);
|
||||||
|
if (!MeleeUI.this.dragSelectPreviewUnits.contains(renderUnit)) {
|
||||||
|
MeleeUI.this.war3MapViewer.showUnitMouseOverHighlight(renderUnit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (final RenderUnit unit : this.dragSelectPreviewUnits) {
|
||||||
|
if (!this.dragSelectPreviewUnitsUpcoming.contains(unit)) {
|
||||||
|
this.war3MapViewer.clearUnitMouseOverHighlight(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Set<RenderUnit> temp = this.dragSelectPreviewUnits;
|
||||||
|
this.dragSelectPreviewUnits = this.dragSelectPreviewUnitsUpcoming;
|
||||||
|
this.dragSelectPreviewUnitsUpcoming = temp;
|
||||||
|
}
|
||||||
|
if ((this.selectedUnits != null) && false) {
|
||||||
|
for (final RenderUnit unit : this.selectedUnits) {
|
||||||
|
final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar();
|
||||||
|
positionHealthBar(simpleStatusBarFrame, unit, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = this.hpBarFrameIndex; i < this.hpBarFrames.size(); i++) {
|
||||||
|
this.hpBarFrames.get(i).setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
screenCoordsVector.set(mouseX, mouseY);
|
screenCoordsVector.set(mouseX, mouseY);
|
||||||
this.uiViewport.unproject(screenCoordsVector);
|
this.uiViewport.unproject(screenCoordsVector);
|
||||||
@ -1058,9 +1125,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
|
|
||||||
if (this.activeCommand != null) {
|
if (this.activeCommand != null) {
|
||||||
if (this.draggingItem != null) {
|
if (this.draggingItem != null) {
|
||||||
this.cursorFrame.setSequence("HoldItem");
|
setCursorState(MenuCursorState.HOLD_ITEM);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
setCursorState(MenuCursorState.TARGET_CURSOR);
|
||||||
this.activeCommand.visit(this.cursorTargetSetupVisitor.reset(baseMouseX, baseMouseY));
|
this.activeCommand.visit(this.cursorTargetSetupVisitor.reset(baseMouseX, baseMouseY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1081,34 +1149,34 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
if (down) {
|
if (down) {
|
||||||
if (left) {
|
if (left) {
|
||||||
this.cursorFrame.setSequence("Scroll Down Left");
|
setCursorState(MenuCursorState.SCROLL_DOWN_LEFT);
|
||||||
}
|
}
|
||||||
else if (right) {
|
else if (right) {
|
||||||
this.cursorFrame.setSequence("Scroll Down Right");
|
setCursorState(MenuCursorState.SCROLL_DOWN_RIGHT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.cursorFrame.setSequence("Scroll Down");
|
setCursorState(MenuCursorState.SCROLL_DOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (up) {
|
else if (up) {
|
||||||
if (left) {
|
if (left) {
|
||||||
this.cursorFrame.setSequence("Scroll Up Left");
|
setCursorState(MenuCursorState.SCROLL_UP_LEFT);
|
||||||
}
|
}
|
||||||
else if (right) {
|
else if (right) {
|
||||||
this.cursorFrame.setSequence("Scroll Up Right");
|
setCursorState(MenuCursorState.SCROLL_UP_RIGHT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.cursorFrame.setSequence("Scroll Up");
|
setCursorState(MenuCursorState.SCROLL_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (left) {
|
else if (left) {
|
||||||
this.cursorFrame.setSequence("Scroll Left");
|
setCursorState(MenuCursorState.SCROLL_LEFT);
|
||||||
}
|
}
|
||||||
else if (right) {
|
else if (right) {
|
||||||
this.cursorFrame.setSequence("Scroll Right");
|
setCursorState(MenuCursorState.SCROLL_RIGHT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.cursorFrame.setSequence("Normal");
|
setCursorState(MenuCursorState.NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.selectedUnit != null) {
|
if (this.selectedUnit != null) {
|
||||||
@ -1142,6 +1210,59 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void positionHealthBar(final SimpleStatusBarFrame simpleStatusBarFrame, final RenderWidget unit,
|
||||||
|
final float alpha) {
|
||||||
|
simpleStatusBarFrame.setVisible(true);
|
||||||
|
clickLocationTemp.x = unit.getX();
|
||||||
|
clickLocationTemp.y = unit.getY();
|
||||||
|
clickLocationTemp.z = unit.getZ();
|
||||||
|
final Bounds unitBounds = unit.getInstance().getBounds();
|
||||||
|
if (unitBounds != null) {
|
||||||
|
final BoundingBox unitBoundsBox = unitBounds.getBoundingBox();
|
||||||
|
if (unitBoundsBox != null) {
|
||||||
|
clickLocationTemp.z += unitBoundsBox.max.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.war3MapViewer.worldScene.camera.worldToScreen(screenCoordsVector, clickLocationTemp);
|
||||||
|
simpleStatusBarFrame.getBarFrame().setTexture("SimpleHpBarConsole", this.rootFrame);
|
||||||
|
simpleStatusBarFrame.getBorderFrame().setTexture("Textures\\Black32.blp", this.rootFrame);
|
||||||
|
simpleStatusBarFrame.getBorderFrame().setColor(0f, 0f, 0f, alpha);
|
||||||
|
final float lifeRatioRemaining = unit.getSimulationWidget().getLife() / unit.getSimulationWidget().getMaxLife();
|
||||||
|
simpleStatusBarFrame.getBarFrame().setColor(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)),
|
||||||
|
Math.min(1.0f, lifeRatioRemaining * 2), 0, alpha);
|
||||||
|
final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector);
|
||||||
|
simpleStatusBarFrame.setWidth(unit.getSelectionScale() * 1.5f);
|
||||||
|
simpleStatusBarFrame.setHeight(16);
|
||||||
|
simpleStatusBarFrame.addSetPoint(
|
||||||
|
new SetPoint(FramePoint.CENTER, this.rootFrame, FramePoint.BOTTOMLEFT, unprojected.x, unprojected.y));
|
||||||
|
simpleStatusBarFrame.setValue(lifeRatioRemaining);
|
||||||
|
simpleStatusBarFrame.positionBounds(this.rootFrame, this.uiViewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleStatusBarFrame getHpBar() {
|
||||||
|
final SimpleStatusBarFrame simpleStatusBarFrame;
|
||||||
|
if (this.hpBarFrameIndex >= this.hpBarFrames.size()) {
|
||||||
|
simpleStatusBarFrame = new SimpleStatusBarFrame("SmashHpBar" + this.hpBarFrameIndex, this.rootFrame, true,
|
||||||
|
true, 3.0f);
|
||||||
|
this.rootFrame.add(simpleStatusBarFrame);
|
||||||
|
this.hpBarFrames.add(simpleStatusBarFrame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
simpleStatusBarFrame = this.hpBarFrames.get(this.hpBarFrameIndex);
|
||||||
|
}
|
||||||
|
this.hpBarFrameIndex++;
|
||||||
|
return simpleStatusBarFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCursorState(final MenuCursorState state) {
|
||||||
|
if (state != this.cursorState) {
|
||||||
|
if (state.getAnimationName() != null) {
|
||||||
|
this.cursorFrame.setSequence(state.getAnimationName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.cursorState = state;
|
||||||
|
}
|
||||||
|
|
||||||
public void render(final SpriteBatch batch, final GlyphLayout glyphLayout) {
|
public void render(final SpriteBatch batch, final GlyphLayout glyphLayout) {
|
||||||
final BitmapFont font = this.rootFrame.getFont();
|
final BitmapFont font = this.rootFrame.getFont();
|
||||||
font.setColor(Color.YELLOW);
|
font.setColor(Color.YELLOW);
|
||||||
@ -1172,6 +1293,26 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
(unprojected.y - (glyphLayout.height / 2)) + textTag.getScreenCoordsZHeight());
|
(unprojected.y - (glyphLayout.height / 2)) + textTag.getScreenCoordsZHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.currentlyDraggingPointer == Input.Buttons.LEFT) {
|
||||||
|
batch.end();
|
||||||
|
this.shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
|
||||||
|
this.shapeRenderer.setColor(Color.GREEN);
|
||||||
|
Gdx.gl.glLineWidth(2);
|
||||||
|
this.shapeRenderer.begin(ShapeType.Line);
|
||||||
|
this.cameraManager.camera.worldToScreen(screenCoordsVector, this.lastMouseDragStart);
|
||||||
|
final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector);
|
||||||
|
final float x = unprojected.x;
|
||||||
|
final float y = unprojected.y;
|
||||||
|
this.cameraManager.camera.worldToScreen(screenCoordsVector, this.lastMouseClickLocation);
|
||||||
|
final Vector2 unprojectedEnd = this.uiViewport.unproject(screenCoordsVector);
|
||||||
|
final float minX = Math.min(x, unprojectedEnd.x);
|
||||||
|
final float minY = Math.min(y, unprojectedEnd.y);
|
||||||
|
this.shapeRenderer.rect(minX, minY, Math.max(x, unprojectedEnd.x) - minX,
|
||||||
|
Math.max(y, unprojectedEnd.y) - minY);
|
||||||
|
this.shapeRenderer.end();
|
||||||
|
Gdx.gl.glLineWidth(1);
|
||||||
|
batch.begin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void portraitTalk() {
|
public void portraitTalk() {
|
||||||
@ -1783,8 +1924,11 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
|
|
||||||
private void reloadSelectedUnitUI(final RenderUnit unit) {
|
private void reloadSelectedUnitUI(final RenderUnit unit) {
|
||||||
final CUnit simulationUnit = unit.getSimulationUnit();
|
final CUnit simulationUnit = unit.getSimulationUnit();
|
||||||
this.rootFrame.setText(this.unitLifeText,
|
final float lifeRatioRemaining = simulationUnit.getLife() / simulationUnit.getMaxLife();
|
||||||
FastNumberFormat.formatWholeNumber(simulationUnit.getLife()) + " / " + simulationUnit.getMaximumLife());
|
this.rootFrame.setText(this.unitLifeText, FastNumberFormat.formatWholeNumber(simulationUnit.getLife()) + " / "
|
||||||
|
+ FastNumberFormat.formatWholeNumber(simulationUnit.getMaxLife()));
|
||||||
|
this.unitLifeText.setColor(new Color(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)),
|
||||||
|
Math.min(1.0f, lifeRatioRemaining * 2), 0, 1.0f));
|
||||||
final int maximumMana = simulationUnit.getMaximumMana();
|
final int maximumMana = simulationUnit.getMaximumMana();
|
||||||
if (maximumMana > 0) {
|
if (maximumMana > 0) {
|
||||||
this.rootFrame.setText(this.unitManaText,
|
this.rootFrame.setText(this.unitManaText,
|
||||||
@ -1940,8 +2084,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.rootFrame.setText(this.simpleNameValue, unitTypeName);
|
this.rootFrame.setText(this.simpleNameValue, unitTypeName);
|
||||||
String classText = null;
|
String classText = null;
|
||||||
for (final CUnitClassification classification : simulationUnit.getClassifications()) {
|
for (final CUnitClassification classification : simulationUnit.getClassifications()) {
|
||||||
if ((classification == CUnitClassification.MECHANICAL)
|
if ((classification == CUnitClassification.MECHANICAL) && simulationUnit.isBuilding()) {
|
||||||
&& simulationUnit.getUnitType().isBuilding()) {
|
|
||||||
// buildings dont display MECHANICAL
|
// buildings dont display MECHANICAL
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2041,7 +2184,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
localArmorIconBackdrop.setTexture(defenseTexture);
|
localArmorIconBackdrop.setTexture(defenseTexture);
|
||||||
|
|
||||||
String defenseDisplayString = Integer.toString(simulationUnit.getCurrentDefenseDisplay());
|
String defenseDisplayString;
|
||||||
|
if (simulationUnit.isInvulnerable()) {
|
||||||
|
defenseDisplayString = this.rootFrame.getTemplates().getDecoratedString("INVULNERABLE");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defenseDisplayString = Integer.toString(simulationUnit.getCurrentDefenseDisplay());
|
||||||
final int temporaryDefenseBonus = simulationUnit.getTemporaryDefenseBonus();
|
final int temporaryDefenseBonus = simulationUnit.getTemporaryDefenseBonus();
|
||||||
if (temporaryDefenseBonus != 0) {
|
if (temporaryDefenseBonus != 0) {
|
||||||
if (temporaryDefenseBonus > 0) {
|
if (temporaryDefenseBonus > 0) {
|
||||||
@ -2051,6 +2199,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
defenseDisplayString += "|cFFFF0000 (+" + temporaryDefenseBonus + ")";
|
defenseDisplayString += "|cFFFF0000 (+" + temporaryDefenseBonus + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.rootFrame.setText(localArmorInfoPanelIconValue, defenseDisplayString);
|
this.rootFrame.setText(localArmorInfoPanelIconValue, defenseDisplayString);
|
||||||
}
|
}
|
||||||
clearAndRepopulateCommandCard();
|
clearAndRepopulateCommandCard();
|
||||||
@ -2165,9 +2314,13 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
selectUnit(null);
|
selectUnit(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final float lifeRatioRemaining = this.selectedUnit.getSimulationUnit().getLife()
|
||||||
|
/ this.selectedUnit.getSimulationUnit().getMaxLife();
|
||||||
this.rootFrame.setText(this.unitLifeText,
|
this.rootFrame.setText(this.unitLifeText,
|
||||||
FastNumberFormat.formatWholeNumber(this.selectedUnit.getSimulationUnit().getLife()) + " / "
|
FastNumberFormat.formatWholeNumber(this.selectedUnit.getSimulationUnit().getLife()) + " / "
|
||||||
+ this.selectedUnit.getSimulationUnit().getMaximumLife());
|
+ FastNumberFormat.formatWholeNumber(this.selectedUnit.getSimulationUnit().getMaxLife()));
|
||||||
|
this.unitLifeText.setColor(new Color(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)),
|
||||||
|
Math.min(1.0f, lifeRatioRemaining * 2), 0, 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2277,6 +2430,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean touchDown(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
public boolean touchDown(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
||||||
|
this.allowDrag = false;
|
||||||
screenCoordsVector.set(screenX, screenY);
|
screenCoordsVector.set(screenX, screenY);
|
||||||
this.uiViewport.unproject(screenCoordsVector);
|
this.uiViewport.unproject(screenCoordsVector);
|
||||||
if (this.meleeUIMinimap.containsMouse(screenCoordsVector.x, screenCoordsVector.y)) {
|
if (this.meleeUIMinimap.containsMouse(screenCoordsVector.x, screenCoordsVector.y)) {
|
||||||
@ -2300,9 +2454,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
clearAndRepopulateCommandCard();
|
clearAndRepopulateCommandCard();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final boolean shiftDown = isShiftDown();
|
||||||
final RenderWidget rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY,
|
final RenderWidget rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY,
|
||||||
this.activeCommandUnitTargetFilter);
|
this.activeCommandUnitTargetFilter);
|
||||||
final boolean shiftDown = isShiftDown();
|
|
||||||
if (rayPickUnit != null) {
|
if (rayPickUnit != null) {
|
||||||
this.unitOrderListener.issueTargetOrder(
|
this.unitOrderListener.issueTargetOrder(
|
||||||
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
||||||
@ -2442,11 +2596,14 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final List<RenderWidget> selectedUnits = this.war3MapViewer.selectUnit(screenX, worldScreenY,
|
if (this.mouseOverUnit != null) {
|
||||||
false);
|
final List<RenderWidget> unitList = Arrays.asList(this.mouseOverUnit);
|
||||||
if (!selectedUnits.isEmpty()) {
|
this.war3MapViewer.doSelectUnit(unitList);
|
||||||
selectWidgets(selectedUnits);
|
selectWidgets(unitList);
|
||||||
}
|
}
|
||||||
|
this.war3MapViewer.getClickLocation(this.lastMouseClickLocation, screenX, (int) worldScreenY);
|
||||||
|
this.lastMouseDragStart.set(this.lastMouseClickLocation);
|
||||||
|
this.allowDrag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2564,6 +2721,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean touchUp(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
public boolean touchUp(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
||||||
|
this.currentlyDraggingPointer = -1;
|
||||||
screenCoordsVector.set(screenX, screenY);
|
screenCoordsVector.set(screenX, screenY);
|
||||||
this.uiViewport.unproject(screenCoordsVector);
|
this.uiViewport.unproject(screenCoordsVector);
|
||||||
final UIFrame clickedUIFrame = this.rootFrame.touchUp(screenCoordsVector.x, screenCoordsVector.y, button);
|
final UIFrame clickedUIFrame = this.rootFrame.touchUp(screenCoordsVector.x, screenCoordsVector.y, button);
|
||||||
@ -2581,6 +2739,34 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
}
|
}
|
||||||
this.mouseDownUIFrame.mouseUp(this.rootFrame, this.uiViewport);
|
this.mouseDownUIFrame.mouseUp(this.rootFrame, this.uiViewport);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (!this.dragSelectPreviewUnits.isEmpty()) {
|
||||||
|
final List<RenderWidget> selectedWidgets = new ArrayList<>();
|
||||||
|
boolean foundGoal = false;
|
||||||
|
for (final RenderUnit unit : this.dragSelectPreviewUnits) {
|
||||||
|
if ((unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex())
|
||||||
|
&& !unit.getSimulationUnit().isBuilding()) {
|
||||||
|
foundGoal = true;
|
||||||
|
selectedWidgets.add(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundGoal) {
|
||||||
|
selectedWidgets.addAll(this.dragSelectPreviewUnits);
|
||||||
|
}
|
||||||
|
Collections.sort(selectedWidgets, new Comparator<RenderWidget>() {
|
||||||
|
@Override
|
||||||
|
public int compare(final RenderWidget widget1, final RenderWidget widget2) {
|
||||||
|
return ((RenderUnit) widget1).getSimulationUnit().getUnitType().getPriority()
|
||||||
|
- ((RenderUnit) widget2).getSimulationUnit().getUnitType().getPriority();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.war3MapViewer.clearUnitMouseOverHighlight();
|
||||||
|
this.war3MapViewer.doSelectUnit(selectedWidgets);
|
||||||
|
selectWidgets(selectedWidgets);
|
||||||
|
this.dragSelectPreviewUnits.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
this.mouseDownUIFrame = null;
|
this.mouseDownUIFrame = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2599,6 +2785,25 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.cameraManager.target.x = worldPoint.x;
|
this.cameraManager.target.x = worldPoint.x;
|
||||||
this.cameraManager.target.y = worldPoint.y;
|
this.cameraManager.target.y = worldPoint.y;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (this.allowDrag) {
|
||||||
|
if (null != this.mouseOverUnit) {
|
||||||
|
this.war3MapViewer.clearUnitMouseOverHighlight();
|
||||||
|
this.dragSelectPreviewUnits.clear();
|
||||||
|
this.mouseOverUnit = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
||||||
|
this.currentlyDraggingPointer = pointer;
|
||||||
|
if (pointer == Input.Buttons.MIDDLE) {
|
||||||
|
this.cameraManager.target.add(this.lastMouseClickLocation.sub(clickLocationTemp).scl(-1));
|
||||||
|
}
|
||||||
|
else if (pointer == Input.Buttons.LEFT) {
|
||||||
|
// update mouseover
|
||||||
|
}
|
||||||
|
this.lastMouseClickLocation.set(clickLocationTemp);
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2625,6 +2830,24 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
|||||||
this.tooltipFrame.setVisible(false);
|
this.tooltipFrame.setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mousedUIFrame == null) {
|
||||||
|
final RenderWidget newMouseOverUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY,
|
||||||
|
new CWidgetFilterFunction() {
|
||||||
|
@Override
|
||||||
|
public boolean call(final CWidget unit) {
|
||||||
|
final RenderWidget renderPeer = MeleeUI.this.war3MapViewer.getRenderPeer(unit);
|
||||||
|
return !unit.isDead() && renderPeer.isSelectable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (newMouseOverUnit != this.mouseOverUnit) {
|
||||||
|
this.war3MapViewer.clearUnitMouseOverHighlight();
|
||||||
|
this.dragSelectPreviewUnits.clear();
|
||||||
|
if (newMouseOverUnit != null) {
|
||||||
|
this.war3MapViewer.showUnitMouseOverHighlight(newMouseOverUnit);
|
||||||
|
}
|
||||||
|
this.mouseOverUnit = newMouseOverUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||||
|
|
||||||
|
public enum MenuCursorState {
|
||||||
|
NORMAL("Normal"),
|
||||||
|
SCROLL_LEFT("Scroll Left"),
|
||||||
|
SCROLL_RIGHT("Scroll Right"),
|
||||||
|
SCROLL_DOWN("Scroll Down"),
|
||||||
|
SCROLL_UP("Scroll Up"),
|
||||||
|
SCROLL_DOWN_LEFT("Scroll Down Left"),
|
||||||
|
SCROLL_DOWN_RIGHT("Scroll Down Right"),
|
||||||
|
SCROLL_UP_LEFT("Scroll Up Left"),
|
||||||
|
SCROLL_UP_RIGHT("Scroll Up Right"),
|
||||||
|
TARGET_CURSOR(null), // handled specially
|
||||||
|
HOLD_ITEM("HoldItem");
|
||||||
|
private String animationName;
|
||||||
|
|
||||||
|
private MenuCursorState(final String animationName) {
|
||||||
|
this.animationName = animationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAnimationName() {
|
||||||
|
return this.animationName;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user