Ghoul lumber harvest, blighted pathing build requirements, Walk Fast animation, shift select

This commit is contained in:
Retera 2021-08-20 19:59:19 -04:00
parent 7db2e0094a
commit ba2eb05207
41 changed files with 653 additions and 307 deletions

View File

@ -127,7 +127,6 @@ public class WarsmashGdxMapScreen implements InputProcessor, Screen {
Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST);
final Scene portraitScene = this.viewer.addSimpleScene(); final Scene portraitScene = this.viewer.addSimpleScene();
portraitScene.alpha = true;
this.uiScene = this.viewer.addSimpleScene(); this.uiScene = this.viewer.addSimpleScene();
this.uiScene.alpha = true; this.uiScene.alpha = true;
if (ENABLE_AUDIO) { if (ENABLE_AUDIO) {
@ -335,8 +334,8 @@ public class WarsmashGdxMapScreen implements InputProcessor, Screen {
private Rectangle setupWorldFrameViewport(final int width, final int height) { private Rectangle setupWorldFrameViewport(final int width, final int height) {
this.tempRect.x = 0; this.tempRect.x = 0;
this.tempRect.width = width; this.tempRect.width = width;
final float topHeight = 0;// 0.02666f * height; final float topHeight = 0.02666f * height;
final float bottomHeight = 0;// 0.21333f * height; final float bottomHeight = 0.21333f * height;
this.tempRect.y = (int) bottomHeight; this.tempRect.y = (int) bottomHeight;
this.tempRect.height = height - (int) (topHeight + bottomHeight); this.tempRect.height = height - (int) (topHeight + bottomHeight);
return this.tempRect; return this.tempRect;

View File

@ -115,7 +115,11 @@ public class BatchGroup extends GenericGroup {
shader.setUniform2fv("u_uvRot", uvAnim, 2, 2); shader.setUniform2fv("u_uvRot", uvAnim, 2, 2);
shader.setUniform1fv("u_uvScale", uvAnim, 4, 1); 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); layer.bindBlended(shader);
} }
else { else {

View File

@ -8,7 +8,7 @@ public class FilterMode {
private static final int[] ERROR_DEFAULT = new int[] { 0, 0 }; 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_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[] 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 }; 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) { public static int[] layerFilterMode(final MdlxLayer.FilterMode filterMode) {

View File

@ -72,6 +72,7 @@ public class MdxComplexInstance extends ModelInstance {
private float animationSpeed = 1.0f; private float animationSpeed = 1.0f;
private float blendTime; private float blendTime;
private float blendTimeRemaining; private float blendTimeRemaining;
public boolean additiveOverrideMeshMode = false;
public MdxComplexInstance(final MdxModel model) { public MdxComplexInstance(final MdxModel model) {
super(model); super(model);
@ -511,8 +512,10 @@ public class MdxComplexInstance extends ModelInstance {
public void renderOpaque(final Matrix4 mvp) { public void renderOpaque(final Matrix4 mvp) {
final MdxModel model = (MdxModel) this.model; final MdxModel model = (MdxModel) this.model;
for (final GenericGroup group : model.opaqueGroups) { if (!this.additiveOverrideMeshMode) {
group.render(this, mvp); for (final GenericGroup group : model.opaqueGroups) {
group.render(this, mvp);
}
} }
final int glGetError = Gdx.gl.glGetError(); final int glGetError = Gdx.gl.glGetError();
@ -528,6 +531,9 @@ public class MdxComplexInstance extends ModelInstance {
} }
final MdxModel model = (MdxModel) this.model; 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) { for (final GenericGroup group : model.translucentGroups) {
group.render(this, this.scene.camera.viewProjectionMatrix); group.render(this, this.scene.camera.viewProjectionMatrix);
@ -555,6 +561,10 @@ public class MdxComplexInstance extends ModelInstance {
final int integerFrameTime = this.frame - lastIntegerFrame; final int integerFrameTime = this.frame - lastIntegerFrame;
this.counter += integerFrameTime; this.counter += integerFrameTime;
this.allowParticleSpawn = true; 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; final long animEnd = interval[1] - 1;
if (this.floatingFrame >= animEnd) { if (this.floatingFrame >= animEnd) {
@ -667,6 +677,12 @@ public class MdxComplexInstance extends ModelInstance {
return this; return this;
} }
public MdxComplexInstance setVertexAlpha(final float alpha) {
this.vertexColor[3] = alpha;
return this;
}
/** /**
* Set the sequence of this instance. * Set the sequence of this instance.
*/ */
@ -686,11 +702,13 @@ public class MdxComplexInstance extends ModelInstance {
this.allowParticleSpawn = false; this.allowParticleSpawn = false;
} }
else { else {
if ((this.blendTime > 0) && (lastSequence != this.sequence) && (lastSequence != -1)) { if ((this.blendTime > 0) && (lastSequence != -1)) {
this.blendTimeRemaining = this.blendTime; if ((this.blendTimeRemaining <= 0) && (this.counter > 0)) {
for (int i = 0, l = this.sortedNodes.length; i < l; i++) { this.blendTimeRemaining = this.blendTime;
final SkeletalNode node = this.sortedNodes[i]; for (int i = 0, l = this.sortedNodes.length; i < l; i++) {
node.beginBlending(); final SkeletalNode node = this.sortedNodes[i];
node.beginBlending();
}
} }
} }

View File

@ -9,7 +9,6 @@ import java.io.UnsupportedEncodingException;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; 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 ALLOW_CUSTOM_TEAM_COLOR = War3ID.fromString("utcc");
private static final War3ID TEAM_COLOR = War3ID.fromString("utco"); private static final War3ID TEAM_COLOR = War3ID.fromString("utco");
private static final War3ID MAX_ROLL = War3ID.fromString("umxr"); 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 War3ID sloc = War3ID.fromString("sloc");
private static final LoadGenericCallback stringDataCallback = new StringDataCallbackImplementation(); private static final LoadGenericCallback stringDataCallback = new StringDataCallbackImplementation();
private static final float[] rayHeap = new float[6]; private static final float[] rayHeap = new float[6];
@ -191,7 +193,6 @@ public class War3MapViewer extends AbstractMdxModelViewer {
public int renderPathing = 0; public int renderPathing = 0;
public int renderLighting = 1; public int renderLighting = 1;
public List<SplatModel> selModels = new ArrayList<>();
private final Set<String> selectedSplatModelKeys = new HashSet<>(); private final Set<String> selectedSplatModelKeys = new HashSet<>();
public List<RenderWidget> selected = new ArrayList<>(); public List<RenderWidget> selected = new ArrayList<>();
private final Set<String> mouseHighlightSplatModelKeys = new HashSet<>(); private final Set<String> mouseHighlightSplatModelKeys = new HashSet<>();
@ -732,6 +733,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
public void heroRevived(final CUnit source) { public void heroRevived(final CUnit source) {
final AbilityUI reviveUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_REVIVE_RAWCODE); final AbilityUI reviveUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_REVIVE_RAWCODE);
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); 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 CPlayer player = War3MapViewer.this.simulation.getPlayer(source.getPlayerIndex());
final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal()); final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal());
spawnFxOnOrigin(renderUnit, heroReviveArt); 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 @Override
public void spawnEffectOnUnit(final CUnit unit, final String effectPath) { public void spawnEffectOnUnit(final CUnit unit, final String effectPath) {
final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(unit); 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, final RenderUnit renderUnit = new RenderUnit(this, model, row, unitX, unitY, unitZ, customTeamColor,
soundset, portraitModel, simulationUnit, typeData, specialArtModel, buildingShadowInstance, soundset, portraitModel, simulationUnit, typeData, specialArtModel, buildingShadowInstance,
this.selectionCircleScaleFactor); this.selectionCircleScaleFactor, typeData.getAnimationWalkSpeed(),
typeData.getAnimationRunSpeed(), typeData.getScalingValue());
this.unitToRenderPeer.put(simulationUnit, renderUnit); this.unitToRenderPeer.put(simulationUnit, renderUnit);
this.widgets.add(renderUnit); this.widgets.add(renderUnit);
this.units.add(renderUnit); this.units.add(renderUnit);
@ -1488,7 +1498,8 @@ public class War3MapViewer extends AbstractMdxModelViewer {
if (unitTypeData == null) { if (unitTypeData == null) {
unitTypeData = new RenderUnitTypeData(row.getFieldAsFloat(MAX_PITCH, 0), row.getFieldAsFloat(MAX_ROLL, 0), 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.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); this.unitIdToTypeData.put(key, unitTypeData);
} }
return unitTypeData; return unitTypeData;
@ -1616,15 +1627,13 @@ public class War3MapViewer extends AbstractMdxModelViewer {
} }
public void deselect() { public void deselect() {
if (!this.selModels.isEmpty()) { for (final String key : this.selectedSplatModelKeys) {
for (final String key : this.selectedSplatModelKeys) { this.terrain.removeSplatBatchModel(key);
this.terrain.removeSplatBatchModel(key);
}
this.selModels.clear();
for (final RenderWidget unit : this.selected) {
unit.unassignSelectionCircle();
}
} }
for (final RenderWidget unit : this.selected) {
unit.unassignSelectionCircle();
}
this.selectedSplatModelKeys.clear();
this.selected.clear(); this.selected.clear();
} }
@ -1667,27 +1676,39 @@ public class War3MapViewer extends AbstractMdxModelViewer {
} }
} }
path = allyKey + path; path = allyKey + path;
if (!splats.containsKey(path)) { final SplatModel splatModel = this.terrain.getSplatModel("selection:" + path);
splats.put(path, new Splat()); if (splatModel != null) {
} final float x = unit.getX();
final float x = unit.getX(); final float y = unit.getY();
final float y = unit.getY(); final SplatMover splatInstance = splatModel.add(x - (selectionSize / 2), y - (selectionSize / 2),
System.out.println("Selecting a unit at " + x + "," + y); x + (selectionSize / 2), y + (selectionSize / 2), 5, this.terrain.centerOffset);
splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2), unit.assignSelectionCircle(splatInstance);
x + (selectionSize / 2), y + (selectionSize / 2), 5 }); if (unit.getInstance().hidden()) {
splats.get(path).unitMapping.add(new Consumer<SplatModel.SplatMover>() { splatInstance.hide();
@Override
public void accept(final SplatMover t) {
unit.assignSelectionCircle(t);
if (unit.getInstance().hidden()) {
t.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<SplatModel.SplatMover>() {
@Override
public void accept(final SplatMover t) {
unit.assignSelectionCircle(t);
if (unit.getInstance().hidden()) {
t.hide();
}
}
});
}
} }
this.selected.add(unit); this.selected.add(unit);
} }
this.selModels.clear();
for (final Map.Entry<String, Terrain.Splat> entry : splats.entrySet()) { for (final Map.Entry<String, Terrain.Splat> entry : splats.entrySet()) {
final String path = entry.getKey(); final String path = entry.getKey();
final String filePath = path.substring(2); final String filePath = path.substring(2);
@ -1715,7 +1736,6 @@ public class War3MapViewer extends AbstractMdxModelViewer {
model.color[3] = this.selectionCircleColorNeutral.a; model.color[3] = this.selectionCircleColorNeutral.a;
break; break;
} }
this.selModels.add(model);
this.terrain.addSplatBatchModel("selection:" + path, model); this.terrain.addSplatBatchModel("selection:" + path, model);
this.selectedSplatModelKeys.add("selection:" + path); this.selectedSplatModelKeys.add("selection:" + path);
} }
@ -1857,32 +1877,6 @@ public class War3MapViewer extends AbstractMdxModelViewer {
this.confirmationInstance.vertexColor[2] = blue; this.confirmationInstance.vertexColor[2] = blue;
} }
public List<RenderWidget> 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<RenderWidget> 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) { public RenderWidget rayPickUnit(final float x, final float y) {
return rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL); return rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL);
} }

View File

@ -138,32 +138,26 @@ public class PathingGrid {
final float offsetY = ((pathingTextureTga.getHeight() % 2) == 1) ? 16f : 0f; final float offsetY = ((pathingTextureTga.getHeight() % 2) == 1) ? 16f : 0f;
final Rectangle pathingMapRectangle = new Rectangle((positionX - (width / 2)) + offsetX, final Rectangle pathingMapRectangle = new Rectangle((positionX - (width / 2)) + offsetX,
(positionY - (height / 2)) + offsetY, width, height); (positionY - (height / 2)) + offsetY, width, height);
short anyPathingTypeWithUnit = 0;
if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks,
MovementType.AMPHIBIOUS)) { MovementType.AMPHIBIOUS)) {
System.out.println("intersects amph unit"); System.out.println("intersects amph unit");
anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE;
anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE;
} }
if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks,
MovementType.FLOAT)) { MovementType.FLOAT)) {
System.out.println("intersects float unit"); System.out.println("intersects float unit");
anyPathingTypesInRegion |= PathingFlags.UNSWIMABLE; anyPathingTypesInRegion |= PathingFlags.UNSWIMABLE;
anyPathingTypeWithUnit |= PathingFlags.UNSWIMABLE;
} }
if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks,
MovementType.FLY)) { MovementType.FLY)) {
System.out.println("intersects fly unit"); System.out.println("intersects fly unit");
anyPathingTypesInRegion |= PathingFlags.UNFLYABLE; anyPathingTypesInRegion |= PathingFlags.UNFLYABLE;
anyPathingTypeWithUnit |= PathingFlags.UNFLYABLE;
} }
if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks,
MovementType.FOOT)) { MovementType.FOOT)) {
System.out.println("intersects foot unit"); System.out.println("intersects foot unit");
anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE;
anyPathingTypeWithUnit |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE;
} }
pathingTypesFillingRegion &= anyPathingTypeWithUnit;
for (final CBuildingPathingType pathingType : preventPathingTypes) { for (final CBuildingPathingType pathingType : preventPathingTypes) {
if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, pathingType)) { if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, pathingType)) {
return false; return false;
@ -328,7 +322,9 @@ public class PathingGrid {
public static int UNWALKABLE = 0x2; public static int UNWALKABLE = 0x2;
public static int UNFLYABLE = 0x4; public static int UNFLYABLE = 0x4;
public static int UNBUILDABLE = 0x8; 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 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) { public static boolean isPathingFlag(final short pathingValue, final int flag) {
return (pathingValue & flag) != 0; return (pathingValue & flag) != 0;
@ -337,7 +333,7 @@ public class PathingGrid {
public static boolean isPathingFlag(final short pathingValue, final CBuildingPathingType pathingType) { public static boolean isPathingFlag(final short pathingValue, final CBuildingPathingType pathingType) {
switch (pathingType) { switch (pathingType) {
case BLIGHTED: case BLIGHTED:
throw new IllegalArgumentException("Blight pathing check system is Not Yet Implemented"); return PathingFlags.isPathingFlag(pathingValue, PathingFlags.BLIGHTED);
case UNAMPH: case UNAMPH:
return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE) return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE)
&& PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); && PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE);

View File

@ -54,6 +54,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.W3xShaders;
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
public class Terrain { public class Terrain {
public static final float CELL_SIZE = 128f;
private static final String[] colorTags = { "R", "G", "B", "A" }; private static final String[] colorTags = { "R", "G", "B", "A" };
private static final float[] sizeHeap = new float[2]; private static final float[] sizeHeap = new float[2];
private static final Vector3 normalHeap1 = new Vector3(); private static final Vector3 normalHeap1 = new Vector3();

View File

@ -153,8 +153,8 @@ public class TerrainShaders {
" float hU = texelFetch(height_texture, height_pos + off.zy, 0).r;\r\n" + // " 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" + // " vec3 normal = normalize(vec3(hL - hR, hD - hU, 2.0));\r\n" + //
"\r\n" + // "\r\n" + //
// " UV = vec2(vPosition.x, 1 - vPosition.y);\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==0?0.01:0.99, vPosition.y==0?0.99:0.01);\r\n" + //
" texture_indices = texelFetch(terrain_texture_list, pos, 0);\r\n" + // " texture_indices = texelFetch(terrain_texture_list, pos, 0);\r\n" + //
" pathing_map_uv = (vPosition + pos) * 4; \r\n" + // " pathing_map_uv = (vPosition + pos) * 4; \r\n" + //
"\r\n" + // "\r\n" + //

View File

@ -29,6 +29,9 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
private boolean dead; private boolean dead;
private BuildingShadow destructableShadow; private BuildingShadow destructableShadow;
private final boolean selectable; 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, public RenderDestructable(final War3MapViewer map, final MdxModel model, final MutableGameObject row,
final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type, final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type,
@ -38,18 +41,21 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
this.life = simulationDestructable.getLife(); this.life = simulationDestructable.getLife();
this.destructableShadow = destructableShadow; this.destructableShadow = destructableShadow;
this.simulationDestructable = simulationDestructable; this.simulationDestructable = simulationDestructable;
String replaceableTextureFile = row.getFieldAsString(TEX_FILE, 0); this.replaceableTextureFile = row.getFieldAsString(TEX_FILE, 0);
final int replaceableTextureId = row.getFieldAsInteger(TEX_ID, 0); this.replaceableTextureId = row.getFieldAsInteger(TEX_ID, 0);
if ((replaceableTextureFile != null) && (replaceableTextureFile.length() > 1)) { if ((this.replaceableTextureFile != null) && (this.replaceableTextureFile.length() > 1)) {
final int dotIndex = replaceableTextureFile.lastIndexOf('.'); final int dotIndex = this.replaceableTextureFile.lastIndexOf('.');
if (dotIndex != -1) { if (dotIndex != -1) {
replaceableTextureFile = replaceableTextureFile.substring(0, dotIndex); this.replaceableTextureFile = this.replaceableTextureFile.substring(0, dotIndex);
} }
replaceableTextureFile += ".blp"; if (simulationDestructable.isBlighted()) {
this.instance.setReplaceableTexture(replaceableTextureId, replaceableTextureFile); this.blighted = true;
this.replaceableTextureFile += "Blight";
}
this.instance.setReplaceableTexture(this.replaceableTextureId, this.replaceableTextureFile + ".blp");
} }
this.selectionScale *= row.getFieldAsFloat(SEL_CIRCLE_SIZE, 0); 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); simulationDestructable.setUnitAnimationListener(this.unitAnimationListenerImpl);
this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true); this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true);
this.selectable = row.readSLKTagBoolean("selectable"); this.selectable = row.readSLKTagBoolean("selectable");
@ -111,6 +117,14 @@ public class RenderDestructable extends RenderDoodad implements RenderWidget {
} }
} }
this.dead = dead; 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(); this.unitAnimationListenerImpl.update();
} }

