Hotkeys and attack move

This commit is contained in:
Retera 2021-07-25 00:32:15 -04:00
parent dd5544109f
commit a4b5da5af0
13 changed files with 418 additions and 211 deletions

View File

@ -601,7 +601,7 @@ public final class MutableObjectData {
} }
// no luck with custom data, look at the standard data // no luck with custom data, look at the standard data
int slkLevel = level; int slkLevel = level;
if (MutableObjectData.this.worldEditorDataType == WorldEditorDataType.UPGRADES) { if ((MutableObjectData.this.worldEditorDataType == WorldEditorDataType.UPGRADES) && false) {
slkLevel -= 1; slkLevel -= 1;
} }
return getFieldStringFromSLKs(field, slkLevel); return getFieldStringFromSLKs(field, slkLevel);

View File

@ -8,7 +8,7 @@ public class WarsmashConstants {
*/ */
public static int GAME_VERSION = 1; public static int GAME_VERSION = 1;
public static final int REPLACEABLE_TEXTURE_LIMIT = 64; public static final int REPLACEABLE_TEXTURE_LIMIT = 64;
public static final float SIMULATION_STEP_TIME = 1 /20f; public static final float SIMULATION_STEP_TIME = 1 / 20f;
public static final int PORT_NUMBER = 6115; public static final int PORT_NUMBER = 6115;
public static final float BUILDING_CONSTRUCT_START_LIFE = 0.1f; public static final float BUILDING_CONSTRUCT_START_LIFE = 0.1f;
public static final int BUILD_QUEUE_SIZE = 7; public static final int BUILD_QUEUE_SIZE = 7;
@ -27,4 +27,6 @@ public class WarsmashConstants {
public static final boolean CATCH_CURSOR = true; public static final boolean CATCH_CURSOR = true;
public static final boolean VERBOSE_LOGGING = true; public static final boolean VERBOSE_LOGGING = true;
public static final boolean ENABLE_DEBUG = false;
public static final char SPECIAL_ESCAPE_KEYCODE = 0x7E;
} }

View File

