mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Build behavior first draft
This commit is contained in:
parent
bc9f7d37a0
commit
4fbb7adeaf
@ -55,8 +55,8 @@ import com.etheller.warsmash.viewer5.handlers.w3x.ui.MeleeUI;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||
|
||||
public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProvider, InputProcessor {
|
||||
private static final boolean ENABLE_AUDIO = false;
|
||||
private static final boolean ENABLE_MUSIC = false;
|
||||
private static final boolean ENABLE_AUDIO = true;
|
||||
private static final boolean ENABLE_MUSIC = true;
|
||||
private DataSource codebase;
|
||||
private War3MapViewer viewer;
|
||||
private final Rectangle tempRect = new Rectangle();
|
||||
|
@ -524,7 +524,8 @@ public class War3MapViewer extends ModelViewer {
|
||||
@Override
|
||||
public CUnit createUnit(final CSimulation simulation, final War3ID typeId, final int playerIndex,
|
||||
final float x, final float y, final float facing) {
|
||||
return null;
|
||||
return createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y, 0f, playerIndex,
|
||||
(float) Math.toRadians(facing));
|
||||
}
|
||||
}, this.terrain.pathingGrid, this.terrain.getEntireMap(), this.seededRandom, w3iFile.getPlayers());
|
||||
|
||||
@ -756,176 +757,21 @@ public class War3MapViewer extends ModelViewer {
|
||||
private void loadUnitsAndItems(final Warcraft3MapObjectData modifications) throws IOException {
|
||||
final War3Map mpq = this.mapMpq;
|
||||
|
||||
this.soundsetNameToSoundset = new HashMap<>();
|
||||
|
||||
if (this.dataSource.has("war3mapUnits.doo")) {
|
||||
final War3MapUnitsDoo dooFile = mpq.readUnits();
|
||||
|
||||
final Map<String, UnitSoundset> soundsetNameToSoundset = new HashMap<>();
|
||||
|
||||
// Collect the units and items data.
|
||||
UnitSoundset soundset = null;
|
||||
for (final com.etheller.warsmash.parsers.w3x.unitsdoo.Unit unit : dooFile.getUnits()) {
|
||||
MutableGameObject row = null;
|
||||
String path = null;
|
||||
Splat unitShadowSplat = null;
|
||||
BufferedImage buildingPathingPixelMap = null;
|
||||
final War3ID unitId = unit.getId();
|
||||
final float unitX = unit.getLocation()[0];
|
||||
final float unitY = unit.getLocation()[1];
|
||||
final float unitZ = unit.getLocation()[2];
|
||||
final int playerIndex = unit.getPlayer();
|
||||
final float unitAngle = unit.getAngle();
|
||||
|
||||
// Hardcoded?
|
||||
WorldEditorDataType type = null;
|
||||
if (sloc.equals(unit.getId())) {
|
||||
// path = "Objects\\StartLocation\\StartLocation.mdx";
|
||||
type = null; /// ??????
|
||||
this.startLocations[unit.getPlayer()] = new Vector2(unit.getLocation()[0], unit.getLocation()[1]);
|
||||
}
|
||||
else {
|
||||
row = modifications.getUnits().get(unit.getId());
|
||||
if (row == null) {
|
||||
row = modifications.getItems().get(unit.getId());
|
||||
if (row != null) {
|
||||
type = WorldEditorDataType.ITEM;
|
||||
path = row.getFieldAsString(ITEM_FILE, 0);
|
||||
|
||||
if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) {
|
||||
path = path.substring(0, path.length() - 4);
|
||||
}
|
||||
|
||||
final String unitShadow = "Shadow";
|
||||
if ((unitShadow != null) && !"_".equals(unitShadow)) {
|
||||
final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp";
|
||||
final float shadowX = 50;
|
||||
final float shadowY = 50;
|
||||
final float shadowWidth = 128;
|
||||
final float shadowHeight = 128;
|
||||
if (!this.terrain.splats.containsKey(texture)) {
|
||||
final Splat splat = new Splat();
|
||||
splat.opacity = 0.5f;
|
||||
this.terrain.splats.put(texture, splat);
|
||||
}
|
||||
final float x = unit.getLocation()[0] - shadowX;
|
||||
final float y = unit.getLocation()[1] - shadowY;
|
||||
this.terrain.splats.get(texture).locations
|
||||
.add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 });
|
||||
unitShadowSplat = this.terrain.splats.get(texture);
|
||||
}
|
||||
|
||||
path += ".mdx";
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = WorldEditorDataType.UNITS;
|
||||
path = row.getFieldAsString(UNIT_FILE, 0);
|
||||
|
||||
if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) {
|
||||
path = path.substring(0, path.length() - 4);
|
||||
}
|
||||
if ((row.readSLKTagInt("fileVerFlags") == 2) && this.dataSource.has(path + "_V1.mdx")) {
|
||||
path += "_V1";
|
||||
}
|
||||
|
||||
path += ".mdx";
|
||||
|
||||
final String uberSplat = row.getFieldAsString(UBER_SPLAT, 0);
|
||||
if (uberSplat != null) {
|
||||
final Element uberSplatInfo = this.terrain.uberSplatTable.get(uberSplat);
|
||||
if (uberSplatInfo != null) {
|
||||
final String texturePath = uberSplatInfo.getField("Dir") + "\\"
|
||||
+ uberSplatInfo.getField("file") + ".blp";
|
||||
if (!this.terrain.splats.containsKey(texturePath)) {
|
||||
this.terrain.splats.put(texturePath, new Splat());
|
||||
}
|
||||
final float x = unit.getLocation()[0];
|
||||
final float y = unit.getLocation()[1];
|
||||
final float s = uberSplatInfo.getFieldFloatValue("Scale");
|
||||
this.terrain.splats.get(texturePath).locations
|
||||
.add(new float[] { x - s, y - s, x + s, y + s, 1 });
|
||||
}
|
||||
}
|
||||
|
||||
final String unitShadow = row.getFieldAsString(UNIT_SHADOW, 0);
|
||||
if ((unitShadow != null) && !"_".equals(unitShadow)) {
|
||||
final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp";
|
||||
final float shadowX = row.getFieldAsFloat(UNIT_SHADOW_X, 0);
|
||||
final float shadowY = row.getFieldAsFloat(UNIT_SHADOW_Y, 0);
|
||||
final float shadowWidth = row.getFieldAsFloat(UNIT_SHADOW_W, 0);
|
||||
final float shadowHeight = row.getFieldAsFloat(UNIT_SHADOW_H, 0);
|
||||
if (this.mapMpq.has(texture)) {
|
||||
if (!this.terrain.splats.containsKey(texture)) {
|
||||
final Splat splat = new Splat();
|
||||
splat.opacity = 0.5f;
|
||||
this.terrain.splats.put(texture, splat);
|
||||
}
|
||||
final float x = unit.getLocation()[0] - shadowX;
|
||||
final float y = unit.getLocation()[1] - shadowY;
|
||||
this.terrain.splats.get(texture).locations
|
||||
.add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 });
|
||||
unitShadowSplat = this.terrain.splats.get(texture);
|
||||
}
|
||||
}
|
||||
|
||||
final String buildingShadow = row.getFieldAsString(BUILDING_SHADOW, 0);
|
||||
if ((buildingShadow != null) && !"_".equals(buildingShadow)) {
|
||||
this.terrain.addShadow(buildingShadow, unit.getLocation()[0], unit.getLocation()[1]);
|
||||
}
|
||||
buildingPathingPixelMap = getBuildingPathingPixelMap(row);
|
||||
if (buildingPathingPixelMap != null) {
|
||||
this.terrain.pathingGrid.blitPathingOverlayTexture(unit.getLocation()[0],
|
||||
unit.getLocation()[1], (int) Math.toDegrees(unit.getAngle()),
|
||||
buildingPathingPixelMap);
|
||||
}
|
||||
|
||||
final String soundName = row.getFieldAsString(UNIT_SOUNDSET, 0);
|
||||
UnitSoundset unitSoundset = soundsetNameToSoundset.get(soundName);
|
||||
if (unitSoundset == null) {
|
||||
unitSoundset = new UnitSoundset(this.dataSource, this.unitAckSoundsTable, soundName);
|
||||
soundsetNameToSoundset.put(soundName, unitSoundset);
|
||||
}
|
||||
soundset = unitSoundset;
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
final MdxModel model = (MdxModel) this.load(path, this.mapPathSolver, this.solverParams);
|
||||
MdxModel portraitModel;
|
||||
final String portraitPath = path.substring(0, path.length() - 4) + "_portrait.mdx";
|
||||
if (this.dataSource.has(portraitPath)) {
|
||||
portraitModel = (MdxModel) this.load(portraitPath, this.mapPathSolver, this.solverParams);
|
||||
}
|
||||
else {
|
||||
portraitModel = model;
|
||||
}
|
||||
if (type == WorldEditorDataType.UNITS) {
|
||||
final float angle = (float) Math.toDegrees(unit.getAngle());
|
||||
final CUnit simulationUnit = this.simulation.createUnit(row.getAlias(), unit.getPlayer(),
|
||||
unit.getLocation()[0], unit.getLocation()[1], angle, buildingPathingPixelMap);
|
||||
final RenderUnitTypeData typeData = getUnitTypeData(unit.getId(), row);
|
||||
final RenderUnit renderUnit = new RenderUnit(this, model, row, unit, soundset, portraitModel,
|
||||
simulationUnit, typeData);
|
||||
this.unitToRenderPeer.put(simulationUnit, renderUnit);
|
||||
this.units.add(renderUnit);
|
||||
if (unitShadowSplat != null) {
|
||||
unitShadowSplat.unitMapping.add(new Consumer<SplatModel.SplatMover>() {
|
||||
@Override
|
||||
public void accept(final SplatMover t) {
|
||||
renderUnit.shadow = t;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.items.add(new RenderItem(this, model, row, unit, soundset, portraitModel)); // TODO store
|
||||
// somewhere
|
||||
if (unitShadowSplat != null) {
|
||||
unitShadowSplat.unitMapping.add(new Consumer<SplatModel.SplatMover>() {
|
||||
@Override
|
||||
public void accept(final SplatMover t) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.err.println("Unknown unit ID: " + unit.getId());
|
||||
}
|
||||
createNewUnit(modifications, unitId, unitX, unitY, unitZ, playerIndex, unitAngle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,6 +781,187 @@ public class War3MapViewer extends ModelViewer {
|
||||
this.anyReady = true;
|
||||
}
|
||||
|
||||
private CUnit createNewUnit(final Warcraft3MapObjectData modifications, final War3ID unitId, float unitX,
|
||||
float unitY, final float unitZ, final int playerIndex, final float unitAngle) {
|
||||
UnitSoundset soundset = null;
|
||||
MutableGameObject row = null;
|
||||
String path = null;
|
||||
Splat unitShadowSplat = null;
|
||||
BufferedImage buildingPathingPixelMap = null;
|
||||
final float unitVertexScale = 1.0f;
|
||||
|
||||
// Hardcoded?
|
||||
WorldEditorDataType type = null;
|
||||
if (sloc.equals(unitId)) {
|
||||
// path = "Objects\\StartLocation\\StartLocation.mdx";
|
||||
type = null; /// ??????
|
||||
this.startLocations[playerIndex] = new Vector2(unitX, unitY);
|
||||
}
|
||||
else {
|
||||
row = modifications.getUnits().get(unitId);
|
||||
if (row == null) {
|
||||
row = modifications.getItems().get(unitId);
|
||||
if (row != null) {
|
||||
type = WorldEditorDataType.ITEM;
|
||||
path = row.getFieldAsString(ITEM_FILE, 0);
|
||||
|
||||
if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) {
|
||||
path = path.substring(0, path.length() - 4);
|
||||
}
|
||||
|
||||
final String unitShadow = "Shadow";
|
||||
if ((unitShadow != null) && !"_".equals(unitShadow)) {
|
||||
final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp";
|
||||
final float shadowX = 50;
|
||||
final float shadowY = 50;
|
||||
final float shadowWidth = 128;
|
||||
final float shadowHeight = 128;
|
||||
if (!this.terrain.splats.containsKey(texture)) {
|
||||
final Splat splat = new Splat();
|
||||
splat.opacity = 0.5f;
|
||||
this.terrain.splats.put(texture, splat);
|
||||
}
|
||||
final float x = unitX - shadowX;
|
||||
final float y = unitY - shadowY;
|
||||
this.terrain.splats.get(texture).locations
|
||||
.add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 });
|
||||
unitShadowSplat = this.terrain.splats.get(texture);
|
||||
}
|
||||
|
||||
path += ".mdx";
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = WorldEditorDataType.UNITS;
|
||||
path = getUnitModelPath(row);
|
||||
|
||||
buildingPathingPixelMap = getBuildingPathingPixelMap(row);
|
||||
if (buildingPathingPixelMap != null) {
|
||||
unitX = Math.round(unitX / 64f) * 64f;
|
||||
unitY = Math.round(unitY / 64f) * 64f;
|
||||
this.terrain.pathingGrid.blitPathingOverlayTexture(unitX, unitY, (int) Math.toDegrees(unitAngle),
|
||||
buildingPathingPixelMap);
|
||||
}
|
||||
|
||||
final String uberSplat = row.getFieldAsString(UBER_SPLAT, 0);
|
||||
if (uberSplat != null) {
|
||||
final Element uberSplatInfo = this.terrain.uberSplatTable.get(uberSplat);
|
||||
if (uberSplatInfo != null) {
|
||||
final String texturePath = uberSplatInfo.getField("Dir") + "\\" + uberSplatInfo.getField("file")
|
||||
+ ".blp";
|
||||
if (!this.terrain.splats.containsKey(texturePath)) {
|
||||
this.terrain.splats.put(texturePath, new Splat());
|
||||
}
|
||||
final float x = unitX;
|
||||
final float y = unitY;
|
||||
final float s = uberSplatInfo.getFieldFloatValue("Scale");
|
||||
this.terrain.splats.get(texturePath).locations
|
||||
.add(new float[] { x - s, y - s, x + s, y + s, 1 });
|
||||
}
|
||||
}
|
||||
|
||||
final String unitShadow = row.getFieldAsString(UNIT_SHADOW, 0);
|
||||
if ((unitShadow != null) && !"_".equals(unitShadow)) {
|
||||
final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp";
|
||||
final float shadowX = row.getFieldAsFloat(UNIT_SHADOW_X, 0);
|
||||
final float shadowY = row.getFieldAsFloat(UNIT_SHADOW_Y, 0);
|
||||
final float shadowWidth = row.getFieldAsFloat(UNIT_SHADOW_W, 0);
|
||||
final float shadowHeight = row.getFieldAsFloat(UNIT_SHADOW_H, 0);
|
||||
if (this.mapMpq.has(texture)) {
|
||||
if (!this.terrain.splats.containsKey(texture)) {
|
||||
final Splat splat = new Splat();
|
||||
splat.opacity = 0.5f;
|
||||
this.terrain.splats.put(texture, splat);
|
||||
}
|
||||
final float x = unitX - shadowX;
|
||||
final float y = unitY - shadowY;
|
||||
this.terrain.splats.get(texture).locations
|
||||
.add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 });
|
||||
unitShadowSplat = this.terrain.splats.get(texture);
|
||||
}
|
||||
}
|
||||
|
||||
final String buildingShadow = row.getFieldAsString(BUILDING_SHADOW, 0);
|
||||
if ((buildingShadow != null) && !"_".equals(buildingShadow)) {
|
||||
this.terrain.addShadow(buildingShadow, unitX, unitY);
|
||||
}
|
||||
|
||||
final String soundName = row.getFieldAsString(UNIT_SOUNDSET, 0);
|
||||
UnitSoundset unitSoundset = this.soundsetNameToSoundset.get(soundName);
|
||||
if (unitSoundset == null) {
|
||||
unitSoundset = new UnitSoundset(this.dataSource, this.unitAckSoundsTable, soundName);
|
||||
this.soundsetNameToSoundset.put(soundName, unitSoundset);
|
||||
}
|
||||
soundset = unitSoundset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
final MdxModel model = (MdxModel) this.load(path, this.mapPathSolver, this.solverParams);
|
||||
MdxModel portraitModel;
|
||||
final String portraitPath = path.substring(0, path.length() - 4) + "_portrait.mdx";
|
||||
if (this.dataSource.has(portraitPath)) {
|
||||
portraitModel = (MdxModel) this.load(portraitPath, this.mapPathSolver, this.solverParams);
|
||||
}
|
||||
else {
|
||||
portraitModel = model;
|
||||
}
|
||||
if (type == WorldEditorDataType.UNITS) {
|
||||
final float angle = (float) Math.toDegrees(unitAngle);
|
||||
final CUnit simulationUnit = this.simulation.createUnit(row.getAlias(), playerIndex, unitX, unitY,
|
||||
angle, buildingPathingPixelMap);
|
||||
final RenderUnitTypeData typeData = getUnitTypeData(unitId, row);
|
||||
final RenderUnit renderUnit = new RenderUnit(this, model, row, unitX, unitY, unitZ, playerIndex,
|
||||
soundset, portraitModel, simulationUnit, typeData);
|
||||
this.unitToRenderPeer.put(simulationUnit, renderUnit);
|
||||
this.units.add(renderUnit);
|
||||
if (unitShadowSplat != null) {
|
||||
unitShadowSplat.unitMapping.add(new Consumer<SplatModel.SplatMover>() {
|
||||
@Override
|
||||
public void accept(final SplatMover t) {
|
||||
renderUnit.shadow = t;
|
||||
}
|
||||
});
|
||||
}
|
||||
return simulationUnit;
|
||||
}
|
||||
else {
|
||||
this.items
|
||||
.add(new RenderItem(this, model, row, unitX, unitY, unitZ, unitAngle, soundset, portraitModel)); // TODO
|
||||
// store
|
||||
// somewhere
|
||||
if (unitShadowSplat != null) {
|
||||
unitShadowSplat.unitMapping.add(new Consumer<SplatModel.SplatMover>() {
|
||||
@Override
|
||||
public void accept(final SplatMover t) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.err.println("Unknown unit ID: " + unitId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getUnitModelPath(final MutableGameObject row) {
|
||||
String path;
|
||||
path = row.getFieldAsString(UNIT_FILE, 0);
|
||||
|
||||
if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) {
|
||||
path = path.substring(0, path.length() - 4);
|
||||
}
|
||||
if ((row.readSLKTagInt("fileVerFlags") == 2) && this.dataSource.has(path + "_V1.mdx")) {
|
||||
path += "_V1";
|
||||
}
|
||||
|
||||
path += ".mdx";
|
||||
return path;
|
||||
}
|
||||
|
||||
private BufferedImage getBuildingPathingPixelMap(final MutableGameObject row) {
|
||||
BufferedImage buildingPathingPixelMap = null;
|
||||
final String pathingTexture = row.getFieldAsString(UNIT_PATHING, 0);
|
||||
@ -962,7 +989,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
return buildingPathingPixelMap;
|
||||
}
|
||||
|
||||
private RenderUnitTypeData getUnitTypeData(final War3ID key, final MutableGameObject row) {
|
||||
public RenderUnitTypeData getUnitTypeData(final War3ID key, final MutableGameObject row) {
|
||||
RenderUnitTypeData unitTypeData = this.unitIdToTypeData.get(key);
|
||||
if (unitTypeData == null) {
|
||||
unitTypeData = new RenderUnitTypeData(row.getFieldAsFloat(MAX_PITCH, 0), row.getFieldAsFloat(MAX_ROLL, 0),
|
||||
@ -1295,6 +1322,7 @@ public class War3MapViewer extends ModelViewer {
|
||||
private WorldEditStrings worldEditStrings;
|
||||
private Warcraft3MapObjectData allObjectData;
|
||||
private AbilityDataUI abilityDataUI;
|
||||
private Map<String, UnitSoundset> soundsetNameToSoundset;
|
||||
|
||||
/**
|
||||
* Returns a power of two size for the given target capacity.
|
||||
@ -1388,6 +1416,10 @@ public class War3MapViewer extends ModelViewer {
|
||||
return this.uiSounds;
|
||||
}
|
||||
|
||||
public Warcraft3MapObjectData getAllObjectData() {
|
||||
return this.allObjectData;
|
||||
}
|
||||
|
||||
public float getWalkableRenderHeight(final float x, final float y) {
|
||||
this.walkableObjectsTree.intersect(x, y, this.walkablesIntersector.reset(x, y));
|
||||
return this.walkablesIntersector.z;
|
||||
|
@ -20,23 +20,19 @@ public class RenderItem {
|
||||
public float radius;
|
||||
public UnitSoundset soundset;
|
||||
public final MdxModel portraitModel;
|
||||
public int playerIndex;
|
||||
|
||||
public RenderItem(final War3MapViewer map, final MdxModel model, final MutableGameObject row,
|
||||
final com.etheller.warsmash.parsers.w3x.unitsdoo.Unit unit, final UnitSoundset soundset,
|
||||
public RenderItem(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x,
|
||||
final float y, final float z, final float angle, final UnitSoundset soundset,
|
||||
final MdxModel portraitModel) {
|
||||
this.portraitModel = portraitModel;
|
||||
final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance();
|
||||
|
||||
final float[] location = unit.getLocation();
|
||||
System.arraycopy(location, 0, this.location, 0, 3);
|
||||
instance.move(location);
|
||||
final float angle = unit.getAngle();
|
||||
this.location[0] = x;
|
||||
this.location[1] = y;
|
||||
this.location[2] = z;
|
||||
instance.move(this.location);
|
||||
// instance.localRotation.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle);
|
||||
instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle));
|
||||
instance.scale(unit.getScale());
|
||||
this.playerIndex = unit.getPlayer();
|
||||
instance.setTeamColor(this.playerIndex);
|
||||
instance.setScene(map.worldScene);
|
||||
|
||||
if (row != null) {
|
||||
|
@ -30,7 +30,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitAnimationListe
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
|
||||
public class RenderUnit {
|
||||
private static final Quaternion tempQuat = new Quaternion();
|
||||
public static final Quaternion tempQuat = new Quaternion();
|
||||
private static final War3ID RED = War3ID.fromString("uclr");
|
||||
private static final War3ID GREEN = War3ID.fromString("uclg");
|
||||
private static final War3ID BLUE = War3ID.fromString("uclb");
|
||||
@ -67,25 +67,25 @@ public class RenderUnit {
|
||||
private boolean boneCorpse;
|
||||
private final RenderUnitTypeData typeData;
|
||||
|
||||
public RenderUnit(final War3MapViewer map, final MdxModel model, final MutableGameObject row,
|
||||
final com.etheller.warsmash.parsers.w3x.unitsdoo.Unit unit, final UnitSoundset soundset,
|
||||
public RenderUnit(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x,
|
||||
final float y, final float z, final int playerIndex, final UnitSoundset soundset,
|
||||
final MdxModel portraitModel, final CUnit simulationUnit, final RenderUnitTypeData typeData) {
|
||||
this.portraitModel = portraitModel;
|
||||
this.simulationUnit = simulationUnit;
|
||||
this.typeData = typeData;
|
||||
final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance();
|
||||
|
||||
final float[] location = unit.getLocation();
|
||||
System.arraycopy(location, 0, this.location, 0, 3);
|
||||
instance.move(location);
|
||||
this.location[0] = x;
|
||||
this.location[1] = y;
|
||||
this.location[2] = z;
|
||||
instance.move(this.location);
|
||||
this.facing = simulationUnit.getFacing();
|
||||
final float angle = (float) Math.toRadians(this.facing);
|
||||
// instance.localRotation.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle);
|
||||
this.x = simulationUnit.getX();
|
||||
this.y = simulationUnit.getY();
|
||||
instance.rotate(tempQuat.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle));
|
||||
instance.scale(unit.getScale());
|
||||
this.playerIndex = unit.getPlayer() & 0xFFFF;
|
||||
this.playerIndex = playerIndex & 0xFFFF;
|
||||
instance.setTeamColor(this.playerIndex);
|
||||
instance.setScene(map.worldScene);
|
||||
this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance);
|
||||
|
@ -24,6 +24,8 @@ public class CGameplayConstants {
|
||||
private final float gameDayHours;
|
||||
private final float gameDayLength;
|
||||
private final float structureDecayTime;
|
||||
private final float buildingAngle;
|
||||
private final float rootAngle;
|
||||
|
||||
public CGameplayConstants(final DataTable parsedDataTable) {
|
||||
final Element miscData = parsedDataTable.get("Misc");
|
||||
@ -41,6 +43,9 @@ public class CGameplayConstants {
|
||||
this.gameDayHours = miscData.getFieldFloatValue("DayHours");
|
||||
this.gameDayLength = miscData.getFieldFloatValue("DayLength");
|
||||
|
||||
this.buildingAngle = miscData.getFieldFloatValue("BuildingAngle");
|
||||
this.rootAngle = miscData.getFieldFloatValue("RootAngle");
|
||||
|
||||
final CDefenseType[] defenseTypeOrder = { CDefenseType.SMALL, CDefenseType.MEDIUM, CDefenseType.LARGE,
|
||||
CDefenseType.FORT, CDefenseType.NORMAL, CDefenseType.HERO, CDefenseType.DIVINE, CDefenseType.NONE, };
|
||||
this.damageBonusTable = new float[CAttackType.values().length][defenseTypeOrder.length];
|
||||
@ -111,4 +116,12 @@ public class CGameplayConstants {
|
||||
public float getStructureDecayTime() {
|
||||
return this.structureDecayTime;
|
||||
}
|
||||
|
||||
public float getBuildingAngle() {
|
||||
return this.buildingAngle;
|
||||
}
|
||||
|
||||
public float getRootAngle() {
|
||||
return this.rootAngle;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ public class CSimulation {
|
||||
private final CAbilityData abilityData;
|
||||
private final CUnitData unitData;
|
||||
private final List<CUnit> units;
|
||||
private final List<CUnit> newUnits;
|
||||
private final List<CPlayer> players;
|
||||
private final List<CAttackProjectile> projectiles;
|
||||
private final List<CAttackProjectile> newProjectiles;
|
||||
@ -60,6 +61,7 @@ public class CSimulation {
|
||||
this.abilityData = new CAbilityData(parsedAbilityData);
|
||||
this.unitData = new CUnitData(parsedUnitData, this.abilityData);
|
||||
this.units = new ArrayList<>();
|
||||
this.newUnits = new ArrayList<>();
|
||||
this.projectiles = new ArrayList<>();
|
||||
this.newProjectiles = new ArrayList<>();
|
||||
this.handleIdAllocator = new HandleIdAllocator();
|
||||
@ -119,7 +121,7 @@ public class CSimulation {
|
||||
final float facing, final BufferedImage buildingPathingPixelMap) {
|
||||
final CUnit unit = this.unitData.create(this, playerIndex, typeId, x, y, facing, buildingPathingPixelMap,
|
||||
this.simulationRenderController, this.handleIdAllocator);
|
||||
this.units.add(unit);
|
||||
this.newUnits.add(unit);
|
||||
this.handleIdToUnit.put(unit.getHandleId(), unit);
|
||||
for (final CAbility ability : unit.getAbilities()) {
|
||||
this.handleIdToAbility.put(ability.getHandleId(), ability);
|
||||
@ -128,6 +130,11 @@ public class CSimulation {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public CUnit createUnit(final War3ID typeId, final int playerIndex, final float x, final float y,
|
||||
final float facing) {
|
||||
return this.simulationRenderController.createUnit(this, typeId, playerIndex, x, y, facing);
|
||||
}
|
||||
|
||||
public CUnit getUnit(final int handleId) {
|
||||
return this.handleIdToUnit.get(handleId);
|
||||
}
|
||||
@ -175,6 +182,8 @@ public class CSimulation {
|
||||
this.simulationRenderController.removeUnit(unit);
|
||||
}
|
||||
}
|
||||
this.units.addAll(this.newUnits);
|
||||
this.newUnits.clear();
|
||||
final Iterator<CAttackProjectile> projectileIterator = this.projectiles.iterator();
|
||||
while (projectileIterator.hasNext()) {
|
||||
final CAttackProjectile projectile = projectileIterator.next();
|
||||
|
@ -462,53 +462,63 @@ public class CUnit extends CWidget {
|
||||
final CUnit targetUnit = (CUnit) target;
|
||||
final CUnitType targetUnitType = targetUnit.getUnitType();
|
||||
if (targetUnitType.isBuilding() && (targetUnitType.getBuildingPathingPixelMap() != null)) {
|
||||
final float relativeOffsetX = getX() - target.getX();
|
||||
final float relativeOffsetY = getY() - target.getY();
|
||||
final int rotation = ((int) targetUnit.getFacing() + 450) % 360;
|
||||
final BufferedImage buildingPathingPixelMap = targetUnitType.getBuildingPathingPixelMap();
|
||||
final int gridWidth = ((rotation % 180) != 0) ? buildingPathingPixelMap.getHeight()
|
||||
: buildingPathingPixelMap.getWidth();
|
||||
final int gridHeight = ((rotation % 180) != 0) ? buildingPathingPixelMap.getWidth()
|
||||
: buildingPathingPixelMap.getHeight();
|
||||
final int relativeGridX = (int) Math.floor(relativeOffsetX / 32f) + (gridWidth / 2);
|
||||
final int relativeGridY = (int) Math.floor(relativeOffsetY / 32f) + (gridHeight / 2);
|
||||
final int rangeInCells = (int) Math.floor(range / 32f);
|
||||
final int rangeInCellsSquare = rangeInCells * rangeInCells;
|
||||
int minCheckX = relativeGridX - rangeInCells;
|
||||
int minCheckY = relativeGridY - rangeInCells;
|
||||
int maxCheckX = relativeGridX + rangeInCells;
|
||||
int maxCheckY = relativeGridY + rangeInCells;
|
||||
if ((minCheckX < gridWidth) && (maxCheckX >= 0)) {
|
||||
if ((minCheckY < gridHeight) && (maxCheckY >= 0)) {
|
||||
if (minCheckX < 0) {
|
||||
minCheckX = 0;
|
||||
}
|
||||
if (minCheckY < 0) {
|
||||
minCheckY = 0;
|
||||
}
|
||||
if (maxCheckX > (gridWidth - 1)) {
|
||||
maxCheckX = gridWidth - 1;
|
||||
}
|
||||
if (maxCheckY > (gridHeight - 1)) {
|
||||
maxCheckY = gridHeight - 1;
|
||||
}
|
||||
for (int checkX = minCheckX; checkX <= maxCheckX; checkX++) {
|
||||
for (int checkY = minCheckY; checkY <= maxCheckY; checkY++) {
|
||||
final int dx = relativeGridX - checkX;
|
||||
final int dy = relativeGridY - checkY;
|
||||
if (((dx * dx) + (dy * dy)) <= rangeInCellsSquare) {
|
||||
if (((getRGBFromPixelData(buildingPathingPixelMap, checkX, checkY, rotation)
|
||||
& 0xFF0000) >>> 16) > 127) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final float targetX = target.getX();
|
||||
final float targetY = target.getY();
|
||||
if (canReachToPathing(range, targetUnit.getFacing(), buildingPathingPixelMap, targetX, targetY)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return distance <= range;
|
||||
}
|
||||
|
||||
public boolean canReachToPathing(final float range, final float rotationForPathing,
|
||||
final BufferedImage buildingPathingPixelMap, final float targetX, final float targetY) {
|
||||
final int rotation = ((int) rotationForPathing + 450) % 360;
|
||||
final float relativeOffsetX = getX() - targetX;
|
||||
final float relativeOffsetY = getY() - targetY;
|
||||
final int gridWidth = ((rotation % 180) != 0) ? buildingPathingPixelMap.getHeight()
|
||||
: buildingPathingPixelMap.getWidth();
|
||||
final int gridHeight = ((rotation % 180) != 0) ? buildingPathingPixelMap.getWidth()
|
||||
: buildingPathingPixelMap.getHeight();
|
||||
final int relativeGridX = (int) Math.floor(relativeOffsetX / 32f) + (gridWidth / 2);
|
||||
final int relativeGridY = (int) Math.floor(relativeOffsetY / 32f) + (gridHeight / 2);
|
||||
final int rangeInCells = (int) Math.floor(range / 32f);
|
||||
final int rangeInCellsSquare = rangeInCells * rangeInCells;
|
||||
int minCheckX = relativeGridX - rangeInCells;
|
||||
int minCheckY = relativeGridY - rangeInCells;
|
||||
int maxCheckX = relativeGridX + rangeInCells;
|
||||
int maxCheckY = relativeGridY + rangeInCells;
|
||||
if ((minCheckX < gridWidth) && (maxCheckX >= 0)) {
|
||||
if ((minCheckY < gridHeight) && (maxCheckY >= 0)) {
|
||||
if (minCheckX < 0) {
|
||||
minCheckX = 0;
|
||||
}
|
||||
if (minCheckY < 0) {
|
||||
minCheckY = 0;
|
||||
}
|
||||
if (maxCheckX > (gridWidth - 1)) {
|
||||
maxCheckX = gridWidth - 1;
|
||||
}
|
||||
if (maxCheckY > (gridHeight - 1)) {
|
||||
maxCheckY = gridHeight - 1;
|
||||
}
|
||||
for (int checkX = minCheckX; checkX <= maxCheckX; checkX++) {
|
||||
for (int checkY = minCheckY; checkY <= maxCheckY; checkY++) {
|
||||
final int dx = relativeGridX - checkX;
|
||||
final int dy = relativeGridY - checkY;
|
||||
if (((dx * dx) + (dy * dy)) <= rangeInCellsSquare) {
|
||||
if (((getRGBFromPixelData(buildingPathingPixelMap, checkX, checkY, rotation)
|
||||
& 0xFF0000) >>> 16) > 127) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return distance <= range;
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getRGBFromPixelData(final BufferedImage buildingPathingPixelMap, final int checkX, final int checkY,
|
||||
|
@ -10,12 +10,11 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.test.IAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver.TargetType;
|
||||
|
||||
public class CAbilityAttack implements CAbility, IAbility {
|
||||
public class CAbilityAttack implements CAbility {
|
||||
private final int handleId;
|
||||
|
||||
public CAbilityAttack(final int handleId) {
|
||||
|
@ -78,6 +78,6 @@ public abstract class AbstractCAbilityBuild extends AbstractCAbility implements
|
||||
|
||||
@Override
|
||||
public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ 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.CAbilityVisitor;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorOrcBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||
|
||||
public class CAbilityOrcBuild extends AbstractCAbilityBuild {
|
||||
private CBehaviorOrcBuild buildBehavior;
|
||||
|
||||
public CAbilityOrcBuild(final int handleId, final List<War3ID> structuresBuilt) {
|
||||
super(handleId, structuresBuilt);
|
||||
@ -24,6 +26,7 @@ public class CAbilityOrcBuild extends AbstractCAbilityBuild {
|
||||
|
||||
@Override
|
||||
public void onAdd(final CSimulation game, final CUnit unit) {
|
||||
this.buildBehavior = new CBehaviorOrcBuild(unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,8 +40,7 @@ public class CAbilityOrcBuild extends AbstractCAbilityBuild {
|
||||
|
||||
@Override
|
||||
public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final Vector2 point) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return this.buildBehavior.reset(point.x, point.y, orderId, getBaseOrderId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,12 +39,8 @@ public class CBehaviorAttack extends CAbstractRangedWidgetTargetBehavior {
|
||||
@Override
|
||||
public boolean isWithinRange(final CSimulation simulation) {
|
||||
float range = this.unitAttack.getRange();
|
||||
if ((this.target instanceof CUnit) && (((CUnit) this.target).isMoving()) && (simulation
|
||||
.getGameTurnTick() < this.unit.getCooldownEndTime() /*
|
||||
* only apply range motion buffer if they were
|
||||
* already in range and attacked
|
||||
*/)) {
|
||||
range += this.unitAttack.getRangeMotionBuffer() + 1000;
|
||||
if (simulation.getGameTurnTick() < this.unit.getCooldownEndTime()) {
|
||||
range += this.unitAttack.getRangeMotionBuffer();
|
||||
}
|
||||
return this.unit.canReach(this.target, range)
|
||||
&& (this.unit.distance(this.target) >= this.unit.getUnitType().getMinimumAttackRange());
|
||||
|
@ -88,7 +88,7 @@ public class CBehaviorMove implements CBehavior {
|
||||
@Override
|
||||
public CBehavior update(final CSimulation simulation) {
|
||||
if ((this.rangedBehavior != null) && this.rangedBehavior.isWithinRange(simulation)) {
|
||||
return this.rangedBehavior;
|
||||
return this.rangedBehavior.update(simulation);
|
||||
}
|
||||
final float prevX = this.unit.getX();
|
||||
final float prevY = this.unit.getY();
|
||||
|
@ -1,35 +1,43 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build;
|
||||
|
||||
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.CUnitType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedPointTargetBehavior;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
|
||||
|
||||
public class CBehaviorBuild extends CAbstractRangedPointTargetBehavior {
|
||||
private int orderId;
|
||||
public class CBehaviorOrcBuild extends CAbstractRangedPointTargetBehavior {
|
||||
private int highlightOrderId;
|
||||
private War3ID orderId;
|
||||
|
||||
public CBehaviorBuild(final CUnit unit) {
|
||||
public CBehaviorOrcBuild(final CUnit unit) {
|
||||
super(unit);
|
||||
}
|
||||
|
||||
public CBehavior reset(final float targetX, final float targetY, final int orderId) {
|
||||
this.orderId = orderId;
|
||||
public CBehavior reset(final float targetX, final float targetY, final int orderId, final int highlightOrderId) {
|
||||
this.highlightOrderId = highlightOrderId;
|
||||
this.orderId = new War3ID(orderId);
|
||||
return innerReset(targetX, targetY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWithinRange(final CSimulation simulation) {
|
||||
return this.unit.distance(this.targetX, this.targetY) <= 23525;
|
||||
final CUnitType unitType = simulation.getUnitData().getUnitType(this.orderId);
|
||||
return this.unit.canReachToPathing(0, simulation.getGameplayConstants().getBuildingAngle(),
|
||||
unitType.getBuildingPathingPixelMap(), this.targetX, this.targetY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHighlightOrderId() {
|
||||
return this.orderId;
|
||||
return this.highlightOrderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CBehavior update(final CSimulation simulation, final boolean withinRange) {
|
||||
return this;
|
||||
simulation.createUnit(this.orderId, this.unit.getPlayerIndex(), this.targetX, this.targetY,
|
||||
simulation.getGameplayConstants().getBuildingAngle());
|
||||
return this.unit.pollNextOrderBehavior(simulation);
|
||||
}
|
||||
|
||||
@Override
|
@ -137,11 +137,11 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
||||
this.commandCardCommandListener.openMenu(this.orderId);
|
||||
}
|
||||
else {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId, false);
|
||||
}
|
||||
}
|
||||
else if (button == Input.Buttons.RIGHT) {
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.autoCastOrderId);
|
||||
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.autoCastOrderId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -30,8 +31,11 @@ import com.etheller.warsmash.parsers.fdf.frames.TextureFrame;
|
||||
import com.etheller.warsmash.parsers.fdf.frames.UIFrame;
|
||||
import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener;
|
||||
import com.etheller.warsmash.parsers.mdlx.Layer.FilterMode;
|
||||
import com.etheller.warsmash.units.manager.MutableObjectData;
|
||||
import com.etheller.warsmash.util.FastNumberFormat;
|
||||
import com.etheller.warsmash.util.ImageUtils;
|
||||
import com.etheller.warsmash.util.RenderMathUtils;
|
||||
import com.etheller.warsmash.util.War3ID;
|
||||
import com.etheller.warsmash.util.WarsmashConstants;
|
||||
import com.etheller.warsmash.viewer5.Scene;
|
||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance;
|
||||
@ -55,10 +59,12 @@ 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.CUnitFilterFunction;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityView;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.AbstractCAbilityBuild;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType;
|
||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType;
|
||||
@ -139,6 +145,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
private CAbilityView activeCommand;
|
||||
private int activeCommandOrderId;
|
||||
private RenderUnit activeCommandUnit;
|
||||
private MdxComplexInstance cursorModelInstance = null;
|
||||
private BufferedImage cursorModelPathing;
|
||||
|
||||
private int selectedSoundCount = 0;
|
||||
private final ActiveCommandUnitTargetFilter activeCommandUnitTargetFilter;
|
||||
@ -373,7 +381,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUsingAbility(final int abilityHandleId, final int orderId) {
|
||||
public void startUsingAbility(final int abilityHandleId, final int orderId, final boolean rightClick) {
|
||||
// TODO not O(N)
|
||||
CAbilityView abilityToUse = null;
|
||||
for (final CAbility ability : this.selectedUnit.getSimulationUnit().getAbilities()) {
|
||||
@ -411,6 +419,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(),
|
||||
abilityHandleId, orderId, isShiftDown());
|
||||
}
|
||||
if (rightClick) {
|
||||
this.war3MapViewer.getUiSounds().getSound("AutoCastButtonClick").play(this.uiScene.audioContext, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -434,8 +445,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
public void update(final float deltaTime) {
|
||||
this.portrait.update();
|
||||
|
||||
int mouseX = Gdx.input.getX();
|
||||
int mouseY = Gdx.input.getY();
|
||||
final int baseMouseX = Gdx.input.getX();
|
||||
int mouseX = baseMouseX;
|
||||
final int baseMouseY = Gdx.input.getY();
|
||||
int mouseY = baseMouseY;
|
||||
final int minX = this.uiViewport.getScreenX();
|
||||
final int maxX = minX + this.uiViewport.getScreenWidth();
|
||||
final int minY = this.uiViewport.getScreenY();
|
||||
@ -458,38 +471,85 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y);
|
||||
|
||||
if (this.activeCommand != null) {
|
||||
this.cursorFrame.setSequence("Target");
|
||||
}
|
||||
else if (down) {
|
||||
if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Down Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Down Right");
|
||||
if (this.activeCommand instanceof AbstractCAbilityBuild) {
|
||||
boolean justLoaded = false;
|
||||
if (this.cursorModelInstance == null) {
|
||||
final MutableObjectData unitData = this.war3MapViewer.getAllObjectData().getUnits();
|
||||
final War3ID buildingTypeId = new War3ID(this.activeCommandOrderId);
|
||||
final String unitModelPath = this.war3MapViewer.getUnitModelPath(unitData.get(buildingTypeId));
|
||||
final MdxModel model = (MdxModel) this.war3MapViewer.load(unitModelPath,
|
||||
this.war3MapViewer.mapPathSolver, this.war3MapViewer.solverParams);
|
||||
this.cursorModelInstance = (MdxComplexInstance) model.addInstance();
|
||||
this.cursorModelInstance.setVertexColor(new float[] { 1, 1, 1, 0.5f });
|
||||
this.cursorModelInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z,
|
||||
this.war3MapViewer.simulation.getGameplayConstants().getBuildingAngle()));
|
||||
this.cursorModelInstance.setAnimationSpeed(0f);
|
||||
justLoaded = true;
|
||||
final CUnitType buildingUnitType = this.war3MapViewer.simulation.getUnitData()
|
||||
.getUnitType(buildingTypeId);
|
||||
this.cursorModelPathing = buildingUnitType.getBuildingPathingPixelMap();
|
||||
}
|
||||
this.war3MapViewer.getClickLocation(clickLocationTemp, baseMouseX,
|
||||
Gdx.graphics.getHeight() - baseMouseY);
|
||||
if (this.cursorModelPathing != null) {
|
||||
clickLocationTemp.x = Math.round(clickLocationTemp.x / 64f) * 64f;
|
||||
clickLocationTemp.y = Math.round(clickLocationTemp.y / 64f) * 64f;
|
||||
clickLocationTemp.z = this.war3MapViewer.terrain.getGroundHeight(clickLocationTemp.x,
|
||||
clickLocationTemp.y);
|
||||
}
|
||||
this.cursorModelInstance.setLocation(clickLocationTemp);
|
||||
SequenceUtils.randomSequence(this.cursorModelInstance, PrimaryTag.STAND);
|
||||
this.cursorFrame.setVisible(false);
|
||||
if (justLoaded) {
|
||||
this.cursorModelInstance.setScene(this.war3MapViewer.worldScene);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Scroll Down");
|
||||
if (this.cursorModelInstance != null) {
|
||||
this.cursorModelInstance.detach();
|
||||
this.cursorModelInstance = null;
|
||||
this.cursorFrame.setVisible(true);
|
||||
}
|
||||
this.cursorFrame.setSequence("Target");
|
||||
}
|
||||
}
|
||||
else if (up) {
|
||||
if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Up Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Up Right");
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Scroll Up");
|
||||
}
|
||||
}
|
||||
else if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Right");
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Normal");
|
||||
if (this.cursorModelInstance != null) {
|
||||
this.cursorModelInstance.detach();
|
||||
this.cursorModelInstance = null;
|
||||
this.cursorFrame.setVisible(true);
|
||||
}
|
||||
if (down) {
|
||||
if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Down Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Down Right");
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Scroll Down");
|
||||
}
|
||||
}
|
||||
else if (up) {
|
||||
if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Up Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Up Right");
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Scroll Up");
|
||||
}
|
||||
}
|
||||
else if (left) {
|
||||
this.cursorFrame.setSequence("Scroll Left");
|
||||
}
|
||||
else if (right) {
|
||||
this.cursorFrame.setSequence("Scroll Right");
|
||||
}
|
||||
else {
|
||||
this.cursorFrame.setSequence("Normal");
|
||||
}
|
||||
}
|
||||
final float groundHeight = Math.max(
|
||||
this.war3MapViewer.terrain.getGroundHeight(this.cameraManager.target.x, this.cameraManager.target.y),
|
||||
@ -866,6 +926,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
}
|
||||
this.selectedSoundCount = 0;
|
||||
if (!shiftDown) {
|
||||
this.subMenuOrderIdStack.clear();
|
||||
this.activeCommandUnit = null;
|
||||
this.activeCommand = null;
|
||||
this.activeCommandOrderId = -1;
|
||||
@ -896,7 +957,12 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
|
||||
portraitTalk();
|
||||
}
|
||||
this.selectedSoundCount = 0;
|
||||
if (this.activeCommand instanceof AbstractCAbilityBuild) {
|
||||
this.war3MapViewer.getUiSounds().getSound("PlaceBuildingDefault")
|
||||
.play(this.uiScene.audioContext, 0, 0);
|
||||
}
|
||||
if (!shiftDown) {
|
||||
this.subMenuOrderIdStack.clear();
|
||||
this.activeCommandUnit = null;
|
||||
this.activeCommand = null;
|
||||
this.activeCommandOrderId = -1;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
||||
|
||||
public interface CommandCardCommandListener {
|
||||
void startUsingAbility(int abilityHandleId, int orderId);
|
||||
void startUsingAbility(int abilityHandleId, int orderId, boolean rightClick);
|
||||
|
||||
void openMenu(int orderId);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user