View File

@ -13,6 +13,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
public class RenderDoodad { public class RenderDoodad {
private static final int SAMPLE_RADIUS = 4; private static final int SAMPLE_RADIUS = 4;
private static final float[] VERTEX_COLOR_BLACK = { 0f, 0f, 0f, 1f };
public final ModelInstance instance; public final ModelInstance instance;
private final MutableGameObject row; private final MutableGameObject row;
private final float maxPitch; private final float maxPitch;
@ -49,6 +50,11 @@ public class RenderDoodad {
float pitch, roll; float pitch, roll;
this.x = doodad.getLocation()[0]; this.x = doodad.getLocation()[0];
this.y = doodad.getLocation()[1]; 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 pitchSampleForwardX = this.x + (SAMPLE_RADIUS * (float) Math.cos(facingRadians));
final float pitchSampleForwardY = this.y + (SAMPLE_RADIUS * (float) Math.sin(facingRadians)); final float pitchSampleForwardY = this.y + (SAMPLE_RADIUS * (float) Math.sin(facingRadians));
final float pitchSampleBackwardX = this.x - (SAMPLE_RADIUS * (float) Math.cos(facingRadians)); final float pitchSampleBackwardX = this.x - (SAMPLE_RADIUS * (float) Math.cos(facingRadians));

View File

@ -137,7 +137,7 @@ public class RenderItem implements RenderWidget {
this.location[2] = this.simulationItem.getFlyHeight() + groundHeight; this.location[2] = this.simulationItem.getFlyHeight() + groundHeight;
this.instance.moveTo(this.location); 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.move(dx, dy, map.terrain.centerOffset);
this.shadow.setHeightAbsolute(currentWalkableUnder != null, groundHeight + map.imageWalkableZOffset); this.shadow.setHeightAbsolute(currentWalkableUnder != null, groundHeight + map.imageWalkableZOffset);
} }

View File

@ -33,7 +33,6 @@ public class RenderUnit implements RenderWidget {
private static final War3ID RED = War3ID.fromString("uclr"); private static final War3ID RED = War3ID.fromString("uclr");
private static final War3ID GREEN = War3ID.fromString("uclg"); private static final War3ID GREEN = War3ID.fromString("uclg");
private static final War3ID BLUE = War3ID.fromString("uclb"); 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 MOVE_HEIGHT = War3ID.fromString("umvh");
private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori"); private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori");
private static final War3ID ANIM_PROPS = War3ID.fromString("uani"); 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, 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 float y, final float z, final int playerIndex, final UnitSoundset soundset,
final MdxModel portraitModel, final CUnit simulationUnit, final RenderUnitTypeData typeData, final MdxModel portraitModel, final CUnit simulationUnit, final RenderUnitTypeData typeData,
final MdxModel specialArtModel, final BuildingShadow buildingShadow, final MdxModel specialArtModel, final BuildingShadow buildingShadow, final float selectionCircleScaleFactor,
final float selectionCircleScaleFactor) { final float animationWalkSpeed, final float animationRunSpeed, final float scalingValue) {
this.portraitModel = portraitModel; this.portraitModel = portraitModel;
this.simulationUnit = simulationUnit; this.simulationUnit = simulationUnit;
this.typeData = typeData; this.typeData = typeData;
@ -96,7 +95,7 @@ public class RenderUnit implements RenderWidget {
this.playerIndex = playerIndex & 0xFFFF; this.playerIndex = playerIndex & 0xFFFF;
instance.setTeamColor(this.playerIndex); instance.setTeamColor(this.playerIndex);
instance.setScene(map.worldScene); instance.setScene(map.worldScene);
this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance); this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance, animationWalkSpeed, animationRunSpeed);
simulationUnit.setUnitAnimationListener(this.unitAnimationListenerImpl); simulationUnit.setUnitAnimationListener(this.unitAnimationListenerImpl);
final String requiredAnimationNames = row.getFieldAsString(ANIM_PROPS, 0); final String requiredAnimationNames = row.getFieldAsString(ANIM_PROPS, 0);
TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) { TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) {
@ -117,14 +116,12 @@ public class RenderUnit implements RenderWidget {
War3ID red; War3ID red;
War3ID green; War3ID green;
War3ID blue; War3ID blue;
War3ID scale;
scale = MODEL_SCALE;
red = RED; red = RED;
green = GREEN; green = GREEN;
blue = BLUE; blue = BLUE;
instance.setVertexColor(new float[] { (row.getFieldAsInteger(red, 0)) / 255f, instance.setVertexColor(new float[] { (row.getFieldAsInteger(red, 0)) / 255f,
(row.getFieldAsInteger(green, 0)) / 255f, (row.getFieldAsInteger(blue, 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.selectionScale = row.getFieldAsFloat(War3MapViewer.UNIT_SELECT_SCALE, 0) * selectionCircleScaleFactor;
this.selectionHeight = row.getFieldAsFloat(UNIT_SELECT_HEIGHT, 0); 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, public void populateCommandCard(final CSimulation game, final GameUI gameUI,
final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI, final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI,
final int subMenuOrderId, boolean multiSelect) { final int subMenuOrderId, final boolean multiSelect) {
final CommandCardPopulatingAbilityVisitor commandCardPopulatingVisitor = CommandCardPopulatingAbilityVisitor.INSTANCE 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()) { for (final CAbility ability : this.simulationUnit.getAbilities()) {
ability.visit(commandCardPopulatingVisitor); ability.visit(commandCardPopulatingVisitor);
} }
@ -271,10 +269,11 @@ public class RenderUnit implements RenderWidget {
removeSplats(map); removeSplats(map);
} }
if (boneCorpse && !this.boneCorpse) { if (boneCorpse && !this.boneCorpse) {
if(simulationUnit.getUnitType().isHero()) { if (this.simulationUnit.getUnitType().isHero()) {
this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DISSIPATE, SequenceUtils.EMPTY, this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DISSIPATE,
this.simulationUnit.getEndingDecayTime(map.simulation), true); SequenceUtils.EMPTY, this.simulationUnit.getEndingDecayTime(map.simulation), true);
} else { }
else {
this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE, this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE,
this.simulationUnit.getEndingDecayTime(map.simulation), true); this.simulationUnit.getEndingDecayTime(map.simulation), true);
} }

View File

@ -6,14 +6,21 @@ public class RenderUnitTypeData {
private final float sampleRadius; private final float sampleRadius;
private final boolean allowCustomTeamColor; private final boolean allowCustomTeamColor;
private final int teamColor; 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, 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.maxPitch = maxPitch;
this.maxRoll = maxRoll; this.maxRoll = maxRoll;
this.sampleRadius = sampleRadius; this.sampleRadius = sampleRadius;
this.allowCustomTeamColor = allowCustomTeamColor; this.allowCustomTeamColor = allowCustomTeamColor;
this.teamColor = teamColor; this.teamColor = teamColor;
this.animationRunSpeed = animationRunSpeed;
this.animationWalkSpeed = animationWalkSpeed;
this.scalingValue = scalingValue;
} }
public float getMaxPitch() { public float getMaxPitch() {
@ -35,4 +42,16 @@ public class RenderUnitTypeData {
public int getTeamColor() { public int getTeamColor() {
return this.teamColor; return this.teamColor;
} }
public float getAnimationRunSpeed() {
return this.animationRunSpeed;
}
public float getAnimationWalkSpeed() {
return this.animationWalkSpeed;
}
public float getScalingValue() {
return this.scalingValue;
}
} }

View File

@ -51,15 +51,47 @@ public interface RenderWidget {
.noneOf(AnimationTokens.SecondaryTag.class); .noneOf(AnimationTokens.SecondaryTag.class);
private final EnumSet<AnimationTokens.SecondaryTag> recycleSet = EnumSet private final EnumSet<AnimationTokens.SecondaryTag> recycleSet = EnumSet
.noneOf(AnimationTokens.SecondaryTag.class); .noneOf(AnimationTokens.SecondaryTag.class);
private final EnumSet<AnimationTokens.SecondaryTag> recycleWalkFastSet = EnumSet
.noneOf(AnimationTokens.SecondaryTag.class);
private PrimaryTag currentAnimation; private PrimaryTag currentAnimation;
private EnumSet<SecondaryTag> currentAnimationSecondaryTags = SequenceUtils.EMPTY; private EnumSet<SecondaryTag> currentAnimationSecondaryTags = SequenceUtils.EMPTY;
private float currentSpeedRatio; private float currentSpeedRatio;
private boolean currentlyAllowingRarityVariations; private boolean currentlyAllowingRarityVariations;
private final Queue<QueuedAnimation> animationQueue = new LinkedList<>(); private final Queue<QueuedAnimation> animationQueue = new LinkedList<>();
private int lastWalkFrame = -1; 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.instance = instance;
this.animationWalkSpeed = animationWalkSpeed;
this.animationRunSpeed = animationRunSpeed;
}
@Override
public void playWalkAnimation(final boolean force, final float currentMovementSpeed,
final boolean allowRarityVariations) {
EnumSet<SecondaryTag> 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 @Override
@ -99,12 +131,13 @@ public interface RenderWidget {
this.recycleSet.addAll(this.secondaryAnimationTags); this.recycleSet.addAll(this.secondaryAnimationTags);
this.recycleSet.addAll(secondaryAnimationTags); this.recycleSet.addAll(secondaryAnimationTags);
this.instance.setAnimationSpeed(speedRatio); this.instance.setAnimationSpeed(speedRatio);
if(animationName != PrimaryTag.WALK && currentAnimation == PrimaryTag.WALK) { if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) {
lastWalkFrame = instance.frame; lastWalkFrame = instance.frame;
} }
if (SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, if (SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet,
allowRarityVariations) != null) { 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)); instance.setFrame(instance.clampFrame(lastWalkFrame));
} }
this.currentAnimation = animationName; this.currentAnimation = animationName;
@ -123,13 +156,14 @@ public interface RenderWidget {
this.recycleSet.clear(); this.recycleSet.clear();
this.recycleSet.addAll(this.secondaryAnimationTags); this.recycleSet.addAll(this.secondaryAnimationTags);
this.recycleSet.addAll(secondaryAnimationTags); this.recycleSet.addAll(secondaryAnimationTags);
if(animationName != PrimaryTag.WALK && currentAnimation == PrimaryTag.WALK) { if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) {
lastWalkFrame = instance.frame; lastWalkFrame = instance.frame;
} }
final Sequence sequence = SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, final Sequence sequence = SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet,
allowRarityVariations); allowRarityVariations);
if (sequence != null) { 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)); instance.setFrame(instance.clampFrame(lastWalkFrame));
} }
this.currentAnimation = animationName; this.currentAnimation = animationName;