@ -12,6 +12,7 @@ import com.etheller.warsmash.units.Element;
import com.etheller.warsmash.units.manager.MutableObjectData; import com.etheller.warsmash.units.manager.MutableObjectData;
import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject;
import com.etheller.warsmash.util.War3ID; import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.util.WarsmashConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer;
public class AbilityDataUI { public class AbilityDataUI {
@ -34,6 +35,10 @@ public class AbilityDataUI {
private static final War3ID ABILITY_EFFECT_SOUND = War3ID.fromString("aefs"); private static final War3ID ABILITY_EFFECT_SOUND = War3ID.fromString("aefs");
private static final War3ID ABILITY_EFFECT_SOUND_LOOPED = War3ID.fromString("aefl"); private static final War3ID ABILITY_EFFECT_SOUND_LOOPED = War3ID.fromString("aefl");
private static final War3ID ABILITY_HOTKEY_NORMAL = War3ID.fromString("ahky");
private static final War3ID ABILITY_HOTKEY_TURNOFF = War3ID.fromString("auhk");
private static final War3ID ABILITY_HOTKEY_LEARN = War3ID.fromString("arhk");
private static final War3ID CASTER_ART = War3ID.fromString("acat"); private static final War3ID CASTER_ART = War3ID.fromString("acat");
private static final War3ID TARGET_ART = War3ID.fromString("atat"); private static final War3ID TARGET_ART = War3ID.fromString("atat");
private static final War3ID SPECIAL_ART = War3ID.fromString("asat"); private static final War3ID SPECIAL_ART = War3ID.fromString("asat");
@ -48,6 +53,7 @@ public class AbilityDataUI {
private static final War3ID UNIT_REVIVE_TIP = War3ID.fromString("utpr"); private static final War3ID UNIT_REVIVE_TIP = War3ID.fromString("utpr");
private static final War3ID UNIT_AWAKEN_TIP = War3ID.fromString("uawt"); private static final War3ID UNIT_AWAKEN_TIP = War3ID.fromString("uawt");
private static final War3ID UNIT_UBER_TIP = War3ID.fromString("utub"); private static final War3ID UNIT_UBER_TIP = War3ID.fromString("utub");
private static final War3ID UNIT_HOTKEY = War3ID.fromString("uhot");
private static final War3ID ITEM_ICON_NORMAL_X = War3ID.fromString("ubpx"); private static final War3ID ITEM_ICON_NORMAL_X = War3ID.fromString("ubpx");
private static final War3ID ITEM_ICON_NORMAL_Y = War3ID.fromString("ubpy"); private static final War3ID ITEM_ICON_NORMAL_Y = War3ID.fromString("ubpy");
@ -55,6 +61,7 @@ public class AbilityDataUI {
private static final War3ID ITEM_TIP = War3ID.fromString("utip"); private static final War3ID ITEM_TIP = War3ID.fromString("utip");
private static final War3ID ITEM_UBER_TIP = War3ID.fromString("utub"); private static final War3ID ITEM_UBER_TIP = War3ID.fromString("utub");
private static final War3ID ITEM_DESCRIPTION = War3ID.fromString("ides"); private static final War3ID ITEM_DESCRIPTION = War3ID.fromString("ides");
private static final War3ID ITEM_HOTKEY = War3ID.fromString("uhot");
private static final War3ID UPGRADE_ICON_NORMAL_X = War3ID.fromString("gbpx"); private static final War3ID UPGRADE_ICON_NORMAL_X = War3ID.fromString("gbpx");
private static final War3ID UPGRADE_ICON_NORMAL_Y = War3ID.fromString("gbpy"); private static final War3ID UPGRADE_ICON_NORMAL_Y = War3ID.fromString("gbpy");
@ -62,6 +69,7 @@ public class AbilityDataUI {
private static final War3ID UPGRADE_LEVELS = War3ID.fromString("glvl"); private static final War3ID UPGRADE_LEVELS = War3ID.fromString("glvl");
private static final War3ID UPGRADE_TIP = War3ID.fromString("gtp1"); private static final War3ID UPGRADE_TIP = War3ID.fromString("gtp1");
private static final War3ID UPGRADE_UBER_TIP = War3ID.fromString("gub1"); private static final War3ID UPGRADE_UBER_TIP = War3ID.fromString("gub1");
private static final War3ID UPGRADE_HOTKEY = War3ID.fromString("ghk1");
private final Map<War3ID, AbilityUI> rawcodeToUI = new HashMap<>(); private final Map<War3ID, AbilityUI> rawcodeToUI = new HashMap<>();
private final Map<War3ID, UnitIconUI> rawcodeToUnitUI = new HashMap<>(); private final Map<War3ID, UnitIconUI> rawcodeToUnitUI = new HashMap<>();
@ -96,10 +104,13 @@ public class AbilityDataUI {
final String iconTurnOffPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ICON_TURN_OFF, 0)); final String iconTurnOffPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ICON_TURN_OFF, 0));
final String iconTip = abilityTypeData.getFieldAsString(ABILITY_TIP, 1); final String iconTip = abilityTypeData.getFieldAsString(ABILITY_TIP, 1);
final String iconUberTip = abilityTypeData.getFieldAsString(ABILITY_UBER_TIP, 1); final String iconUberTip = abilityTypeData.getFieldAsString(ABILITY_UBER_TIP, 1);
final char iconHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_NORMAL);
final String iconTurnOffTip = abilityTypeData.getFieldAsString(ABILITY_UN_TIP, 1); final String iconTurnOffTip = abilityTypeData.getFieldAsString(ABILITY_UN_TIP, 1);
final String iconTurnOffUberTip = abilityTypeData.getFieldAsString(ABILITY_UN_UBER_TIP, 1); final String iconTurnOffUberTip = abilityTypeData.getFieldAsString(ABILITY_UN_UBER_TIP, 1);
final char iconTurnOffHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_TURNOFF);
final String iconResearchTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_TIP, 1); final String iconResearchTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_TIP, 1);
final String iconResearchUberTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_UBER_TIP, 1); final String iconResearchUberTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_UBER_TIP, 1);
final char iconResearchHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_LEARN);
final int iconResearchX = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_X, 0); final int iconResearchX = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_X, 0);
final int iconResearchY = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_Y, 0); final int iconResearchY = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_Y, 0);
final int iconNormalX = abilityTypeData.getFieldAsInteger(ICON_NORMAL_X, 0); final int iconNormalX = abilityTypeData.getFieldAsInteger(ICON_NORMAL_X, 0);
@ -127,10 +138,11 @@ public class AbilityDataUI {
this.rawcodeToUI.put(alias, this.rawcodeToUI.put(alias,
new AbilityUI( new AbilityUI(
new IconUI(iconResearch, iconResearchDisabled, iconResearchX, iconResearchY, new IconUI(iconResearch, iconResearchDisabled, iconResearchX, iconResearchY,
iconResearchTip, iconResearchUberTip), iconResearchTip, iconResearchUberTip, iconResearchHotkey),
new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip), new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip,
iconHotkey),
new IconUI(iconTurnOff, iconTurnOffDisabled, iconTurnOffX, iconTurnOffY, iconTurnOffTip, new IconUI(iconTurnOff, iconTurnOffDisabled, iconTurnOffX, iconTurnOffY, iconTurnOffTip,
iconTurnOffUberTip), iconTurnOffUberTip, iconTurnOffHotkey),
casterArt, targetArt, specialArt, effectArt, areaEffectArt, missileArt, effectSound, casterArt, targetArt, specialArt, effectArt, areaEffectArt, missileArt, effectSound,
effectSoundLooped)); effectSoundLooped));
} }
@ -143,10 +155,11 @@ public class AbilityDataUI {
final String reviveTip = abilityTypeData.getFieldAsString(UNIT_REVIVE_TIP, 0); final String reviveTip = abilityTypeData.getFieldAsString(UNIT_REVIVE_TIP, 0);
final String awakenTip = abilityTypeData.getFieldAsString(UNIT_AWAKEN_TIP, 0); final String awakenTip = abilityTypeData.getFieldAsString(UNIT_AWAKEN_TIP, 0);
final String iconUberTip = abilityTypeData.getFieldAsString(UNIT_UBER_TIP, 0); final String iconUberTip = abilityTypeData.getFieldAsString(UNIT_UBER_TIP, 0);
final char iconHotkey = getHotkey(abilityTypeData, UNIT_HOTKEY);
final Texture iconNormal = gameUI.loadTexture(iconNormalPath); final Texture iconNormal = gameUI.loadTexture(iconNormalPath);
final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix));
this.rawcodeToUnitUI.put(alias, this.rawcodeToUnitUI.put(alias, new UnitIconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY,
new UnitIconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip, reviveTip, awakenTip)); iconTip, iconUberTip, iconHotkey, reviveTip, awakenTip));
} }
for (final War3ID alias : itemData.keySet()) { for (final War3ID alias : itemData.keySet()) {
final MutableGameObject abilityTypeData = itemData.get(alias); final MutableGameObject abilityTypeData = itemData.get(alias);
@ -156,12 +169,15 @@ public class AbilityDataUI {
final String iconTip = abilityTypeData.getFieldAsString(ITEM_TIP, 0); final String iconTip = abilityTypeData.getFieldAsString(ITEM_TIP, 0);
final String iconUberTip = abilityTypeData.getFieldAsString(ITEM_UBER_TIP, 0); final String iconUberTip = abilityTypeData.getFieldAsString(ITEM_UBER_TIP, 0);
final String iconDescription = abilityTypeData.getFieldAsString(ITEM_DESCRIPTION, 0); final String iconDescription = abilityTypeData.getFieldAsString(ITEM_DESCRIPTION, 0);
final char iconHotkey = getHotkey(abilityTypeData, ITEM_HOTKEY);
final Texture iconNormal = gameUI.loadTexture(iconNormalPath); final Texture iconNormal = gameUI.loadTexture(iconNormalPath);
final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix));
this.rawcodeToItemUI.put(alias, this.rawcodeToItemUI
new ItemUI( .put(alias,
new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip), new ItemUI(
abilityTypeData.getName(), iconDescription, iconNormalPath)); new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip,
iconUberTip, iconHotkey),
abilityTypeData.getName(), iconDescription, iconNormalPath));
} }
for (final War3ID alias : upgradeData.keySet()) { for (final War3ID alias : upgradeData.keySet()) {
final MutableGameObject upgradeTypeData = upgradeData.get(alias); final MutableGameObject upgradeTypeData = upgradeData.get(alias);
@ -174,10 +190,11 @@ public class AbilityDataUI {
final String iconUberTip = upgradeTypeData.getFieldAsString(UPGRADE_UBER_TIP, 0); final String iconUberTip = upgradeTypeData.getFieldAsString(UPGRADE_UBER_TIP, 0);
final String iconNormalPath = gameUI final String iconNormalPath = gameUI
.trySkinField(upgradeTypeData.getFieldAsString(UPGRADE_ICON_NORMAL, i)); .trySkinField(upgradeTypeData.getFieldAsString(UPGRADE_ICON_NORMAL, i));
final char iconHotkey = getHotkey(upgradeTypeData, UPGRADE_HOTKEY, i);
final Texture iconNormal = gameUI.loadTexture(iconNormalPath); final Texture iconNormal = gameUI.loadTexture(iconNormalPath);
final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix));
upgradeIconsByLevel.add( upgradeIconsByLevel.add(new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip,
new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip)); iconUberTip, iconHotkey));
} }
this.rawcodeToUpgradeUI.put(alias, upgradeIconsByLevel); this.rawcodeToUpgradeUI.put(alias, upgradeIconsByLevel);
} }
@ -200,6 +217,16 @@ public class AbilityDataUI {
this.selectSkillUI = createBuiltInIconUI(gameUI, "CmdSelectSkill", disabledPrefix); this.selectSkillUI = createBuiltInIconUI(gameUI, "CmdSelectSkill", disabledPrefix);
} }
private char getHotkey(final MutableGameObject abilityTypeData, final War3ID abilityHotkeyNormal) {
return getHotkey(abilityTypeData, abilityHotkeyNormal, 1);
}
private char getHotkey(final MutableGameObject abilityTypeData, final War3ID abilityHotkeyNormal, final int level) {
final String iconHotkeyString = abilityTypeData.getFieldAsString(abilityHotkeyNormal, level);
final char itemHotkey = getHotkeyChar(iconHotkeyString);
return itemHotkey;
}
private IconUI createBuiltInIconUI(final GameUI gameUI, final String key, final String disabledPrefix) { private IconUI createBuiltInIconUI(final GameUI gameUI, final String key, final String disabledPrefix) {
final Element builtInAbility = gameUI.getSkinData().get(key); final Element builtInAbility = gameUI.getSkinData().get(key);
final String iconPath = gameUI.trySkinField(builtInAbility.getField("Art")); final String iconPath = gameUI.trySkinField(builtInAbility.getField("Art"));
@ -209,7 +236,20 @@ public class AbilityDataUI {
final int buttonPositionY = builtInAbility.getFieldValue("Buttonpos", 1); final int buttonPositionY = builtInAbility.getFieldValue("Buttonpos", 1);
final String tip = builtInAbility.getField("Tip"); final String tip = builtInAbility.getField("Tip");
final String uberTip = builtInAbility.getField("UberTip"); final String uberTip = builtInAbility.getField("UberTip");
return new IconUI(icon, iconDisabled, buttonPositionX, buttonPositionY, tip, uberTip); final String hotkeyString = builtInAbility.getField("Hotkey");
final char hotkey = getHotkeyChar(hotkeyString);
return new IconUI(icon, iconDisabled, buttonPositionX, buttonPositionY, tip, uberTip, hotkey);
}
private char getHotkeyChar(final String hotkeyString) {
if (hotkeyString.length() > 1) {
final int hotkeyInt = Integer.parseInt(hotkeyString);
if (hotkeyInt == 512) {
return WarsmashConstants.SPECIAL_ESCAPE_KEYCODE;
}
return (char) hotkeyInt;
}
return hotkeyString.length() > 0 ? hotkeyString.charAt(0) : '\0';
} }
public AbilityUI getUI(final War3ID rawcode) { public AbilityUI getUI(final War3ID rawcode) {

View File

@ -9,15 +9,17 @@ public class IconUI {
private final int buttonPositionY; private final int buttonPositionY;
private final String toolTip; private final String toolTip;
private final String uberTip; private final String uberTip;
private final char hotkey;
public IconUI(final Texture icon, final Texture iconDisabled, final int buttonPositionX, final int buttonPositionY, public IconUI(final Texture icon, final Texture iconDisabled, final int buttonPositionX, final int buttonPositionY,
final String toolTip, final String uberTip) { final String toolTip, final String uberTip, final char hotkey) {
this.icon = icon; this.icon = icon;
this.iconDisabled = iconDisabled; this.iconDisabled = iconDisabled;
this.buttonPositionX = buttonPositionX; this.buttonPositionX = buttonPositionX;
this.buttonPositionY = buttonPositionY; this.buttonPositionY = buttonPositionY;
this.toolTip = toolTip; this.toolTip = toolTip;
this.uberTip = uberTip; this.uberTip = uberTip;
this.hotkey = hotkey;
} }
public Texture getIcon() { public Texture getIcon() {
@ -43,4 +45,8 @@ public class IconUI {
public String getUberTip() { public String getUberTip() {
return this.uberTip; return this.uberTip;
} }
public char getHotkey() {
return this.hotkey;
}
} }

View File

@ -2,21 +2,23 @@ package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
public class UnitIconUI extends IconUI { public class UnitIconUI extends IconUI {
private String reviveTip; private final String reviveTip;
private String awakenTip; private final String awakenTip;
public UnitIconUI(Texture icon, Texture iconDisabled, int buttonPositionX, int buttonPositionY, String toolTip, String uberTip, String reviveTip, String awakenTip) { public UnitIconUI(final Texture icon, final Texture iconDisabled, final int buttonPositionX,
super(icon, iconDisabled, buttonPositionX, buttonPositionY, toolTip, uberTip); final int buttonPositionY, final String toolTip, final String uberTip, final char hotkey,
this.reviveTip = reviveTip; final String reviveTip, final String awakenTip) {
this.awakenTip = awakenTip; super(icon, iconDisabled, buttonPositionX, buttonPositionY, toolTip, uberTip, hotkey);
} this.reviveTip = reviveTip;
this.awakenTip = awakenTip;
}
public String getReviveTip() { public String getReviveTip() {
return reviveTip; return this.reviveTip;
} }
public String getAwakenTip() { public String getAwakenTip() {
return awakenTip; return this.awakenTip;
} }
} }

View File

@ -36,5 +36,5 @@ public interface CommandButtonListener {
// int getOrderId(); // int getOrderId();
void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId, void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId,
int autoCastOrderId, boolean active, boolean autoCastActive, boolean menuButton, String tip, String uberTip, int autoCastOrderId, boolean active, boolean autoCastActive, boolean menuButton, String tip, String uberTip,
int goldCost, int lumberCost, int foodCost); char hotkey, int goldCost, int lumberCost, int foodCost);
} }

View File

@ -48,11 +48,11 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
private boolean hasStop; private boolean hasStop;
private final CommandCardActivationReceiverPreviewCallback previewCallback = new CommandCardActivationReceiverPreviewCallback(); private final CommandCardActivationReceiverPreviewCallback previewCallback = new CommandCardActivationReceiverPreviewCallback();
private GameUI gameUI; private GameUI gameUI;
private boolean hasCancel ; private boolean hasCancel;
public CommandCardPopulatingAbilityVisitor reset(final CSimulation game, final GameUI gameUI, final CUnit unit, public CommandCardPopulatingAbilityVisitor reset(final CSimulation game, final GameUI gameUI, final CUnit unit,
final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI, final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI,
final int menuBaseOrderId, boolean multiSelect) { final int menuBaseOrderId, final boolean multiSelect) {
this.game = game; this.game = game;
this.gameUI = gameUI; this.gameUI = gameUI;
this.unit = unit; this.unit = unit;
@ -61,7 +61,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
this.menuBaseOrderId = menuBaseOrderId; this.menuBaseOrderId = menuBaseOrderId;
this.multiSelect = multiSelect; this.multiSelect = multiSelect;
this.hasStop = false; this.hasStop = false;
hasCancel = false; this.hasCancel = false;
return this; return this;
} }
@ -107,14 +107,15 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
@Override @Override
public Void accept(final CAbilityGeneric ability) { public Void accept(final CAbilityGeneric ability) {
if(ENABLE_PLACEHOLDERS) { if (ENABLE_PLACEHOLDERS) {
if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) {
final AbilityUI abilityUI = this.abilityDataUI.getUI(ability.getRawcode()); final AbilityUI abilityUI = this.abilityDataUI.getUI(ability.getRawcode());
if (abilityUI != null) { if (abilityUI != null) {
addCommandButton(ability, abilityUI.getOnIconUI(), ability.getHandleId(), 0, 0, false, false); addCommandButton(ability, abilityUI.getOnIconUI(), ability.getHandleId(), 0, 0, false, false);
} }
else { else {
addCommandButton(ability, this.abilityDataUI.getStopUI(), ability.getHandleId(), 0, 0, false, false); addCommandButton(ability, this.abilityDataUI.getStopUI(), ability.getHandleId(), 0, 0, false,
false);
} }
} }
} }
@ -213,7 +214,7 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
} }
} }
else { else {
if(multiSelect) { if (this.multiSelect) {
return; return;
} }
addCommandButton(ability, buildUI, ability.getHandleId(), ability.getBaseOrderId(), 0, false, true); addCommandButton(ability, buildUI, ability.getHandleId(), ability.getBaseOrderId(), 0, false, true);
@ -226,14 +227,16 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
} }
private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId, private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId,
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, int goldCost, final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, final int goldCost,
int lumberCost, int foodCost) { final int lumberCost, final int foodCost) {
addCommandButton(ability, iconUI, iconUI.getToolTip(), iconUI.getButtonPositionX(), iconUI.getButtonPositionY(), handleId, orderId, autoCastOrderId, autoCastActive, menuButton, goldCost, lumberCost, foodCost); addCommandButton(ability, iconUI, iconUI.getToolTip(), iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
handleId, orderId, autoCastOrderId, autoCastActive, menuButton, goldCost, lumberCost, foodCost);
} }
private void addCommandButton(final CAbility ability, final IconUI iconUI, String toolTip, int buttonPosX, int buttonPosY, final int handleId, final int orderId, private void addCommandButton(final CAbility ability, final IconUI iconUI, final String toolTip,
final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, int goldCost, final int buttonPosX, final int buttonPosY, final int handleId, final int orderId,
int lumberCost, int foodCost) { final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, int goldCost,
int lumberCost, int foodCost) {
ability.checkCanUse(this.game, this.unit, orderId, this.previewCallback.reset()); ability.checkCanUse(this.game, this.unit, orderId, this.previewCallback.reset());
final boolean active = ((this.unit.getCurrentBehavior() != null) final boolean active = ((this.unit.getCurrentBehavior() != null)
&& (orderId == this.unit.getCurrentBehavior().getHighlightOrderId())); && (orderId == this.unit.getCurrentBehavior().getHighlightOrderId()));
@ -250,8 +253,8 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
} }
this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(), this.commandButtonListener.commandButton(iconUI.getButtonPositionX(), iconUI.getButtonPositionY(),
disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId, disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId,
autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, goldCost, lumberCost, autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, iconUI.getHotkey(), goldCost,
foodCost); lumberCost, foodCost);
} }
@Override @Override
@ -264,29 +267,31 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
} }
@Override @Override
public Void accept(CAbilityReviveHero ability) { public Void accept(final CAbilityReviveHero ability) {
if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) {
int heroIndex = 0; int heroIndex = 0;
for(CUnit playerHero: game.getPlayerHeroes(unit.getPlayerIndex())) { for (final CUnit playerHero : this.game.getPlayerHeroes(this.unit.getPlayerIndex())) {
CAbilityHero heroData = playerHero.getHeroData(); final CAbilityHero heroData = playerHero.getHeroData();
if(playerHero.isDead() && heroData != null && heroData.isAwaitingRevive()) { if (playerHero.isDead() && (heroData != null) && heroData.isAwaitingRevive()) {
UnitIconUI unitUI = this.abilityDataUI.getUnitUI(playerHero.getTypeId()); final UnitIconUI unitUI = this.abilityDataUI.getUnitUI(playerHero.getTypeId());
if (unitUI != null) { if (unitUI != null) {
final CUnitType simulationUnitType = playerHero.getUnitType(); final CUnitType simulationUnitType = playerHero.getUnitType();
int goldCost = game.getGameplayConstants().getHeroReviveGoldCost(simulationUnitType.getGoldCost(), heroData.getHeroLevel()); final int goldCost = this.game.getGameplayConstants()
int lumberCost = game.getGameplayConstants().getHeroReviveLumberCost(simulationUnitType.getLumberCost(), heroData.getHeroLevel()); .getHeroReviveGoldCost(simulationUnitType.getGoldCost(), heroData.getHeroLevel());
addCommandButton(ability, unitUI, unitUI.getReviveTip() + " - " + heroData.getProperName(), heroIndex++, 0, ability.getHandleId(), playerHero.getHandleId(), 0, false, false, final int lumberCost = this.game.getGameplayConstants()
goldCost, lumberCost, .getHeroReviveLumberCost(simulationUnitType.getLumberCost(), heroData.getHeroLevel());
simulationUnitType.getFoodUsed()); addCommandButton(ability, unitUI, unitUI.getReviveTip() + " - " + heroData.getProperName(),
heroIndex++, 0, ability.getHandleId(), playerHero.getHandleId(), 0, false, false,
goldCost, lumberCost, simulationUnitType.getFoodUsed());
} }
} }
} }
if (this.unit.getBuildQueueTypes()[0] != null) { if (this.unit.getBuildQueueTypes()[0] != null) {
if(!hasCancel) { if (!this.hasCancel) {
hasCancel = true; this.hasCancel = true;
addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(), OrderIds.cancel, addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(),
0, false, false); OrderIds.cancel, 0, false, false);
} }
} }
} }
@ -305,20 +310,21 @@ public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor<Void
simulationUnitType.getFoodUsed()); simulationUnitType.getFoodUsed());
} }
} }
if(ENABLE_PLACEHOLDERS) { if (ENABLE_PLACEHOLDERS) {
for (final War3ID unitType : ability.getResearchesAvailable()) { for (final War3ID unitType : ability.getResearchesAvailable()) {
final CPlayer player = this.game.getPlayer(this.unit.getPlayerIndex()); final CPlayer player = this.game.getPlayer(this.unit.getPlayerIndex());
final IconUI unitUI = this.abilityDataUI.getUpgradeUI(unitType, player.getTechtreeUnlocked(unitType)); final IconUI unitUI = this.abilityDataUI.getUpgradeUI(unitType,
player.getTechtreeUnlocked(unitType));
if (unitUI != null) { if (unitUI != null) {
addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false); addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false);
} }
} }
} }
if (this.unit.getBuildQueueTypes()[0] != null) { if (this.unit.getBuildQueueTypes()[0] != null) {
if(!hasCancel) { if (!this.hasCancel) {
hasCancel = true; this.hasCancel = true;
addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(), OrderIds.cancel, addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(),
0, false, false); OrderIds.cancel, 0, false, false);
} }
} }
} }

