mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Make UI icons clickable
This commit is contained in:
parent
e919f35904
commit
2173c993bc
@ -10,7 +10,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.badlogic.gdx.ApplicationAdapter;
|
import com.badlogic.gdx.ApplicationAdapter;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Input;
|
|
||||||
import com.badlogic.gdx.InputProcessor;
|
import com.badlogic.gdx.InputProcessor;
|
||||||
import com.badlogic.gdx.audio.Music;
|
import com.badlogic.gdx.audio.Music;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
@ -26,8 +25,6 @@ import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFont
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.math.Matrix4;
|
import com.badlogic.gdx.math.Matrix4;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
|
||||||
import com.badlogic.gdx.math.Vector3;
|
|
||||||
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
import com.badlogic.gdx.utils.viewport.ExtendViewport;
|
||||||
import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor;
|
import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor;
|
||||||
import com.etheller.warsmash.datasources.DataSource;
|
import com.etheller.warsmash.datasources.DataSource;
|
||||||
@ -50,17 +47,15 @@ import com.etheller.warsmash.viewer5.Scene;
|
|||||||
import com.etheller.warsmash.viewer5.TextureMapper;
|
import com.etheller.warsmash.viewer5.TextureMapper;
|
||||||
import com.etheller.warsmash.viewer5.handlers.ModelHandler;
|
import com.etheller.warsmash.viewer5.handlers.ModelHandler;
|
||||||
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset;
|
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates;
|
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderExecutor;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.ui.MeleeUI;
|
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 {
|
public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProvider, InputProcessor {
|
||||||
private static final boolean ENABLE_MUSIC = false;
|
private static final boolean ENABLE_MUSIC = false;
|
||||||
private static final Vector3 clickLocationTemp = new Vector3();
|
|
||||||
private static final Vector2 clickLocationTemp2 = new Vector2();
|
|
||||||
private DataSource codebase;
|
private DataSource codebase;
|
||||||
private War3MapViewer viewer;
|
private War3MapViewer viewer;
|
||||||
private final Rectangle tempRect = new Rectangle();
|
private final Rectangle tempRect = new Rectangle();
|
||||||
@ -73,8 +68,6 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
|||||||
private ExtendViewport uiViewport;
|
private ExtendViewport uiViewport;
|
||||||
private GlyphLayout glyphLayout;
|
private GlyphLayout glyphLayout;
|
||||||
|
|
||||||
private int selectedSoundCount = 0;
|
|
||||||
|
|
||||||
private Texture solidGreenTexture;
|
private Texture solidGreenTexture;
|
||||||
|
|
||||||
private ShapeRenderer shapeRenderer;
|
private ShapeRenderer shapeRenderer;
|
||||||
@ -227,7 +220,12 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
|||||||
music.play();
|
music.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, new CPlayerUnitOrderExecutor(this.viewer.simulation, new CommandErrorListener() {
|
||||||
|
@Override
|
||||||
|
public void showCommandError(final String message) {
|
||||||
|
WarsmashGdxMapGame.this.meleeUI.showCommandError(message);
|
||||||
|
}
|
||||||
|
}));
|
||||||
final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "",
|
final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "",
|
||||||
this.viewer.mapPathSolver, "").addInstance();
|
this.viewer.mapPathSolver, "").addInstance();
|
||||||
libgdxContentInstance.setScene(this.uiScene);
|
libgdxContentInstance.setScene(this.uiScene);
|
||||||
@ -361,85 +359,10 @@ public class WarsmashGdxMapGame extends ApplicationAdapter implements CanvasProv
|
|||||||
@Override
|
@Override
|
||||||
public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) {
|
public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) {
|
||||||
final float worldScreenY = getHeight() - screenY;
|
final float worldScreenY = getHeight() - screenY;
|
||||||
System.out.println(screenX + "," + screenY);
|
|
||||||
|
|
||||||
clickLocationTemp2.x = screenX;
|
if (this.meleeUI.touchDown(screenX, screenY, worldScreenY, button)) {
|
||||||
clickLocationTemp2.y = screenY;
|
|
||||||
this.uiViewport.unproject(clickLocationTemp2);
|
|
||||||
|
|
||||||
if (this.meleeUI.touchDown(clickLocationTemp2.x, clickLocationTemp2.y, button)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (button == Input.Buttons.RIGHT) {
|
|
||||||
final RenderUnit rayPickUnit = this.viewer.rayPickUnit(screenX, worldScreenY);
|
|
||||||
if (this.meleeUI.getSelectedUnit() != null) {
|
|
||||||
if ((rayPickUnit != null) && (rayPickUnit.playerIndex != this.meleeUI.getSelectedUnit().playerIndex)
|
|
||||||
&& !rayPickUnit.getSimulationUnit().isDead()) {
|
|
||||||
if (this.viewer.orderSmart(rayPickUnit)) {
|
|
||||||
if (this.meleeUI.getSelectedUnit().soundset.yesAttack.playUnitResponse(
|
|
||||||
this.viewer.worldScene.audioContext, this.meleeUI.getSelectedUnit())) {
|
|
||||||
this.meleeUI.portraitTalk();
|
|
||||||
}
|
|
||||||
this.selectedSoundCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.viewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
|
||||||
System.out.println(clickLocationTemp);
|
|
||||||
this.viewer.showConfirmation(clickLocationTemp, 0, 1, 0);
|
|
||||||
final int x = (int) ((clickLocationTemp.x - this.viewer.terrain.centerOffset[0]) / 128);
|
|
||||||
final int y = (int) ((clickLocationTemp.y - this.viewer.terrain.centerOffset[1]) / 128);
|
|
||||||
System.out.println(x + "," + y);
|
|
||||||
this.viewer.terrain.logRomp(x, y);
|
|
||||||
if (this.viewer.orderSmart(clickLocationTemp.x, clickLocationTemp.y)) {
|
|
||||||
if (this.meleeUI.getSelectedUnit().soundset.yes.playUnitResponse(
|
|
||||||
this.viewer.worldScene.audioContext, this.meleeUI.getSelectedUnit())) {
|
|
||||||
this.meleeUI.portraitTalk();
|
|
||||||
}
|
|
||||||
this.selectedSoundCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final List<RenderUnit> selectedUnits = this.viewer.selectUnit(screenX, worldScreenY, false);
|
|
||||||
if (!selectedUnits.isEmpty()) {
|
|
||||||
final RenderUnit unit = selectedUnits.get(0);
|
|
||||||
final boolean selectionChanged = this.meleeUI.getSelectedUnit() != unit;
|
|
||||||
boolean playedNewSound = false;
|
|
||||||
if (selectionChanged) {
|
|
||||||
this.selectedSoundCount = 0;
|
|
||||||
}
|
|
||||||
if (unit.soundset != null) {
|
|
||||||
UnitSound ackSoundToPlay = unit.soundset.what;
|
|
||||||
final int pissedSoundCount = unit.soundset.pissed.getSoundCount();
|
|
||||||
int soundIndex;
|
|
||||||
if ((this.selectedSoundCount >= 3) && (pissedSoundCount > 0)) {
|
|
||||||
soundIndex = this.selectedSoundCount - 3;
|
|
||||||
ackSoundToPlay = unit.soundset.pissed;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount());
|
|
||||||
}
|
|
||||||
if (ackSoundToPlay.playUnitResponse(this.viewer.worldScene.audioContext, unit, soundIndex)) {
|
|
||||||
this.selectedSoundCount++;
|
|
||||||
if ((this.selectedSoundCount - 3) >= pissedSoundCount) {
|
|
||||||
this.selectedSoundCount = 0;
|
|
||||||
}
|
|
||||||
playedNewSound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectionChanged) {
|
|
||||||
this.meleeUI.selectUnit(unit);
|
|
||||||
}
|
|
||||||
if (playedNewSound) {
|
|
||||||
this.meleeUI.portraitTalk();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.meleeUI.selectUnit(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,19 @@ public final class GameUI extends AbstractUIFrame implements UIFrame {
|
|||||||
return textureFrame;
|
return textureFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StringFrame createStringFrame(final String name, final UIFrame parent, final Color color,
|
||||||
|
final TextJustify justifyH, final TextJustify justifyV, final float fdfFontSize) {
|
||||||
|
this.fontParam.size = (int) convertY(this.viewport, fdfFontSize);
|
||||||
|
if (this.fontParam.size == 0) {
|
||||||
|
this.fontParam.size = 24;
|
||||||
|
}
|
||||||
|
final BitmapFont frameFont = this.fontGenerator.generateFont(this.fontParam);
|
||||||
|
final StringFrame stringFrame = new StringFrame(name, parent, color, justifyH, justifyV, frameFont);
|
||||||
|
this.nameToFrame.put(name, stringFrame);
|
||||||
|
add(stringFrame);
|
||||||
|
return stringFrame;
|
||||||
|
}
|
||||||
|
|
||||||
public UIFrame inflate(final FrameDefinition frameDefinition, final UIFrame parent,
|
public UIFrame inflate(final FrameDefinition frameDefinition, final UIFrame parent,
|
||||||
final FrameDefinition parentDefinitionIfAvailable) {
|
final FrameDefinition parentDefinitionIfAvailable) {
|
||||||
UIFrame inflatedFrame = null;
|
UIFrame inflatedFrame = null;
|
||||||
|
@ -81,17 +81,16 @@ import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataU
|
|||||||
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.CUnitClassification;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitFilterFunction;
|
||||||
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.CAbilityAttack;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.CWidgetAbilityTargetCheckReceiver;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.CWidgetAbilityTargetCheckReceiver;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.PointAbilityTargetCheckReceiver;
|
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController;
|
||||||
|
|
||||||
import mpq.MPQArchive;
|
import mpq.MPQArchive;
|
||||||
@ -1135,6 +1134,10 @@ public class War3MapViewer extends ModelViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public RenderUnit rayPickUnit(final float x, final float y) {
|
public RenderUnit rayPickUnit(final float x, final float y) {
|
||||||
|
return rayPickUnit(x, y, CUnitFilterFunction.ACCEPT_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderUnit rayPickUnit(final float x, final float y, final CUnitFilterFunction filter) {
|
||||||
final float[] ray = rayHeap;
|
final float[] ray = rayHeap;
|
||||||
mousePosHeap.set(x, y);
|
mousePosHeap.set(x, y);
|
||||||
this.worldScene.camera.screenToWorldRay(ray, mousePosHeap);
|
this.worldScene.camera.screenToWorldRay(ray, mousePosHeap);
|
||||||
@ -1146,7 +1149,11 @@ public class War3MapViewer extends ModelViewer {
|
|||||||
final MdxComplexInstance instance = unit.instance;
|
final MdxComplexInstance instance = unit.instance;
|
||||||
if (instance.isVisible(this.worldScene.camera) && instance.intersectRayWithCollision(gdxRayHeap,
|
if (instance.isVisible(this.worldScene.camera) && instance.intersectRayWithCollision(gdxRayHeap,
|
||||||
intersectionHeap, unit.getSimulationUnit().getUnitType().isBuilding())) {
|
intersectionHeap, unit.getSimulationUnit().getUnitType().isBuilding())) {
|
||||||
entity = unit;
|
if (filter.call(unit.getSimulationUnit())) {
|
||||||
|
if ((entity == null) || (entity.instance.depth > instance.depth)) {
|
||||||
|
entity = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return entity;
|
return entity;
|
||||||
@ -1235,41 +1242,6 @@ public class War3MapViewer extends ModelViewer {
|
|||||||
return (numElements < 0) ? 1 : (numElements >= MAXIMUM_ACCEPTED) ? MAXIMUM_ACCEPTED : numElements + 1;
|
return (numElements < 0) ? 1 : (numElements >= MAXIMUM_ACCEPTED) ? MAXIMUM_ACCEPTED : numElements + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean orderSmart(final float x, final float y) {
|
|
||||||
mousePosHeap.x = x;
|
|
||||||
mousePosHeap.y = y;
|
|
||||||
boolean ordered = false;
|
|
||||||
for (final RenderUnit unit : this.selected) {
|
|
||||||
for (final CAbility ability : unit.getSimulationUnit().getAbilities()) {
|
|
||||||
if (ability instanceof CAbilityMove) {
|
|
||||||
ability.checkCanUse(this.simulation, unit.getSimulationUnit(), OrderIds.smart,
|
|
||||||
BooleanAbilityActivationReceiver.INSTANCE);
|
|
||||||
if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) {
|
|
||||||
ability.checkCanTarget(this.simulation, unit.getSimulationUnit(), OrderIds.smart, mousePosHeap,
|
|
||||||
PointAbilityTargetCheckReceiver.INSTANCE);
|
|
||||||
final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
|
||||||
if (target != null) {
|
|
||||||
ability.onOrder(this.simulation, unit.getSimulationUnit(), OrderIds.smart, mousePosHeap,
|
|
||||||
false);
|
|
||||||
ordered = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Target not valid.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not ok to use.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.err.println("Ability not move.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean orderSmart(final RenderUnit target) {
|
public boolean orderSmart(final RenderUnit target) {
|
||||||
boolean ordered = false;
|
boolean ordered = false;
|
||||||
for (final RenderUnit unit : this.selected) {
|
for (final RenderUnit unit : this.selected) {
|
||||||
|
@ -34,5 +34,5 @@ public interface CommandButtonListener {
|
|||||||
// int getButtonPositionY();
|
// int getButtonPositionY();
|
||||||
//
|
//
|
||||||
// int getOrderId();
|
// int getOrderId();
|
||||||
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int orderId);
|
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,6 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
|
|||||||
|
|
||||||
private void addCommandButton(final IconUI iconUI, final int handleId, final int orderId) {
|
private void addCommandButton(final IconUI iconUI, final int handleId, final int orderId) {
|
||||||
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
|
||||||
iconUI.getIcon(), orderId);
|
iconUI.getIcon(), handleId, orderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation;
|
|||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
@ -14,6 +16,7 @@ import com.etheller.warsmash.units.manager.MutableObjectData;
|
|||||||
import com.etheller.warsmash.util.War3ID;
|
import com.etheller.warsmash.util.War3ID;
|
||||||
import com.etheller.warsmash.util.WarsmashConstants;
|
import com.etheller.warsmash.util.WarsmashConstants;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid;
|
import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile;
|
||||||
@ -42,6 +45,8 @@ public class CSimulation {
|
|||||||
private final CGameplayConstants gameplayConstants;
|
private final CGameplayConstants gameplayConstants;
|
||||||
private final Random seededRandom;
|
private final Random seededRandom;
|
||||||
private float currentGameDayTimeElapsed;
|
private float currentGameDayTimeElapsed;
|
||||||
|
private final Map<Integer, CUnit> handleIdToUnit = new HashMap<>();
|
||||||
|
private final Map<Integer, CAbility> handleIdToAbility = new HashMap<>();
|
||||||
|
|
||||||
public CSimulation(final DataTable miscData, final MutableObjectData parsedUnitData,
|
public CSimulation(final DataTable miscData, final MutableObjectData parsedUnitData,
|
||||||
final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController,
|
final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController,
|
||||||
@ -106,10 +111,22 @@ public class CSimulation {
|
|||||||
final CUnit unit = this.unitData.create(this, playerIndex, typeId, x, y, facing, buildingPathingPixelMap,
|
final CUnit unit = this.unitData.create(this, playerIndex, typeId, x, y, facing, buildingPathingPixelMap,
|
||||||
this.simulationRenderController, this.handleIdAllocator);
|
this.simulationRenderController, this.handleIdAllocator);
|
||||||
this.units.add(unit);
|
this.units.add(unit);
|
||||||
|
this.handleIdToUnit.put(unit.getHandleId(), unit);
|
||||||
|
for (final CAbility ability : unit.getAbilities()) {
|
||||||
|
this.handleIdToAbility.put(ability.getHandleId(), ability);
|
||||||
|
}
|
||||||
this.worldCollision.addUnit(unit);
|
this.worldCollision.addUnit(unit);
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CUnit getUnit(final int handleId) {
|
||||||
|
return this.handleIdToUnit.get(handleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CAbility getAbility(final int handleId) {
|
||||||
|
return this.handleIdToAbility.get(handleId);
|
||||||
|
}
|
||||||
|
|
||||||
public CAttackProjectile createProjectile(final CUnit source, final float launchX, final float launchY,
|
public CAttackProjectile createProjectile(final CUnit source, final float launchX, final float launchY,
|
||||||
final float launchFacing, final CUnitAttackMissile attack, final CWidget target, final float damage,
|
final float launchFacing, final CUnitAttackMissile attack, final CWidget target, final float damage,
|
||||||
final int bounceIndex) {
|
final int bounceIndex) {
|
||||||
@ -142,6 +159,10 @@ public class CSimulation {
|
|||||||
final CUnit unit = unitIterator.next();
|
final CUnit unit = unitIterator.next();
|
||||||
if (unit.update(this)) {
|
if (unit.update(this)) {
|
||||||
unitIterator.remove();
|
unitIterator.remove();
|
||||||
|
for (final CAbility ability : unit.getAbilities()) {
|
||||||
|
this.handleIdToAbility.remove(ability.getHandleId());
|
||||||
|
}
|
||||||
|
this.handleIdToUnit.remove(unit.getHandleId());
|
||||||
this.simulationRenderController.removeUnit(unit);
|
this.simulationRenderController.removeUnit(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation;
|
||||||
|
|
||||||
|
public interface CUnitFilterFunction {
|
||||||
|
boolean call(CUnit unit);
|
||||||
|
|
||||||
|
CUnitFilterFunction ACCEPT_ALL = new CUnitFilterFunction() {
|
||||||
|
@Override
|
||||||
|
public boolean call(final CUnit unit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
|
||||||
|
|
||||||
public interface CPlayerController {
|
|
||||||
boolean issueTargetOrder(int unitHandleId, int orderId, int targetHandleId);
|
|
||||||
|
|
||||||
boolean issuePointOrder(int unitHandleId, int orderId, float x, float y);
|
|
||||||
|
|
||||||
boolean issueImmediateOrder(int unitHandleId, int orderId);
|
|
||||||
}
|
|
@ -0,0 +1,101 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
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.CAbility;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener;
|
||||||
|
|
||||||
|
public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener {
|
||||||
|
private final CSimulation game;
|
||||||
|
private final CommandErrorListener errorListener;
|
||||||
|
private final StringMsgTargetCheckReceiver<?> targetCheckReceiver = new StringMsgTargetCheckReceiver<>();
|
||||||
|
private final StringMsgAbilityActivationReceiver abilityActivationReceiver = new StringMsgAbilityActivationReceiver();
|
||||||
|
|
||||||
|
private <T> StringMsgTargetCheckReceiver<T> targetCheckReceiver() {
|
||||||
|
return (StringMsgTargetCheckReceiver<T>) this.targetCheckReceiver.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CPlayerUnitOrderExecutor(final CSimulation game, final CommandErrorListener errorListener) {
|
||||||
|
this.game = game;
|
||||||
|
this.errorListener = errorListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||||
|
final int targetHandleId, final boolean queue) {
|
||||||
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
|
final CAbility ability = this.game.getAbility(abilityHandleId);
|
||||||
|
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
||||||
|
if (this.abilityActivationReceiver.isUseOk()) {
|
||||||
|
final CUnit target = this.game.getUnit(targetHandleId);
|
||||||
|
final StringMsgTargetCheckReceiver<CWidget> targetReceiver = this.<CWidget>targetCheckReceiver();
|
||||||
|
ability.checkCanTarget(this.game, unit, orderId, target, targetReceiver);
|
||||||
|
if (targetReceiver.getTarget() != null) {
|
||||||
|
ability.onOrder(this.game, unit, orderId, target, queue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(targetReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x,
|
||||||
|
final float y, final boolean queue) {
|
||||||
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
|
final CAbility ability = this.game.getAbility(abilityHandleId);
|
||||||
|
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
||||||
|
if (this.abilityActivationReceiver.isUseOk()) {
|
||||||
|
final Vector2 target = new Vector2(x, y);
|
||||||
|
final StringMsgTargetCheckReceiver<Vector2> targetReceiver = this.<Vector2>targetCheckReceiver();
|
||||||
|
ability.checkCanTarget(this.game, unit, orderId, target, targetReceiver);
|
||||||
|
if (targetReceiver.getTarget() != null) {
|
||||||
|
ability.onOrder(this.game, unit, orderId, target, queue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(targetReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId,
|
||||||
|
final boolean queue) {
|
||||||
|
final CUnit unit = this.game.getUnit(unitHandleId);
|
||||||
|
final CAbility ability = this.game.getAbility(abilityHandleId);
|
||||||
|
ability.checkCanUse(this.game, unit, orderId, this.abilityActivationReceiver.reset());
|
||||||
|
if (this.abilityActivationReceiver.isUseOk()) {
|
||||||
|
final StringMsgTargetCheckReceiver<Void> targetReceiver = this.<Void>targetCheckReceiver();
|
||||||
|
ability.checkCanTargetNoTarget(this.game, unit, orderId, targetReceiver);
|
||||||
|
if (targetReceiver.getTarget() != null) {
|
||||||
|
ability.onOrderNoTarget(this.game, unit, orderId, queue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(targetReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.errorListener.showCommandError(this.abilityActivationReceiver.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players;
|
||||||
|
|
||||||
|
public interface CPlayerUnitOrderListener {
|
||||||
|
boolean issueTargetOrder(int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, boolean queue);
|
||||||
|
|
||||||
|
boolean issuePointOrder(int unitHandleId, int abilityHandleId, int orderId, float x, float y, boolean queue);
|
||||||
|
|
||||||
|
// Below: used for "DROP ITEM AT POINT" ????
|
||||||
|
// boolean issueTargetAndPointOrder(int unitHandleId, int orderId, int targetHandleId, float x, float y);
|
||||||
|
|
||||||
|
boolean issueImmediateOrder(int unitHandleId, int abilityHandleId, int orderId, boolean queue);
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||||
|
|
||||||
|
public final class BooleanAbilityTargetCheckReceiver<TARGET_TYPE> implements AbilityTargetCheckReceiver<TARGET_TYPE> {
|
||||||
|
private static final BooleanAbilityTargetCheckReceiver<?> INSTANCE = new BooleanAbilityTargetCheckReceiver<>();
|
||||||
|
|
||||||
|
public static <T> BooleanAbilityTargetCheckReceiver<T> getInstance() {
|
||||||
|
return (BooleanAbilityTargetCheckReceiver<T>) INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean targetable = false;
|
||||||
|
|
||||||
|
public boolean isTargetable() {
|
||||||
|
return this.targetable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanAbilityTargetCheckReceiver<TARGET_TYPE> reset() {
|
||||||
|
this.targetable = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetOk(final TARGET_TYPE target) {
|
||||||
|
this.targetable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mustTargetTeamType(final TeamType correctType) {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mustTargetType(final TargetType correctType) {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetOutsideRange(final double howMuch) {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notAnActiveAbility() {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetNotVisible() {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetTooComplicated() {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetNotInPlayableMap() {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void orderIdNotAccepted() {
|
||||||
|
this.targetable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||||
|
|
||||||
|
public class StringMsgAbilityActivationReceiver implements AbilityActivationReceiver {
|
||||||
|
private static final StringMsgAbilityActivationReceiver INSTANCE = new StringMsgAbilityActivationReceiver();
|
||||||
|
|
||||||
|
public static StringMsgAbilityActivationReceiver getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
private boolean useOk = false;
|
||||||
|
|
||||||
|
public StringMsgAbilityActivationReceiver reset() {
|
||||||
|
this.message = null;
|
||||||
|
this.useOk = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseOk() {
|
||||||
|
return this.useOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void useOk() {
|
||||||
|
this.useOk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notEnoughResources(final ResourceType resource, final int amount) {
|
||||||
|
this.message = "NOTEXTERN: Requires " + amount + " " + resource.name().toLowerCase() + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notAnActiveAbility() {
|
||||||
|
this.message = "NOTEXTERN: Not an active ability.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void missingRequirement(final String name) {
|
||||||
|
this.message = "NOTEXTERN: Requires " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cargoCapacityUnavailable() {
|
||||||
|
this.message = "NOTEXTERN: Cargo capacity unavailable.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void casterMovementDisabled() {
|
||||||
|
this.message = "NOTEXTERN: Caster movement disabled.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util;
|
||||||
|
|
||||||
|
public final class StringMsgTargetCheckReceiver<TARGET_TYPE> implements AbilityTargetCheckReceiver<TARGET_TYPE> {
|
||||||
|
private static final StringMsgTargetCheckReceiver<?> INSTANCE = new StringMsgTargetCheckReceiver<>();
|
||||||
|
|
||||||
|
public static <T> StringMsgTargetCheckReceiver<T> getInstance() {
|
||||||
|
return (StringMsgTargetCheckReceiver<T>) INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TARGET_TYPE target;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public TARGET_TYPE getTarget() {
|
||||||
|
return this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringMsgTargetCheckReceiver<TARGET_TYPE> reset() {
|
||||||
|
this.target = null;
|
||||||
|
this.message = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetOk(final TARGET_TYPE target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mustTargetTeamType(final TeamType correctType) {
|
||||||
|
switch (correctType) {
|
||||||
|
case ALLIED:
|
||||||
|
this.message = "NOTEXTERN: Must target an allied unit.";
|
||||||
|
break;
|
||||||
|
case ENEMY:
|
||||||
|
this.message = "NOTEXTERN: Must target an enemy unit.";
|
||||||
|
break;
|
||||||
|
case PLAYER_UNITS:
|
||||||
|
this.message = "NOTEXTERN: Unable to target a unit you do not control.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.message = "NOTEXTERN: Must target team type: " + correctType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mustTargetType(final TargetType correctType) {
|
||||||
|
switch (correctType) {
|
||||||
|
case POINT:
|
||||||
|
this.message = "NOTEXTERN: Must target a point.";
|
||||||
|
break;
|
||||||
|
case UNIT:
|
||||||
|
this.message = "NOTEXTERN: Must target a unit.";
|
||||||
|
break;
|
||||||
|
case UNIT_OR_POINT:
|
||||||
|
this.message = "NOTEXTERN: Must target a unit or point.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.message = "NOTEXTERN: Must target type: " + correctType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetOutsideRange(final double howMuch) {
|
||||||
|
this.message = "NOTEXTERN: Target is outside range.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notAnActiveAbility() {
|
||||||
|
this.message = "NOTEXTERN: Not an active ability.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetNotVisible() {
|
||||||
|
this.message = "NOTEXTERN: Target is not visible.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetTooComplicated() {
|
||||||
|
this.message = "NOTEXTERN: Target is too complicated.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetNotInPlayableMap() {
|
||||||
|
this.message = "NOTEXTERN: Target is not within the designed combat area.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void orderIdNotAccepted() {
|
||||||
|
this.message = "NOTEXTERN: OrderID not accepted.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||||
@ -11,6 +12,7 @@ import com.etheller.warsmash.parsers.fdf.frames.TextureFrame;
|
|||||||
import com.etheller.warsmash.parsers.fdf.frames.UIFrame;
|
import com.etheller.warsmash.parsers.fdf.frames.UIFrame;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButton;
|
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButton;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandCardCommandListener;
|
||||||
|
|
||||||
public class CommandCardIcon extends AbstractRenderableFrame {
|
public class CommandCardIcon extends AbstractRenderableFrame {
|
||||||
|
|
||||||
@ -18,9 +20,14 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
private SpriteFrame cooldownFrame;
|
private SpriteFrame cooldownFrame;
|
||||||
private SpriteFrame autocastFrame;
|
private SpriteFrame autocastFrame;
|
||||||
private CommandButton commandButton;
|
private CommandButton commandButton;
|
||||||
|
private int abilityHandleId;
|
||||||
|
private int orderId;
|
||||||
|
private final CommandCardCommandListener commandCardCommandListener;
|
||||||
|
|
||||||
public CommandCardIcon(final String name, final UIFrame parent) {
|
public CommandCardIcon(final String name, final UIFrame parent,
|
||||||
|
final CommandCardCommandListener commandCardCommandListener) {
|
||||||
super(name, parent);
|
super(name, parent);
|
||||||
|
this.commandCardCommandListener = commandCardCommandListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(final TextureFrame iconFrame, final SpriteFrame cooldownFrame, final SpriteFrame autocastFrame) {
|
public void set(final TextureFrame iconFrame, final SpriteFrame cooldownFrame, final SpriteFrame autocastFrame) {
|
||||||
@ -57,11 +64,13 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommandButtonData(final Texture texture, final int orderId) {
|
public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId) {
|
||||||
this.iconFrame.setVisible(true);
|
this.iconFrame.setVisible(true);
|
||||||
this.cooldownFrame.setVisible(false);
|
this.cooldownFrame.setVisible(false);
|
||||||
this.autocastFrame.setVisible(false);
|
this.autocastFrame.setVisible(false);
|
||||||
this.iconFrame.setTexture(texture);
|
this.iconFrame.setTexture(texture);
|
||||||
|
this.abilityHandleId = abilityHandleId;
|
||||||
|
this.orderId = orderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,6 +90,12 @@ public class CommandCardIcon extends AbstractRenderableFrame {
|
|||||||
@Override
|
@Override
|
||||||
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
public UIFrame touchDown(final float screenX, final float screenY, final int button) {
|
||||||
if (this.renderBounds.contains(screenX, screenY)) {
|
if (this.renderBounds.contains(screenX, screenY)) {
|
||||||
|
if (button == Input.Buttons.LEFT) {
|
||||||
|
this.commandCardCommandListener.startUsingAbility(this.abilityHandleId, this.orderId);
|
||||||
|
}
|
||||||
|
else if (button == Input.Buttons.RIGHT) {
|
||||||
|
this.commandCardCommandListener.toggleAutoCastAbility(this.abilityHandleId);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Input;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
@ -13,11 +15,13 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
import com.badlogic.gdx.math.Rectangle;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.viewport.Viewport;
|
import com.badlogic.gdx.utils.viewport.Viewport;
|
||||||
import com.etheller.warsmash.datasources.DataSource;
|
import com.etheller.warsmash.datasources.DataSource;
|
||||||
import com.etheller.warsmash.parsers.fdf.GameUI;
|
import com.etheller.warsmash.parsers.fdf.GameUI;
|
||||||
import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition;
|
import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition;
|
||||||
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint;
|
||||||
|
import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify;
|
||||||
import com.etheller.warsmash.parsers.fdf.frames.SetPoint;
|
import com.etheller.warsmash.parsers.fdf.frames.SetPoint;
|
||||||
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame;
|
||||||
import com.etheller.warsmash.parsers.fdf.frames.StringFrame;
|
import com.etheller.warsmash.parsers.fdf.frames.StringFrame;
|
||||||
@ -34,6 +38,7 @@ import com.etheller.warsmash.viewer5.handlers.mdx.ReplaceableIds;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode;
|
||||||
import com.etheller.warsmash.viewer5.handlers.tga.TgaFile;
|
import com.etheller.warsmash.viewer5.handlers.tga.TgaFile;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset;
|
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates;
|
import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates;
|
||||||
@ -41,18 +46,34 @@ import com.etheller.warsmash.viewer5.handlers.w3x.camera.GameCameraManager;
|
|||||||
import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager;
|
import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit;
|
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButtonListener;
|
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButtonListener;
|
||||||
|
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.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.CUnitStateListener;
|
||||||
|
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.combat.CAttackType;
|
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.CDefenseType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack;
|
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.CPlayerUnitOrderListener;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityTargetCheckReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.CWidgetAbilityTargetCheckReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.PointAbilityTargetCheckReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandCardCommandListener;
|
||||||
|
|
||||||
public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
public class MeleeUI implements CUnitStateListener, CommandButtonListener, CommandCardCommandListener {
|
||||||
private static final int COMMAND_CARD_WIDTH = 4;
|
private static final int COMMAND_CARD_WIDTH = 4;
|
||||||
private static final int COMMAND_CARD_HEIGHT = 3;
|
private static final int COMMAND_CARD_HEIGHT = 3;
|
||||||
|
|
||||||
private static final Vector2 screenCoordsVector = new Vector2();
|
private static final Vector2 screenCoordsVector = new Vector2();
|
||||||
|
private static final Vector3 clickLocationTemp = new Vector3();
|
||||||
|
private static final Vector2 clickLocationTemp2 = new Vector2();
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final Viewport uiViewport;
|
private final Viewport uiViewport;
|
||||||
private final FreeTypeFontGenerator fontGenerator;
|
private final FreeTypeFontGenerator fontGenerator;
|
||||||
@ -104,11 +125,20 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
private UIFrame inventoryCover;
|
private UIFrame inventoryCover;
|
||||||
private SpriteFrame cursorFrame;
|
private SpriteFrame cursorFrame;
|
||||||
private MeleeUIMinimap meleeUIMinimap;
|
private MeleeUIMinimap meleeUIMinimap;
|
||||||
|
private final CPlayerUnitOrderListener unitOrderListener;
|
||||||
|
private StringFrame errorMessageFrame;
|
||||||
|
|
||||||
|
private CAbilityView activeCommand;
|
||||||
|
private int activeCommandOrderId;
|
||||||
|
private RenderUnit activeCommandUnit;
|
||||||
|
|
||||||
|
private int selectedSoundCount = 0;
|
||||||
|
private final ActiveCommandUnitTargetFilter activeCommandUnitTargetFilter;
|
||||||
|
|
||||||
public MeleeUI(final DataSource dataSource, final Viewport uiViewport, final FreeTypeFontGenerator fontGenerator,
|
public MeleeUI(final DataSource dataSource, final Viewport uiViewport, final FreeTypeFontGenerator fontGenerator,
|
||||||
final Scene uiScene, final Scene portraitScene, final CameraPreset[] cameraPresets,
|
final Scene uiScene, final Scene portraitScene, final CameraPreset[] cameraPresets,
|
||||||
final CameraRates cameraRates, final War3MapViewer war3MapViewer,
|
final CameraRates cameraRates, final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener,
|
||||||
final RootFrameListener rootFrameListener) {
|
final CPlayerUnitOrderListener unitOrderListener) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.uiViewport = uiViewport;
|
this.uiViewport = uiViewport;
|
||||||
this.fontGenerator = fontGenerator;
|
this.fontGenerator = fontGenerator;
|
||||||
@ -116,6 +146,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
this.portraitScene = portraitScene;
|
this.portraitScene = portraitScene;
|
||||||
this.war3MapViewer = war3MapViewer;
|
this.war3MapViewer = war3MapViewer;
|
||||||
this.rootFrameListener = rootFrameListener;
|
this.rootFrameListener = rootFrameListener;
|
||||||
|
this.unitOrderListener = unitOrderListener;
|
||||||
|
|
||||||
this.cameraManager = new GameCameraManager(cameraPresets, cameraRates);
|
this.cameraManager = new GameCameraManager(cameraPresets, cameraRates);
|
||||||
|
|
||||||
@ -127,6 +158,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
|
|
||||||
this.activeButtonTexture = ImageUtils.getBLPTexture(war3MapViewer.mapMpq,
|
this.activeButtonTexture = ImageUtils.getBLPTexture(war3MapViewer.mapMpq,
|
||||||
"UI\\Widgets\\Console\\Human\\CommandButton\\human-activebutton.blp");
|
"UI\\Widgets\\Console\\Human\\CommandButton\\human-activebutton.blp");
|
||||||
|
this.activeCommandUnitTargetFilter = new ActiveCommandUnitTargetFilter();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +202,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
// =================================
|
// =================================
|
||||||
// Load skins and templates
|
// Load skins and templates
|
||||||
// =================================
|
// =================================
|
||||||
this.rootFrame = new GameUI(this.dataSource, GameUI.loadSkin(this.dataSource, 3), this.uiViewport,
|
this.rootFrame = new GameUI(this.dataSource, GameUI.loadSkin(this.dataSource, 0), this.uiViewport,
|
||||||
this.fontGenerator, this.uiScene, this.war3MapViewer);
|
this.fontGenerator, this.uiScene, this.war3MapViewer);
|
||||||
this.rootFrameListener.onCreate(this.rootFrame);
|
this.rootFrameListener.onCreate(this.rootFrame);
|
||||||
try {
|
try {
|
||||||
@ -259,11 +291,17 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
|
|
||||||
this.inventoryCover = this.rootFrame.createSimpleFrame("SmashConsoleInventoryCover", this.rootFrame, 0);
|
this.inventoryCover = this.rootFrame.createSimpleFrame("SmashConsoleInventoryCover", this.rootFrame, 0);
|
||||||
|
|
||||||
|
this.errorMessageFrame = this.rootFrame.createStringFrame("SmashErrorMessageFrame", this.consoleUI,
|
||||||
|
new Color(0xFFFFCC00), TextJustify.LEFT, TextJustify.MIDDLE, 0.014f);
|
||||||
|
this.errorMessageFrame.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT,
|
||||||
|
GameUI.convertX(this.uiViewport, 0.275f), GameUI.convertY(this.uiViewport, 0.275f)));
|
||||||
|
this.errorMessageFrame.setWidth(GameUI.convertX(this.uiViewport, 0.25f));
|
||||||
|
|
||||||
int commandButtonIndex = 0;
|
int commandButtonIndex = 0;
|
||||||
for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) {
|
for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) {
|
||||||
for (int i = 0; i < COMMAND_CARD_WIDTH; i++) {
|
for (int i = 0; i < COMMAND_CARD_WIDTH; i++) {
|
||||||
final CommandCardIcon commandCardIcon = new CommandCardIcon("SmashCommandButton_" + commandButtonIndex,
|
final CommandCardIcon commandCardIcon = new CommandCardIcon("SmashCommandButton_" + commandButtonIndex,
|
||||||
this.rootFrame);
|
this.rootFrame, this);
|
||||||
this.rootFrame.add(commandCardIcon);
|
this.rootFrame.add(commandCardIcon);
|
||||||
final TextureFrame iconFrame = this.rootFrame.createTextureFrame(
|
final TextureFrame iconFrame = this.rootFrame.createTextureFrame(
|
||||||
"SmashCommandButton_" + (commandButtonIndex) + "_Icon", this.rootFrame, false, null);
|
"SmashCommandButton_" + (commandButtonIndex) + "_Icon", this.rootFrame, false, null);
|
||||||
@ -271,17 +309,20 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
"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);
|
||||||
iconFrame.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT,
|
commandCardIcon.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT,
|
||||||
GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)),
|
GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)),
|
||||||
GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j))));
|
GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j))));
|
||||||
|
commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||||
|
commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||||
|
iconFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||||
iconFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
iconFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||||
iconFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
iconFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||||
iconFrame.setTexture(ImageUtils.DEFAULT_ICON_PATH, this.rootFrame);
|
iconFrame.setTexture(ImageUtils.DEFAULT_ICON_PATH, this.rootFrame);
|
||||||
cooldownFrame.addSetPoint(new SetPoint(FramePoint.CENTER, iconFrame, FramePoint.CENTER, 0, 0));
|
cooldownFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||||
this.rootFrame.setSpriteFrameModel(cooldownFrame, this.rootFrame.getSkinField("CommandButtonCooldown"));
|
this.rootFrame.setSpriteFrameModel(cooldownFrame, this.rootFrame.getSkinField("CommandButtonCooldown"));
|
||||||
cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||||
cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||||
autocastFrame.addSetPoint(new SetPoint(FramePoint.CENTER, iconFrame, FramePoint.CENTER, 0, 0));
|
autocastFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0));
|
||||||
this.rootFrame.setSpriteFrameModel(autocastFrame, this.rootFrame.getSkinField("CommandButtonAutocast"));
|
this.rootFrame.setSpriteFrameModel(autocastFrame, this.rootFrame.getSkinField("CommandButtonAutocast"));
|
||||||
autocastFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
autocastFrame.setWidth(GameUI.convertX(this.uiViewport, 0.039f));
|
||||||
autocastFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
autocastFrame.setHeight(GameUI.convertY(this.uiViewport, 0.039f));
|
||||||
@ -305,6 +346,51 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
selectUnit(null);
|
selectUnit(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUsingAbility(final int abilityHandleId, final int orderId) {
|
||||||
|
// TODO not O(N)
|
||||||
|
CAbilityView abilityToUse = null;
|
||||||
|
for (final CAbility ability : this.selectedUnit.getSimulationUnit().getAbilities()) {
|
||||||
|
if (ability.getHandleId() == abilityHandleId) {
|
||||||
|
abilityToUse = ability;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (abilityToUse != null) {
|
||||||
|
final StringMsgAbilityActivationReceiver stringMsgActivationReceiver = StringMsgAbilityActivationReceiver
|
||||||
|
.getInstance().reset();
|
||||||
|
abilityToUse.checkCanUse(this.war3MapViewer.simulation, this.selectedUnit.getSimulationUnit(), orderId,
|
||||||
|
stringMsgActivationReceiver);
|
||||||
|
if (!stringMsgActivationReceiver.isUseOk()) {
|
||||||
|
showCommandError(stringMsgActivationReceiver.getMessage());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final BooleanAbilityTargetCheckReceiver<Void> noTargetReceiver = BooleanAbilityTargetCheckReceiver
|
||||||
|
.<Void>getInstance().reset();
|
||||||
|
abilityToUse.checkCanTargetNoTarget(this.war3MapViewer.simulation,
|
||||||
|
this.selectedUnit.getSimulationUnit(), orderId, noTargetReceiver);
|
||||||
|
if (noTargetReceiver.isTargetable()) {
|
||||||
|
this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(),
|
||||||
|
abilityHandleId, orderId, isShiftDown());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.activeCommand = abilityToUse;
|
||||||
|
this.activeCommandOrderId = orderId;
|
||||||
|
this.activeCommandUnit = this.selectedUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showCommandError(final String message) {
|
||||||
|
this.errorMessageFrame.setText(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toggleAutoCastAbility(final int abilityHandleId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void update(final float deltaTime) {
|
public void update(final float deltaTime) {
|
||||||
this.portrait.update();
|
this.portrait.update();
|
||||||
|
|
||||||
@ -329,7 +415,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
this.cursorFrame.setFramePointX(FramePoint.LEFT, screenCoordsVector.x);
|
this.cursorFrame.setFramePointX(FramePoint.LEFT, screenCoordsVector.x);
|
||||||
this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y);
|
this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y);
|
||||||
|
|
||||||
if (down) {
|
if (this.activeCommand != null) {
|
||||||
|
this.cursorFrame.setSequence("Target");
|
||||||
|
}
|
||||||
|
else if (down) {
|
||||||
if (left) {
|
if (left) {
|
||||||
this.cursorFrame.setSequence("Scroll Down Left");
|
this.cursorFrame.setSequence("Scroll Down Left");
|
||||||
}
|
}
|
||||||
@ -383,6 +472,17 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
this.portrait.talk();
|
this.portrait.talk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class ActiveCommandUnitTargetFilter implements CUnitFilterFunction {
|
||||||
|
@Override
|
||||||
|
public boolean call(final CUnit unit) {
|
||||||
|
final BooleanAbilityTargetCheckReceiver<CWidget> targetReceiver = BooleanAbilityTargetCheckReceiver
|
||||||
|
.<CWidget>getInstance();
|
||||||
|
MeleeUI.this.activeCommand.checkCanTarget(MeleeUI.this.war3MapViewer.simulation, unit,
|
||||||
|
MeleeUI.this.activeCommandOrderId, unit, targetReceiver);
|
||||||
|
return targetReceiver.isTargetable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class Portrait {
|
private static final class Portrait {
|
||||||
private MdxComplexInstance modelInstance;
|
private MdxComplexInstance modelInstance;
|
||||||
private final PortraitCameraManager portraitCameraManager;
|
private final PortraitCameraManager portraitCameraManager;
|
||||||
@ -539,11 +639,10 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon,
|
public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon,
|
||||||
final int orderId) {
|
final int abilityHandleId, final int orderId) {
|
||||||
final int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX));
|
final int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX));
|
||||||
final int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY));
|
final int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY));
|
||||||
this.commandCard[y][x].setCommandButtonData(icon, orderId);
|
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resize(final Rectangle viewport) {
|
public void resize(final Rectangle viewport) {
|
||||||
@ -649,17 +748,191 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener {
|
|||||||
this.cameraManager.scrolled(amount);
|
this.cameraManager.scrolled(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean touchDown(final float screenX, final float screenY, final int button) {
|
public boolean touchDown(final int screenX, final int screenY, final float worldScreenY, final int button) {
|
||||||
if (this.meleeUIMinimap.containsMouse(screenX, screenY)) {
|
screenCoordsVector.set(screenX, screenY);
|
||||||
final Vector2 worldPoint = this.meleeUIMinimap.getWorldPointFromScreen(screenX, screenY);
|
this.uiViewport.unproject(screenCoordsVector);
|
||||||
|
if (this.meleeUIMinimap.containsMouse(screenCoordsVector.x, screenCoordsVector.y)) {
|
||||||
|
final Vector2 worldPoint = this.meleeUIMinimap.getWorldPointFromScreen(screenCoordsVector.x,
|
||||||
|
screenCoordsVector.y);
|
||||||
this.cameraManager.target.x = worldPoint.x;
|
this.cameraManager.target.x = worldPoint.x;
|
||||||
this.cameraManager.target.y = worldPoint.y;
|
this.cameraManager.target.y = worldPoint.y;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
screenCoordsVector.set(screenX, screenY);
|
final UIFrame clickedUIFrame = this.rootFrame.touchDown(screenCoordsVector.x, screenCoordsVector.y, button);
|
||||||
this.uiViewport.unproject(screenCoordsVector);
|
if (clickedUIFrame == null) {
|
||||||
this.rootFrame.touchDown(GameUI.unconvertX(this.uiViewport, screenCoordsVector.x),
|
// try to interact with world
|
||||||
GameUI.unconvertY(this.uiViewport, screenCoordsVector.y), button);
|
if (this.activeCommand != null) {
|
||||||
|
if (button == Input.Buttons.RIGHT) {
|
||||||
|
this.activeCommandUnit = null;
|
||||||
|
this.activeCommand = null;
|
||||||
|
this.activeCommandOrderId = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final RenderUnit rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY,
|
||||||
|
this.activeCommandUnitTargetFilter);
|
||||||
|
final boolean shiftDown = isShiftDown();
|
||||||
|
if (rayPickUnit != null) {
|
||||||
|
if (this.unitOrderListener.issueTargetOrder(
|
||||||
|
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
||||||
|
this.activeCommand.getHandleId(), this.activeCommandOrderId,
|
||||||
|
rayPickUnit.getSimulationUnit().getHandleId(), shiftDown)) {
|
||||||
|
if (getSelectedUnit().soundset.yesAttack
|
||||||
|
.playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
|
portraitTalk();
|
||||||
|
}
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
if (!shiftDown) {
|
||||||
|
this.activeCommandUnit = null;
|
||||||
|
this.activeCommand = null;
|
||||||
|
this.activeCommandOrderId = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
||||||
|
this.activeCommand.checkCanTarget(this.war3MapViewer.simulation,
|
||||||
|
this.activeCommandUnit.getSimulationUnit(), this.activeCommandOrderId,
|
||||||
|
clickLocationTemp2, PointAbilityTargetCheckReceiver.INSTANCE);
|
||||||
|
final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
||||||
|
if (target != null) {
|
||||||
|
if (this.activeCommand instanceof CAbilityAttack) {
|
||||||
|
this.war3MapViewer.showConfirmation(clickLocationTemp, 1, 0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0);
|
||||||
|
}
|
||||||
|
if (this.unitOrderListener.issuePointOrder(
|
||||||
|
this.activeCommandUnit.getSimulationUnit().getHandleId(),
|
||||||
|
this.activeCommand.getHandleId(), this.activeCommandOrderId, clickLocationTemp2.x,
|
||||||
|
clickLocationTemp2.y, shiftDown)) {
|
||||||
|
if (getSelectedUnit().soundset.yes.playUnitResponse(
|
||||||
|
this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
|
portraitTalk();
|
||||||
|
}
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
if (!shiftDown) {
|
||||||
|
this.activeCommandUnit = null;
|
||||||
|
this.activeCommand = null;
|
||||||
|
this.activeCommandOrderId = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (button == Input.Buttons.RIGHT) {
|
||||||
|
final RenderUnit rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY);
|
||||||
|
if (getSelectedUnit() != null) {
|
||||||
|
if ((rayPickUnit != null) && (rayPickUnit.playerIndex != getSelectedUnit().playerIndex)
|
||||||
|
&& !rayPickUnit.getSimulationUnit().isDead()) {
|
||||||
|
boolean ordered = false;
|
||||||
|
for (final RenderUnit unit : this.war3MapViewer.selected) {
|
||||||
|
for (final CAbility ability : unit.getSimulationUnit().getAbilities()) {
|
||||||
|
ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(),
|
||||||
|
OrderIds.smart, rayPickUnit.getSimulationUnit(),
|
||||||
|
CWidgetAbilityTargetCheckReceiver.INSTANCE);
|
||||||
|
final CWidget targetWidget = CWidgetAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
||||||
|
if (targetWidget != null) {
|
||||||
|
this.unitOrderListener.issueTargetOrder(unit.getSimulationUnit().getHandleId(),
|
||||||
|
ability.getHandleId(), OrderIds.smart, targetWidget.getHandleId(),
|
||||||
|
isShiftDown());
|
||||||
|
ordered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ordered) {
|
||||||
|
if (getSelectedUnit().soundset.yesAttack.playUnitResponse(
|
||||||
|
this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
|
portraitTalk();
|
||||||
|
}
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY);
|
||||||
|
this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0);
|
||||||
|
clickLocationTemp2.set(clickLocationTemp.x, clickLocationTemp.y);
|
||||||
|
|
||||||
|
boolean ordered = false;
|
||||||
|
for (final RenderUnit unit : this.war3MapViewer.selected) {
|
||||||
|
for (final CAbility ability : unit.getSimulationUnit().getAbilities()) {
|
||||||
|
ability.checkCanUse(this.war3MapViewer.simulation, unit.getSimulationUnit(),
|
||||||
|
OrderIds.smart, BooleanAbilityActivationReceiver.INSTANCE);
|
||||||
|
if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) {
|
||||||
|
ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(),
|
||||||
|
OrderIds.smart, clickLocationTemp2,
|
||||||
|
PointAbilityTargetCheckReceiver.INSTANCE);
|
||||||
|
final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget();
|
||||||
|
if (target != null) {
|
||||||
|
this.unitOrderListener.issuePointOrder(
|
||||||
|
unit.getSimulationUnit().getHandleId(), ability.getHandleId(),
|
||||||
|
OrderIds.smart, clickLocationTemp2.x, clickLocationTemp2.y,
|
||||||
|
isShiftDown());
|
||||||
|
ordered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ordered) {
|
||||||
|
if (getSelectedUnit().soundset.yes.playUnitResponse(
|
||||||
|
this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) {
|
||||||
|
portraitTalk();
|
||||||
|
}
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final List<RenderUnit> selectedUnits = this.war3MapViewer.selectUnit(screenX, worldScreenY, false);
|
||||||
|
if (!selectedUnits.isEmpty()) {
|
||||||
|
final RenderUnit unit = selectedUnits.get(0);
|
||||||
|
final boolean selectionChanged = getSelectedUnit() != unit;
|
||||||
|
boolean playedNewSound = false;
|
||||||
|
if (selectionChanged) {
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
}
|
||||||
|
if (unit.soundset != null) {
|
||||||
|
UnitSound ackSoundToPlay = unit.soundset.what;
|
||||||
|
final int pissedSoundCount = unit.soundset.pissed.getSoundCount();
|
||||||
|
int soundIndex;
|
||||||
|
if ((this.selectedSoundCount >= 3) && (pissedSoundCount > 0)) {
|
||||||
|
soundIndex = this.selectedSoundCount - 3;
|
||||||
|
ackSoundToPlay = unit.soundset.pissed;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount());
|
||||||
|
}
|
||||||
|
if (ackSoundToPlay.playUnitResponse(this.war3MapViewer.worldScene.audioContext, unit,
|
||||||
|
soundIndex)) {
|
||||||
|
this.selectedSoundCount++;
|
||||||
|
if ((this.selectedSoundCount - 3) >= pissedSoundCount) {
|
||||||
|
this.selectedSoundCount = 0;
|
||||||
|
}
|
||||||
|
playedNewSound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selectionChanged) {
|
||||||
|
selectUnit(unit);
|
||||||
|
}
|
||||||
|
if (playedNewSound) {
|
||||||
|
portraitTalk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectUnit(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isShiftDown() {
|
||||||
|
return Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Input.Keys.SHIFT_RIGHT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
||||||
|
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||||
|
|
||||||
|
public interface ActiveCommand {
|
||||||
|
boolean finish(CSimulation simulation, CUnit selectedUnit, float mouseScreenX, float mouseScreenY);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
||||||
|
|
||||||
|
public interface CommandCardCommandListener {
|
||||||
|
void startUsingAbility(int abilityHandleId, int orderId);
|
||||||
|
|
||||||
|
void toggleAutoCastAbility(int abilityHandleId);
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.etheller.warsmash.viewer5.handlers.w3x.ui.command;
|
||||||
|
|
||||||
|
public interface CommandErrorListener {
|
||||||
|
void showCommandError(String message);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user