View File

@ -251,7 +251,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
if (this.previewCallback.isShowingRequirements()) { if (this.previewCallback.isShowingRequirements()) {
uberTip = this.previewCallback.getRequirementsText() + "|r" + uberTip; uberTip = this.previewCallback.getRequirementsText() + "|r" + uberTip;
} }
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(), this.commandButtonListener.commandButton(buttonPosX, buttonPosY,
disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId, disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId,
autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, iconUI.getHotkey(), goldCost, autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, iconUI.getHotkey(), goldCost,
lumberCost, foodCost); lumberCost, foodCost);
@ -272,7 +272,8 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
int heroIndex = 0; int heroIndex = 0;
for (final CUnit playerHero : this.game.getPlayerHeroes(this.unit.getPlayerIndex())) { for (final CUnit playerHero : this.game.getPlayerHeroes(this.unit.getPlayerIndex())) {
final CAbilityHero heroData = playerHero.getHeroData(); final CAbilityHero heroData = playerHero.getHeroData();
if (playerHero.isDead() && (heroData != null) && heroData.isAwaitingRevive()) { if (playerHero.isDead() && (heroData != null) && heroData.isAwaitingRevive()
&& !heroData.isReviving()) {
final UnitIconUI unitUI = this.abilityDataUI.getUnitUI(playerHero.getTypeId()); final UnitIconUI unitUI = this.abilityDataUI.getUnitUI(playerHero.getTypeId());
if (unitUI != null) { if (unitUI != null) {

View File

@ -7,6 +7,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderWidget.UnitAni
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType;
public class CDestructable extends CWidget { public class CDestructable extends CWidget {
@ -15,6 +16,7 @@ public class CDestructable extends CWidget {
private final RemovablePathingMapInstance pathingInstanceDeath; private final RemovablePathingMapInstance pathingInstanceDeath;
private UnitAnimationListenerImpl unitAnimationListenerImpl; private UnitAnimationListenerImpl unitAnimationListenerImpl;
private boolean invulnerable; private boolean invulnerable;
private boolean blighted;
public CDestructable(final int handleId, final float x, final float y, final float life, public CDestructable(final int handleId, final float x, final float y, final float life,
final CDestructableType destTypeInstance, final RemovablePathingMapInstance pathingInstance, final CDestructableType destTypeInstance, final RemovablePathingMapInstance pathingInstance,
@ -95,4 +97,18 @@ public class CDestructable extends CWidget {
public boolean isInvulnerable() { public boolean isInvulnerable() {
return this.invulnerable; return this.invulnerable;
} }
public void setBlighted(final boolean blighted) {
this.blighted = blighted;
}
public boolean isBlighted() {
return this.blighted;
}
public boolean checkIsOnBlight(final CSimulation game) {
return !game.getPathingGrid().checkPathingTexture(getX(), getY(), 0, this.destType.getPathingPixelMap(),
EnumSet.of(CBuildingPathingType.BLIGHTED), EnumSet.noneOf(CBuildingPathingType.class),
game.getWorldCollision(), null);
}
} }

View File

@ -17,6 +17,7 @@ public class CGameplayConstants {
private final float maxCollisionRadius; private final float maxCollisionRadius;
private final float decayTime; private final float decayTime;
private final float boneDecayTime; private final float boneDecayTime;
private final float dissipateTime;
private final float bulletDeathTime; private final float bulletDeathTime;
private final float closeEnoughRange; private final float closeEnoughRange;
private final float dawnTimeGameHours; private final float dawnTimeGameHours;
@ -111,6 +112,7 @@ public class CGameplayConstants {
this.maxCollisionRadius = miscData.getFieldFloatValue("MaxCollisionRadius"); this.maxCollisionRadius = miscData.getFieldFloatValue("MaxCollisionRadius");
this.decayTime = miscData.getFieldFloatValue("DecayTime"); this.decayTime = miscData.getFieldFloatValue("DecayTime");
this.boneDecayTime = miscData.getFieldFloatValue("BoneDecayTime"); this.boneDecayTime = miscData.getFieldFloatValue("BoneDecayTime");
this.dissipateTime = miscData.getFieldFloatValue("DissipateTime");
this.structureDecayTime = miscData.getFieldFloatValue("StructureDecayTime"); this.structureDecayTime = miscData.getFieldFloatValue("StructureDecayTime");
this.bulletDeathTime = miscData.getFieldFloatValue("BulletDeathTime"); this.bulletDeathTime = miscData.getFieldFloatValue("BulletDeathTime");
this.closeEnoughRange = miscData.getFieldFloatValue("CloseEnoughRange"); this.closeEnoughRange = miscData.getFieldFloatValue("CloseEnoughRange");
@ -181,7 +183,6 @@ public class CGameplayConstants {
this.awakenLumberLevelFactor = miscData.getFieldFloatValue("AwakenLumberLevelFactor"); this.awakenLumberLevelFactor = miscData.getFieldFloatValue("AwakenLumberLevelFactor");
this.awakenMaxFactor = miscData.getFieldFloatValue("AwakenMaxFactor"); this.awakenMaxFactor = miscData.getFieldFloatValue("AwakenMaxFactor");
this.maxHeroLevel = miscData.getFieldValue("MaxHeroLevel"); this.maxHeroLevel = miscData.getFieldValue("MaxHeroLevel");
this.maxUnitLevel = miscData.getFieldValue("MaxUnitLevel"); this.maxUnitLevel = miscData.getFieldValue("MaxUnitLevel");
@ -257,6 +258,10 @@ public class CGameplayConstants {
return this.boneDecayTime; return this.boneDecayTime;
} }
public float getDissipateTime() {
return this.dissipateTime;
}
public float getBulletDeathTime() { public float getBulletDeathTime() {
return this.bulletDeathTime; return this.bulletDeathTime;
} }
@ -421,31 +426,33 @@ public class CGameplayConstants {
return this.spellCastRangeBuffer; return this.spellCastRangeBuffer;
} }
public int getHeroReviveGoldCost(int originalCost, int level) { public int getHeroReviveGoldCost(final int originalCost, final int level) {
int goldRevivalCost = (int)(originalCost * (reviveBaseFactor + (reviveLevelFactor * (level-1)))); final int goldRevivalCost = (int) (originalCost
return Math.min(goldRevivalCost, (int)(originalCost * reviveMaxFactor)); * (this.reviveBaseFactor + (this.reviveLevelFactor * (level - 1))));
return Math.min(goldRevivalCost, (int) (originalCost * this.reviveMaxFactor));
} }
public int getHeroReviveLumberCost(int originalCost, int level) { public int getHeroReviveLumberCost(final int originalCost, final int level) {
int lumberRevivalCost = (int)(originalCost * (reviveBaseLumberFactor + (reviveLumberLevelFactor * (level-1)))); final int lumberRevivalCost = (int) (originalCost
return Math.min(lumberRevivalCost, (int)(originalCost * reviveMaxFactor)); * (this.reviveBaseLumberFactor + (this.reviveLumberLevelFactor * (level - 1))));
return Math.min(lumberRevivalCost, (int) (originalCost * this.reviveMaxFactor));
} }
public int getHeroReviveTime(int originalTime, int level) { public int getHeroReviveTime(final int originalTime, final int level) {
int revivalTime = (int)(originalTime * level * reviveTimeFactor); final int revivalTime = (int) (originalTime * level * this.reviveTimeFactor);
return Math.min(revivalTime, (int)(originalTime * reviveMaxTimeFactor)); return Math.min(revivalTime, (int) (originalTime * this.reviveMaxTimeFactor));
} }
public float getHeroReviveLifeFactor() { public float getHeroReviveLifeFactor() {
return heroReviveLifeFactor; return this.heroReviveLifeFactor;
} }
public float getHeroReviveManaFactor() { public float getHeroReviveManaFactor() {
return heroReviveManaFactor; return this.heroReviveManaFactor;
} }
public float getHeroReviveManaStart() { public float getHeroReviveManaStart() {
return heroReviveManaStart; return this.heroReviveManaStart;
} }
private static int getTableValue(final int[] table, int level) { private static int getTableValue(final int[] table, int level) {

View File

@ -112,7 +112,7 @@ public class CSimulation implements CPlayerAPI {
for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) {
final CBasePlayer configPlayer = config.getPlayer(i); final CBasePlayer configPlayer = config.getPlayer(i);
final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex()); final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex());
final CRace defaultRace = CRace.NIGHTELF; final CRace defaultRace = CRace.UNDEAD;
final CPlayer newPlayer = new CPlayer(defaultRace, new float[] { startLoc.getX(), startLoc.getY() }, final CPlayer newPlayer = new CPlayer(defaultRace, new float[] { startLoc.getX(), startLoc.getY() },
configPlayer); configPlayer);
this.players.add(newPlayer); this.players.add(newPlayer);
@ -193,6 +193,7 @@ public class CSimulation implements CPlayerAPI {
pathingInstance, pathingInstanceDeath); pathingInstance, pathingInstanceDeath);
this.handleIdToDestructable.put(dest.getHandleId(), dest); this.handleIdToDestructable.put(dest.getHandleId(), dest);
this.destructables.add(dest); this.destructables.add(dest);
dest.setBlighted(dest.checkIsOnBlight(this));
return dest; return dest;
} }
@ -481,6 +482,10 @@ public class CSimulation implements CPlayerAPI {
} }
public void heroDeathEvent(final CUnit cUnit) { public void heroDeathEvent(final CUnit cUnit) {
this.simulationRenderController.heroDeathEvent(cUnit);
}
public void heroDissipateEvent(final CUnit cUnit) {
getPlayer(cUnit.getPlayerIndex()).onHeroDeath(cUnit); getPlayer(cUnit.getPlayerIndex()).onHeroDeath(cUnit);
} }

View File

@ -279,18 +279,15 @@ public class CUnit extends CWidget {
this.boneCorpse = true; this.boneCorpse = true;
// start final phase immediately for "cant raise" case // start final phase immediately for "cant raise" case
} }
if (!this.unitType.isDecay()) { if (!this.unitType.isHero()) {
// if we dont raise AND dont decay, then now that death anim is over if (!this.unitType.isDecay()) {
// we just delete the unit // if we dont raise AND dont decay, then now that death anim is over
if (this.unitType.isHero()) { // we just delete the unit
if (!getHeroData().isAwaitingRevive()) { return true;
setHidden(true);
getHeroData().setAwaitingRevive(true);
game.heroDeathEvent(this);
}
return false;
} }
return true; }
else {
game.heroDeathEvent(this);
} }
this.deathTurnTick = gameTurnTick; this.deathTurnTick = gameTurnTick;
} }
@ -308,7 +305,7 @@ public class CUnit extends CWidget {
if (!getHeroData().isAwaitingRevive()) { if (!getHeroData().isAwaitingRevive()) {
setHidden(true); setHidden(true);
getHeroData().setAwaitingRevive(true); getHeroData().setAwaitingRevive(true);
game.heroDeathEvent(this); game.heroDissipateEvent(this);
} }
return false; return false;
} }
@ -413,6 +410,8 @@ public class CUnit extends CWidget {
if (this.constructionProgress >= gameplayConstants.getHeroReviveTime( if (this.constructionProgress >= gameplayConstants.getHeroReviveTime(
trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) { trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) {
this.constructionProgress = 0; this.constructionProgress = 0;
revivingHero.getHeroData().setReviving(false);
revivingHero.getHeroData().setAwaitingRevive(false);
revivingHero.corpse = false; revivingHero.corpse = false;
revivingHero.boneCorpse = false; revivingHero.boneCorpse = false;
revivingHero.deathTurnTick = 0; revivingHero.deathTurnTick = 0;
@ -517,6 +516,9 @@ public class CUnit extends CWidget {
if (this.isBuilding()) { if (this.isBuilding()) {
return game.getGameplayConstants().getStructureDecayTime(); return game.getGameplayConstants().getStructureDecayTime();
} }
if (this.unitType.isHero()) {
return game.getGameplayConstants().getDissipateTime();
}
return game.getGameplayConstants().getBoneDecayTime(); return game.getGameplayConstants().getBoneDecayTime();
} }
@ -1399,7 +1401,7 @@ public class CUnit extends CWidget {
final CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue()); final CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue());
final CUnitType unitType = hero.getUnitType(); final CUnitType unitType = hero.getUnitType();
final CAbilityHero heroData = hero.getHeroData(); final CAbilityHero heroData = hero.getHeroData();
heroData.setAwaitingRevive(true); heroData.setReviving(false);
final CGameplayConstants gameplayConstants = game.getGameplayConstants(); final CGameplayConstants gameplayConstants = game.getGameplayConstants();
player.refund( player.refund(
gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()), gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()),
@ -1466,7 +1468,7 @@ public class CUnit extends CWidget {
public void queueRevivingHero(final CSimulation game, final CUnit hero) { public void queueRevivingHero(final CSimulation game, final CUnit hero) {
if (queue(game, new War3ID(hero.getHandleId()), QueueItemType.HERO_REVIVE)) { 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 CPlayer player = game.getPlayer(this.playerIndex);
final int heroReviveGoldCost = game.getGameplayConstants() final int heroReviveGoldCost = game.getGameplayConstants()
.getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); .getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel());
@ -1742,8 +1744,4 @@ public class CUnit extends CWidget {
return this.updateType; return this.updateType;
} }
} }
public float getAnimationRunSpeedRatio() {
return this.unitType.getAnimationRunSpeed() / this.speed;
}
} }

View File

@ -9,10 +9,13 @@ public interface CUnitAnimationListener {
void playAnimation(boolean force, final PrimaryTag animationName, void playAnimation(boolean force, final PrimaryTag animationName,
final EnumSet<SecondaryTag> secondaryAnimationTags, float speedRatio, boolean allowRarityVariations); final EnumSet<SecondaryTag> secondaryAnimationTags, float speedRatio, boolean allowRarityVariations);
void playWalkAnimation(boolean force, float currentMovementSpeed, boolean allowRarityVariations);
void queueAnimation(final PrimaryTag animationName, final EnumSet<SecondaryTag> secondaryAnimationTags, void queueAnimation(final PrimaryTag animationName, final EnumSet<SecondaryTag> secondaryAnimationTags,
boolean allowRarityVariations); boolean allowRarityVariations);
void addSecondaryTag(SecondaryTag secondaryTag); void addSecondaryTag(SecondaryTag secondaryTag);
void removeSecondaryTag(SecondaryTag secondaryTag); void removeSecondaryTag(SecondaryTag secondaryTag);
} }

View File

@ -76,7 +76,6 @@ public class CUnitType {
private final boolean canFlee; private final boolean canFlee;
private final int priority; private final int priority;
private final boolean revivesHeroes; private final boolean revivesHeroes;
private final float animationRunSpeed;
public CUnitType(final String name, final String legacyName, final War3ID typeId, final int maxLife, 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, 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 strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence,
final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute, final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute,
final List<War3ID> heroAbilityList, final List<String> heroProperNames, final int properNamesCount, final List<War3ID> heroAbilityList, final List<String> heroProperNames, final int properNamesCount,
final boolean canFlee, final int priority, final boolean revivesHeroes, final float animationRunSpeed) { final boolean canFlee, final int priority, final boolean revivesHeroes) {
this.name = name; this.name = name;
this.legacyName = legacyName; this.legacyName = legacyName;
this.typeId = typeId; this.typeId = typeId;
@ -149,7 +148,6 @@ public class CUnitType {
this.canFlee = canFlee; this.canFlee = canFlee;
this.priority = priority; this.priority = priority;
this.revivesHeroes = revivesHeroes; this.revivesHeroes = revivesHeroes;
this.animationRunSpeed = animationRunSpeed;
} }
public String getName() { public String getName() {
@ -367,8 +365,4 @@ public class CUnitType {
public boolean isRevivesHeroes() { public boolean isRevivesHeroes() {
return this.revivesHeroes; return this.revivesHeroes;
} }
public float getAnimationRunSpeed() {
return this.animationRunSpeed;
}
} }

View File

@ -112,7 +112,9 @@ public class CAbilityAttack extends AbstractCAbility {
@Override @Override
public void onAdd(final CSimulation game, final CUnit unit) { public void onAdd(final CSimulation game, final CUnit unit) {
unit.setAttackBehavior(new CBehaviorAttack(unit)); unit.setAttackBehavior(new CBehaviorAttack(unit));
unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit)); if (!unit.isMovementDisabled()) {
unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit));
}
} }
@Override @Override

View File

@ -29,6 +29,7 @@ public class CAbilityHero extends AbstractCAbility {
private HeroStatValue intelligence; private HeroStatValue intelligence;
private String properName; private String properName;
private boolean awaitingRevive; private boolean awaitingRevive;
private boolean reviving;
public CAbilityHero(final int handleId, final List<War3ID> skillsAvailable) { public CAbilityHero(final int handleId, final List<War3ID> skillsAvailable) {
super(handleId); super(handleId);
@ -169,12 +170,20 @@ public class CAbilityHero extends AbstractCAbility {
return this.properName; return this.properName;
} }
public void setAwaitingRevive(boolean awaitingRevive) { public void setAwaitingRevive(final boolean awaitingRevive) {
this.awaitingRevive = awaitingRevive; this.awaitingRevive = awaitingRevive;
} }
public boolean isAwaitingRevive() { 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) { public void addXp(final CSimulation simulation, final CUnit unit, final int xp) {
@ -241,7 +250,7 @@ public class CAbilityHero extends AbstractCAbility {
unit.setAgilityDefenseBonus(agilityDefenseBonus); unit.setAgilityDefenseBonus(agilityDefenseBonus);
} }
public static final class HeroStatValue { public static final class HeroStatValue {
private final float perLevelFactor; private final float perLevelFactor;
private int base; private int base;
private int bonus; private int bonus;

View File

@ -66,7 +66,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) { 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++) { for (int i = 0; i < this.itemsHeld.length; i++) {
if (this.itemsHeld[i] == target) { if (this.itemsHeld[i] == target) {
final CItem temp = this.itemsHeld[i]; 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); final CAbility cAbility = this.itemsHeldAbilities[orderId - OrderIds.itemuse00].get(0);
int forwardedOrderId = orderId; int forwardedOrderId = orderId;
if (cAbility instanceof GenericSingleIconActiveAbility) { if (cAbility instanceof GenericSingleIconActiveAbility) {
@ -158,7 +158,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
} }
} }
else { else {
if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag08)) { if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag05)) {
if (target instanceof CItem) { if (target instanceof CItem) {
final int slot = getSlot((CItem) target); final int slot = getSlot((CItem) target);
if (slot != -1) { if (slot != -1) {
@ -197,7 +197,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) { final AbilityTargetCheckReceiver<Void> receiver) {
if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse08)) { if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) {
receiver.targetOk(null); receiver.targetOk(null);
} }
else { else {
@ -208,7 +208,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) { final AbilityActivationReceiver receiver) {
if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse08)) { if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) {
final int slot = orderId - OrderIds.itemuse00; final int slot = orderId - OrderIds.itemuse00;
if (this.itemsHeldAbilities[slot].size() < 1) { if (this.itemsHeldAbilities[slot].size() < 1) {
receiver.notAnActiveAbility(); receiver.notAnActiveAbility();

View File

@ -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<CWidget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityPointTarget target, final AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
receiver.orderIdNotAccepted();
}
@Override
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) {
receiver.orderIdNotAccepted();
}
@Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) {
receiver.notAnActiveAbility();
}
@Override
public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) {
}
public int getGold() {
return this.gold;
}
public void setGold(final int gold) {
this.gold = gold;
}
}

View File

@ -1,7 +1,8 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue; package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue;
import com.etheller.warsmash.util.War3ID; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.*; 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.AbstractCAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; 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.AbilityTargetCheckReceiver;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; 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 final class CAbilityReviveHero extends AbstractCAbility {
public CAbilityReviveHero(final int handleId) { public CAbilityReviveHero(final int handleId) {
super(handleId); super(handleId);
} }
@Override @Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) { final AbilityActivationReceiver receiver) {
CUnit deadHero = game.getUnit(orderId); final CUnit deadHero = game.getUnit(orderId);
if (deadHero != null if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) {
&& deadHero.getPlayerIndex()==unit.getPlayerIndex()) { final CAbilityHero heroData = deadHero.getHeroData();
CAbilityHero heroData = deadHero.getHeroData(); if ((heroData != null) && heroData.isAwaitingRevive() && !heroData.isReviving()) {
if( heroData != null && heroData.isAwaitingRevive()) {
final CPlayer player = game.getPlayer(unit.getPlayerIndex()); final CPlayer player = game.getPlayer(unit.getPlayerIndex());
int heroReviveGoldCost = game.getGameplayConstants().getHeroReviveGoldCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); final int heroReviveGoldCost = game.getGameplayConstants()
int heroReviveLumberCost = game.getGameplayConstants().getHeroReviveLumberCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); .getHeroReviveGoldCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel());
final int heroReviveLumberCost = game.getGameplayConstants()
.getHeroReviveLumberCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel());
if (player.getGold() >= heroReviveGoldCost) { if (player.getGold() >= heroReviveGoldCost) {
if (player.getLumber() >= heroReviveLumberCost) { if (player.getLumber() >= heroReviveLumberCost) {
if ((deadHero.getUnitType().getFoodUsed() == 0) if ((deadHero.getUnitType().getFoodUsed() == 0)
|| ((player.getFoodUsed() + deadHero.getUnitType().getFoodUsed()) <= player.getFoodCap())) { || ((player.getFoodUsed() + deadHero.getUnitType().getFoodUsed()) <= player
.getFoodCap())) {
receiver.useOk(); receiver.useOk();
} }
else { else {
@ -77,9 +75,8 @@ public final class CAbilityReviveHero extends AbstractCAbility {
@Override @Override
public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) { final AbilityTargetCheckReceiver<Void> receiver) {
CUnit deadHero = game.getUnit(orderId); final CUnit deadHero = game.getUnit(orderId);
if (deadHero != null if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) {
&& deadHero.getPlayerIndex()==unit.getPlayerIndex()) {
receiver.targetOk(null); receiver.targetOk(null);
} }
else if (orderId == OrderIds.cancel) { else if (orderId == OrderIds.cancel) {
@ -91,7 +88,8 @@ public final class CAbilityReviveHero extends AbstractCAbility {
} }
@Override @Override
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId,
final AbilityTarget target) {
return true; return true;
} }

View File

@ -14,8 +14,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType;
public class CAbilityTypeDefinitionHarvest extends AbstractCAbilityTypeDefinition<CAbilityTypeHarvestLevelData> public class CAbilityTypeDefinitionHarvest extends AbstractCAbilityTypeDefinition<CAbilityTypeHarvestLevelData>
implements CAbilityTypeDefinition { implements CAbilityTypeDefinition {
protected static final War3ID DAMAGE_TO_TREE = War3ID.fromString("Har1"); 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("Har2");
protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har3"); protected static final War3ID GOLD_CAPACITY = War3ID.fromString("Har3");
@Override @Override
protected CAbilityTypeHarvestLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) { protected CAbilityTypeHarvestLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) {

View File

@ -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<CAbilityTypeHarvestLumberLevelData> 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<CTargetType> 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<CAbilityTypeHarvestLumberLevelData> levelData) {
return new CAbilityTypeHarvestLumber(alias, abilityEditorData.getCode(), levelData);
}
}

View File

@ -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<CAbilityTypeHarvestLumberLevelData> {
public CAbilityTypeHarvestLumber(final War3ID alias, final War3ID code,
final List<CAbilityTypeHarvestLumberLevelData> 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());
}
}

View File

@ -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<CTargetType> 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;
}
}

View File

@ -325,8 +325,7 @@ public class CBehaviorMove implements CBehavior {
return this; return this;
} }
} }
this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.WALK, SequenceUtils.FAST, this.unit.getUnitAnimationListener().playWalkAnimation(false, this.unit.getSpeed(), true);
this.unit.getAnimationRunSpeedRatio(), true);
this.wasWithinPropWindow = true; this.wasWithinPropWindow = true;
} }
while (continueDistance > 0); while (continueDistance > 0);

View File

@ -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.CItem;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; 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.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.CWidget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; 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.harvest.CAbilityHarvest;
@ -47,7 +48,7 @@ public class CBehaviorHarvest extends CAbstractRangedBehavior
@Override @Override
public boolean isWithinRange(final CSimulation simulation) { 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 @Override
@ -140,6 +141,11 @@ public class CBehaviorHarvest extends CAbstractRangedBehavior
Math.min(this.abilityHarvest.getCarriedResourceAmount() + this.abilityHarvest.getDamageToTree(), Math.min(this.abilityHarvest.getCarriedResourceAmount() + this.abilityHarvest.getDamageToTree(),
this.abilityHarvest.getLumberCapacity())); this.abilityHarvest.getLumberCapacity()));
this.unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.LUMBER); this.unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.LUMBER);
if (target instanceof CDestructable) {
if (this.unit.getUnitType().getClassifications().contains(CUnitClassification.UNDEAD)) {
((CDestructable) target).setBlighted(true);
}
}
} }
@Override @Override