View File

@ -30,6 +30,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackMove;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove;
@ -98,6 +99,7 @@ public class CUnit extends CWidget {
private transient CBehaviorMove moveBehavior; private transient CBehaviorMove moveBehavior;
private transient CBehaviorAttack attackBehavior; private transient CBehaviorAttack attackBehavior;
private transient CBehaviorAttackMove attackMoveBehavior;
private transient CBehaviorFollow followBehavior; private transient CBehaviorFollow followBehavior;
private transient CBehaviorPatrol patrolBehavior; private transient CBehaviorPatrol patrolBehavior;
private transient CBehaviorStop stopBehavior; private transient CBehaviorStop stopBehavior;
@ -187,7 +189,7 @@ public class CUnit extends CWidget {
ability.onAdd(simulation, this); ability.onAdd(simulation, this);
} }
public void remove(CSimulation simulation, CAbility ability) { public void remove(final CSimulation simulation, final CAbility ability) {
this.abilities.remove(ability); this.abilities.remove(ability);
simulation.onAbilityRemovedFromUnit(this, ability); simulation.onAbilityRemovedFromUnit(this, ability);
ability.onRemove(simulation, this); ability.onRemove(simulation, this);
@ -251,14 +253,14 @@ public class CUnit extends CWidget {
* this unit from the game. * this unit from the game.
*/ */
public boolean update(final CSimulation game) { public boolean update(final CSimulation game) {
for(StateListenerUpdate update: this.stateListenersUpdates) { for (final StateListenerUpdate update : this.stateListenersUpdates) {
switch(update.getUpdateType()) { switch (update.getUpdateType()) {
case ADD: case ADD:
stateNotifier.subscribe(update.listener); this.stateNotifier.subscribe(update.listener);
break; break;
case REMOVE: case REMOVE:
stateNotifier.unsubscribe(update.listener); this.stateNotifier.unsubscribe(update.listener);
break; break;
} }
} }
if (isDead()) { if (isDead()) {
@ -280,8 +282,8 @@ public class CUnit extends CWidget {
if (!this.unitType.isDecay()) { if (!this.unitType.isDecay()) {
// if we dont raise AND dont decay, then now that death anim is over // if we dont raise AND dont decay, then now that death anim is over
// we just delete the unit // we just delete the unit
if(unitType.isHero()) { if (this.unitType.isHero()) {
if(!getHeroData().isAwaitingRevive()) { if (!getHeroData().isAwaitingRevive()) {
setHidden(true); setHidden(true);
getHeroData().setAwaitingRevive(true); getHeroData().setAwaitingRevive(true);
game.heroDeathEvent(this); game.heroDeathEvent(this);
@ -302,8 +304,8 @@ public class CUnit extends CWidget {
} }
else if (game.getGameTurnTick() > (this.deathTurnTick else if (game.getGameTurnTick() > (this.deathTurnTick
+ (int) (getEndingDecayTime(game) / WarsmashConstants.SIMULATION_STEP_TIME))) { + (int) (getEndingDecayTime(game) / WarsmashConstants.SIMULATION_STEP_TIME))) {
if(unitType.isHero()) { if (this.unitType.isHero()) {
if(!getHeroData().isAwaitingRevive()) { if (!getHeroData().isAwaitingRevive()) {
setHidden(true); setHidden(true);
getHeroData().setAwaitingRevive(true); getHeroData().setAwaitingRevive(true);
game.heroDeathEvent(this); game.heroDeathEvent(this);
@ -405,10 +407,11 @@ public class CUnit extends CWidget {
} }
} }
else if (this.buildQueueTypes[0] == QueueItemType.HERO_REVIVE) { else if (this.buildQueueTypes[0] == QueueItemType.HERO_REVIVE) {
CUnit revivingHero = game.getUnit(queuedRawcode.getValue()); final CUnit revivingHero = game.getUnit(queuedRawcode.getValue());
final CUnitType trainedUnitType = revivingHero.getUnitType(); final CUnitType trainedUnitType = revivingHero.getUnitType();
CGameplayConstants gameplayConstants = game.getGameplayConstants(); final CGameplayConstants gameplayConstants = game.getGameplayConstants();
if (this.constructionProgress >= gameplayConstants.getHeroReviveTime(trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) { if (this.constructionProgress >= gameplayConstants.getHeroReviveTime(
trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) {
this.constructionProgress = 0; this.constructionProgress = 0;
revivingHero.corpse = false; revivingHero.corpse = false;
revivingHero.boneCorpse = false; revivingHero.boneCorpse = false;
@ -418,8 +421,11 @@ public class CUnit extends CWidget {
game.getWorldCollision().addUnit(revivingHero); game.getWorldCollision().addUnit(revivingHero);
revivingHero.setPoint(getX(), getY(), game.getWorldCollision(), game.getRegionManager()); revivingHero.setPoint(getX(), getY(), game.getWorldCollision(), game.getRegionManager());
revivingHero.setHidden(false); revivingHero.setHidden(false);
revivingHero.setLife(game, revivingHero.getMaximumLife() * gameplayConstants.getHeroReviveLifeFactor()); revivingHero.setLife(game,
revivingHero.setMana( revivingHero.getMaximumMana() * gameplayConstants.getHeroReviveManaFactor() + gameplayConstants.getHeroReviveManaStart() * trainedUnitType.getManaInitial()); revivingHero.getMaximumLife() * gameplayConstants.getHeroReviveLifeFactor());
revivingHero.setMana((revivingHero.getMaximumMana()
* gameplayConstants.getHeroReviveManaFactor())
+ (gameplayConstants.getHeroReviveManaStart() * trainedUnitType.getManaInitial()));
// dont add food cost to player 2x // dont add food cost to player 2x
revivingHero.setFoodUsed(trainedUnitType.getFoodUsed()); revivingHero.setFoodUsed(trainedUnitType.getFoodUsed());
final CPlayer player = game.getPlayer(this.playerIndex); final CPlayer player = game.getPlayer(this.playerIndex);
@ -1139,7 +1145,7 @@ public class CUnit extends CWidget {
return this.acquisitionRange; return this.acquisitionRange;
} }
public void heal(CSimulation game, int lifeToRegain) { public void heal(final CSimulation game, final int lifeToRegain) {
setLife(game, Math.min(getLife() + lifeToRegain, getMaximumLife())); setLife(game, Math.min(getLife() + lifeToRegain, getMaximumLife()));
} }
@ -1165,8 +1171,7 @@ public class CUnit extends CWidget {
for (final CUnitAttack attack : this.source.getAttacks()) { for (final CUnitAttack attack : this.source.getAttacks()) {
if (this.source.canReach(unit, this.source.acquisitionRange) if (this.source.canReach(unit, this.source.acquisitionRange)
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed()) && unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
&& (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange()) && (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) {
) {
if (this.source.currentBehavior != null) { if (this.source.currentBehavior != null) {
this.source.currentBehavior.end(this.game, false); this.source.currentBehavior.end(this.game, false);
} }
@ -1198,6 +1203,14 @@ public class CUnit extends CWidget {
this.attackBehavior = attackBehavior; this.attackBehavior = attackBehavior;
} }
public void setAttackMoveBehavior(final CBehaviorAttackMove attackMoveBehavior) {
this.attackMoveBehavior = attackMoveBehavior;
}
public CBehaviorAttackMove getAttackMoveBehavior() {
return this.attackMoveBehavior;
}
public CBehaviorStop getStopBehavior() { public CBehaviorStop getStopBehavior() {
return this.stopBehavior; return this.stopBehavior;
} }
@ -1338,9 +1351,10 @@ public class CUnit extends CWidget {
return trainedUnitType.getBuildTime(); return trainedUnitType.getBuildTime();
} }
case HERO_REVIVE: { case HERO_REVIVE: {
CUnit hero = simulation.getUnit(this.buildQueue[0].getValue()); final CUnit hero = simulation.getUnit(this.buildQueue[0].getValue());
final CUnitType trainedUnitType = hero.getUnitType(); final CUnitType trainedUnitType = hero.getUnitType();
return simulation.getGameplayConstants().getHeroReviveTime(trainedUnitType.getBuildTime(), hero.getHeroData().getHeroLevel()); return simulation.getGameplayConstants().getHeroReviveTime(trainedUnitType.getBuildTime(),
hero.getHeroData().getHeroLevel());
} }
default: default:
return 0; return 0;
@ -1382,13 +1396,15 @@ public class CUnit extends CWidget {
} }
case HERO_REVIVE: { case HERO_REVIVE: {
final CPlayer player = game.getPlayer(this.playerIndex); final CPlayer player = game.getPlayer(this.playerIndex);
CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue()); final CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue());
final CUnitType unitType = hero.getUnitType(); final CUnitType unitType = hero.getUnitType();
CAbilityHero heroData = hero.getHeroData(); final CAbilityHero heroData = hero.getHeroData();
heroData.setAwaitingRevive(true); heroData.setAwaitingRevive(true);
CGameplayConstants gameplayConstants = game.getGameplayConstants(); final CGameplayConstants gameplayConstants = game.getGameplayConstants();
player.refund(gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()), player.refund(
gameplayConstants.getHeroReviveLumberCost(unitType.getLumberCost(), heroData.getHeroLevel())); gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()),
gameplayConstants.getHeroReviveLumberCost(unitType.getLumberCost(),
heroData.getHeroLevel()));
break; break;
} }
} }
@ -1408,7 +1424,7 @@ public class CUnit extends CWidget {
if (index == 0) { if (index == 0) {
this.queuedUnitFoodPaid = true; this.queuedUnitFoodPaid = true;
if (rawcode != null) { if (rawcode != null) {
if(queueItemType == QueueItemType.UNIT) { if (queueItemType == QueueItemType.UNIT) {
final CPlayer player = game.getPlayer(this.playerIndex); final CPlayer player = game.getPlayer(this.playerIndex);
final CUnitType unitType = game.getUnitData().getUnitType(this.buildQueue[index]); final CUnitType unitType = game.getUnitData().getUnitType(this.buildQueue[index]);
if (unitType.getFoodUsed() != 0) { if (unitType.getFoodUsed() != 0) {
@ -1421,7 +1437,8 @@ public class CUnit extends CWidget {
game.getCommandErrorListener(this.playerIndex).showNoFoodError(); game.getCommandErrorListener(this.playerIndex).showNoFoodError();
} }
} }
} else if(queueItemType == QueueItemType.HERO_REVIVE) { }
else if (queueItemType == QueueItemType.HERO_REVIVE) {
final CPlayer player = game.getPlayer(this.playerIndex); final CPlayer player = game.getPlayer(this.playerIndex);
final CUnitType unitType = game.getUnit(this.buildQueue[index].getValue()).getUnitType(); final CUnitType unitType = game.getUnit(this.buildQueue[index].getValue()).getUnitType();
if (unitType.getFoodUsed() != 0) { if (unitType.getFoodUsed() != 0) {
@ -1451,8 +1468,10 @@ public class CUnit extends CWidget {
if (queue(game, new War3ID(hero.getHandleId()), QueueItemType.HERO_REVIVE)) { if (queue(game, new War3ID(hero.getHandleId()), QueueItemType.HERO_REVIVE)) {
hero.getHeroData().setAwaitingRevive(false); hero.getHeroData().setAwaitingRevive(false);
final CPlayer player = game.getPlayer(this.playerIndex); final CPlayer player = game.getPlayer(this.playerIndex);
int heroReviveGoldCost = game.getGameplayConstants().getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); final int heroReviveGoldCost = game.getGameplayConstants()
int heroReviveLumberCost = game.getGameplayConstants().getHeroReviveLumberCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); .getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel());
final int heroReviveLumberCost = game.getGameplayConstants()
.getHeroReviveLumberCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel());
player.charge(heroReviveGoldCost, heroReviveLumberCost); player.charge(heroReviveGoldCost, heroReviveLumberCost);
} }
} }
@ -1702,24 +1721,25 @@ public class CUnit extends CWidget {
} }
private static enum StateListenerUpdateType { private static enum StateListenerUpdateType {
ADD, REMOVE; ADD,
REMOVE;
} }
private static final class StateListenerUpdate { private static final class StateListenerUpdate {
private CUnitStateListener listener; private final CUnitStateListener listener;
private StateListenerUpdateType updateType; private final StateListenerUpdateType updateType;
public StateListenerUpdate(CUnitStateListener listener, StateListenerUpdateType updateType) { public StateListenerUpdate(final CUnitStateListener listener, final StateListenerUpdateType updateType) {
this.listener = listener; this.listener = listener;
this.updateType = updateType; this.updateType = updateType;
} }
public CUnitStateListener getListener() { public CUnitStateListener getListener() {
return listener; return this.listener;
} }
public StateListenerUpdateType getUpdateType() { public StateListenerUpdateType getUpdateType() {
return updateType; return this.updateType;
} }
} }
} }

View File

@ -8,6 +8,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackMove;
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.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType;
@ -111,6 +112,7 @@ public class CAbilityAttack extends AbstractCAbility {
@Override @Override
public void onAdd(final CSimulation game, final CUnit unit) { public void onAdd(final CSimulation game, final CUnit unit) {
unit.setAttackBehavior(new CBehaviorAttack(unit)); unit.setAttackBehavior(new CBehaviorAttack(unit));
unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit));
} }
@Override @Override
@ -142,10 +144,11 @@ public class CAbilityAttack extends AbstractCAbility {
final AbilityPointTarget point) { final AbilityPointTarget point) {
switch (orderId) { switch (orderId) {
case OrderIds.attack: case OrderIds.attack:
if (caster.getMoveBehavior() == null) { if (caster.getAttackMoveBehavior() == null) {
return caster.pollNextOrderBehavior(game); return caster.pollNextOrderBehavior(game);
} }
return caster.getMoveBehavior().reset(OrderIds.attack, point); caster.setDefaultBehavior(caster.getAttackMoveBehavior());
return caster.getAttackMoveBehavior().reset(point);
case OrderIds.attackground: case OrderIds.attackground:
CBehavior behavior = null; CBehavior behavior = null;
for (final CUnitAttack attack : caster.getAttacks()) { for (final CUnitAttack attack : caster.getAttacks()) {

View File

@ -1,5 +1,8 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory; package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory;
import java.util.ArrayList;
import java.util.List;
import com.etheller.warsmash.util.War3ID; import com.etheller.warsmash.util.War3ID;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType;
@ -11,6 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.A
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorDropItem; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorDropItem;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorGetItem; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorGetItem;
@ -18,9 +22,6 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; 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;
import java.util.ArrayList;
import java.util.List;
public class CAbilityInventory extends AbstractGenericNoIconAbility { public class CAbilityInventory extends AbstractGenericNoIconAbility {
private final boolean canDropItems; private final boolean canDropItems;
private final boolean canGetItems; private final boolean canGetItems;
@ -41,8 +42,8 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
this.dropItemsOnDeath = dropItemsOnDeath; this.dropItemsOnDeath = dropItemsOnDeath;
this.itemsHeld = new CItem[itemCapacity]; this.itemsHeld = new CItem[itemCapacity];
this.itemsHeldAbilities = new List[itemCapacity]; this.itemsHeldAbilities = new List[itemCapacity];
for(int i = 0 ;i < itemsHeldAbilities.length; i++) { for (int i = 0; i < this.itemsHeldAbilities.length; i++) {
itemsHeldAbilities[i] = new ArrayList<>(); this.itemsHeldAbilities[i] = new ArrayList<>();
} }
} }
@ -69,20 +70,21 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
for (int i = 0; i < this.itemsHeld.length; i++) { for (int i = 0; i < this.itemsHeld.length; i++) {
if (this.itemsHeld[i] == target) { if (this.itemsHeld[i] == target) {
final CItem temp = this.itemsHeld[i]; final CItem temp = this.itemsHeld[i];
List<CAbility> swapList = itemsHeldAbilities[i]; final List<CAbility> swapList = this.itemsHeldAbilities[i];
final int dragDropDestinationIndex = orderId - OrderIds.itemdrag00; final int dragDropDestinationIndex = orderId - OrderIds.itemdrag00;
this.itemsHeld[i] = this.itemsHeld[dragDropDestinationIndex]; this.itemsHeld[i] = this.itemsHeld[dragDropDestinationIndex];
itemsHeldAbilities[i] = itemsHeldAbilities[dragDropDestinationIndex]; this.itemsHeldAbilities[i] = this.itemsHeldAbilities[dragDropDestinationIndex];
this.itemsHeld[dragDropDestinationIndex] = temp; this.itemsHeld[dragDropDestinationIndex] = temp;
itemsHeldAbilities[dragDropDestinationIndex] = swapList; this.itemsHeldAbilities[dragDropDestinationIndex] = swapList;
return false; return false;
} }
} }
} else if (orderId >= OrderIds.itemuse00 && orderId <= OrderIds.itemuse05) { }
CAbility cAbility = itemsHeldAbilities[orderId - OrderIds.itemuse00].get(0); else if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) {
final CAbility cAbility = this.itemsHeldAbilities[orderId - OrderIds.itemuse00].get(0);
int forwardedOrderId = orderId; int forwardedOrderId = orderId;
if(cAbility instanceof GenericSingleIconActiveAbility) { if (cAbility instanceof GenericSingleIconActiveAbility) {
forwardedOrderId = ((GenericSingleIconActiveAbility)cAbility).getBaseOrderId(); forwardedOrderId = ((GenericSingleIconActiveAbility) cAbility).getBaseOrderId();
} }
cAbility.checkBeforeQueue(game, caster, forwardedOrderId, target); cAbility.checkBeforeQueue(game, caster, forwardedOrderId, target);
} }
@ -94,8 +96,6 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
} }
public int getItemCapacity() { public int getItemCapacity() {
return this.itemsHeld.length; return this.itemsHeld.length;
} }
@ -130,10 +130,10 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) {
int slot = orderId - OrderIds.itemuse00; final int slot = orderId - OrderIds.itemuse00;
CBehavior behavior = itemsHeldAbilities[slot].get(0).beginNoTarget(game, caster, orderId); final CBehavior behavior = this.itemsHeldAbilities[slot].get(0).beginNoTarget(game, caster, orderId);
CItem cItem = itemsHeld[slot]; final CItem cItem = this.itemsHeld[slot];
if(cItem.getItemType().isPerishable()) { if (cItem.getItemType().isPerishable()) {
dropItem(game, caster, slot, caster.getX(), caster.getY(), false); dropItem(game, caster, slot, caster.getX(), caster.getY(), false);
game.removeItem(cItem); game.removeItem(cItem);
} }
@ -197,9 +197,10 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId,
final AbilityTargetCheckReceiver<Void> receiver) { final AbilityTargetCheckReceiver<Void> receiver) {
if(orderId >= OrderIds.itemuse00 && orderId <= OrderIds.itemuse05) { if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) {
receiver.targetOk(null); receiver.targetOk(null);
} else { }
else {
receiver.orderIdNotAccepted(); receiver.orderIdNotAccepted();
} }
} }
@ -207,14 +208,16 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
@Override @Override
protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId,
final AbilityActivationReceiver receiver) { final AbilityActivationReceiver receiver) {
if(orderId >= OrderIds.itemuse00 && orderId <= OrderIds.itemuse05){ if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) {
int slot = orderId - OrderIds.itemuse00; final int slot = orderId - OrderIds.itemuse00;
if(itemsHeldAbilities[slot].size() < 1) { if (this.itemsHeldAbilities[slot].size() < 1) {
receiver.notAnActiveAbility(); receiver.notAnActiveAbility();
} else {
itemsHeldAbilities[slot].get(0).checkCanUse(game, unit, orderId, receiver);
} }
} else { else {
this.itemsHeldAbilities[slot].get(0).checkCanUse(game, unit, orderId, receiver);
}
}
else {
receiver.useOk(); receiver.useOk();
} }
} }
@ -241,11 +244,15 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
if (this.itemsHeld[i] == null) { if (this.itemsHeld[i] == null) {
this.itemsHeld[i] = item; this.itemsHeld[i] = item;
item.setHidden(true); item.setHidden(true);
for(War3ID abilityId: item.getItemType().getAbilityList()) { for (final War3ID abilityId : item.getItemType().getAbilityList()) {
CAbility abilityFromItem = simulation.getAbilityData().getAbilityType(abilityId).createAbility(simulation.getHandleIdAllocator().createId()); final CAbilityType<?> abilityType = simulation.getAbilityData().getAbilityType(abilityId);
abilityFromItem.setIconShowing(false); if (abilityType != null) {
hero.add(simulation, abilityFromItem); final CAbility abilityFromItem = abilityType
itemsHeldAbilities[i].add(abilityFromItem); .createAbility(simulation.getHandleIdAllocator().createId());
abilityFromItem.setIconShowing(false);
hero.add(simulation, abilityFromItem);
this.itemsHeldAbilities[i].add(abilityFromItem);
}
} }
hero.onPickUpItem(simulation, item, true); hero.onPickUpItem(simulation, item, true);
return i; return i;
@ -264,7 +271,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
final CItem droppedItem = this.itemsHeld[slotIndex]; final CItem droppedItem = this.itemsHeld[slotIndex];
hero.onDropItem(simulation, droppedItem, playUserUISounds); hero.onDropItem(simulation, droppedItem, playUserUISounds);
this.itemsHeld[slotIndex] = null; this.itemsHeld[slotIndex] = null;
for(CAbility ability: itemsHeldAbilities[slotIndex]) { for (final CAbility ability : this.itemsHeldAbilities[slotIndex]) {
hero.remove(simulation, ability); hero.remove(simulation, ability);
} }
droppedItem.setHidden(false); droppedItem.setHidden(false);
@ -285,7 +292,7 @@ public class CAbilityInventory extends AbstractGenericNoIconAbility {
if (foundItem) { if (foundItem) {
hero.onDropItem(simulation, itemToDrop, playUserUISounds); hero.onDropItem(simulation, itemToDrop, playUserUISounds);
itemToDrop.setHidden(false); itemToDrop.setHidden(false);
for(CAbility ability: itemsHeldAbilities[index]) { for (final CAbility ability : this.itemsHeldAbilities[index]) {
hero.remove(simulation, ability); hero.remove(simulation, ability);
} }
itemToDrop.setPointAndCheckUnstuck(x, y, simulation); itemToDrop.setPointAndCheckUnstuck(x, y, simulation);

View File

@ -0,0 +1,69 @@
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors;
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.abilities.targeting.AbilityPointTarget;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds;
public class CBehaviorAttackMove implements CRangedBehavior {
private final CUnit unit;
private AbilityPointTarget target;
private boolean justAutoAttacked = false;
private boolean endedMove = false;
public CBehaviorAttackMove(final CUnit unit) {
this.unit = unit;
}
public CBehavior reset(final AbilityPointTarget target) {
this.target = target;
this.endedMove = false;
return this;
}
@Override
public int getHighlightOrderId() {
return OrderIds.attack;
}
@Override
public boolean isWithinRange(final CSimulation simulation) {
if (this.justAutoAttacked = this.unit.autoAcquireAttackTargets(simulation, false)) {
// kind of a hack
return true;
}
return innerIsWithinRange(); // TODO this is not how it was meant to be used
}
private boolean innerIsWithinRange() {
return this.unit.distance(this.target.x, this.target.y) <= 16f;
}
@Override
public CBehavior update(final CSimulation simulation) {
if (this.justAutoAttacked) {
this.justAutoAttacked = false;
return this.unit.getCurrentBehavior();
}
if (innerIsWithinRange()) {
this.unit.setDefaultBehavior(this.unit.getStopBehavior());
return this.unit.pollNextOrderBehavior(simulation);
}
return this.unit.getMoveBehavior().reset(this.target, this, false);
}
@Override
public void begin(final CSimulation game) {
}
@Override
public void end(final CSimulation game, final boolean interrupted) {
}
@Override
public void endMove(final CSimulation game, final boolean interrupted) {
}
}

View File

@ -34,6 +34,7 @@ public class CommandCardIcon extends AbstractRenderableFrame implements Clickabl
private int tipGoldCost; private int tipGoldCost;
private int tipLumberCost; private int tipLumberCost;
private int tipFoodCost; private int tipFoodCost;
private char hotkey;
public CommandCardIcon(final String name, final UIFrame parent, public CommandCardIcon(final String name, final UIFrame parent,
final CommandCardCommandListener commandCardCommandListener) { final CommandCardCommandListener commandCardCommandListener) {
@ -59,12 +60,15 @@ public class CommandCardIcon extends AbstractRenderableFrame implements Clickabl
this.autocastFrame.setVisible(false); this.autocastFrame.setVisible(false);
} }
setVisible(false); setVisible(false);
this.hotkey = '\0';
} }
public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId, public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId,
final int autoCastOrderId, final boolean active, final boolean autoCastActive, final boolean menuButton, final int autoCastOrderId, final boolean active, final boolean autoCastActive, final boolean menuButton,
final String tip, final String uberTip, final int goldCost, final int lumberCost, final int foodCost) { final String tip, final String uberTip, final char hotkey, final int goldCost, final int lumberCost,
final int foodCost) {
this.menuButton = menuButton; this.menuButton = menuButton;
this.hotkey = hotkey;
setVisible(true); setVisible(true);
this.iconFrame.setVisible(true); this.iconFrame.setVisible(true);
if (this.activeHighlightFrame != null) { if (this.activeHighlightFrame != null) {
@ -131,6 +135,15 @@ public class CommandCardIcon extends AbstractRenderableFrame implements Clickabl
return super.touchDown(screenX, screenY, button); return super.touchDown(screenX, screenY, button);
} }
public boolean checkHotkey(final char c, final int keycode) {
if ((c == this.hotkey) || (Character.toUpperCase(c) == this.hotkey)
|| ((this.hotkey == 0x7E) && (keycode == Input.Keys.ESCAPE))) {
onClick(Input.Buttons.LEFT);
return true;
}
return false;
}
@Override @Override
public UIFrame touchUp(final float screenX, final float screenY, final int button) { public UIFrame touchUp(final float screenX, final float screenY, final int button) {
if (isVisible() && this.renderBounds.contains(screenX, screenY)) { if (isVisible() && this.renderBounds.contains(screenX, screenY)) {

View File

@ -91,8 +91,20 @@ import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI;
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.ItemUI; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.ItemUI;
import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.UnitIconUI; import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.UnitIconUI;
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.*; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CGameplayConstants;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener;
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.QueueItemType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit.QueueItemType;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification;
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction;
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.CWidgetFilterFunction;
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.CAbilityGeneric; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric;
@ -1000,25 +1012,26 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
abilityToUse.checkCanTargetNoTarget(this.war3MapViewer.simulation, abilityToUse.checkCanTargetNoTarget(this.war3MapViewer.simulation,
this.selectedUnit.getSimulationUnit(), orderId, noTargetReceiver); this.selectedUnit.getSimulationUnit(), orderId, noTargetReceiver);
if (noTargetReceiver.isTargetable()) { if (noTargetReceiver.isTargetable()) {
boolean shiftDown = isShiftDown(); final boolean shiftDown = isShiftDown();
this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(), this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(),
abilityHandleId, orderId, shiftDown); abilityHandleId, orderId, shiftDown);
if(selectedUnits.size() > 1){ if (this.selectedUnits.size() > 1) {
for(RenderUnit otherSelectedUnit: selectedUnits) { for (final RenderUnit otherSelectedUnit : this.selectedUnits) {
if(otherSelectedUnit != activeCommandUnit) { if (otherSelectedUnit != this.activeCommandUnit) {
abilityToUse = null; abilityToUse = null;
for(CAbility ability: otherSelectedUnit.getSimulationUnit().getAbilities()) { for (final CAbility ability : otherSelectedUnit.getSimulationUnit().getAbilities()) {
BooleanAbilityTargetCheckReceiver<Void> receiver = BooleanAbilityTargetCheckReceiver.<Void>getInstance().reset(); final BooleanAbilityTargetCheckReceiver<Void> receiver = BooleanAbilityTargetCheckReceiver
ability.checkCanTargetNoTarget(war3MapViewer.simulation, otherSelectedUnit.getSimulationUnit(), activeCommandOrderId, receiver); .<Void>getInstance().reset();
if(receiver.isTargetable()) { ability.checkCanTargetNoTarget(this.war3MapViewer.simulation,
otherSelectedUnit.getSimulationUnit(), this.activeCommandOrderId, receiver);
if (receiver.isTargetable()) {
abilityToUse = ability; abilityToUse = ability;
} }
} }
if(abilityToUse != null) { if (abilityToUse != null) {
this.unitOrderListener.issueImmediateOrder( this.unitOrderListener.issueImmediateOrder(
otherSelectedUnit.getSimulationUnit().getHandleId(), otherSelectedUnit.getSimulationUnit().getHandleId(),
abilityToUse.getHandleId(), this.activeCommandOrderId, abilityToUse.getHandleId(), this.activeCommandOrderId, shiftDown);
shiftDown);
} }
} }
} }
@ -1035,9 +1048,9 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
else { else {
this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(), this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(),
abilityHandleId, orderId, isShiftDown()); abilityHandleId, orderId, isShiftDown());
if(selectedUnits.size() > 1) { if (this.selectedUnits.size() > 1) {
for (RenderUnit otherSelectedUnit : selectedUnits) { for (final RenderUnit otherSelectedUnit : this.selectedUnits) {
if (otherSelectedUnit != activeCommandUnit) { if (otherSelectedUnit != this.activeCommandUnit) {
this.unitOrderListener.issueImmediateOrder(otherSelectedUnit.getSimulationUnit().getHandleId(), this.unitOrderListener.issueImmediateOrder(otherSelectedUnit.getSimulationUnit().getHandleId(),
abilityHandleId, orderId, isShiftDown()); abilityHandleId, orderId, isShiftDown());
} }
@ -1126,7 +1139,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
this.hpBarFrameIndex = 0; this.hpBarFrameIndex = 0;
if (this.currentlyDraggingPointer == -1) { if (this.currentlyDraggingPointer == -1) {
if ((this.mouseOverUnit != null) && !this.mouseOverUnit.getSimulationWidget().isInvulnerable() && this.mouseOverUnit.isSelectable() && !this.mouseOverUnit.getSimulationWidget().isDead()) { if ((this.mouseOverUnit != null) && !this.mouseOverUnit.getSimulationWidget().isInvulnerable()
&& this.mouseOverUnit.isSelectable() && !this.mouseOverUnit.getSimulationWidget().isDead()) {
final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar(); final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar();
positionHealthBar(simpleStatusBarFrame, this.mouseOverUnit, 1.0f); positionHealthBar(simpleStatusBarFrame, this.mouseOverUnit, 1.0f);
} }
@ -1285,7 +1299,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
simpleStatusBarFrame.getBarFrame().setColor(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)), simpleStatusBarFrame.getBarFrame().setColor(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)),
Math.min(1.0f, lifeRatioRemaining * 2), 0, alpha); Math.min(1.0f, lifeRatioRemaining * 2), 0, alpha);
final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector); final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector);
simpleStatusBarFrame.setWidth(unit.getSelectionScale() * 1.5f * Gdx.graphics.getWidth() / 2560); simpleStatusBarFrame.setWidth((unit.getSelectionScale() * 1.5f * Gdx.graphics.getWidth()) / 2560);
simpleStatusBarFrame.setHeight(16); simpleStatusBarFrame.setHeight(16);
simpleStatusBarFrame.addSetPoint( simpleStatusBarFrame.addSetPoint(
new SetPoint(FramePoint.CENTER, this.rootFrame, FramePoint.BOTTOMLEFT, unprojected.x, unprojected.y)); new SetPoint(FramePoint.CENTER, this.rootFrame, FramePoint.BOTTOMLEFT, unprojected.x, unprojected.y));
@ -1471,7 +1485,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
@Override @Override
public Void accept(CAbilityReviveHero ability) { public Void accept(final CAbilityReviveHero ability) {
handleTargetCursor(ability); handleTargetCursor(ability);
return null; return null;
} }
@ -1806,8 +1820,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
final CItem item = inventory.getItemInSlot(index); final CItem item = inventory.getItemInSlot(index);
if (item == null) { if (item == null) {
if (index < inventory.getItemCapacity()) { if (index < inventory.getItemCapacity()) {
inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null, null, 0, inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null, null,
0, 0); '\0', 0, 0, 0);
} }
} }
index++; index++;
@ -1986,7 +2000,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
private void reloadSelectedUnitUI(final RenderUnit unit) { private void reloadSelectedUnitUI(final RenderUnit unit) {
if(unit == null) { if (unit == null) {
return; return;
} }
final CUnit simulationUnit = unit.getSimulationUnit(); final CUnit simulationUnit = unit.getSimulationUnit();
@ -2029,14 +2043,14 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.queueIconFrames[i].setUberTip(upgradeUI.getUberTip()); this.queueIconFrames[i].setUberTip(upgradeUI.getUberTip());
break; break;
case HERO_REVIVE: { case HERO_REVIVE: {
War3ID handleIdEncoded = simulationUnit.getBuildQueue()[i]; final War3ID handleIdEncoded = simulationUnit.getBuildQueue()[i];
CUnit hero = war3MapViewer.simulation.getUnit(handleIdEncoded.getValue()); final CUnit hero = this.war3MapViewer.simulation.getUnit(handleIdEncoded.getValue());
final UnitIconUI unitUI = this.war3MapViewer.getAbilityDataUI() final UnitIconUI unitUI = this.war3MapViewer.getAbilityDataUI().getUnitUI(hero.getTypeId());
.getUnitUI(hero.getTypeId()); this.queueIconFrames[i].setTexture(unitUI.getIcon());
this.queueIconFrames[i].setTexture(unitUI.getIcon()); this.queueIconFrames[i]
this.queueIconFrames[i].setToolTip(unitUI.getReviveTip() + " - " + hero.getHeroData().getProperName()); .setToolTip(unitUI.getReviveTip() + " - " + hero.getHeroData().getProperName());
this.queueIconFrames[i].setUberTip(unitUI.getUberTip()); this.queueIconFrames[i].setUberTip(unitUI.getUberTip());
break; break;
} }
case UNIT: case UNIT:
default: { default: {
@ -2061,7 +2075,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.UNIT) { if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.UNIT) {
this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, this.rootFrame.setText(this.simpleBuildingBuildingActionLabel,
this.rootFrame.getTemplates().getDecoratedString("TRAINING")); this.rootFrame.getTemplates().getDecoratedString("TRAINING"));
} else if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.HERO_REVIVE) { }
else if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.HERO_REVIVE) {
this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, this.rootFrame.setText(this.simpleBuildingBuildingActionLabel,
this.rootFrame.getTemplates().getDecoratedString("REVIVING")); this.rootFrame.getTemplates().getDecoratedString("REVIVING"));
} }
@ -2291,19 +2306,19 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
this.recycleStringBuilder.append(uberTip); this.recycleStringBuilder.append(uberTip);
inventoryIcon.setCommandButtonData(iconUI.getIcon(), 0, inventoryIcon.setCommandButtonData(iconUI.getIcon(), 0,
activelyUsed ? (OrderIds.itemuse00+index) : 0, index + 1, activelyUsed, activelyUsed ? (OrderIds.itemuse00 + index) : 0, index + 1, activelyUsed, false, false,
false, false, itemUI.getName(), this.recycleStringBuilder.toString(), itemUI.getName(), this.recycleStringBuilder.toString(), '\0', itemType.getGoldCost(),
itemType.getGoldCost(), itemType.getLumberCost(), 0); itemType.getLumberCost(), 0);
} }
else { else {
if (index >= inventory.getItemCapacity()) { if (index >= inventory.getItemCapacity()) {
inventoryIcon.setCommandButtonData(this.consoleInventoryNoCapacityTexture, 0, 0, 0, false, inventoryIcon.setCommandButtonData(this.consoleInventoryNoCapacityTexture, 0, 0, 0, false,
false, false, null, null, 0, 0, 0); false, false, null, null, '\0', 0, 0, 0);
} }
else { else {
if (this.draggingItem != null) { if (this.draggingItem != null) {
inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null, inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null,
null, 0, 0, 0); null, '\0', 0, 0, 0);
} }
else { else {
inventoryIcon.clear(); inventoryIcon.clear();
@ -2329,7 +2344,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
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 abilityHandleId, final int orderId, final int autoCastId, final boolean active, final int abilityHandleId, final int orderId, final int autoCastId, final boolean active,
final boolean autoCastActive, final boolean menuButton, final String tip, final String uberTip, final boolean autoCastActive, final boolean menuButton, final String tip, final String uberTip,
final int goldCost, final int lumberCost, final int foodCost) { final char hotkey, final int goldCost, final int lumberCost, final int foodCost) {
int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX)); int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX));
int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY)); int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY));
while ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT) && this.commandCard[y][x].isVisible()) { while ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT) && this.commandCard[y][x].isVisible()) {
@ -2341,7 +2356,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
if ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT)) { if ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT)) {
this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active, this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active,
autoCastActive, menuButton, tip, uberTip, goldCost, lumberCost, foodCost); autoCastActive, menuButton, tip, uberTip, hotkey, goldCost, lumberCost, foodCost);
} }
} }
@ -2422,7 +2437,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
@Override @Override
public void lifeChanged() { public void lifeChanged() {
if(selectedUnit == null) { if (this.selectedUnit == null) {
return; return;
} }
if (this.selectedUnit.getSimulationUnit().isDead()) { if (this.selectedUnit.getSimulationUnit().isDead()) {
@ -2478,8 +2493,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
@Override @Override
public void heroDeath() { public void heroDeath() {
if(this.selectedUnit!=null) { if (this.selectedUnit != null) {
if(this.selectedUnit.getSimulationUnit().getUnitType().isRevivesHeroes()) { if (this.selectedUnit.getSimulationUnit().getUnitType().isRevivesHeroes()) {
reloadSelectedUnitUI(this.selectedUnit); reloadSelectedUnitUI(this.selectedUnit);
} }
} }
@ -2516,7 +2531,8 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
if ((this.activeCommand != null) && (this.draggingItem == null)) { if ((this.activeCommand != null) && (this.draggingItem == null)) {
final IconUI cancelUI = abilityDataUI.getCancelUI(); final IconUI cancelUI = abilityDataUI.getCancelUI();
this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0, this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0,
menuOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, 0); menuOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(),
cancelUI.getHotkey(), 0, 0, 0);
} }
else { else {
if (menuOrderId != 0) { if (menuOrderId != 0) {
@ -2525,11 +2541,11 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
: 0; : 0;
final IconUI cancelUI = abilityDataUI.getCancelUI(); final IconUI cancelUI = abilityDataUI.getCancelUI();
this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(),
0, exitOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), 0, 0, 0, exitOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(),
0); cancelUI.getHotkey(), 0, 0, 0);
} }
this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this.rootFrame, this, this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this.rootFrame, this,
abilityDataUI, menuOrderId, selectedUnits.size() > 1); abilityDataUI, menuOrderId, this.selectedUnits.size() > 1);
} }
} }
} }
@ -2544,11 +2560,23 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
} }
public boolean keyDown(final int keycode) { public boolean keyDown(final int keycode) {
if (keycode == Input.Keys.Z) { if (WarsmashConstants.ENABLE_DEBUG) {
War3MapViewer.DEBUG_DEPTH++; if (keycode == Input.Keys.Z) {
War3MapViewer.DEBUG_DEPTH++;
}
if (keycode == Input.Keys.X) {
War3MapViewer.DEBUG_DEPTH = 0;
}
} }
if (keycode == Input.Keys.X) { final String keyString = Input.Keys.toString(keycode);
War3MapViewer.DEBUG_DEPTH = 0; final char c = keyString.length() == 1 ? keyString.charAt(0) : ' ';
for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) {
for (int i = 0; i < COMMAND_CARD_WIDTH; i++) {
if (this.commandCard[j][i].checkHotkey(c, keycode)) {
this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0,
0);
}
}
} }
return this.cameraManager.keyDown(keycode); return this.cameraManager.keyDown(keycode);
} }
@ -2594,20 +2622,24 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.activeCommandUnit.getSimulationUnit().getHandleId(), this.activeCommandUnit.getSimulationUnit().getHandleId(),
this.activeCommand.getHandleId(), this.activeCommandOrderId, this.activeCommand.getHandleId(), this.activeCommandOrderId,
rayPickUnit.getSimulationWidget().getHandleId(), shiftDown); rayPickUnit.getSimulationWidget().getHandleId(), shiftDown);
if(selectedUnits.size() > 1){ if (this.selectedUnits.size() > 1) {
for(RenderUnit otherSelectedUnit: selectedUnits) { for (final RenderUnit otherSelectedUnit : this.selectedUnits) {
if(otherSelectedUnit != activeCommandUnit) { if (otherSelectedUnit != this.activeCommandUnit) {
CAbility abilityToUse = null; CAbility abilityToUse = null;
CWidget targetToUse = null; CWidget targetToUse = null;
for(CAbility ability: otherSelectedUnit.getSimulationUnit().getAbilities()) { for (final CAbility ability : otherSelectedUnit.getSimulationUnit()
CWidgetAbilityTargetCheckReceiver receiver = CWidgetAbilityTargetCheckReceiver.INSTANCE.reset(); .getAbilities()) {
ability.checkCanTarget(war3MapViewer.simulation, otherSelectedUnit.getSimulationUnit(), activeCommandOrderId, rayPickUnit.getSimulationWidget(), receiver); final CWidgetAbilityTargetCheckReceiver receiver = CWidgetAbilityTargetCheckReceiver.INSTANCE
if(receiver.getTarget() != null) { .reset();
ability.checkCanTarget(this.war3MapViewer.simulation,
otherSelectedUnit.getSimulationUnit(), this.activeCommandOrderId,
rayPickUnit.getSimulationWidget(), receiver);
if (receiver.getTarget() != null) {
abilityToUse = ability; abilityToUse = ability;
targetToUse = receiver.getTarget(); targetToUse = receiver.getTarget();
} }
} }
if(abilityToUse != null) { if (abilityToUse != null) {
this.unitOrderListener.issueTargetOrder( this.unitOrderListener.issueTargetOrder(
otherSelectedUnit.getSimulationUnit().getHandleId(), otherSelectedUnit.getSimulationUnit().getHandleId(),
abilityToUse.getHandleId(), this.activeCommandOrderId, abilityToUse.getHandleId(), this.activeCommandOrderId,
@ -2674,20 +2706,24 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
this.activeCommandUnit.getSimulationUnit().getHandleId(), this.activeCommandUnit.getSimulationUnit().getHandleId(),
this.activeCommand.getHandleId(), this.activeCommandOrderId, this.activeCommand.getHandleId(), this.activeCommandOrderId,
clickLocationTemp2.x, clickLocationTemp2.y, shiftDown); clickLocationTemp2.x, clickLocationTemp2.y, shiftDown);
if(selectedUnits.size() > 1){ if (this.selectedUnits.size() > 1) {
for(RenderUnit otherSelectedUnit: selectedUnits) { for (final RenderUnit otherSelectedUnit : this.selectedUnits) {
if(otherSelectedUnit != activeCommandUnit) { if (otherSelectedUnit != this.activeCommandUnit) {
CAbility abilityToUse = null; CAbility abilityToUse = null;
AbilityPointTarget targetToUse = null; AbilityPointTarget targetToUse = null;
for(CAbility ability: otherSelectedUnit.getSimulationUnit().getAbilities()) { for (final CAbility ability : otherSelectedUnit.getSimulationUnit()
PointAbilityTargetCheckReceiver receiver = PointAbilityTargetCheckReceiver.INSTANCE.reset(); .getAbilities()) {
ability.checkCanTarget(war3MapViewer.simulation, otherSelectedUnit.getSimulationUnit(), activeCommandOrderId, clickLocationTemp2, receiver); final PointAbilityTargetCheckReceiver receiver = PointAbilityTargetCheckReceiver.INSTANCE
if(receiver.getTarget() != null) { .reset();
ability.checkCanTarget(this.war3MapViewer.simulation,
otherSelectedUnit.getSimulationUnit(),
this.activeCommandOrderId, clickLocationTemp2, receiver);
if (receiver.getTarget() != null) {
abilityToUse = ability; abilityToUse = ability;
targetToUse = receiver.getTarget(); targetToUse = receiver.getTarget();
} }
} }
if(abilityToUse != null) { if (abilityToUse != null) {
this.unitOrderListener.issuePointOrder( this.unitOrderListener.issuePointOrder(
otherSelectedUnit.getSimulationUnit().getHandleId(), otherSelectedUnit.getSimulationUnit().getHandleId(),
abilityToUse.getHandleId(), this.activeCommandOrderId, abilityToUse.getHandleId(), this.activeCommandOrderId,
@ -2745,7 +2781,7 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
targetToUse = targetWidget; targetToUse = targetWidget;
} }
} }
if(abilityToUse != null) { if (abilityToUse != null) {
this.unitOrderListener.issueTargetOrder(unit.getSimulationUnit().getHandleId(), this.unitOrderListener.issueTargetOrder(unit.getSimulationUnit().getHandleId(),
abilityToUse.getHandleId(), OrderIds.smart, targetToUse.getHandleId(), abilityToUse.getHandleId(), OrderIds.smart, targetToUse.getHandleId(),
isShiftDown()); isShiftDown());
@ -3172,17 +3208,20 @@ public class MeleeUI implements CUnitStateListener, CommandButtonListener, Comma
MeleeUI.this.activeCommandUnit = selectedUnit2; MeleeUI.this.activeCommandUnit = selectedUnit2;
} }
} }
} else { }
CSimulation game = war3MapViewer.simulation; else {
BooleanAbilityActivationReceiver receiver = BooleanAbilityActivationReceiver.INSTANCE; final CSimulation game = MeleeUI.this.war3MapViewer.simulation;
CAbilityInventory inventoryData = simulationUnit.getInventoryData(); final BooleanAbilityActivationReceiver receiver = BooleanAbilityActivationReceiver.INSTANCE;
final CAbilityInventory inventoryData = simulationUnit.getInventoryData();
inventoryData.checkCanUse(game, simulationUnit, orderId, receiver); inventoryData.checkCanUse(game, simulationUnit, orderId, receiver);
if(receiver.isOk()) { if (receiver.isOk()) {
BooleanAbilityTargetCheckReceiver<Void> targetReceiver = BooleanAbilityTargetCheckReceiver.getInstance(); final BooleanAbilityTargetCheckReceiver<Void> targetReceiver = BooleanAbilityTargetCheckReceiver
.getInstance();
targetReceiver.reset(); targetReceiver.reset();
inventoryData.checkCanTargetNoTarget(game, simulationUnit, orderId, targetReceiver); inventoryData.checkCanTargetNoTarget(game, simulationUnit, orderId, targetReceiver);
if(targetReceiver.isTargetable()) { if (targetReceiver.isTargetable()) {
MeleeUI.this.unitOrderListener.issueImmediateOrder(simulationUnit.getHandleId(), inventoryData.getHandleId(), orderId, isShiftDown()); MeleeUI.this.unitOrderListener.issueImmediateOrder(simulationUnit.getHandleId(),
inventoryData.getHandleId(), orderId, isShiftDown());
} }
} }
} }