From ba2eb05207e8a7543076c6c48b3fbe2f296f8c00 Mon Sep 17 00:00:00 2001 From: Retera Date: Fri, 20 Aug 2021 19:59:19 -0400 Subject: [PATCH] Ghoul lumber harvest, blighted pathing build requirements, Walk Fast animation, shift select --- .../warsmash/WarsmashGdxMapScreen.java | 5 +- .../viewer5/handlers/mdx/BatchGroup.java | 6 +- .../viewer5/handlers/mdx/FilterMode.java | 2 +- .../handlers/mdx/MdxComplexInstance.java | 32 +++- .../viewer5/handlers/w3x/War3MapViewer.java | 106 +++++++------ .../handlers/w3x/environment/PathingGrid.java | 10 +- .../handlers/w3x/environment/Terrain.java | 1 + .../w3x/environment/TerrainShaders.java | 4 +- .../w3x/rendersim/RenderDestructable.java | 30 +++- .../handlers/w3x/rendersim/RenderDoodad.java | 6 + .../handlers/w3x/rendersim/RenderItem.java | 2 +- .../handlers/w3x/rendersim/RenderUnit.java | 25 ++-- .../w3x/rendersim/RenderUnitTypeData.java | 21 ++- .../handlers/w3x/rendersim/RenderWidget.java | 44 +++++- .../CommandCardPopulatingAbilityVisitor.java | 5 +- .../w3x/simulation/CDestructable.java | 16 ++ .../w3x/simulation/CGameplayConstants.java | 33 +++-- .../handlers/w3x/simulation/CSimulation.java | 7 +- .../handlers/w3x/simulation/CUnit.java | 34 ++--- .../simulation/CUnitAnimationListener.java | 3 + .../handlers/w3x/simulation/CUnitType.java | 8 +- .../simulation/abilities/CAbilityAttack.java | 4 +- .../abilities/hero/CAbilityHero.java | 15 +- .../inventory/CAbilityInventory.java | 10 +- .../mine/CAbilityBlightedGoldMine.java | 118 +++++++++++++++ .../abilities/queue/CAbilityReviveHero.java | 36 +++-- .../impl/CAbilityTypeDefinitionHarvest.java | 4 +- .../CAbilityTypeDefinitionHarvestLumber.java | 38 +++++ .../types/impl/CAbilityTypeHarvestLumber.java | 24 +++ .../CAbilityTypeHarvestLumberLevelData.java | 39 +++++ .../simulation/behaviors/CBehaviorMove.java | 3 +- .../behaviors/harvest/CBehaviorHarvest.java | 8 +- .../w3x/simulation/data/CAbilityData.java | 2 + .../w3x/simulation/data/CUnitData.java | 6 +- .../w3x/simulation/orders/OrderIds.java | 30 ++-- .../util/SimulationRenderController.java | 6 +- .../viewer5/handlers/w3x/ui/MeleeUI.java | 140 ++++++++++-------- .../handlers/w3x/ui/MeleeUIMinimap.java | 18 +-- .../warsmash/desktop/DesktopLauncher.java | 40 +++-- .../UI/FrameDef/SmashUI/InventoryCover.fdf | 17 ++- .../UI/FrameDef/SmashUI/UnitPortrait.fdf | 2 +- 41 files changed, 653 insertions(+), 307 deletions(-) create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java b/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java index 9b62b8e..59c09e2 100644 --- a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java +++ b/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java @@ -127,7 +127,6 @@ public class WarsmashGdxMapScreen implements InputProcessor, Screen { Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); final Scene portraitScene = this.viewer.addSimpleScene(); - portraitScene.alpha = true; this.uiScene = this.viewer.addSimpleScene(); this.uiScene.alpha = true; if (ENABLE_AUDIO) { @@ -335,8 +334,8 @@ public class WarsmashGdxMapScreen implements InputProcessor, Screen { private Rectangle setupWorldFrameViewport(final int width, final int height) { this.tempRect.x = 0; this.tempRect.width = width; - final float topHeight = 0;// 0.02666f * height; - final float bottomHeight = 0;// 0.21333f * height; + final float topHeight = 0.02666f * height; + final float bottomHeight = 0.21333f * height; this.tempRect.y = (int) bottomHeight; this.tempRect.height = height - (int) (topHeight + bottomHeight); return this.tempRect; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java index d8072f4..74aa956 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java @@ -115,7 +115,11 @@ public class BatchGroup extends GenericGroup { shader.setUniform2fv("u_uvRot", uvAnim, 2, 2); shader.setUniform1fv("u_uvScale", uvAnim, 4, 1); - if (instance.vertexColor[3] < 1.0f) { + if (instance.additiveOverrideMeshMode) { + layer.bindBlended(shader); + gl.glBlendFunc(FilterMode.ADDITIVE_ALPHA[0], FilterMode.ADDITIVE_ALPHA[1]); + } + else if (instance.vertexColor[3] < 1.0f) { layer.bindBlended(shader); } else { diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java index aa82c90..d610cff 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java @@ -8,7 +8,7 @@ public class FilterMode { private static final int[] ERROR_DEFAULT = new int[] { 0, 0 }; private static final int[] MODULATE_2X = new int[] { GL20.GL_DST_COLOR, GL20.GL_SRC_COLOR }; private static final int[] MODULATE = new int[] { GL20.GL_ZERO, GL20.GL_SRC_COLOR }; - private static final int[] ADDITIVE_ALPHA = new int[] { GL20.GL_SRC_ALPHA, GL20.GL_ONE }; + public static final int[] ADDITIVE_ALPHA = new int[] { GL20.GL_SRC_ALPHA, GL20.GL_ONE }; private static final int[] BLEND = new int[] { GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA }; public static int[] layerFilterMode(final MdlxLayer.FilterMode filterMode) { diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java index 0b3ce1a..460b981 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java @@ -72,6 +72,7 @@ public class MdxComplexInstance extends ModelInstance { private float animationSpeed = 1.0f; private float blendTime; private float blendTimeRemaining; + public boolean additiveOverrideMeshMode = false; public MdxComplexInstance(final MdxModel model) { super(model); @@ -511,8 +512,10 @@ public class MdxComplexInstance extends ModelInstance { public void renderOpaque(final Matrix4 mvp) { final MdxModel model = (MdxModel) this.model; - for (final GenericGroup group : model.opaqueGroups) { - group.render(this, mvp); + if (!this.additiveOverrideMeshMode) { + for (final GenericGroup group : model.opaqueGroups) { + group.render(this, mvp); + } } final int glGetError = Gdx.gl.glGetError(); @@ -528,6 +531,9 @@ public class MdxComplexInstance extends ModelInstance { } final MdxModel model = (MdxModel) this.model; + for (final GenericGroup group : model.opaqueGroups) { + group.render(this, this.scene.camera.viewProjectionMatrix); + } for (final GenericGroup group : model.translucentGroups) { group.render(this, this.scene.camera.viewProjectionMatrix); @@ -555,6 +561,10 @@ public class MdxComplexInstance extends ModelInstance { final int integerFrameTime = this.frame - lastIntegerFrame; this.counter += integerFrameTime; this.allowParticleSpawn = true; + if (this.additiveOverrideMeshMode) { + this.vertexColor[3] = Math.max(0, + this.vertexColor[3] - (integerFrameTime / (float) (interval[1] - interval[0]))); + } final long animEnd = interval[1] - 1; if (this.floatingFrame >= animEnd) { @@ -667,6 +677,12 @@ public class MdxComplexInstance extends ModelInstance { return this; } + public MdxComplexInstance setVertexAlpha(final float alpha) { + this.vertexColor[3] = alpha; + + return this; + } + /** * Set the sequence of this instance. */ @@ -686,11 +702,13 @@ public class MdxComplexInstance extends ModelInstance { this.allowParticleSpawn = false; } else { - if ((this.blendTime > 0) && (lastSequence != this.sequence) && (lastSequence != -1)) { - this.blendTimeRemaining = this.blendTime; - for (int i = 0, l = this.sortedNodes.length; i < l; i++) { - final SkeletalNode node = this.sortedNodes[i]; - node.beginBlending(); + if ((this.blendTime > 0) && (lastSequence != -1)) { + if ((this.blendTimeRemaining <= 0) && (this.counter > 0)) { + this.blendTimeRemaining = this.blendTime; + for (int i = 0, l = this.sortedNodes.length; i < l; i++) { + final SkeletalNode node = this.sortedNodes[i]; + node.beginBlending(); + } } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java index 178b166..a6220f8 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java @@ -9,7 +9,6 @@ import java.io.UnsupportedEncodingException; import java.nio.channels.SeekableByteChannel; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -150,6 +149,9 @@ public class War3MapViewer extends AbstractMdxModelViewer { private static final War3ID ALLOW_CUSTOM_TEAM_COLOR = War3ID.fromString("utcc"); private static final War3ID TEAM_COLOR = War3ID.fromString("utco"); private static final War3ID MAX_ROLL = War3ID.fromString("umxr"); + private static final War3ID ANIMATION_RUN_SPEED = War3ID.fromString("urun"); + private static final War3ID ANIMATION_WALK_SPEED = War3ID.fromString("uwal"); + private static final War3ID MODEL_SCALE = War3ID.fromString("usca"); private static final War3ID sloc = War3ID.fromString("sloc"); private static final LoadGenericCallback stringDataCallback = new StringDataCallbackImplementation(); private static final float[] rayHeap = new float[6]; @@ -191,7 +193,6 @@ public class War3MapViewer extends AbstractMdxModelViewer { public int renderPathing = 0; public int renderLighting = 1; - public List selModels = new ArrayList<>(); private final Set selectedSplatModelKeys = new HashSet<>(); public List selected = new ArrayList<>(); private final Set mouseHighlightSplatModelKeys = new HashSet<>(); @@ -732,6 +733,8 @@ public class War3MapViewer extends AbstractMdxModelViewer { public void heroRevived(final CUnit source) { final AbilityUI reviveUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_REVIVE_RAWCODE); final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); + renderUnit.instance.additiveOverrideMeshMode = false; + renderUnit.instance.setVertexAlpha(1.0f); final CPlayer player = War3MapViewer.this.simulation.getPlayer(source.getPlayerIndex()); final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal()); spawnFxOnOrigin(renderUnit, heroReviveArt); @@ -758,6 +761,12 @@ public class War3MapViewer extends AbstractMdxModelViewer { } } + @Override + public void heroDeathEvent(final CUnit source) { + final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); + renderUnit.instance.additiveOverrideMeshMode = true; + } + @Override public void spawnEffectOnUnit(final CUnit unit, final String effectPath) { final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(unit); @@ -1380,7 +1389,8 @@ public class War3MapViewer extends AbstractMdxModelViewer { } final RenderUnit renderUnit = new RenderUnit(this, model, row, unitX, unitY, unitZ, customTeamColor, soundset, portraitModel, simulationUnit, typeData, specialArtModel, buildingShadowInstance, - this.selectionCircleScaleFactor); + this.selectionCircleScaleFactor, typeData.getAnimationWalkSpeed(), + typeData.getAnimationRunSpeed(), typeData.getScalingValue()); this.unitToRenderPeer.put(simulationUnit, renderUnit); this.widgets.add(renderUnit); this.units.add(renderUnit); @@ -1488,7 +1498,8 @@ public class War3MapViewer extends AbstractMdxModelViewer { if (unitTypeData == null) { unitTypeData = new RenderUnitTypeData(row.getFieldAsFloat(MAX_PITCH, 0), row.getFieldAsFloat(MAX_ROLL, 0), row.getFieldAsFloat(ELEVATION_SAMPLE_RADIUS, 0), row.getFieldAsBoolean(ALLOW_CUSTOM_TEAM_COLOR, 0), - row.getFieldAsInteger(TEAM_COLOR, 0)); + row.getFieldAsInteger(TEAM_COLOR, 0), row.getFieldAsFloat(ANIMATION_RUN_SPEED, 0), + row.getFieldAsFloat(ANIMATION_WALK_SPEED, 0), row.getFieldAsFloat(MODEL_SCALE, 0)); this.unitIdToTypeData.put(key, unitTypeData); } return unitTypeData; @@ -1616,15 +1627,13 @@ public class War3MapViewer extends AbstractMdxModelViewer { } public void deselect() { - if (!this.selModels.isEmpty()) { - for (final String key : this.selectedSplatModelKeys) { - this.terrain.removeSplatBatchModel(key); - } - this.selModels.clear(); - for (final RenderWidget unit : this.selected) { - unit.unassignSelectionCircle(); - } + for (final String key : this.selectedSplatModelKeys) { + this.terrain.removeSplatBatchModel(key); } + for (final RenderWidget unit : this.selected) { + unit.unassignSelectionCircle(); + } + this.selectedSplatModelKeys.clear(); this.selected.clear(); } @@ -1667,27 +1676,39 @@ public class War3MapViewer extends AbstractMdxModelViewer { } } path = allyKey + path; - if (!splats.containsKey(path)) { - splats.put(path, new Splat()); - } - final float x = unit.getX(); - final float y = unit.getY(); - System.out.println("Selecting a unit at " + x + "," + y); - splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2), - x + (selectionSize / 2), y + (selectionSize / 2), 5 }); - splats.get(path).unitMapping.add(new Consumer() { - @Override - public void accept(final SplatMover t) { - unit.assignSelectionCircle(t); - if (unit.getInstance().hidden()) { - t.hide(); - } + final SplatModel splatModel = this.terrain.getSplatModel("selection:" + 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), 5, this.terrain.centerOffset); + unit.assignSelectionCircle(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(); + System.out.println("Selecting a unit at " + x + "," + y); + splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2), + x + (selectionSize / 2), y + (selectionSize / 2), 5 }); + splats.get(path).unitMapping.add(new Consumer() { + @Override + public void accept(final SplatMover t) { + unit.assignSelectionCircle(t); + if (unit.getInstance().hidden()) { + t.hide(); + } + } + }); + } } this.selected.add(unit); } - this.selModels.clear(); for (final Map.Entry entry : splats.entrySet()) { final String path = entry.getKey(); final String filePath = path.substring(2); @@ -1715,7 +1736,6 @@ public class War3MapViewer extends AbstractMdxModelViewer { model.color[3] = this.selectionCircleColorNeutral.a; break; } - this.selModels.add(model); this.terrain.addSplatBatchModel("selection:" + path, model); this.selectedSplatModelKeys.add("selection:" + path); } @@ -1857,32 +1877,6 @@ public class War3MapViewer extends AbstractMdxModelViewer { this.confirmationInstance.vertexColor[2] = blue; } - public List selectUnit(final float x, final float y, final boolean toggle) { - System.out.println("world: " + x + "," + y); - final RenderWidget entity = rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL_LIVING); - List sel; - if (entity != null) { - if (toggle) { - sel = new ArrayList<>(this.selected); - final int idx = sel.indexOf(entity); - if (idx >= 0) { - sel.remove(idx); - } - else { - sel.add(entity); - } - } - else { - sel = Arrays.asList(entity); - } - this.doSelectUnit(sel); - } - else { - sel = Collections.emptyList(); - } - return sel; - } - public RenderWidget rayPickUnit(final float x, final float y) { return rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java index 7f1b4ba..ac16514 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java @@ -138,32 +138,26 @@ public class PathingGrid { final float offsetY = ((pathingTextureTga.getHeight() % 2) == 1) ? 16f : 0f; final Rectangle pathingMapRectangle = new Rectangle((positionX - (width / 2)) + offsetX, (positionY - (height / 2)) + offsetY, width, height); - short anyPathingTypeWithUnit = 0; if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.AMPHIBIOUS)) { System.out.println("intersects amph unit"); anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; - anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FLOAT)) { System.out.println("intersects float unit"); anyPathingTypesInRegion |= PathingFlags.UNSWIMABLE; - anyPathingTypeWithUnit |= PathingFlags.UNSWIMABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FLY)) { System.out.println("intersects fly unit"); anyPathingTypesInRegion |= PathingFlags.UNFLYABLE; - anyPathingTypeWithUnit |= PathingFlags.UNFLYABLE; } if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, MovementType.FOOT)) { System.out.println("intersects foot unit"); anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; - anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; } - pathingTypesFillingRegion &= anyPathingTypeWithUnit; for (final CBuildingPathingType pathingType : preventPathingTypes) { if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, pathingType)) { return false; @@ -328,7 +322,9 @@ public class PathingGrid { public static int UNWALKABLE = 0x2; public static int UNFLYABLE = 0x4; public static int UNBUILDABLE = 0x8; + public static int BLIGHTED = 0x20; public static int UNSWIMABLE = 0x40; // PROBABLY, didn't confirm this flag value is accurate + public static int BOUDNARY = 0xF0; public static boolean isPathingFlag(final short pathingValue, final int flag) { return (pathingValue & flag) != 0; @@ -337,7 +333,7 @@ public class PathingGrid { public static boolean isPathingFlag(final short pathingValue, final CBuildingPathingType pathingType) { switch (pathingType) { case BLIGHTED: - throw new IllegalArgumentException("Blight pathing check system is Not Yet Implemented"); + return PathingFlags.isPathingFlag(pathingValue, PathingFlags.BLIGHTED); case UNAMPH: return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE) && PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java index 1503580..359cc18 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java @@ -54,6 +54,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.W3xShaders; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; public class Terrain { + public static final float CELL_SIZE = 128f; private static final String[] colorTags = { "R", "G", "B", "A" }; private static final float[] sizeHeap = new float[2]; private static final Vector3 normalHeap1 = new Vector3(); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java index 985cf0a..b43b4ab 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java @@ -153,8 +153,8 @@ public class TerrainShaders { " float hU = texelFetch(height_texture, height_pos + off.zy, 0).r;\r\n" + // " vec3 normal = normalize(vec3(hL - hR, hD - hU, 2.0));\r\n" + // "\r\n" + // -// " UV = vec2(vPosition.x, 1 - vPosition.y);\r\n" + // - " UV = vec2(vPosition.x==0?0.01:0.99, vPosition.y==0?0.99:0.01);\r\n" + // + " UV = vec2(vPosition.x, 1 - vPosition.y);\r\n" + // + // " UV = vec2(vPosition.x==0?0.01:0.99, vPosition.y==0?0.99:0.01);\r\n" + // " texture_indices = texelFetch(terrain_texture_list, pos, 0);\r\n" + // " pathing_map_uv = (vPosition + pos) * 4; \r\n" + // "\r\n" + // diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java index 4f5249b..d646817 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java @@ -29,6 +29,9 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget { private boolean dead; private BuildingShadow destructableShadow; private final boolean selectable; + private boolean blighted = false; + private final int replaceableTextureId; + private String replaceableTextureFile; public RenderDestructable(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type, @@ -38,18 +41,21 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget { this.life = simulationDestructable.getLife(); this.destructableShadow = destructableShadow; this.simulationDestructable = simulationDestructable; - String replaceableTextureFile = row.getFieldAsString(TEX_FILE, 0); - final int replaceableTextureId = row.getFieldAsInteger(TEX_ID, 0); - if ((replaceableTextureFile != null) && (replaceableTextureFile.length() > 1)) { - final int dotIndex = replaceableTextureFile.lastIndexOf('.'); + this.replaceableTextureFile = row.getFieldAsString(TEX_FILE, 0); + this.replaceableTextureId = row.getFieldAsInteger(TEX_ID, 0); + if ((this.replaceableTextureFile != null) && (this.replaceableTextureFile.length() > 1)) { + final int dotIndex = this.replaceableTextureFile.lastIndexOf('.'); if (dotIndex != -1) { - replaceableTextureFile = replaceableTextureFile.substring(0, dotIndex); + this.replaceableTextureFile = this.replaceableTextureFile.substring(0, dotIndex); } - replaceableTextureFile += ".blp"; - this.instance.setReplaceableTexture(replaceableTextureId, replaceableTextureFile); + if (simulationDestructable.isBlighted()) { + this.blighted = true; + this.replaceableTextureFile += "Blight"; + } + this.instance.setReplaceableTexture(this.replaceableTextureId, this.replaceableTextureFile + ".blp"); } this.selectionScale *= row.getFieldAsFloat(SEL_CIRCLE_SIZE, 0); - this.unitAnimationListenerImpl = new UnitAnimationListenerImpl((MdxComplexInstance) this.instance); + this.unitAnimationListenerImpl = new UnitAnimationListenerImpl((MdxComplexInstance) this.instance, 0, 0); simulationDestructable.setUnitAnimationListener(this.unitAnimationListenerImpl); this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true); this.selectable = row.readSLKTagBoolean("selectable"); @@ -111,6 +117,14 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget { } } this.dead = dead; + final boolean blighted = this.simulationDestructable.isBlighted(); + if (blighted && !this.blighted) { + this.blighted = blighted; + if (this.replaceableTextureFile != null) { + this.replaceableTextureFile += "Blight"; + } + this.instance.setReplaceableTexture(this.replaceableTextureId, this.replaceableTextureFile + ".blp"); + } this.unitAnimationListenerImpl.update(); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java index 0b56b77..2ce6b6e 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java @@ -13,6 +13,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; public class RenderDoodad { private static final int SAMPLE_RADIUS = 4; + private static final float[] VERTEX_COLOR_BLACK = { 0f, 0f, 0f, 1f }; public final ModelInstance instance; private final MutableGameObject row; private final float maxPitch; @@ -49,6 +50,11 @@ public class RenderDoodad { float pitch, roll; this.x = doodad.getLocation()[0]; this.y = doodad.getLocation()[1]; + { + if (!map.terrain.inPlayableArea(this.x, this.y)) { + ((MdxComplexInstance) instance).setVertexColor(VERTEX_COLOR_BLACK); + } + } final float pitchSampleForwardX = this.x + (SAMPLE_RADIUS * (float) Math.cos(facingRadians)); final float pitchSampleForwardY = this.y + (SAMPLE_RADIUS * (float) Math.sin(facingRadians)); final float pitchSampleBackwardX = this.x - (SAMPLE_RADIUS * (float) Math.cos(facingRadians)); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java index c16d9da..626f3db 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java @@ -137,7 +137,7 @@ public class RenderItem implements RenderWidget { this.location[2] = this.simulationItem.getFlyHeight() + groundHeight; this.instance.moveTo(this.location); - if (this.shadow != null && !hidden) { + if ((this.shadow != null) && !hidden) { this.shadow.move(dx, dy, map.terrain.centerOffset); this.shadow.setHeightAbsolute(currentWalkableUnder != null, groundHeight + map.imageWalkableZOffset); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java index cc1ce59..77d022b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java @@ -33,7 +33,6 @@ public class RenderUnit implements RenderWidget { private static final War3ID RED = War3ID.fromString("uclr"); private static final War3ID GREEN = War3ID.fromString("uclg"); private static final War3ID BLUE = War3ID.fromString("uclb"); - private static final War3ID MODEL_SCALE = War3ID.fromString("usca"); private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh"); private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori"); private static final War3ID ANIM_PROPS = War3ID.fromString("uani"); @@ -76,8 +75,8 @@ public class RenderUnit implements RenderWidget { public RenderUnit(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x, final float y, final float z, final int playerIndex, final UnitSoundset soundset, final MdxModel portraitModel, final CUnit simulationUnit, final RenderUnitTypeData typeData, - final MdxModel specialArtModel, final BuildingShadow buildingShadow, - final float selectionCircleScaleFactor) { + final MdxModel specialArtModel, final BuildingShadow buildingShadow, final float selectionCircleScaleFactor, + final float animationWalkSpeed, final float animationRunSpeed, final float scalingValue) { this.portraitModel = portraitModel; this.simulationUnit = simulationUnit; this.typeData = typeData; @@ -96,7 +95,7 @@ public class RenderUnit implements RenderWidget { this.playerIndex = playerIndex & 0xFFFF; instance.setTeamColor(this.playerIndex); instance.setScene(map.worldScene); - this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance); + this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance, animationWalkSpeed, animationRunSpeed); simulationUnit.setUnitAnimationListener(this.unitAnimationListenerImpl); final String requiredAnimationNames = row.getFieldAsString(ANIM_PROPS, 0); TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) { @@ -117,14 +116,12 @@ public class RenderUnit implements RenderWidget { War3ID red; War3ID green; War3ID blue; - War3ID scale; - scale = MODEL_SCALE; red = RED; green = GREEN; blue = BLUE; instance.setVertexColor(new float[] { (row.getFieldAsInteger(red, 0)) / 255f, (row.getFieldAsInteger(green, 0)) / 255f, (row.getFieldAsInteger(blue, 0)) / 255f }); - instance.uniformScale(row.getFieldAsFloat(scale, 0)); + instance.uniformScale(scalingValue); this.selectionScale = row.getFieldAsFloat(War3MapViewer.UNIT_SELECT_SCALE, 0) * selectionCircleScaleFactor; this.selectionHeight = row.getFieldAsFloat(UNIT_SELECT_HEIGHT, 0); @@ -147,9 +144,10 @@ public class RenderUnit implements RenderWidget { public void populateCommandCard(final CSimulation game, final GameUI gameUI, final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI, - final int subMenuOrderId, boolean multiSelect) { + final int subMenuOrderId, final boolean multiSelect) { final CommandCardPopulatingAbilityVisitor commandCardPopulatingVisitor = CommandCardPopulatingAbilityVisitor.INSTANCE - .reset(game, gameUI, this.simulationUnit, commandButtonListener, abilityDataUI, subMenuOrderId, multiSelect); + .reset(game, gameUI, this.simulationUnit, commandButtonListener, abilityDataUI, subMenuOrderId, + multiSelect); for (final CAbility ability : this.simulationUnit.getAbilities()) { ability.visit(commandCardPopulatingVisitor); } @@ -271,10 +269,11 @@ public class RenderUnit implements RenderWidget { removeSplats(map); } if (boneCorpse && !this.boneCorpse) { - if(simulationUnit.getUnitType().isHero()) { - this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DISSIPATE, SequenceUtils.EMPTY, - this.simulationUnit.getEndingDecayTime(map.simulation), true); - } else { + if (this.simulationUnit.getUnitType().isHero()) { + this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DISSIPATE, + SequenceUtils.EMPTY, this.simulationUnit.getEndingDecayTime(map.simulation), true); + } + else { this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE, this.simulationUnit.getEndingDecayTime(map.simulation), true); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java index e6c1c6b..96ab81a 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java @@ -6,14 +6,21 @@ public class RenderUnitTypeData { private final float sampleRadius; private final boolean allowCustomTeamColor; private final int teamColor; + private final float animationRunSpeed; + private final float scalingValue; + private final float animationWalkSpeed; public RenderUnitTypeData(final float maxPitch, final float maxRoll, final float sampleRadius, - final boolean allowCustomTeamColor, final int teamColor) { + final boolean allowCustomTeamColor, final int teamColor, final float animationRunSpeed, + final float animationWalkSpeed, final float scalingValue) { this.maxPitch = maxPitch; this.maxRoll = maxRoll; this.sampleRadius = sampleRadius; this.allowCustomTeamColor = allowCustomTeamColor; this.teamColor = teamColor; + this.animationRunSpeed = animationRunSpeed; + this.animationWalkSpeed = animationWalkSpeed; + this.scalingValue = scalingValue; } public float getMaxPitch() { @@ -35,4 +42,16 @@ public class RenderUnitTypeData { public int getTeamColor() { return this.teamColor; } + + public float getAnimationRunSpeed() { + return this.animationRunSpeed; + } + + public float getAnimationWalkSpeed() { + return this.animationWalkSpeed; + } + + public float getScalingValue() { + return this.scalingValue; + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java index a9300da..5b7821d 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java @@ -51,15 +51,47 @@ public interface RenderWidget { .noneOf(AnimationTokens.SecondaryTag.class); private final EnumSet recycleSet = EnumSet .noneOf(AnimationTokens.SecondaryTag.class); + private final EnumSet recycleWalkFastSet = EnumSet + .noneOf(AnimationTokens.SecondaryTag.class); private PrimaryTag currentAnimation; private EnumSet currentAnimationSecondaryTags = SequenceUtils.EMPTY; private float currentSpeedRatio; private boolean currentlyAllowingRarityVariations; private final Queue animationQueue = new LinkedList<>(); private int lastWalkFrame = -1; + private final float animationWalkSpeed; + private final float animationRunSpeed; - public UnitAnimationListenerImpl(final MdxComplexInstance instance) { + public UnitAnimationListenerImpl(final MdxComplexInstance instance, final float animationWalkSpeed, + final float animationRunSpeed) { this.instance = instance; + this.animationWalkSpeed = animationWalkSpeed; + this.animationRunSpeed = animationRunSpeed; + } + + @Override + public void playWalkAnimation(final boolean force, final float currentMovementSpeed, + final boolean allowRarityVariations) { + EnumSet secondaryWalkTags; + float animationMoveSpeed; + if (animationWalkSpeed < animationRunSpeed) { + final float midpoint = (animationWalkSpeed + animationRunSpeed) / 2; + if (currentMovementSpeed >= midpoint) { + secondaryWalkTags = SequenceUtils.FAST; + animationMoveSpeed = animationRunSpeed; + } + else { + secondaryWalkTags = SequenceUtils.EMPTY; + animationMoveSpeed = animationWalkSpeed; + } + } + else { + secondaryWalkTags = SequenceUtils.EMPTY; + animationMoveSpeed = animationWalkSpeed; + } + animationMoveSpeed *= instance.localScale.x; + final float speedRatio = (currentMovementSpeed) / animationMoveSpeed; + playAnimation(force, PrimaryTag.WALK, secondaryWalkTags, speedRatio, allowRarityVariations); } @Override @@ -99,12 +131,13 @@ public interface RenderWidget { this.recycleSet.addAll(this.secondaryAnimationTags); this.recycleSet.addAll(secondaryAnimationTags); this.instance.setAnimationSpeed(speedRatio); - if(animationName != PrimaryTag.WALK && currentAnimation == PrimaryTag.WALK) { + if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) { lastWalkFrame = instance.frame; } if (SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, allowRarityVariations) != null) { - if(lastWalkFrame != -1 && animationName == PrimaryTag.WALK && currentAnimation != PrimaryTag.WALK) { + if ((lastWalkFrame != -1) && (animationName == PrimaryTag.WALK) + && (currentAnimation != PrimaryTag.WALK)) { instance.setFrame(instance.clampFrame(lastWalkFrame)); } this.currentAnimation = animationName; @@ -123,13 +156,14 @@ public interface RenderWidget { this.recycleSet.clear(); this.recycleSet.addAll(this.secondaryAnimationTags); this.recycleSet.addAll(secondaryAnimationTags); - if(animationName != PrimaryTag.WALK && currentAnimation == PrimaryTag.WALK) { + if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) { lastWalkFrame = instance.frame; } final Sequence sequence = SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, allowRarityVariations); if (sequence != null) { - if(lastWalkFrame != -1 && animationName == PrimaryTag.WALK && currentAnimation != PrimaryTag.WALK) { + if ((lastWalkFrame != -1) && (animationName == PrimaryTag.WALK) + && (currentAnimation != PrimaryTag.WALK)) { instance.setFrame(instance.clampFrame(lastWalkFrame)); } this.currentAnimation = animationName; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java index 409c08d..8aeab7c 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java @@ -251,7 +251,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor= gameplayConstants.getHeroReviveTime( trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) { this.constructionProgress = 0; + revivingHero.getHeroData().setReviving(false); + revivingHero.getHeroData().setAwaitingRevive(false); revivingHero.corpse = false; revivingHero.boneCorpse = false; revivingHero.deathTurnTick = 0; @@ -517,6 +516,9 @@ public class CUnit extends CWidget { if (this.isBuilding()) { return game.getGameplayConstants().getStructureDecayTime(); } + if (this.unitType.isHero()) { + return game.getGameplayConstants().getDissipateTime(); + } return game.getGameplayConstants().getBoneDecayTime(); } @@ -1399,7 +1401,7 @@ public class CUnit extends CWidget { final CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue()); final CUnitType unitType = hero.getUnitType(); final CAbilityHero heroData = hero.getHeroData(); - heroData.setAwaitingRevive(true); + heroData.setReviving(false); final CGameplayConstants gameplayConstants = game.getGameplayConstants(); player.refund( gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()), @@ -1466,7 +1468,7 @@ public class CUnit extends CWidget { public void queueRevivingHero(final CSimulation game, final CUnit hero) { if (queue(game, new War3ID(hero.getHandleId()), QueueItemType.HERO_REVIVE)) { - hero.getHeroData().setAwaitingRevive(false); + hero.getHeroData().setReviving(true); final CPlayer player = game.getPlayer(this.playerIndex); final int heroReviveGoldCost = game.getGameplayConstants() .getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); @@ -1742,8 +1744,4 @@ public class CUnit extends CWidget { return this.updateType; } } - - public float getAnimationRunSpeedRatio() { - return this.unitType.getAnimationRunSpeed() / this.speed; - } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java index 2a0029b..65f616c 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java @@ -9,10 +9,13 @@ public interface CUnitAnimationListener { void playAnimation(boolean force, final PrimaryTag animationName, final EnumSet secondaryAnimationTags, float speedRatio, boolean allowRarityVariations); + void playWalkAnimation(boolean force, float currentMovementSpeed, boolean allowRarityVariations); + void queueAnimation(final PrimaryTag animationName, final EnumSet secondaryAnimationTags, boolean allowRarityVariations); void addSecondaryTag(SecondaryTag secondaryTag); void removeSecondaryTag(SecondaryTag secondaryTag); + } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java index 2c620f8..cea6b5f 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java @@ -76,7 +76,6 @@ public class CUnitType { private final boolean canFlee; private final int priority; private final boolean revivesHeroes; - private final float animationRunSpeed; public CUnitType(final String name, final String legacyName, final War3ID typeId, final int maxLife, final int manaInitial, final int manaMaximum, final int speed, final int defense, final String abilityList, @@ -94,7 +93,7 @@ public class CUnitType { final float strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence, final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute, final List heroAbilityList, final List heroProperNames, final int properNamesCount, - final boolean canFlee, final int priority, final boolean revivesHeroes, final float animationRunSpeed) { + final boolean canFlee, final int priority, final boolean revivesHeroes) { this.name = name; this.legacyName = legacyName; this.typeId = typeId; @@ -149,7 +148,6 @@ public class CUnitType { this.canFlee = canFlee; this.priority = priority; this.revivesHeroes = revivesHeroes; - this.animationRunSpeed = animationRunSpeed; } public String getName() { @@ -367,8 +365,4 @@ public class CUnitType { public boolean isRevivesHeroes() { return this.revivesHeroes; } - - public float getAnimationRunSpeed() { - return this.animationRunSpeed; - } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java index 3bb9c3c..d0e59a2 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java @@ -112,7 +112,9 @@ public class CAbilityAttack extends AbstractCAbility { @Override public void onAdd(final CSimulation game, final CUnit unit) { unit.setAttackBehavior(new CBehaviorAttack(unit)); - unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit)); + if (!unit.isMovementDisabled()) { + unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit)); + } } @Override diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java index b3bd895..a8afef8 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java @@ -29,6 +29,7 @@ public class CAbilityHero extends AbstractCAbility { private HeroStatValue intelligence; private String properName; private boolean awaitingRevive; + private boolean reviving; public CAbilityHero(final int handleId, final List skillsAvailable) { super(handleId); @@ -169,12 +170,20 @@ public class CAbilityHero extends AbstractCAbility { return this.properName; } - public void setAwaitingRevive(boolean awaitingRevive) { + public void setAwaitingRevive(final boolean awaitingRevive) { this.awaitingRevive = awaitingRevive; } public boolean isAwaitingRevive() { - return awaitingRevive; + return this.awaitingRevive; + } + + public void setReviving(final boolean reviving) { + this.reviving = reviving; + } + + public boolean isReviving() { + return this.reviving; } public void addXp(final CSimulation simulation, final CUnit unit, final int xp) { @@ -241,7 +250,7 @@ public class CAbilityHero extends AbstractCAbility { unit.setAgilityDefenseBonus(agilityDefenseBonus); } - public static final class HeroStatValue { + public static final class HeroStatValue { private final float perLevelFactor; private int base; private int bonus; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java index 593bea7..803dc6e 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java @@ -66,7 +66,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility { @Override public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, final AbilityTarget target) { - if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag08)) { + if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag05)) { for (int i = 0; i < this.itemsHeld.length; i++) { if (this.itemsHeld[i] == target) { final CItem temp = this.itemsHeld[i]; @@ -80,7 +80,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility { } } } - else if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse08)) { + else if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { final CAbility cAbility = this.itemsHeldAbilities[orderId - OrderIds.itemuse00].get(0); int forwardedOrderId = orderId; if (cAbility instanceof GenericSingleIconActiveAbility) { @@ -158,7 +158,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility { } } else { - if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag08)) { + if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag05)) { if (target instanceof CItem) { final int slot = getSlot((CItem) target); if (slot != -1) { @@ -197,7 +197,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility { @Override public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, final AbilityTargetCheckReceiver receiver) { - if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse08)) { + if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { receiver.targetOk(null); } else { @@ -208,7 +208,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility { @Override protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, final AbilityActivationReceiver receiver) { - if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse08)) { + if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { final int slot = orderId - OrderIds.itemuse00; if (this.itemsHeldAbilities[slot].size() < 1) { receiver.notAnActiveAbility(); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java new file mode 100644 index 0000000..b029b99 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java @@ -0,0 +1,118 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine; + +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 CAbilityBlightedGoldMine extends AbstractGenericNoIconAbility { + private int gold; + private final int goldPerInterval; + private final float intervalDuration; + private final int maxNumberOfMiners; + private final float radiusOfMiningRing; + + public CAbilityBlightedGoldMine(final int handleId, final War3ID alias, final int goldPerInterval, + final float intervalDuration, final int maxNumberOfMiners, final float radiusOfMiningRing) { + super(handleId, alias); + this.goldPerInterval = goldPerInterval; + this.intervalDuration = intervalDuration; + this.maxNumberOfMiners = maxNumberOfMiners; + this.radiusOfMiningRing = radiusOfMiningRing; + } + + @Override + public void onAdd(final CSimulation game, final CUnit unit) { + + } + + @Override + public void onRemove(final CSimulation game, final CUnit unit) { + + } + + @Override + public void onTick(final CSimulation game, final CUnit unit) { +// final boolean empty = this.activeMiners.isEmpty(); +// if (empty != this.wasEmpty) { +// if (empty) { +// unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.WORK); +// } +// else { +// unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.WORK); +// } +// this.wasEmpty = empty; +// } +// for (int i = this.activeMiners.size() - 1; i >= 0; i--) { +// final CBehaviorHarvest activeMiner = this.activeMiners.get(i); +// if (game.getGameTurnTick() >= activeMiner.getPopoutFromMineTurnTick()) { +// +// final int goldMined = Math.min(this.gold, activeMiner.getGoldCapacity()); +// this.gold -= goldMined; +// if (this.gold <= 0) { +// unit.setLife(game, 0); +// } +// activeMiner.popoutFromMine(goldMined); +// this.activeMiners.remove(i); +// } +// } + } + + @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 receiver) { + receiver.orderIdNotAccepted(); + } + + @Override + public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, + final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { + receiver.orderIdNotAccepted(); + } + + @Override + public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, + final AbilityTargetCheckReceiver 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) { + } + + public int getGold() { + return this.gold; + } + + public void setGold(final int gold) { + this.gold = gold; + } + +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java index 73aa8b3..5767087 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java @@ -1,7 +1,8 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.*; +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.AbstractCAbility; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; @@ -14,33 +15,30 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivat import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - public final class CAbilityReviveHero extends AbstractCAbility { public CAbilityReviveHero(final int handleId) { super(handleId); } - @Override protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, final AbilityActivationReceiver receiver) { - CUnit deadHero = game.getUnit(orderId); - if (deadHero != null - && deadHero.getPlayerIndex()==unit.getPlayerIndex()) { - CAbilityHero heroData = deadHero.getHeroData(); - if( heroData != null && heroData.isAwaitingRevive()) { + final CUnit deadHero = game.getUnit(orderId); + if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) { + final CAbilityHero heroData = deadHero.getHeroData(); + if ((heroData != null) && heroData.isAwaitingRevive() && !heroData.isReviving()) { final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - int heroReviveGoldCost = game.getGameplayConstants().getHeroReviveGoldCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); - int heroReviveLumberCost = game.getGameplayConstants().getHeroReviveLumberCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); + final int heroReviveGoldCost = game.getGameplayConstants() + .getHeroReviveGoldCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); + final int heroReviveLumberCost = game.getGameplayConstants() + .getHeroReviveLumberCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); if (player.getGold() >= heroReviveGoldCost) { if (player.getLumber() >= heroReviveLumberCost) { if ((deadHero.getUnitType().getFoodUsed() == 0) - || ((player.getFoodUsed() + deadHero.getUnitType().getFoodUsed()) <= player.getFoodCap())) { + || ((player.getFoodUsed() + deadHero.getUnitType().getFoodUsed()) <= player + .getFoodCap())) { receiver.useOk(); } else { @@ -77,9 +75,8 @@ public final class CAbilityReviveHero extends AbstractCAbility { @Override public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, final AbilityTargetCheckReceiver receiver) { - CUnit deadHero = game.getUnit(orderId); - if (deadHero != null - && deadHero.getPlayerIndex()==unit.getPlayerIndex()) { + final CUnit deadHero = game.getUnit(orderId); + if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) { receiver.targetOk(null); } else if (orderId == OrderIds.cancel) { @@ -91,7 +88,8 @@ public final class CAbilityReviveHero extends AbstractCAbility { } @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; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java index 4998ab9..2efca49 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java @@ -14,8 +14,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; public class CAbilityTypeDefinitionHarvest extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { protected static final War3ID DAMAGE_TO_TREE = War3ID.fromString("Har1"); - protected static final War3ID GOLD_CAPACITY = War3ID.fromString("Har2"); - protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har3"); + protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har2"); + protected static final War3ID GOLD_CAPACITY = War3ID.fromString("Har3"); @Override protected CAbilityTypeHarvestLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) { diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java new file mode 100644 index 0000000..b89f69b --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java @@ -0,0 +1,38 @@ +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.definitions.CAbilityTypeDefinition; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvestLumber; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvestLumberLevelData; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; + +public class CAbilityTypeDefinitionHarvestLumber + extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { + protected static final War3ID DAMAGE_TO_TREE = War3ID.fromString("Har1"); + protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har2"); + + @Override + protected CAbilityTypeHarvestLumberLevelData createLevelData(final MutableGameObject abilityEditorData, + final int level) { + final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); + final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); + final int damageToTree = abilityEditorData.getFieldAsInteger(DAMAGE_TO_TREE, level); + final int lumberCapacity = abilityEditorData.getFieldAsInteger(LUMBER_CAPACITY, level); + final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level); + final float duration = abilityEditorData.getFieldAsFloat(DURATION, level); + return new CAbilityTypeHarvestLumberLevelData(targetsAllowedAtLevel, damageToTree, lumberCapacity, castRange, + duration); + } + + @Override + protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, + final List levelData) { + return new CAbilityTypeHarvestLumber(alias, abilityEditorData.getCode(), levelData); + } + +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java new file mode 100644 index 0000000..b433318 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java @@ -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.harvest.CAbilityHarvest; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; + +public class CAbilityTypeHarvestLumber extends CAbilityType { + + public CAbilityTypeHarvestLumber(final War3ID alias, final War3ID code, + final List levelData) { + super(alias, code, levelData); + } + + @Override + public CAbility createAbility(final int handleId) { + final CAbilityTypeHarvestLumberLevelData levelData = getLevelData(0); + return new CAbilityHarvest(handleId, getAlias(), levelData.getDamageToTree(), 0, levelData.getLumberCapacity(), + levelData.getCastRange(), levelData.getDuration()); + } + +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java new file mode 100644 index 0000000..acdad7b --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java @@ -0,0 +1,39 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; + +import java.util.EnumSet; + +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; + +public class CAbilityTypeHarvestLumberLevelData extends CAbilityTypeLevelData { + private final int damageToTree; + private final int lumberCapacity; + private final float castRange; + private final float duration; + + public CAbilityTypeHarvestLumberLevelData(final EnumSet targetsAllowed, final int damageToTree, + final int lumberCapacity, final float castRange, final float duration) { + super(targetsAllowed); + this.damageToTree = damageToTree; + this.lumberCapacity = lumberCapacity; + this.castRange = castRange; + this.duration = duration; + } + + public int getDamageToTree() { + return this.damageToTree; + } + + public int getLumberCapacity() { + return this.lumberCapacity; + } + + public float getCastRange() { + return this.castRange; + } + + public float getDuration() { + return this.duration; + } + +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java index 6bf668a..f49b472 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java @@ -325,8 +325,7 @@ public class CBehaviorMove implements CBehavior { return this; } } - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.WALK, SequenceUtils.FAST, - this.unit.getAnimationRunSpeedRatio(), true); + this.unit.getUnitAnimationListener().playWalkAnimation(false, this.unit.getSpeed(), true); this.wasWithinPropWindow = true; } while (continueDistance > 0); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java index 9ae7eb5..396d48b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java @@ -8,6 +8,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; 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.CUnitClassification; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest; @@ -47,7 +48,7 @@ public class CBehaviorHarvest extends CAbstractRangedBehavior @Override public boolean isWithinRange(final CSimulation simulation) { - return this.unit.canReach(this.target, abilityHarvest.getTreeAttack().getRange()); + return this.unit.canReach(this.target, this.abilityHarvest.getTreeAttack().getRange()); } @Override @@ -140,6 +141,11 @@ public class CBehaviorHarvest extends CAbstractRangedBehavior Math.min(this.abilityHarvest.getCarriedResourceAmount() + this.abilityHarvest.getDamageToTree(), this.abilityHarvest.getLumberCapacity())); this.unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.LUMBER); + if (target instanceof CDestructable) { + if (this.unit.getUnitType().getClassifications().contains(CUnitClassification.UNDEAD)) { + ((CDestructable) target).setBlighted(true); + } + } } @Override diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java index c6b2f61..4533bdf 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java @@ -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.CAbilityTypeDefinitionCoupleInstant; 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.CAbilityTypeDefinitionHarvestLumber; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHumanRepair; 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; @@ -39,6 +40,7 @@ public class CAbilityData { this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest()); + this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahrl"), new CAbilityTypeDefinitionHarvestLumber()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("ANcl"), new CAbilityTypeDefinitionChannelTest()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Arep"), new CAbilityTypeDefinitionHumanRepair()); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java index cbb9add..abfb4e4 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java @@ -172,8 +172,6 @@ public class CUnitData { private static final War3ID CAN_FLEE = War3ID.fromString("ufle"); private static final War3ID PRIORITY = War3ID.fromString("upri"); - private static final War3ID ANIMATION_RUN_SPEED = War3ID.fromString("urun"); - private final CGameplayConstants gameplayConstants; private final MutableObjectData unitData; private final Map unitIdToUnitType = new HashMap<>(); @@ -285,8 +283,6 @@ public class CUnitData { final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0); final int priority = unitType.getFieldAsInteger(PRIORITY, 0); - final float animationRunSpeed = unitType.getFieldAsFloat(ANIMATION_RUN_SPEED, 0); - final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0); final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0); final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0); @@ -549,7 +545,7 @@ public class CUnitData { goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus, intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, - canFlee, priority, revivesHeroes, animationRunSpeed); + canFlee, priority, revivesHeroes); this.unitIdToUnitType.put(typeId, unitTypeInstance); this.jassLegacyNameToUnitId.put(legacyName, typeId); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java index f64be80..ee9022d 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java @@ -25,74 +25,68 @@ public class OrderIds { * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag00 = 952002; + public static final int itemdrag00 = 852002; /** * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag01 = 952003; + public static final int itemdrag01 = 852003; /** * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag02 = 952004; + public static final int itemdrag02 = 852004; /** * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag03 = 952005; + public static final int itemdrag03 = 852005; /** * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag04 = 952006; + public static final int itemdrag04 = 852006; /** * An item targeted order that move the target item to a certain inventory slot * of the ordered hero. */ - public static final int itemdrag05 = 952007; - public static final int itemdrag06 = 952008; - public static final int itemdrag07 = 952009; - public static final int itemdrag08 = 952010; + public static final int itemdrag05 = 852007; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse00 = 952011; // War3 852008 !! Smash 852011 + public static final int itemuse00 = 852008; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse01 = 952012;// War3 852009 + public static final int itemuse01 = 852009; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse02 = 952013;// War3 852010 + public static final int itemuse02 = 852010; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse03 = 952014;// War3 852011 + public static final int itemuse03 = 852011; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse04 = 952015;// War3 852012 + public static final int itemuse04 = 852012; /** * An order that will make the ordered hero use the item in a certain inventory * slot. If it's an order with no target or object or point targeted depends on * the type of item. */ - public static final int itemuse05 = 952016;// War3 852013 - public static final int itemuse06 = 952017;// War3 852013 - public static final int itemuse07 = 952018;// War3 852013 - public static final int itemuse08 = 952019;// War3 852013 + public static final int itemuse05 = 852013; /** * Order for AIaa ability, which blizzard made for tome of attack, but never * used it. But it can actually change caster's base attack! diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java index 74a668a..49fdf0c 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java @@ -52,7 +52,7 @@ public interface SimulationRenderController { void spawnEffectOnUnit(CUnit unit, String effectPath); - void spawnSpellEffectOnUnit(CUnit unit, War3ID alias); + void spawnSpellEffectOnUnit(CUnit unit, War3ID alias); void spawnUIUnitGetItemSound(CUnit cUnit, CItem item); @@ -62,6 +62,8 @@ public interface SimulationRenderController { void unitPreferredSelectionReplacement(CUnit unit, CUnit newUnit); - void heroRevived(CUnit trainedUnit); + void heroRevived(CUnit trainedUnit); + + void heroDeathEvent(CUnit cUnit); } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java index 213f772..5a3fb5e 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java @@ -163,11 +163,11 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma private static final long WORLD_FRAME_MESSAGE_FADE_DURATION = WORLD_FRAME_MESSAGE_EXPIRE_MILLIS - WORLD_FRAME_MESSAGE_FADEOUT_MILLIS; private static final String BUILDING_PATHING_PREVIEW_KEY = "buildingPathingPreview"; - public static final float DEFAULT_COMMAND_CARD_ICON_WIDTH = 0.03254f; + public static final float DEFAULT_COMMAND_CARD_ICON_WIDTH = 0.039f; public static final float DEFAULT_INVENTORY_ICON_WIDTH = 0.03125f; - private static final int COMMAND_CARD_WIDTH = 6; - private static final int COMMAND_CARD_HEIGHT = 2; - private static final int INVENTORY_WIDTH = 3; + private static final int COMMAND_CARD_WIDTH = 4; + private static final int COMMAND_CARD_HEIGHT = 3; + private static final int INVENTORY_WIDTH = 2; private static final int INVENTORY_HEIGHT = 3; private static final Vector2 screenCoordsVector = new Vector2(); @@ -357,16 +357,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma } private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) { - screenCoordsVector.x = this.uiViewport.getScreenX(); - screenCoordsVector.y = 0; - this.uiViewport.unproject(screenCoordsVector); - final float mapScale = 0.7f; - final Rectangle minimapDisplayArea = new Rectangle( - screenCoordsVector.x + (18.75f * this.widthRatioCorrection * mapScale), - 13.75f * this.heightRatioCorrection * mapScale, 278.75f * this.widthRatioCorrection * mapScale, - 276.25f * this.heightRatioCorrection * mapScale); - final Rectangle minimapBorderArea = new Rectangle(screenCoordsVector.x, 0, - 512f * this.widthRatioCorrection * mapScale, 512f * this.heightRatioCorrection * mapScale); + final Rectangle minimapDisplayArea = new Rectangle(18.75f * this.widthRatioCorrection, + 13.75f * this.heightRatioCorrection, 278.75f * this.widthRatioCorrection, + 276.25f * this.heightRatioCorrection); Texture minimapTexture = null; if (war3MapViewer.dataSource.has("war3mapMap.tga")) { try { @@ -381,16 +374,13 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma else if (war3MapViewer.dataSource.has("war3mapMap.blp")) { minimapTexture = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, "war3mapMap.blp"); } - final Texture mapBorder = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, - "ui\\console\\nightelf\\nightelfuitilemapborder.blp"); final Texture[] teamColors = new Texture[WarsmashConstants.MAX_PLAYERS]; for (int i = 0; i < teamColors.length; i++) { teamColors[i] = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, "ReplaceableTextures\\" + ReplaceableIds.getPathString(1) + ReplaceableIds.getIdString(i) + ".blp"); } final Rectangle playableMapArea = war3MapViewer.terrain.getPlayableMapArea(); - return new MeleeUIMinimap(minimapDisplayArea, playableMapArea, minimapTexture, teamColors, mapBorder, - minimapBorderArea); + return new MeleeUIMinimap(minimapDisplayArea, playableMapArea, minimapTexture, teamColors); } /** @@ -615,10 +605,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.unitManaText = (StringFrame) this.rootFrame.getFrameByName("UnitPortraitManaPointText", 0); final float infoPanelUnitDetailWidth = GameUI.convertY(this.uiViewport, 0.180f); - final float infoPanelUnitDetailHeight = GameUI.convertY(this.uiViewport, 0.072f); + final float infoPanelUnitDetailHeight = GameUI.convertY(this.uiViewport, 0.112f); this.smashSimpleInfoPanel = this.rootFrame.createSimpleFrame("SmashSimpleInfoPanel", this.rootFrame, 0); - this.smashSimpleInfoPanel.addAnchor(new AnchorDefinition(FramePoint.BOTTOM, - GameUI.convertX(this.uiViewport, -0.1f), GameUI.convertY(this.uiViewport, 0.0f))); + this.smashSimpleInfoPanel + .addAnchor(new AnchorDefinition(FramePoint.BOTTOM, 0, GameUI.convertY(this.uiViewport, 0.0f))); this.smashSimpleInfoPanel.setWidth(infoPanelUnitDetailWidth); this.smashSimpleInfoPanel.setHeight(infoPanelUnitDetailHeight); @@ -676,9 +666,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma queueIconFrameBackdrop0 .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[0], FramePoint.CENTER, 0, 0)); this.queueIconFrames[0].set(queueIconFrameBackdrop0); - this.queueIconFrames[0].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, - FramePoint.BOTTOMLEFT, (infoPanelUnitDetailWidth * (15 + 19f)) / 256, - ((infoPanelUnitDetailWidth * (66 + 19f)) / 256) - GameUI.convertY(this.uiViewport, 0.01f))); + this.queueIconFrames[0] + .addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, FramePoint.BOTTOMLEFT, + (infoPanelUnitDetailWidth * (15 + 19f)) / 256, (infoPanelUnitDetailWidth * (66 + 19f)) / 256)); final float frontQueueIconWidth = (infoPanelUnitDetailWidth * 38) / 256; this.queueIconFrames[0].setWidth(frontQueueIconWidth); this.queueIconFrames[0].setHeight(frontQueueIconWidth); @@ -695,7 +685,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[i], FramePoint.CENTER, 0, 0)); this.queueIconFrames[i].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, FramePoint.BOTTOMLEFT, (infoPanelUnitDetailWidth * (13 + 14.5f + (40 * (i - 1)))) / 256, - ((infoPanelUnitDetailWidth * (24 + 14.5f)) / 256) - GameUI.convertY(this.uiViewport, 0.01f))); + (infoPanelUnitDetailWidth * (24 + 14.5f)) / 256)); final float queueIconWidth = (infoPanelUnitDetailWidth * 29) / 256; this.queueIconFrames[i].setWidth(queueIconWidth); this.queueIconFrames[i].setHeight(queueIconWidth); @@ -742,9 +732,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.smashAttack1IconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconDamage", this.simpleInfoPanelUnitDetail, 0); this.smashAttack1IconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, 0, GameUI.convertY(this.uiViewport, -0.022f))); + FramePoint.TOPLEFT, 0, GameUI.convertY(this.uiViewport, -0.032f))); this.smashAttack1IconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashAttack1IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.020125f)); + this.smashAttack1IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); this.attack1Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack1IconWrapper, 0); this.attack1IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); @@ -755,9 +745,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.simpleInfoPanelUnitDetail, 0); this.smashAttack2IconWrapper .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.02125f))); + GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.03125f))); this.smashAttack2IconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashAttack2IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.020125f)); + this.smashAttack2IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); this.attack2Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack2IconWrapper, 1); this.attack2IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 1); @@ -767,9 +757,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.smashArmorIconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconArmor", this.simpleInfoPanelUnitDetail, 0); this.smashArmorIconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0425f))); + FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0625f))); this.smashArmorIconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashArmorIconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.020125f)); + this.smashArmorIconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); this.armorIcon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconArmor", this.smashArmorIconWrapper, 0); this.armorIconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); this.armorInfoPanelIconValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconValue", 0); @@ -778,9 +768,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.smashHeroInfoPanelWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconHero", this.simpleInfoPanelUnitDetail, 0); this.smashHeroInfoPanelWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.02f))); + FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.029f))); this.smashHeroInfoPanelWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashHeroInfoPanelWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.0325f)); + this.smashHeroInfoPanelWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.0625f)); this.heroInfoPanel = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconHero", this.smashHeroInfoPanelWrapper, 0); this.primaryAttributeIcon = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroIcon", 0); @@ -790,11 +780,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.inventoryBarFrame = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInventoryBar", this.rootFrame, 0); - this.inventoryBarFrame.setWidth(GameUI.convertX(this.uiViewport, 0.115f)); - this.inventoryBarFrame.setHeight(GameUI.convertY(this.uiViewport, 0.079f)); - this.inventoryBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this.consoleUI, FramePoint.BOTTOMRIGHT, - GameUI.convertX(this.uiViewport, 0.15f - 0.256f), - GameUI.convertY(this.uiViewport, -0.006f + (DEFAULT_INVENTORY_ICON_WIDTH * 1.25f)))); + this.inventoryBarFrame.setWidth(GameUI.convertX(this.uiViewport, 0.079f)); + this.inventoryBarFrame.setHeight(GameUI.convertY(this.uiViewport, 0.115f)); + this.inventoryBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, this.consoleUI, FramePoint.BOTTOMLEFT, + GameUI.convertX(this.uiViewport, 0.591f), GameUI.convertY(this.uiViewport, 0.0f))); if (GameUI.DEBUG) { final FilterModeTextureFrame placeholderPreview = new FilterModeTextureFrame(null, this.inventoryBarFrame, @@ -838,9 +827,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.inventoryTitleFrame = this.rootFrame.createStringFrame("SmashInventoryText", this.inventoryBarFrame, new Color(0xFCDE12FF), TextJustify.CENTER, TextJustify.MIDDLE, 0.0109f); this.rootFrame.setText(this.inventoryTitleFrame, this.rootFrame.getTemplates().getDecoratedString("INVENTORY")); - this.inventoryTitleFrame.addSetPoint(new SetPoint(FramePoint.TOP, this.inventoryBarFrame, FramePoint.TOP, - GameUI.convertX(this.uiViewport, 0.000f), GameUI.convertY(this.uiViewport, 0.0165625f))); - this.inventoryTitleFrame.setWidth(GameUI.convertX(this.uiViewport, 0.10f));// 0.071f + this.inventoryTitleFrame + .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.inventoryBarFrame, FramePoint.TOPLEFT, + GameUI.convertX(this.uiViewport, 0.004f), GameUI.convertY(this.uiViewport, 0.0165625f))); + this.inventoryTitleFrame.setWidth(GameUI.convertX(this.uiViewport, 0.071f)); this.inventoryTitleFrame.setHeight(GameUI.convertX(this.uiViewport, 0.01125f)); this.inventoryTitleFrame.setFontShadowColor(new Color(0f, 0f, 0f, 0.9f)); this.inventoryTitleFrame.setFontShadowOffsetX(GameUI.convertX(this.uiViewport, 0.001f)); @@ -879,12 +869,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma "SmashCommandButton_" + (commandButtonIndex) + "_Cooldown", this.rootFrame, "", 0); final SpriteFrame autocastFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", "SmashCommandButton_" + (commandButtonIndex) + "_Autocast", this.rootFrame, "", 0); - final int indexing = i + (j * COMMAND_CARD_WIDTH); - final int displayXIndex = i;// indexing % 6; - final int displayYIndex = j;// indexing / 6; commandCardIcon.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT, - GameUI.convertX(this.uiViewport, 0.4155f + (0.03621f * displayXIndex)), - GameUI.convertY(this.uiViewport, 0.0375f - (0.03621f * displayYIndex)))); + GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)), + GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j)))); commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); iconFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); @@ -1357,7 +1344,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma } - this.meleeUIMinimap.render(batch, this.war3MapViewer.units, this.uiViewport); + this.meleeUIMinimap.render(batch, this.war3MapViewer.units); this.timeIndicator.setFrameByRatio(this.war3MapViewer.simulation.getGameTimeOfDay() / this.war3MapViewer.simulation.getGameplayConstants().getGameDayHours()); for (final TextTag textTag : this.war3MapViewer.textTags) { @@ -2171,7 +2158,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.smashArmorIconWrapper.addSetPoint( new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0425f))); + GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0625f))); this.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport); this.armorIcon.positionBounds(this.rootFrame, this.uiViewport); } @@ -2181,7 +2168,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma this.smashArmorIconWrapper.addSetPoint( new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.021f))); + GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.032f))); this.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport); this.armorIcon.positionBounds(this.rootFrame, this.uiViewport); } @@ -2212,6 +2199,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma final String infopanelLevelClass = this.rootFrame.getTemplates() .getDecoratedString("INFOPANEL_LEVEL_CLASS").replace("%u", "%d"); // :( final int heroLevel = heroData.getHeroLevel(); + this.simpleClassValue.setVisible(true); this.rootFrame.setText(this.simpleClassValue, String.format(infopanelLevelClass, heroLevel, unitTypeName)); this.rootFrame.setText(this.simpleNameValue, heroData.getProperName()); @@ -2221,13 +2209,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma / (float) gameplayConstants.getNeedHeroXP(heroLevel)); } else { + this.simpleClassValue.setVisible(!simulationUnit.isBuilding()); this.rootFrame.setText(this.simpleNameValue, unitTypeName); String classText = null; for (final CUnitClassification classification : simulationUnit.getClassifications()) { - if ((classification == CUnitClassification.MECHANICAL) && simulationUnit.isBuilding()) { - // buildings dont display MECHANICAL - continue; - } if (classification.getDisplayName() != null) { classText = classification.getDisplayName(); } @@ -2376,17 +2361,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma public void resize(final Rectangle viewport) { this.cameraManager.resize(viewport); positionPortrait(); - - screenCoordsVector.x = this.uiViewport.getScreenX(); - screenCoordsVector.y = 0; - this.uiViewport.unproject(screenCoordsVector); - this.meleeUIMinimap.resizeNewX(screenCoordsVector.x); } public void positionPortrait() { - this.projectionTemp1.x = 222 * this.widthRatioCorrection; + this.projectionTemp1.x = 422 * this.widthRatioCorrection; this.projectionTemp1.y = 57 * this.heightRatioCorrection; - this.projectionTemp2.x = (222 + 167) * this.widthRatioCorrection; + this.projectionTemp2.x = (422 + 167) * this.widthRatioCorrection; this.projectionTemp2.y = (57 + 170) * this.heightRatioCorrection; this.uiViewport.project(this.projectionTemp1); this.uiViewport.project(this.projectionTemp2); @@ -2831,12 +2811,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma } } else { - if (this.mouseOverUnit != null) { - final List unitList = Arrays.asList(this.mouseOverUnit); - this.war3MapViewer.doSelectUnit(unitList); - selectWidgets(unitList); - } this.war3MapViewer.getClickLocation(this.lastMouseClickLocation, screenX, (int) worldScreenY); + if (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT)) { + final short pathing = this.war3MapViewer.simulation.getPathingGrid() + .getPathing(this.lastMouseClickLocation.x, this.lastMouseClickLocation.y); + System.out.println(Integer.toBinaryString(pathing)); + } this.lastMouseDragStart.set(this.lastMouseClickLocation); this.allowDrag = true; } @@ -3006,6 +2986,14 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma if (!foundGoal) { selectedWidgets.addAll(this.dragSelectPreviewUnits); } + final boolean shiftDown = isShiftDown(); + if (shiftDown) { + for (final RenderUnit unit : this.selectedUnits) { + if (!selectedWidgets.contains(unit)) { + selectedWidgets.add(unit); + } + } + } Collections.sort(selectedWidgets, new Comparator() { @Override public int compare(final RenderWidget widget1, final RenderWidget widget2) { @@ -3015,10 +3003,32 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma }); this.war3MapViewer.clearUnitMouseOverHighlight(); + this.war3MapViewer.doSelectUnit(selectedWidgets); selectWidgets(selectedWidgets); this.dragSelectPreviewUnits.clear(); } + else { + if ((button == Input.Buttons.LEFT) && (this.mouseOverUnit != null)) { + final List unitList = new ArrayList<>(); + final boolean shiftDown = isShiftDown(); + if (shiftDown) { + if (this.selectedUnits.contains(this.mouseOverUnit)) { + unitList.addAll(this.selectedUnits); + unitList.remove(this.mouseOverUnit); + } + else { + unitList.addAll(this.selectedUnits); + unitList.add(this.mouseOverUnit); + } + } + else { + unitList.add(this.mouseOverUnit); + } + this.war3MapViewer.doSelectUnit(unitList); + selectWidgets(unitList); + } + } } this.mouseDownUIFrame = null; return false; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java index c256e72..c3af169 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java @@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.viewport.Viewport; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; public class MeleeUIMinimap { @@ -13,17 +12,13 @@ public class MeleeUIMinimap { private final Texture minimapTexture; private final Rectangle playableMapArea; private final Texture[] teamColors; - private final Texture mapBorder; - private final Rectangle minimapBorderArea; public MeleeUIMinimap(final Rectangle displayArea, final Rectangle playableMapArea, final Texture minimapTexture, - final Texture[] teamColors, final Texture mapBorder, final Rectangle minimapBorderArea) { + final Texture[] teamColors) { this.playableMapArea = playableMapArea; this.minimapTexture = minimapTexture; this.teamColors = teamColors; this.minimap = displayArea; - this.mapBorder = mapBorder; - this.minimapBorderArea = minimapBorderArea; final float worldWidth = playableMapArea.getWidth(); final float worldHeight = playableMapArea.getHeight(); final float worldSize = Math.max(worldWidth, worldHeight); @@ -35,9 +30,7 @@ public class MeleeUIMinimap { minimapFilledHeight); } - public void render(final SpriteBatch batch, final Iterable units, final Viewport uiViewport) { - batch.draw(this.mapBorder, this.minimapBorderArea.x, this.minimapBorderArea.y, this.minimapBorderArea.width, - this.minimapBorderArea.height); + public void render(final SpriteBatch batch, final Iterable units) { batch.draw(this.minimapTexture, this.minimap.x, this.minimap.y, this.minimap.width, this.minimap.height); for (final RenderUnit unit : units) { @@ -66,11 +59,4 @@ public class MeleeUIMinimap { public boolean containsMouse(final float x, final float y) { return this.minimapFilledArea.contains(x, y); } - - public void resizeNewX(final float x) { - final float dx = x - this.minimapBorderArea.x; - this.minimapBorderArea.x += dx; - this.minimap.x += dx; - this.minimapFilledArea.x += dx; - } } diff --git a/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java b/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java index 1ba74fc..598d1e9 100644 --- a/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java +++ b/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java @@ -4,9 +4,13 @@ import static org.lwjgl.openal.AL10.AL_ORIENTATION; import static org.lwjgl.openal.AL10.AL_POSITION; import static org.lwjgl.openal.AL10.alListener; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.nio.FloatBuffer; -import java.util.Date; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; @@ -37,17 +41,6 @@ import com.etheller.warsmash.viewer5.gl.WireframeExtension; public class DesktopLauncher { public static void main(final String[] arg) { - new File("Logs").mkdir(); - try { - System.setOut(new PrintStream(new FileOutputStream(new File("Logs/"+System.currentTimeMillis()+".out.log")))); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - try { - System.setErr(new PrintStream(new FileOutputStream(new File("Logs/"+System.currentTimeMillis()+".err.log")))); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); config.useGL30 = true; config.gles30ContextMajorVersion = 3; @@ -61,10 +54,14 @@ public class DesktopLauncher { config.height = desktopDisplayMode.height; String fileToLoad = null; config.fullscreen = true; + boolean noLogs = false; for (int argIndex = 0; argIndex < arg.length; argIndex++) { if ("-windowed".equals(arg[argIndex])) { config.fullscreen = false; } + else if ("-nolog".equals(arg[argIndex])) { + noLogs = true; + } else if ((arg.length > (argIndex + 1)) && "-loadfile".equals(arg[argIndex])) { argIndex++; fileToLoad = arg[argIndex]; @@ -78,6 +75,23 @@ public class DesktopLauncher { MultiplayerHack.LP_VAL = Integer.parseInt(arg[argIndex]); } } + if (!noLogs) { + new File("Logs").mkdir(); + try { + System.setOut(new PrintStream( + new FileOutputStream(new File("Logs/" + System.currentTimeMillis() + ".out.log")))); + } + catch (final FileNotFoundException e) { + e.printStackTrace(); + } + try { + System.setErr(new PrintStream( + new FileOutputStream(new File("Logs/" + System.currentTimeMillis() + ".err.log")))); + } + catch (final FileNotFoundException e) { + e.printStackTrace(); + } + } loadExtensions(); final DataTable warsmashIni = loadWarsmashIni(); final WarsmashGdxMultiScreenGame warsmashGdxMultiScreenGame = new WarsmashGdxMultiScreenGame(); diff --git a/resources/UI/FrameDef/SmashUI/InventoryCover.fdf b/resources/UI/FrameDef/SmashUI/InventoryCover.fdf index 8e81920..378e707 100644 --- a/resources/UI/FrameDef/SmashUI/InventoryCover.fdf +++ b/resources/UI/FrameDef/SmashUI/InventoryCover.fdf @@ -2,13 +2,14 @@ Frame "SIMPLEFRAME" "SmashConsoleInventoryCover" { DecorateFileNames, SetAllPoints, - // Texture "SmashConsoleInventoryCoverTexture" { - // File "ConsoleInventoryCoverTexture", - // Width 0.128, - // Height 0.176, - // AlphaMode "ALPHAKEY", - // TexCoord 0, 1, 0.3125, 1, - // Anchor BOTTOMLEFT,0.472,0.0, - // } + // The top of the UI console + Texture "SmashConsoleInventoryCoverTexture" { + File "ConsoleInventoryCoverTexture", + Width 0.128, + Height 0.176, + AlphaMode "ALPHAKEY", + TexCoord 0, 1, 0.3125, 1, + Anchor BOTTOMLEFT,0.472,0.0, + } } diff --git a/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf b/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf index c996c58..eb3aa55 100644 --- a/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf +++ b/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf @@ -14,7 +14,7 @@ String "UnitPortraitTextTemplate" { Frame "SIMPLEFRAME" "UnitPortrait" { DecorateFileNames, - SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0.111,0, + SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0.211,0, Width 0.0835, Height 0.114,