View File

@ -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.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.CAbilityTypeDefinitionGoldMine;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.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.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.CAbilityTypeDefinitionInventory;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable;
@ -39,6 +40,7 @@ public class CAbilityData {
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest()); 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("ANcl"), new CAbilityTypeDefinitionChannelTest());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory());
this.codeToAbilityTypeDefinition.put(War3ID.fromString("Arep"), new CAbilityTypeDefinitionHumanRepair()); this.codeToAbilityTypeDefinition.put(War3ID.fromString("Arep"), new CAbilityTypeDefinitionHumanRepair());

View File

@ -172,8 +172,6 @@ public class CUnitData {
private static final War3ID CAN_FLEE = War3ID.fromString("ufle"); private static final War3ID CAN_FLEE = War3ID.fromString("ufle");
private static final War3ID PRIORITY = War3ID.fromString("upri"); private static final War3ID PRIORITY = War3ID.fromString("upri");
private static final War3ID ANIMATION_RUN_SPEED = War3ID.fromString("urun");
private final CGameplayConstants gameplayConstants; private final CGameplayConstants gameplayConstants;
private final MutableObjectData unitData; private final MutableObjectData unitData;
private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>(); private final Map<War3ID, CUnitType> unitIdToUnitType = new HashMap<>();
@ -285,8 +283,6 @@ public class CUnitData {
final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0); final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0);
final int priority = unitType.getFieldAsInteger(PRIORITY, 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 float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0);
final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0); final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0);
final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0); final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0);
@ -549,7 +545,7 @@ public class CUnitData {
goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes,
propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus, propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus,
intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount,
canFlee, priority, revivesHeroes, animationRunSpeed); canFlee, priority, revivesHeroes);
this.unitIdToUnitType.put(typeId, unitTypeInstance); this.unitIdToUnitType.put(typeId, unitTypeInstance);
this.jassLegacyNameToUnitId.put(legacyName, typeId); this.jassLegacyNameToUnitId.put(legacyName, typeId);
} }

View File

@ -25,74 +25,68 @@ public class OrderIds {
* An item targeted order that move the target item to a certain inventory slot * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * 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 * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * 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 * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * 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 * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * 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 * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * 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 * An item targeted order that move the target item to a certain inventory slot
* of the ordered hero. * of the ordered hero.
*/ */
public static final int itemdrag05 = 952007; public static final int itemdrag05 = 852007;
public static final int itemdrag06 = 952008;
public static final int itemdrag07 = 952009;
public static final int itemdrag08 = 952010;
/** /**
* An order that will make the ordered hero use the item in a certain inventory * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * 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 * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * 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 * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * 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 * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * 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 * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * 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 * 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 * slot. If it's an order with no target or object or point targeted depends on
* the type of item. * the type of item.
*/ */
public static final int itemuse05 = 952016;// War3 852013 public static final int itemuse05 = 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
/** /**
* Order for AIaa ability, which blizzard made for tome of attack, but never * Order for AIaa ability, which blizzard made for tome of attack, but never
* used it. But it can actually change caster's base attack! * used it. But it can actually change caster's base attack!

View File

@ -52,7 +52,7 @@ public interface SimulationRenderController {
void spawnEffectOnUnit(CUnit unit, String effectPath); void spawnEffectOnUnit(CUnit unit, String effectPath);
void spawnSpellEffectOnUnit(CUnit unit, War3ID alias); void spawnSpellEffectOnUnit(CUnit unit, War3ID alias);
void spawnUIUnitGetItemSound(CUnit cUnit, CItem item); void spawnUIUnitGetItemSound(CUnit cUnit, CItem item);
@ -62,6 +62,8 @@ public interface SimulationRenderController {
void unitPreferredSelectionReplacement(CUnit unit, CUnit newUnit); void unitPreferredSelectionReplacement(CUnit unit, CUnit newUnit);
void heroRevived(CUnit trainedUnit); void heroRevived(CUnit trainedUnit);
void heroDeathEvent(CUnit cUnit);
} }

View File

@ -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 private static final long WORLD_FRAME_MESSAGE_FADE_DURATION = WORLD_FRAME_MESSAGE_EXPIRE_MILLIS
- WORLD_FRAME_MESSAGE_FADEOUT_MILLIS; - WORLD_FRAME_MESSAGE_FADEOUT_MILLIS;
private static final String BUILDING_PATHING_PREVIEW_KEY = "buildingPathingPreview"; 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; public static final float DEFAULT_INVENTORY_ICON_WIDTH = 0.03125f;
private static final int COMMAND_CARD_WIDTH = 6; private static final int COMMAND_CARD_WIDTH = 4;
private static final int COMMAND_CARD_HEIGHT = 2; private static final int COMMAND_CARD_HEIGHT = 3;
private static final int INVENTORY_WIDTH = 3; private static final int INVENTORY_WIDTH = 2;
private static final int INVENTORY_HEIGHT = 3; private static final int INVENTORY_HEIGHT = 3;
private static final Vector2 screenCoordsVector = new Vector2(); private static final Vector2 screenCoordsVector = new Vector2();
@ -357,16 +357,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) { private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) {
screenCoordsVector.x = this.uiViewport.getScreenX(); final Rectangle minimapDisplayArea = new Rectangle(18.75f * this.widthRatioCorrection,
screenCoordsVector.y = 0; 13.75f * this.heightRatioCorrection, 278.75f * this.widthRatioCorrection,
this.uiViewport.unproject(screenCoordsVector); 276.25f * this.heightRatioCorrection);
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);
Texture minimapTexture = null; Texture minimapTexture = null;
if (war3MapViewer.dataSource.has("war3mapMap.tga")) { if (war3MapViewer.dataSource.has("war3mapMap.tga")) {
try { try {
@ -381,16 +374,13 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
else if (war3MapViewer.dataSource.has("war3mapMap.blp")) { else if (war3MapViewer.dataSource.has("war3mapMap.blp")) {
minimapTexture = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, "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]; final Texture[] teamColors = new Texture[WarsmashConstants.MAX_PLAYERS];
for (int i = 0; i < teamColors.length; i++) { for (int i = 0; i < teamColors.length; i++) {
teamColors[i] = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, teamColors[i] = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource,
"ReplaceableTextures\\" + ReplaceableIds.getPathString(1) + ReplaceableIds.getIdString(i) + ".blp"); "ReplaceableTextures\\" + ReplaceableIds.getPathString(1) + ReplaceableIds.getIdString(i) + ".blp");
} }
final Rectangle playableMapArea = war3MapViewer.terrain.getPlayableMapArea(); final Rectangle playableMapArea = war3MapViewer.terrain.getPlayableMapArea();
return new MeleeUIMinimap(minimapDisplayArea, playableMapArea, minimapTexture, teamColors, mapBorder, return new MeleeUIMinimap(minimapDisplayArea, playableMapArea, minimapTexture, teamColors);
minimapBorderArea);
} }
/** /**
@ -615,10 +605,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.unitManaText = (StringFrame) this.rootFrame.getFrameByName("UnitPortraitManaPointText", 0); this.unitManaText = (StringFrame) this.rootFrame.getFrameByName("UnitPortraitManaPointText", 0);
final float infoPanelUnitDetailWidth = GameUI.convertY(this.uiViewport, 0.180f); 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 = this.rootFrame.createSimpleFrame("SmashSimpleInfoPanel", this.rootFrame, 0);
this.smashSimpleInfoPanel.addAnchor(new AnchorDefinition(FramePoint.BOTTOM, this.smashSimpleInfoPanel
GameUI.convertX(this.uiViewport, -0.1f), GameUI.convertY(this.uiViewport, 0.0f))); .addAnchor(new AnchorDefinition(FramePoint.BOTTOM, 0, GameUI.convertY(this.uiViewport, 0.0f)));
this.smashSimpleInfoPanel.setWidth(infoPanelUnitDetailWidth); this.smashSimpleInfoPanel.setWidth(infoPanelUnitDetailWidth);
this.smashSimpleInfoPanel.setHeight(infoPanelUnitDetailHeight); this.smashSimpleInfoPanel.setHeight(infoPanelUnitDetailHeight);
@ -676,9 +666,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
queueIconFrameBackdrop0 queueIconFrameBackdrop0
.addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[0], FramePoint.CENTER, 0, 0)); .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[0], FramePoint.CENTER, 0, 0));
this.queueIconFrames[0].set(queueIconFrameBackdrop0); this.queueIconFrames[0].set(queueIconFrameBackdrop0);
this.queueIconFrames[0].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, this.queueIconFrames[0]
FramePoint.BOTTOMLEFT, (infoPanelUnitDetailWidth * (15 + 19f)) / 256, .addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, FramePoint.BOTTOMLEFT,
((infoPanelUnitDetailWidth * (66 + 19f)) / 256) - GameUI.convertY(this.uiViewport, 0.01f))); (infoPanelUnitDetailWidth * (15 + 19f)) / 256, (infoPanelUnitDetailWidth * (66 + 19f)) / 256));
final float frontQueueIconWidth = (infoPanelUnitDetailWidth * 38) / 256; final float frontQueueIconWidth = (infoPanelUnitDetailWidth * 38) / 256;
this.queueIconFrames[0].setWidth(frontQueueIconWidth); this.queueIconFrames[0].setWidth(frontQueueIconWidth);
this.queueIconFrames[0].setHeight(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)); .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[i], FramePoint.CENTER, 0, 0));
this.queueIconFrames[i].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, this.queueIconFrames[i].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel,
FramePoint.BOTTOMLEFT, (infoPanelUnitDetailWidth * (13 + 14.5f + (40 * (i - 1)))) / 256, 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; final float queueIconWidth = (infoPanelUnitDetailWidth * 29) / 256;
this.queueIconFrames[i].setWidth(queueIconWidth); this.queueIconFrames[i].setWidth(queueIconWidth);
this.queueIconFrames[i].setHeight(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.smashAttack1IconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconDamage",
this.simpleInfoPanelUnitDetail, 0); this.simpleInfoPanelUnitDetail, 0);
this.smashAttack1IconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, 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.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, this.attack1Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack1IconWrapper,
0); 0);
this.attack1IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); this.attack1IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0);
@ -755,9 +745,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.simpleInfoPanelUnitDetail, 0); this.simpleInfoPanelUnitDetail, 0);
this.smashAttack2IconWrapper this.smashAttack2IconWrapper
.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, .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.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, this.attack2Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack2IconWrapper,
1); 1);
this.attack2IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 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.smashArmorIconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconArmor",
this.simpleInfoPanelUnitDetail, 0); this.simpleInfoPanelUnitDetail, 0);
this.smashArmorIconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, 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.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.armorIcon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconArmor", this.smashArmorIconWrapper, 0);
this.armorIconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); this.armorIconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0);
this.armorInfoPanelIconValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconValue", 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.smashHeroInfoPanelWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconHero",
this.simpleInfoPanelUnitDetail, 0); this.simpleInfoPanelUnitDetail, 0);
this.smashHeroInfoPanelWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, 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.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, this.heroInfoPanel = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconHero", this.smashHeroInfoPanelWrapper,
0); 0);
this.primaryAttributeIcon = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroIcon", 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.inventoryBarFrame = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInventoryBar",
this.rootFrame, 0); this.rootFrame, 0);
this.inventoryBarFrame.setWidth(GameUI.convertX(this.uiViewport, 0.115f)); this.inventoryBarFrame.setWidth(GameUI.convertX(this.uiViewport, 0.079f));
this.inventoryBarFrame.setHeight(GameUI.convertY(this.uiViewport, 0.079f)); this.inventoryBarFrame.setHeight(GameUI.convertY(this.uiViewport, 0.115f));
this.inventoryBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this.consoleUI, FramePoint.BOTTOMRIGHT, this.inventoryBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, this.consoleUI, FramePoint.BOTTOMLEFT,
GameUI.convertX(this.uiViewport, 0.15f - 0.256f), GameUI.convertX(this.uiViewport, 0.591f), GameUI.convertY(this.uiViewport, 0.0f)));
GameUI.convertY(this.uiViewport, -0.006f + (DEFAULT_INVENTORY_ICON_WIDTH * 1.25f))));
if (GameUI.DEBUG) { if (GameUI.DEBUG) {
final FilterModeTextureFrame placeholderPreview = new FilterModeTextureFrame(null, this.inventoryBarFrame, 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, this.inventoryTitleFrame = this.rootFrame.createStringFrame("SmashInventoryText", this.inventoryBarFrame,
new Color(0xFCDE12FF), TextJustify.CENTER, TextJustify.MIDDLE, 0.0109f); new Color(0xFCDE12FF), TextJustify.CENTER, TextJustify.MIDDLE, 0.0109f);
this.rootFrame.setText(this.inventoryTitleFrame, this.rootFrame.getTemplates().getDecoratedString("INVENTORY")); this.rootFrame.setText(this.inventoryTitleFrame, this.rootFrame.getTemplates().getDecoratedString("INVENTORY"));
this.inventoryTitleFrame.addSetPoint(new SetPoint(FramePoint.TOP, this.inventoryBarFrame, FramePoint.TOP, this.inventoryTitleFrame
GameUI.convertX(this.uiViewport, 0.000f), GameUI.convertY(this.uiViewport, 0.0165625f))); .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.inventoryBarFrame, FramePoint.TOPLEFT,
this.inventoryTitleFrame.setWidth(GameUI.convertX(this.uiViewport, 0.10f));// 0.071f 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.setHeight(GameUI.convertX(this.uiViewport, 0.01125f));
this.inventoryTitleFrame.setFontShadowColor(new Color(0f, 0f, 0f, 0.9f)); this.inventoryTitleFrame.setFontShadowColor(new Color(0f, 0f, 0f, 0.9f));
this.inventoryTitleFrame.setFontShadowOffsetX(GameUI.convertX(this.uiViewport, 0.001f)); 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); "SmashCommandButton_" + (commandButtonIndex) + "_Cooldown", this.rootFrame, "", 0);
final SpriteFrame autocastFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", final SpriteFrame autocastFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE",
"SmashCommandButton_" + (commandButtonIndex) + "_Autocast", this.rootFrame, "", 0); "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, commandCardIcon.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT,
GameUI.convertX(this.uiViewport, 0.4155f + (0.03621f * displayXIndex)), GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)),
GameUI.convertY(this.uiViewport, 0.0375f - (0.03621f * displayYIndex)))); GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j))));
commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH));
commandCardIcon.setHeight(GameUI.convertY(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)); 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.timeIndicator.setFrameByRatio(this.war3MapViewer.simulation.getGameTimeOfDay()
/ this.war3MapViewer.simulation.getGameplayConstants().getGameDayHours()); / this.war3MapViewer.simulation.getGameplayConstants().getGameDayHours());
for (final TextTag textTag : this.war3MapViewer.textTags) { for (final TextTag textTag : this.war3MapViewer.textTags) {
@ -2171,7 +2158,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.smashArmorIconWrapper.addSetPoint( this.smashArmorIconWrapper.addSetPoint(
new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, 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.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport);
this.armorIcon.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( this.smashArmorIconWrapper.addSetPoint(
new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, 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.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport);
this.armorIcon.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() final String infopanelLevelClass = this.rootFrame.getTemplates()
.getDecoratedString("INFOPANEL_LEVEL_CLASS").replace("%u", "%d"); // :( .getDecoratedString("INFOPANEL_LEVEL_CLASS").replace("%u", "%d"); // :(
final int heroLevel = heroData.getHeroLevel(); final int heroLevel = heroData.getHeroLevel();
this.simpleClassValue.setVisible(true);
this.rootFrame.setText(this.simpleClassValue, this.rootFrame.setText(this.simpleClassValue,
String.format(infopanelLevelClass, heroLevel, unitTypeName)); String.format(infopanelLevelClass, heroLevel, unitTypeName));
this.rootFrame.setText(this.simpleNameValue, heroData.getProperName()); this.rootFrame.setText(this.simpleNameValue, heroData.getProperName());
@ -2221,13 +2209,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
/ (float) gameplayConstants.getNeedHeroXP(heroLevel)); / (float) gameplayConstants.getNeedHeroXP(heroLevel));
} }
else { else {
this.simpleClassValue.setVisible(!simulationUnit.isBuilding());
this.rootFrame.setText(this.simpleNameValue, unitTypeName); this.rootFrame.setText(this.simpleNameValue, unitTypeName);
String classText = null; String classText = null;
for (final CUnitClassification classification : simulationUnit.getClassifications()) { for (final CUnitClassification classification : simulationUnit.getClassifications()) {
if ((classification == CUnitClassification.MECHANICAL) && simulationUnit.isBuilding()) {
// buildings dont display MECHANICAL
continue;
}
if (classification.getDisplayName() != null) { if (classification.getDisplayName() != null) {
classText = classification.getDisplayName(); classText = classification.getDisplayName();
} }
@ -2376,17 +2361,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
public void resize(final Rectangle viewport) { public void resize(final Rectangle viewport) {
this.cameraManager.resize(viewport); this.cameraManager.resize(viewport);
positionPortrait(); positionPortrait();
screenCoordsVector.x = this.uiViewport.getScreenX();
screenCoordsVector.y = 0;
this.uiViewport.unproject(screenCoordsVector);
this.meleeUIMinimap.resizeNewX(screenCoordsVector.x);
} }
public void positionPortrait() { public void positionPortrait() {
this.projectionTemp1.x = 222 * this.widthRatioCorrection; this.projectionTemp1.x = 422 * this.widthRatioCorrection;
this.projectionTemp1.y = 57 * this.heightRatioCorrection; 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.projectionTemp2.y = (57 + 170) * this.heightRatioCorrection;
this.uiViewport.project(this.projectionTemp1); this.uiViewport.project(this.projectionTemp1);
this.uiViewport.project(this.projectionTemp2); this.uiViewport.project(this.projectionTemp2);
@ -2831,12 +2811,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
} }
else { else {
if (this.mouseOverUnit != null) {
final List<RenderWidget> unitList = Arrays.asList(this.mouseOverUnit);
this.war3MapViewer.doSelectUnit(unitList);
selectWidgets(unitList);
}
this.war3MapViewer.getClickLocation(this.lastMouseClickLocation, screenX, (int) worldScreenY); 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.lastMouseDragStart.set(this.lastMouseClickLocation);
this.allowDrag = true; this.allowDrag = true;
} }
@ -3006,6 +2986,14 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
if (!foundGoal) { if (!foundGoal) {
selectedWidgets.addAll(this.dragSelectPreviewUnits); 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<RenderWidget>() { Collections.sort(selectedWidgets, new Comparator<RenderWidget>() {
@Override @Override
public int compare(final RenderWidget widget1, final RenderWidget widget2) { 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.clearUnitMouseOverHighlight();
this.war3MapViewer.doSelectUnit(selectedWidgets); this.war3MapViewer.doSelectUnit(selectedWidgets);
selectWidgets(selectedWidgets); selectWidgets(selectedWidgets);
this.dragSelectPreviewUnits.clear(); this.dragSelectPreviewUnits.clear();
} }
else {
if ((button == Input.Buttons.LEFT) && (this.mouseOverUnit != null)) {
final List<RenderWidget> 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; this.mouseDownUIFrame = null;
return false; return false;

View File

@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit;
public class MeleeUIMinimap { public class MeleeUIMinimap {
@ -13,17 +12,13 @@ public class MeleeUIMinimap {
private final Texture minimapTexture; private final Texture minimapTexture;
private final Rectangle playableMapArea; private final Rectangle playableMapArea;
private final Texture[] teamColors; private final Texture[] teamColors;
private final Texture mapBorder;
private final Rectangle minimapBorderArea;
public MeleeUIMinimap(final Rectangle displayArea, final Rectangle playableMapArea, final Texture minimapTexture, 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.playableMapArea = playableMapArea;
this.minimapTexture = minimapTexture; this.minimapTexture = minimapTexture;
this.teamColors = teamColors; this.teamColors = teamColors;
this.minimap = displayArea; this.minimap = displayArea;
this.mapBorder = mapBorder;
this.minimapBorderArea = minimapBorderArea;
final float worldWidth = playableMapArea.getWidth(); final float worldWidth = playableMapArea.getWidth();
final float worldHeight = playableMapArea.getHeight(); final float worldHeight = playableMapArea.getHeight();
final float worldSize = Math.max(worldWidth, worldHeight); final float worldSize = Math.max(worldWidth, worldHeight);
@ -35,9 +30,7 @@ public class MeleeUIMinimap {
minimapFilledHeight); minimapFilledHeight);
} }
public void render(final SpriteBatch batch, final Iterable<RenderUnit> units, final Viewport uiViewport) { public void render(final SpriteBatch batch, final Iterable<RenderUnit> units) {
batch.draw(this.mapBorder, this.minimapBorderArea.x, this.minimapBorderArea.y, this.minimapBorderArea.width,
this.minimapBorderArea.height);
batch.draw(this.minimapTexture, this.minimap.x, this.minimap.y, this.minimap.width, this.minimap.height); batch.draw(this.minimapTexture, this.minimap.x, this.minimap.y, this.minimap.width, this.minimap.height);
for (final RenderUnit unit : units) { for (final RenderUnit unit : units) {
@ -66,11 +59,4 @@ public class MeleeUIMinimap {
public boolean containsMouse(final float x, final float y) { public boolean containsMouse(final float x, final float y) {
return this.minimapFilledArea.contains(x, 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;
}
} }

View File

@ -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.AL_POSITION;
import static org.lwjgl.openal.AL10.alListener; 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.nio.FloatBuffer;
import java.util.Date;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -37,17 +41,6 @@ import com.etheller.warsmash.viewer5.gl.WireframeExtension;
public class DesktopLauncher { public class DesktopLauncher {
public static void main(final String[] arg) { 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(); final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.useGL30 = true; config.useGL30 = true;
config.gles30ContextMajorVersion = 3; config.gles30ContextMajorVersion = 3;
@ -61,10 +54,14 @@ public class DesktopLauncher {
config.height = desktopDisplayMode.height; config.height = desktopDisplayMode.height;
String fileToLoad = null; String fileToLoad = null;
config.fullscreen = true; config.fullscreen = true;
boolean noLogs = false;
for (int argIndex = 0; argIndex < arg.length; argIndex++) { for (int argIndex = 0; argIndex < arg.length; argIndex++) {
if ("-windowed".equals(arg[argIndex])) { if ("-windowed".equals(arg[argIndex])) {
config.fullscreen = false; config.fullscreen = false;
} }
else if ("-nolog".equals(arg[argIndex])) {
noLogs = true;
}
else if ((arg.length > (argIndex + 1)) && "-loadfile".equals(arg[argIndex])) { else if ((arg.length > (argIndex + 1)) && "-loadfile".equals(arg[argIndex])) {
argIndex++; argIndex++;
fileToLoad = arg[argIndex]; fileToLoad = arg[argIndex];
@ -78,6 +75,23 @@ public class DesktopLauncher {
MultiplayerHack.LP_VAL = Integer.parseInt(arg[argIndex]); 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(); loadExtensions();
final DataTable warsmashIni = loadWarsmashIni(); final DataTable warsmashIni = loadWarsmashIni();
final WarsmashGdxMultiScreenGame warsmashGdxMultiScreenGame = new WarsmashGdxMultiScreenGame(); final WarsmashGdxMultiScreenGame warsmashGdxMultiScreenGame = new WarsmashGdxMultiScreenGame();

View File

@ -2,13 +2,14 @@ Frame "SIMPLEFRAME" "SmashConsoleInventoryCover" {
DecorateFileNames, DecorateFileNames,
SetAllPoints, SetAllPoints,
// Texture "SmashConsoleInventoryCoverTexture" { // The top of the UI console
// File "ConsoleInventoryCoverTexture", Texture "SmashConsoleInventoryCoverTexture" {
// Width 0.128, File "ConsoleInventoryCoverTexture",
// Height 0.176, Width 0.128,
// AlphaMode "ALPHAKEY", Height 0.176,
// TexCoord 0, 1, 0.3125, 1, AlphaMode "ALPHAKEY",
// Anchor BOTTOMLEFT,0.472,0.0, TexCoord 0, 1, 0.3125, 1,
// } Anchor BOTTOMLEFT,0.472,0.0,
}
} }

View File

@ -14,7 +14,7 @@ String "UnitPortraitTextTemplate" {
Frame "SIMPLEFRAME" "UnitPortrait" { Frame "SIMPLEFRAME" "UnitPortrait" {
DecorateFileNames, DecorateFileNames,
SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0.111,0, SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0.211,0,
Width 0.0835, Width 0.0835,
Height 0.114, Height 0.114,