From 257dfe79bcaad63309cde31aa8c0be38ba9caa4c Mon Sep 17 00:00:00 2001 From: Glasir Date: Sun, 5 Nov 2023 06:03:46 -0500 Subject: [PATCH] Implemented Ability Requirements! * AB: Implemented requirement checks * AB: Added ability actions for adding and removing when the ability is disabled (used primarily for transformations) * Core: Added hooks for ability requirement checks * Core: Added callbacks to enable and disabled abilities as techtree requirements change * Core: Updated ability tooltips to list requirements * Core: Updated ability disable methods to track different sources of disabling * AB: Fixed issues with morph flags not working on takeoff * Core: Fixed issue with flying height changing unexpectedly on unit type change --- .../abilityBehaviors/Transformations.json | 28 +-- .../abilityBehaviors/humanUnitActives.json | 2 +- .../etheller/warsmash/parsers/jass/Jass2.java | 2 +- ...CardActivationReceiverPreviewCallback.java | 2 +- .../CommandCardPopulatingAbilityVisitor.java | 3 +- .../handlers/w3x/simulation/CSimulation.java | 4 +- .../handlers/w3x/simulation/CUnit.java | 96 ++++++++-- .../abilities/AbstractCAbility.java | 35 +++- .../w3x/simulation/abilities/CAbility.java | 10 +- .../abilities/CAbilityDisableType.java | 20 ++ .../simulation/abilities/CAbilityView.java | 4 + .../root/CAbilityEntangleGoldMine.java | 1 + .../types/definitions/impl/AbilityFields.java | 4 + ...AbilityAbilityBuilderActiveFlexTarget.java | 7 +- .../CAbilityAbilityBuilderGenericActive.java | 173 ++++++++++++------ .../unit/ABActionDisableWorkerAbilities.java | 4 +- .../unit/ABActionEnableWorkerAbilities.java | 4 +- .../handler/TransformationHandler.java | 10 +- .../parser/AbilityBuilderConfiguration.java | 35 +++- .../parser/AbilityBuilderParser.java | 32 +++- .../TransformationMorphAnimationTimer.java | 13 +- .../CAbilityTypeDefinitionAbilityBuilder.java | 14 +- ...yTypeDefinitionAbilityTemplateBuilder.java | 14 +- .../CAbilityTypeAbilityBuilderLevelData.java | 19 +- ...yDisableWhileUnderConstructionVisitor.java | 49 ++--- .../AbilityDisableWhileUpgradingVisitor.java | 47 ++--- .../behaviors/build/CBehaviorHumanBuild.java | 1 + .../behaviors/build/CBehaviorOrcBuild.java | 1 + .../behaviors/build/CBehaviorUndeadBuild.java | 1 + .../w3x/simulation/players/CPlayer.java | 23 ++- 30 files changed, 494 insertions(+), 164 deletions(-) create mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityDisableType.java diff --git a/core/assets/abilityBehaviors/Transformations.json b/core/assets/abilityBehaviors/Transformations.json index bebf038e..8ce59d5a 100644 --- a/core/assets/abilityBehaviors/Transformations.json +++ b/core/assets/abilityBehaviors/Transformations.json @@ -219,7 +219,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "if", "condition": { "type": "isToggleAbilityActive" @@ -301,7 +301,7 @@ }], "elseActions": [] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -657,7 +657,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "if", "condition": { "type": "isToggleAbilityActive" @@ -745,7 +745,7 @@ }], "elseActions": [] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -1110,7 +1110,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "createNonStackingStatBuff", "buffType": { "type": "getNonStackingStatBuffTypeFromString", @@ -1226,7 +1226,7 @@ }], "elseActions": [] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -1621,7 +1621,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "createStateModBuff", "buffType": "ETHEREAL" },{ @@ -1732,7 +1732,7 @@ } }] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -2108,7 +2108,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "createStateModBuff", "buffType": "ETHEREAL" },{ @@ -2211,7 +2211,7 @@ }], "elseActions": [] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -2596,7 +2596,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "if", "condition": { "type": "isToggleAbilityActive" @@ -2678,7 +2678,7 @@ }], "elseActions": [] }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" @@ -3038,7 +3038,7 @@ } } }, - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "createNonStackingStatBuff", "buffType": { "type": "getNonStackingStatBuffTypeFromString", @@ -3055,7 +3055,7 @@ "dataField": "E" } }], - "onRemoveAbility": [{ + "onRemoveDisabledAbility": [{ "type": "transformedUnitAbilityRemove", "unit": { "type": "getCastingUnit" diff --git a/core/assets/abilityBehaviors/humanUnitActives.json b/core/assets/abilityBehaviors/humanUnitActives.json index 401e8775..b25a419b 100644 --- a/core/assets/abilityBehaviors/humanUnitActives.json +++ b/core/assets/abilityBehaviors/humanUnitActives.json @@ -569,7 +569,7 @@ } } }], - "onAddAbility": [{ + "onAddDisabledAbility": [{ "type": "if", "condition": { "type": "isToggleAbilityActive" diff --git a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java b/core/src/com/etheller/warsmash/parsers/jass/Jass2.java index 22e64762..4be1c565 100644 --- a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java +++ b/core/src/com/etheller/warsmash/parsers/jass/Jass2.java @@ -2330,7 +2330,7 @@ public JassValue call(final List arguments, final GlobalScope globalS final double facing = arguments.get(3).visit(RealJassValueVisitor.getInstance()); final War3ID blightedMineRawcode = War3ID.fromString("ugol"); final War3ID goldMineRawcode = War3ID.fromString("ngol"); - player.addTechtreeUnlocked(blightedMineRawcode); + player.addTechtreeUnlocked(simulation, blightedMineRawcode); final CUnit blightedMine = CommonEnvironment.this.simulation.createUnitSimple( blightedMineRawcode, player.getId(), (float) x, (float) y, (float) facing); final CUnit goldMine = CommonEnvironment.this.simulation.createUnitSimple(goldMineRawcode, diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardActivationReceiverPreviewCallback.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardActivationReceiverPreviewCallback.java index 916721f8..6b659c4d 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardActivationReceiverPreviewCallback.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardActivationReceiverPreviewCallback.java @@ -56,7 +56,7 @@ public void missingRequirement(final War3ID type, final int level) { final CUnitType unitType = unitData.getUnitType(type); String requirementString; if (unitType != null) { - requirementString = unitType.getName(); + requirementString = level + " " + unitType.getName() + (level > 1 ? "s" : ""); } else { final CUpgradeType upgradeType = upgradeData .getType(type); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java index 8e0f0527..9556ccb3 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java @@ -459,7 +459,7 @@ private void addCommandButton(final CAbility ability, final IconUI iconUI, final private void addCommandButton(final CAbility ability, final Texture icon, final Texture iconDisabled, final String toolTip, String uberTip, final int buttonPosX, final int buttonPosY, final int handleId, final int orderId, final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, - int goldCost, int lumberCost, int foodCost, final int manaCost, final int numberOverlay, + int goldCost, int lumberCost, int foodCost, int manaCost, final int numberOverlay, final char hotkey) { boolean requiresPatron = false; if (this.unit.getPlayerIndex() != this.localPlayerIndex) { @@ -496,6 +496,7 @@ private void addCommandButton(final CAbility ability, final Texture icon, final goldCost = 0; lumberCost = 0; foodCost = 0; + manaCost = 0; } if (this.previewCallback.isShowingRequirements()) { uberTip = this.previewCallback.getRequirementsText() + "|r" + uberTip; diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java index ff0f66eb..7fbd5baa 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java @@ -303,7 +303,7 @@ public CUnit createUnitSimple(final War3ID typeId, final int playerIndex, final if (newUnitType.getFoodMade() != 0) { player.setFoodCap(player.getFoodCap() + newUnitType.getFoodMade()); } - player.addTechtreeUnlocked(typeId); + player.addTechtreeUnlocked(this, typeId); // nudge unit newUnit.setPointAndCheckUnstuck(x, y, this); if (!newUnit.isBuilding()) { @@ -677,7 +677,7 @@ public void unitsLoaded() { final CPlayer player = this.players.get(unit.getPlayerIndex()); player.setUnitFoodUsed(unit, unit.getUnitType().getFoodUsed()); player.setUnitFoodMade(unit, unit.getUnitType().getFoodMade()); - player.addTechtreeUnlocked(unit.getTypeId()); + player.addTechtreeUnlocked(this, unit.getTypeId()); } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java index dfa2cb6a..5e0dd3aa 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java @@ -28,6 +28,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener.CUnitStateNotifier; 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.CAbilityDisableType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.GetAbilityByRawcodeVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; @@ -149,6 +150,7 @@ public class CUnit extends CWidget { private int playerIndex; private final List abilities = new ArrayList<>(); + private final List disabledAbilities = new ArrayList<>(); private CBehavior currentBehavior; private final Queue orderQueue = new LinkedList<>(); @@ -456,8 +458,9 @@ public void computeUnitState(CSimulation game, StateModBuffType type) { } CAbility attack = this.getFirstAbilityOfType(CAbilityAttack.class); if (attack != null) { - attack.setDisabled(isDisableAttack); + attack.setDisabled(isDisableAttack, CAbilityDisableType.ATTACKDISABLED); } + this.checkDisabledAbilities(game, isDisableAttack); if (isEthereal) { if (!this.damageTakenModificationListeners.contains(CUnitDefaultEtherealDamageModListener.INSTANCE)) { @@ -574,8 +577,10 @@ public void computeUnitState(CSimulation game, StateModBuffType type) { this.setFlyHeight(0); this.moveDisabled = true; } else { - this.setFlyHeight(this.unitType.getDefaultFlyingHeight()); - this.moveDisabled = false; + if (this.moveDisabled) { + this.setFlyHeight(this.unitType.getDefaultFlyingHeight()); + this.moveDisabled = false; + } } break; case INVULNERABLE: @@ -1269,10 +1274,22 @@ public CUnitAnimationListener getUnitAnimationListener() { } public void add(final CSimulation simulation, final CAbility ability) { - this.abilities.add(ability); - simulation.onAbilityAddedToUnit(this, ability); - ability.onAdd(simulation, this); - this.stateNotifier.abilitiesChanged(); + if (!ability.isRequirementsMet(simulation, this)) { + ability.setDisabled(true, CAbilityDisableType.REQUIREMENTS); + } + if (ability.isDisabled()) { + this.disabledAbilities.add(ability); + this.abilities.add(ability); + simulation.onAbilityAddedToUnit(this, ability); + ability.onAddDisabled(simulation, this); + this.stateNotifier.abilitiesChanged(); + } else { + this.abilities.add(ability); + simulation.onAbilityAddedToUnit(this, ability); + ability.onAddDisabled(simulation, this); + ability.onAdd(simulation, this); + this.stateNotifier.abilitiesChanged(); + } } public void add(final CSimulation simulation, final CBuff ability) { @@ -1287,10 +1304,19 @@ public void add(final CSimulation simulation, final CBuff ability) { } public void remove(final CSimulation simulation, final CAbility ability) { - this.abilities.remove(ability); - simulation.onAbilityRemovedFromUnit(this, ability); - ability.onRemove(simulation, this); - // this.stateNotifier.abilitiesChanged(); + if (this.disabledAbilities.contains(ability)) { + this.abilities.remove(ability); + this.disabledAbilities.remove(ability); + simulation.onAbilityRemovedFromUnit(this, ability); + ability.onRemoveDisabled(simulation, this); + this.stateNotifier.abilitiesChanged(); + } else { + this.abilities.remove(ability); + simulation.onAbilityRemovedFromUnit(this, ability); + ability.onRemove(simulation, this); + ability.onRemoveDisabled(simulation, this); + this.stateNotifier.abilitiesChanged(); + } } public void remove(final CSimulation simulation, final CBuff ability) { @@ -1299,6 +1325,34 @@ public void remove(final CSimulation simulation, final CBuff ability) { ability.onRemove(simulation, this); this.stateNotifier.abilitiesChanged(); } + + public void checkDisabledAbilities(final CSimulation simulation, final boolean disable) { + if (disable) { + for (CAbility ability : this.abilities) { + if (!ability.isRequirementsMet(simulation, this)) { + ability.setDisabled(true, CAbilityDisableType.REQUIREMENTS); + } + if (ability.isDisabled() && !this.disabledAbilities.contains(ability)) { +// System.err.println("Disabling ability: " + ability.getAlias().asStringValue()); + this.disabledAbilities.add(ability); + ability.onRemove(simulation, this); + } + } + } else { + final Iterator abilityIterator = this.disabledAbilities.iterator(); + while (abilityIterator.hasNext()) { + final CAbility ability = abilityIterator.next(); + if (ability.isRequirementsMet(simulation, this)) { + ability.setDisabled(false, CAbilityDisableType.REQUIREMENTS); + } + if (!ability.isDisabled()) { +// System.err.println("Enabling ability: " + ability.getAlias().asStringValue()); + ability.onAdd(simulation, this); + abilityIterator.remove(); + } + } + } + } public War3ID getTypeId() { return this.typeId; @@ -1329,7 +1383,10 @@ public void setTypeId(final CSimulation game, final War3ID typeId) { public void setTypeId(final CSimulation game, final War3ID typeId, boolean updateArt) { game.getWorldCollision().removeUnit(this); + CPlayer player = game.getPlayer(this.playerIndex); + player.removeTechtreeUnlocked(game, this.typeId); this.typeId = typeId; + player.addTechtreeUnlocked(game, this.typeId); final float lifeRatio = this.maximumLife == 0 ? 1 : this.life / this.maximumLife; final float manaRatio = this.maximumMana == 0 ? Float.NaN : this.mana / this.maximumMana; final CUnitType previousUnitType = getUnitType(); @@ -1536,10 +1593,11 @@ public boolean update(final CSimulation game) { if (ability instanceof CAbilityBuildInProgress) { abilityIterator.remove(); } else { - ability.setDisabled(false); + ability.setDisabled(false, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(true); } } + this.checkDisabledAbilities(game, false); final CPlayer player = game.getPlayer(this.playerIndex); if (upgrading) { if (this.unitType.getFoodMade() != 0) { @@ -1552,7 +1610,7 @@ public boolean update(final CSimulation game) { player.setFoodCap(player.getFoodCap() + this.unitType.getFoodMade()); } player.removeTechtreeInProgress(this.unitType.getTypeId()); - player.addTechtreeUnlocked(this.unitType.getTypeId()); + player.addTechtreeUnlocked(game, this.unitType.getTypeId()); if (!upgrading) { game.unitConstructFinishEvent(this); fireConstructFinishEvents(game); @@ -1612,7 +1670,7 @@ public boolean update(final CSimulation game) { final CPlayer player = game.getPlayer(this.playerIndex); player.setUnitFoodMade(trainedUnit, trainedUnitType.getFoodMade()); player.removeTechtreeInProgress(queuedRawcode); - player.addTechtreeUnlocked(queuedRawcode); + player.addTechtreeUnlocked(game, queuedRawcode); fireTrainFinishEvents(game, trainedUnit); // nudge the trained unit out around us trainedUnit.nudgeAround(game, this); @@ -1642,7 +1700,7 @@ public boolean update(final CSimulation game) { final CPlayer player = game.getPlayer(this.playerIndex); player.setUnitFoodMade(trainedUnit, trainedUnitType.getFoodMade()); player.removeTechtreeInProgress(queuedRawcode); - player.addTechtreeUnlocked(queuedRawcode); + player.addTechtreeUnlocked(game, queuedRawcode); fireTrainFinishEvents(game, trainedUnit); // nudge the trained unit out around us trainedUnit.nudgeAround(game, this); @@ -2419,7 +2477,7 @@ private void kill(final CSimulation simulation, final CUnit source) { if (this.constructing) { player.removeTechtreeInProgress(this.unitType.getTypeId()); } else { - player.removeTechtreeUnlocked(this.unitType.getTypeId()); + player.removeTechtreeUnlocked(simulation, this.unitType.getTypeId()); } } // else its a hero and techtree "remains unlocked" which is currently meaning @@ -3575,7 +3633,7 @@ public void onRemove(final CSimulation simulation) { if (this.constructing) { player.removeTechtreeInProgress(this.unitType.getTypeId()); } else { - player.removeTechtreeUnlocked(this.unitType.getTypeId()); + player.removeTechtreeUnlocked(simulation, this.unitType.getTypeId()); } setHidden(true); // setting hidden to let things that refer to this before it gets garbage @@ -3626,10 +3684,11 @@ public void cancelUpgrade(final CSimulation game) { if (ability instanceof CAbilityBuildInProgress) { abilityIterator.remove(); } else { - ability.setDisabled(false); + ability.setDisabled(false, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(true); } } + this.checkDisabledAbilities(game, false); game.unitCancelUpgradingEvent(this, this.upgradeIdType); this.upgradeIdType = null; @@ -3659,6 +3718,7 @@ public void beginUpgrade(final CSimulation game, final War3ID rawcode) { for (final CAbility ability : getAbilities()) { ability.visit(AbilityDisableWhileUpgradingVisitor.INSTANCE); } + this.checkDisabledAbilities(game, true); player.addTechtreeInProgress(rawcode); game.unitUpgradingEvent(this, rawcode); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java index 087d6987..8283d1db 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java @@ -8,7 +8,7 @@ public abstract class AbstractCAbility implements CAbility { private final int handleId; - private boolean disabled = false; + private byte disabled = 0; private boolean iconShowing = true; private boolean permanent = false; @@ -35,12 +35,16 @@ public War3ID getAlias() { @Override public final boolean isDisabled() { - return this.disabled; + return this.disabled != 0; } @Override - public final void setDisabled(final boolean disabled) { - this.disabled = disabled; + public final void setDisabled(final boolean disabled, CAbilityDisableType type) { + if (disabled) { + this.disabled |= type.getMask(); + } else { + this.disabled &= ~type.getMask(); + } } @Override @@ -71,8 +75,9 @@ public void setItemAbility(CItem item, int slot) { @Override public final void checkCanUse(final CSimulation game, final CUnit unit, final int orderId, final AbilityActivationReceiver receiver) { - if (this.disabled) { + if (this.isDisabled()) { receiver.disabled(); + this.checkRequirementsMet(game, unit, receiver); } else { innerCheckCanUse(game, unit, orderId, receiver); @@ -85,4 +90,24 @@ protected abstract void innerCheckCanUse(final CSimulation game, final CUnit uni @Override public void onSetUnitType(final CSimulation game, final CUnit cUnit) { } + + @Override + public void checkRequirementsMet(CSimulation game, CUnit unit, AbilityActivationReceiver receiver) { + + } + + @Override + public boolean isRequirementsMet(CSimulation game, CUnit unit) { + return true; + } + + @Override + public void onAddDisabled(CSimulation game, CUnit unit) { + //do nothing + } + + @Override + public void onRemoveDisabled(CSimulation game, CUnit unit) { + //do nothing + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java index ee16b5ec..0865794a 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java @@ -10,11 +10,17 @@ public interface CAbility extends CAbilityView { /* should fire when ability added to unit */ + void onAddDisabled(CSimulation game, CUnit unit); + + /* should fire when ability added to unit only if the ability is not disabled at the time */ void onAdd(CSimulation game, CUnit unit); - /* should fire when ability removed from unit */ + /* should fire when ability removed from unit only if the ability is not disabled at the time */ void onRemove(CSimulation game, CUnit unit); + /* should fire when ability removed from unit */ + void onRemoveDisabled(CSimulation game, CUnit unit); + void onTick(CSimulation game, CUnit unit); void onDeath(CSimulation game, CUnit cUnit); @@ -35,7 +41,7 @@ public interface CAbility extends CAbilityView { CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId); - void setDisabled(boolean disabled); + void setDisabled(boolean disabled, CAbilityDisableType type); void setIconShowing(boolean iconShowing); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityDisableType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityDisableType.java new file mode 100644 index 00000000..637a9056 --- /dev/null +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityDisableType.java @@ -0,0 +1,20 @@ +package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; + +public enum CAbilityDisableType { + REQUIREMENTS((byte) 1), + CONSTRUCTION((byte) 2), + TRANSFORMATION((byte) 4), + TRIGGER((byte) 8), + ATTACKDISABLED((byte) 16); + + private byte mask; + + CAbilityDisableType(byte i) { + this.mask = i; + } + + public byte getMask() { + return mask; + } + +} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java index e9618697..b325e40b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java @@ -20,6 +20,10 @@ void checkCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarge void checkCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver receiver); + void checkRequirementsMet(CSimulation game, CUnit unit, AbilityActivationReceiver receiver); + + boolean isRequirementsMet(CSimulation game, CUnit unit); + @Override int getHandleId(); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/nightelf/root/CAbilityEntangleGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/nightelf/root/CAbilityEntangleGoldMine.java index be646ab4..ee613f63 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/nightelf/root/CAbilityEntangleGoldMine.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/nightelf/root/CAbilityEntangleGoldMine.java @@ -138,6 +138,7 @@ public boolean doEffect(final CSimulation simulation, final CUnit unit, final Ab for (final CAbility ability : this.entangledMine.getAbilities()) { ability.visit(AbilityDisableWhileUnderConstructionVisitor.INSTANCE); } + unit.checkDisabledAbilities(simulation, true); } this.entangledMine.setFoodUsed(this.entangledMine.getUnitType().getFoodUsed()); simulation.getPlayer(unit.getPlayerIndex()).addTechtreeInProgress(this.resultingTypeId); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbilityFields.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbilityFields.java index c3452b08..6a92db84 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbilityFields.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbilityFields.java @@ -33,4 +33,8 @@ public interface AbilityFields { public static final String REQUIRED_LEVEL = "reqLevel"; // replaced from 'arlv' public static final String REQUIRED_LEVEL_SKIP = "levelSkip"; // replaced from 'alsk' + public static final String CHECK_DEPENDENCIES = "checkDep"; + public static final String REQUIREMENTS = "Requires"; + public static final String REQUIREMENT_LEVELS = "Requiresamount"; + } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderActiveFlexTarget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderActiveFlexTarget.java index 35325928..427bd722 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderActiveFlexTarget.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderActiveFlexTarget.java @@ -92,8 +92,13 @@ public void setLevel(CSimulation game, CUnit unit, int level) { } @Override - public void onAdd(CSimulation game, CUnit unit) { + public void onAddDisabled(CSimulation game, CUnit unit) { localStore.put(ABLocalStoreKeys.FLEXABILITY, this); + super.onAddDisabled(game, unit); + } + + @Override + public void onAdd(CSimulation game, CUnit unit) { this.behavior = new CBehaviorAbilityBuilderBase(unit, localStore, this); this.setTargeted(game, unit); this.setPointTarget(game, unit); diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderGenericActive.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderGenericActive.java index 29748251..af050f7b 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderGenericActive.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderGenericActive.java @@ -14,6 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconNoSmartActiveAbility; @@ -63,7 +64,7 @@ public abstract class CAbilityAbilityBuilderGenericActive extends AbstractGeneri protected int manaCost = 0; protected float area = 0; protected float range = 0; - + protected boolean hideAreaCursor = false; protected int bufferMana = 0; @@ -123,8 +124,6 @@ public void setLevel(CSimulation game, CUnit unit, int level) { @Override public void onAdd(CSimulation game, CUnit unit) { - localStore.put(ABLocalStoreKeys.GAME, game); - localStore.put(ABLocalStoreKeys.THISUNIT, unit); setSpellFields(game, unit); determineToggleableFields(game, unit); if (config.getOnAddAbility() != null) { @@ -134,33 +133,61 @@ public void onAdd(CSimulation game, CUnit unit) { } } + @Override + public void onAddDisabled(CSimulation game, CUnit unit) { + localStore.put(ABLocalStoreKeys.GAME, game); + localStore.put(ABLocalStoreKeys.THISUNIT, unit); + setSpellFields(game, unit); + determineToggleableFields(game, unit); + if (config.getOnAddDisabledAbility() != null) { + for (ABAction action : config.getOnAddDisabledAbility()) { + action.runAction(game, unit, localStore, castId); + } + } + } + + @Override + public void onRemoveDisabled(CSimulation game, CUnit unit) { + if (config.getOnRemoveDisabledAbility() != null) { + for (ABAction action : config.getOnRemoveDisabledAbility()) { + action.runAction(game, unit, localStore, castId); + } + } + } + private void determineToggleableFields(CSimulation game, CUnit unit) { if (config.getDisplayFields() != null && config.getDisplayFields().getSeparateOnAndOff() != null) { - this.separateOnAndOff = config.getDisplayFields().getSeparateOnAndOff().callback(game, unit, localStore, castId); + this.separateOnAndOff = config.getDisplayFields().getSeparateOnAndOff().callback(game, unit, localStore, + castId); } if (config.getDisplayFields() != null && config.getDisplayFields().getToggleable() != null) { this.toggleable = config.getDisplayFields().getToggleable().callback(game, unit, localStore, castId); } if (config.getDisplayFields() != null && config.getDisplayFields().getCastToggleOff() != null) { - this.allowCastlessDeactivate = !config.getDisplayFields().getCastToggleOff().callback(game, unit, localStore, castId); + this.allowCastlessDeactivate = !config.getDisplayFields().getCastToggleOff().callback(game, unit, + localStore, castId); } if (toggleable && config.getDisplayFields() != null && config.getDisplayFields().getAlternateUnitId() != null) { - if (unit.getTypeId().equals(config.getDisplayFields().getAlternateUnitId().callback(game, unit, localStore, castId))) { + if (unit.getTypeId() + .equals(config.getDisplayFields().getAlternateUnitId().callback(game, unit, localStore, castId))) { this.active = true; } } if (config.getSpecialFields() != null && config.getSpecialFields().getBufferManaRequired() != null) { - this.bufferMana = config.getSpecialFields().getBufferManaRequired().callback(game, unit, localStore, castId); + this.bufferMana = config.getSpecialFields().getBufferManaRequired().callback(game, unit, localStore, + castId); } - if (this.toggleable) { + if (this.toggleable) { localStore.put(ABLocalStoreKeys.TOGGLEDABILITY, this); int manaPerSec = 0; if (config.getSpecialFields() != null && config.getSpecialFields().getManaDrainedPerSecond() != null) { - manaPerSec = config.getSpecialFields().getManaDrainedPerSecond().callback(game, unit, localStore, castId); + manaPerSec = config.getSpecialFields().getManaDrainedPerSecond().callback(game, unit, localStore, + castId); } if (manaPerSec != 0) { if (manaDrain == null) { - manaDrain = new NonStackingStatBuff(NonStackingStatBuffType.MPGEN, NonStackingStatBuff.ALLOW_STACKING_KEY, (-1 * manaPerSec)); + manaDrain = new NonStackingStatBuff(NonStackingStatBuffType.MPGEN, + NonStackingStatBuff.ALLOW_STACKING_KEY, (-1 * manaPerSec)); } else { manaDrain.setValue((-1 * manaPerSec)); } @@ -171,19 +198,22 @@ private void determineToggleableFields(CSimulation game, CUnit unit) { this.manaDrain = null; this.timer = null; } - + if (config.getDisplayFields() != null && config.getDisplayFields().getAlternateUnitId() != null) { - if (unit.getTypeId().equals(config.getDisplayFields().getAlternateUnitId().callback(game, unit, localStore, manaPerSec))) { + if (unit.getTypeId().equals( + config.getDisplayFields().getAlternateUnitId().callback(game, unit, localStore, manaPerSec))) { this.active = true; } } if (this.config.getOverrideFields() != null) { if (this.config.getOverrideFields().getOnTooltipOverride() != null) { - this.onTooltipOverride = this.config.getOverrideFields().getOnTooltipOverride().callback(game, unit, localStore, castId); + this.onTooltipOverride = this.config.getOverrideFields().getOnTooltipOverride().callback(game, unit, + localStore, castId); } if (this.config.getOverrideFields().getOffTooltipOverride() != null) { - this.offTooltipOverride = this.config.getOverrideFields().getOffTooltipOverride().callback(game, unit, localStore, castId); + this.offTooltipOverride = this.config.getOverrideFields().getOffTooltipOverride().callback(game, + unit, localStore, castId); } } } @@ -200,20 +230,22 @@ protected void setSpellFields(CSimulation game, CUnit unit) { this.area = this.config.getOverrideFields().getAreaOverride().callback(game, unit, localStore, castId); } if (this.config.getOverrideFields().getRangeOverride() != null) { - this.range = this.config.getOverrideFields().getRangeOverride().callback(game, unit, localStore, castId); + this.range = this.config.getOverrideFields().getRangeOverride().callback(game, unit, localStore, + castId); } if (this.config.getOverrideFields().getCooldownOverride() != null) { - this.cooldown = this.config.getOverrideFields().getCooldownOverride().callback(game, unit, localStore, castId); + this.cooldown = this.config.getOverrideFields().getCooldownOverride().callback(game, unit, localStore, + castId); } if (this.config.getOverrideFields().getManaCostOverride() != null) { - this.manaCost = this.config.getOverrideFields().getManaCostOverride().callback(game, unit, localStore, castId); + this.manaCost = this.config.getOverrideFields().getManaCostOverride().callback(game, unit, localStore, + castId); } } - if (this.config.getDisplayFields() != null - && this.config.getDisplayFields().getHideAreaCursor() != null) { - this.hideAreaCursor = this.config.getDisplayFields() - .getHideAreaCursor().callback(game, unit, localStore, this.getLevel()); + if (this.config.getDisplayFields() != null && this.config.getDisplayFields().getHideAreaCursor() != null) { + this.hideAreaCursor = this.config.getDisplayFields().getHideAreaCursor().callback(game, unit, localStore, + this.getLevel()); } } @@ -232,7 +264,7 @@ public void resetCooldown(CSimulation game, CUnit unit) { unit.beginCooldown(game, cdID, 0); } } - + private War3ID getCooldownId() { if (this.item != null) { if (item.getItemType().isIgnoreCooldown()) { @@ -282,12 +314,12 @@ public AbilityBuilderConfiguration getConfig() { public Map getLocalStore() { return this.localStore; } - + @Override public War3ID getOnTooltipOverride() { return onTooltipOverride; } - + @Override public War3ID getOffTooltipOverride() { return offTooltipOverride; @@ -297,7 +329,7 @@ public War3ID getOffTooltipOverride() { public int getUIManaCost() { return (this.toggleable && this.active && this.allowCastlessDeactivate) ? 0 : this.manaCost + this.bufferMana; } - + @Override public int getChargedManaCost() { return this.manaCost; @@ -352,8 +384,9 @@ public void setAutoCastOn(final boolean autoCastOn) { protected ABBehavior createNoTargetBehavior(CUnit unit) { ABBehavior beh = new CBehaviorAbilityBuilderNoTarget(unit, localStore, this); - if (this.item != null || (this.config.getDisplayFields() != null && this.config.getDisplayFields().getInstantCast() != null - && this.config.getDisplayFields().getInstantCast().callback(null, unit, localStore, castId))) { + if (this.item != null + || (this.config.getDisplayFields() != null && this.config.getDisplayFields().getInstantCast() != null + && this.config.getDisplayFields().getInstantCast().callback(null, unit, localStore, castId))) { beh.setInstant(true); } return beh; @@ -361,8 +394,9 @@ protected ABBehavior createNoTargetBehavior(CUnit unit) { protected ABBehavior createRangedBehavior(CUnit unit) { ABBehavior beh = new CBehaviorAbilityBuilderBase(unit, localStore, this); - if (this.item != null || (this.config.getDisplayFields() != null && this.config.getDisplayFields().getInstantCast() != null - && this.config.getDisplayFields().getInstantCast().callback(null, unit, localStore, castId))) { + if (this.item != null + || (this.config.getDisplayFields() != null && this.config.getDisplayFields().getInstantCast() != null + && this.config.getDisplayFields().getInstantCast().callback(null, unit, localStore, castId))) { beh.setInstant(true); } return beh; @@ -376,19 +410,21 @@ protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final return; } final int cooldownRemaining = unit.getCooldownRemainingTicks(game, getCooldownId()); - + if (this.toggleable && this.active && this.allowCastlessDeactivate) { if (cooldownRemaining > 0 && !(receiver instanceof MeleeUIAbilityActivationReceiver)) { float cooldownLengthDisplay = unit.getCooldownLengthDisplayTicks(game, getCooldownId()) * WarsmashConstants.SIMULATION_STEP_TIME; - receiver.cooldownNotYetReady(cooldownRemaining * WarsmashConstants.SIMULATION_STEP_TIME, cooldownLengthDisplay); + receiver.cooldownNotYetReady(cooldownRemaining * WarsmashConstants.SIMULATION_STEP_TIME, + cooldownLengthDisplay); } receiver.useOk(); } else { if (cooldownRemaining > 0) { float cooldownLengthDisplay = unit.getCooldownLengthDisplayTicks(game, getCooldownId()) * WarsmashConstants.SIMULATION_STEP_TIME; - receiver.cooldownNotYetReady(cooldownRemaining * WarsmashConstants.SIMULATION_STEP_TIME, cooldownLengthDisplay); + receiver.cooldownNotYetReady(cooldownRemaining * WarsmashConstants.SIMULATION_STEP_TIME, + cooldownLengthDisplay); } else if (unit.getMana() < (this.manaCost + this.bufferMana)) { receiver.activationCheckFailed(CommandStringErrorKeys.NOT_ENOUGH_MANA); } else { @@ -450,25 +486,21 @@ public void checkCanTarget(final CSimulation game, final CUnit unit, final int o final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { if (innerCheckCastOrderId(game, unit, orderId)) { innerCheckCanTarget(game, unit, orderId, target, receiver); - } - else if (orderId == OrderIds.smart) { + } else if (orderId == OrderIds.smart) { innerCheckCanSmartTarget(game, unit, orderId, target, receiver); - } - else { + } else { receiver.orderIdNotAccepted(); } } - + @Override public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, final AbilityTargetCheckReceiver receiver) { if ((orderId != 0) && ((orderId == getAutoCastOffOrderId()) || (orderId == getAutoCastOnOrderId()))) { receiver.targetOk(null); - } - else if (innerCheckCastOrderId(game, unit, orderId)) { + } else if (innerCheckCastOrderId(game, unit, orderId)) { innerCheckCanTargetNoTarget(game, unit, orderId, receiver); - } - else { + } else { receiver.orderIdNotAccepted(); } } @@ -539,7 +571,8 @@ protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int ord } protected boolean innerCheckCastOrderId(final CSimulation game, final CUnit unit, final int orderId) { - return (!this.active && orderId == getBaseOrderId()) || ((this.active || this.separateOnAndOff) && orderId == getOffOrderId()); + return (!this.active && orderId == getBaseOrderId()) + || ((this.active || this.separateOnAndOff) && orderId == getOffOrderId()); } protected boolean innerCheckTargetTargetable(CSimulation game, CUnit unit, CWidget target) { @@ -547,8 +580,7 @@ protected boolean innerCheckTargetTargetable(CSimulation game, CUnit unit, CWidg } protected boolean innerCheckTargetInRange(CUnit unit, AbilityTarget target) { - return !unit.isMovementDisabled() - || unit.canReach(target, this.getCastRange()); + return !unit.isMovementDisabled() || unit.canReach(target, this.getCastRange()); } protected String innerCheckExtraTargetConditions(CSimulation game, CUnit unit, int orderId) { @@ -643,7 +675,7 @@ public void onDeath(CSimulation game, CUnit unit) { } } } - + @Override public void runOnOrderIssuedActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnOrderIssued() != null) { @@ -652,7 +684,7 @@ public void runOnOrderIssuedActions(final CSimulation game, final CUnit caster, } } } - + @Override public void runBeginCastingActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnBeginCasting() != null) { @@ -661,7 +693,7 @@ public void runBeginCastingActions(final CSimulation game, final CUnit caster, i } } } - + @Override public void runEndCastingActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnEndCasting() != null) { @@ -669,7 +701,7 @@ public void runEndCastingActions(final CSimulation game, final CUnit caster, int action.runAction(game, caster, localStore, castId); } } - if (this.toggleable) { + if (this.toggleable) { if (orderId == this.getBaseOrderId()) { this.activate(game, caster); } @@ -678,7 +710,7 @@ public void runEndCastingActions(final CSimulation game, final CUnit caster, int } } } - + @Override public void runChannelTickActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnChannelTick() != null) { @@ -687,7 +719,7 @@ public void runChannelTickActions(final CSimulation game, final CUnit caster, in } } } - + @Override public void runEndChannelActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnEndChannel() != null) { @@ -696,7 +728,7 @@ public void runEndChannelActions(final CSimulation game, final CUnit caster, int } } } - + @Override public void runCancelPreCastActions(final CSimulation game, final CUnit caster, int orderId) { if (config.getOnCancelPreCast() != null) { @@ -705,7 +737,7 @@ public void runCancelPreCastActions(final CSimulation game, final CUnit caster, } } } - + @Override public void activate(final CSimulation game, final CUnit caster) { Boolean failed = (Boolean) this.localStore.get(ABLocalStoreKeys.FAILEDTOCAST + castId); @@ -766,9 +798,44 @@ public void onTick(CSimulation game, CUnit unit) { public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) { } - + @Override public T visit(final CAbilityVisitor visitor) { return visitor.accept(this); } + + @Override + public void checkRequirementsMet(CSimulation game, CUnit unit, AbilityActivationReceiver receiver) { + List reqs = this.levelData.get(this.getLevel() - 1).getRequirements(); + CPlayer player = game.getPlayer(unit.getPlayerIndex()); + if (reqs != null) { + for (final CUnitTypeRequirement requirement : reqs) { +// System.err.println("Checking reqs for " + this.getAlias() + ": looking for " +// + requirement.getRequirement() + " at amount " + requirement.getRequiredLevel() + " and found " +// + player.getTechtreeUnlocked(requirement.getRequirement())); + if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement.getRequiredLevel()) { + receiver.missingRequirement(requirement.getRequirement(), requirement.getRequiredLevel()); + } + } + } + } + + @Override + public boolean isRequirementsMet(CSimulation game, CUnit unit) { + List reqs = this.levelData.get(this.getLevel() - 1).getRequirements(); + CPlayer player = game.getPlayer(unit.getPlayerIndex()); + boolean requirementsMet = player.isTechtreeAllowedByMax(this.getAlias()); + if (reqs != null) { + for (final CUnitTypeRequirement requirement : reqs) { +// System.err.println("Checking reqs for " + this.getAlias() + ": looking for " +// + requirement.getRequirement() + " at amount " + requirement.getRequiredLevel() + " and found " +// + player.getTechtreeUnlocked(requirement.getRequirement())); + if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement.getRequiredLevel()) { + requirementsMet = false; + } + } + } +// System.err.println("Returning "+requirementsMet+" for " + this.getAlias()); + return requirementsMet; + } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionDisableWorkerAbilities.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionDisableWorkerAbilities.java index 7b7077c2..983dd145 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionDisableWorkerAbilities.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionDisableWorkerAbilities.java @@ -5,6 +5,7 @@ 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.CAbility; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityDisableType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; @@ -38,8 +39,9 @@ public void runAction(CSimulation game, CUnit caster, Map localS for (Class type : workerAbils) { CAbility abil = targetUnit.getFirstAbilityOfType(type); if (abil != null) { - abil.setDisabled(true); + abil.setDisabled(true, CAbilityDisableType.TRANSFORMATION); abil.setIconShowing(false); + targetUnit.checkDisabledAbilities(game, true); } } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionEnableWorkerAbilities.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionEnableWorkerAbilities.java index 206ef261..fa659e17 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionEnableWorkerAbilities.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/behavior/action/unit/ABActionEnableWorkerAbilities.java @@ -5,6 +5,7 @@ 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.CAbility; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityDisableType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; @@ -38,8 +39,9 @@ public void runAction(CSimulation game, CUnit caster, Map localS for (Class type : workerAbils) { CAbility abil = targetUnit.getFirstAbilityOfType(type); if (abil != null) { - abil.setDisabled(false); + abil.setDisabled(false, CAbilityDisableType.TRANSFORMATION); abil.setIconShowing(true); + targetUnit.checkDisabledAbilities(game, false); } } } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/handler/TransformationHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/handler/TransformationHandler.java index b57a8a8e..9e1bcb55 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/handler/TransformationHandler.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/handler/TransformationHandler.java @@ -62,8 +62,14 @@ public static void setUnitID(CSimulation game, Map localStore, C } public static void playMorphAnimation(CUnit unit, boolean addAlternateTagAfter) { - unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, - addAlternateTagAfter ? SequenceUtils.EMPTY : EnumSet.of(SecondaryTag.ALTERNATE), 1.0f, true); + if (addAlternateTagAfter) { + unit.getUnitAnimationListener().removeSecondaryTagForFutureAnimations(SecondaryTag.ALTERNATE); + unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, + SequenceUtils.EMPTY, 1.0f, true); + } else { + unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, + EnumSet.of(SecondaryTag.ALTERNATE), 1.0f, true); + } unit.getUnitAnimationListener().queueAnimation(PrimaryTag.STAND, addAlternateTagAfter ? EnumSet.of(SecondaryTag.ALTERNATE) : SequenceUtils.EMPTY, true); if (addAlternateTagAfter) { diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderConfiguration.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderConfiguration.java index ce5013d4..99a18187 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderConfiguration.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderConfiguration.java @@ -23,7 +23,10 @@ public class AbilityBuilderConfiguration { private List extraCastConditions; private List onAddAbility; + private List onAddDisabledAbility; private List onRemoveAbility; + private List onRemoveDisabledAbility; + private List onDeathPreCast; private List onCancelPreCast; private List onOrderIssued; @@ -52,10 +55,12 @@ public AbilityBuilderConfiguration(AbilityBuilderParser parser, AbilityBuilderDu this.extraCastConditions = parser.getExtraCastConditions(); this.onAddAbility = parser.getOnAddAbility(); + this.onAddDisabledAbility = parser.getOnAddDisabledAbility(); this.onRemoveAbility = parser.getOnRemoveAbility(); + this.onRemoveDisabledAbility = parser.getOnRemoveDisabledAbility(); this.onDeathPreCast = parser.getOnDeathPreCast(); this.onCancelPreCast = parser.getOnCancelPreCast(); - this.setOnOrderIssued(parser.getOnOrderIssued()); + this.onOrderIssued = parser.getOnOrderIssued(); this.onActivate = parser.getOnActivate(); this.onDeactivate = parser.getOnDeactivate(); @@ -167,6 +172,20 @@ public void setOnAddAbility(List onAddAbility) { this.onAddAbility = onAddAbility; } + /** + * @return the onAddDisabledAbility + */ + public List getOnAddDisabledAbility() { + return onAddDisabledAbility; + } + + /** + * @param onAddDisabledAbility the onAddDisabledAbility to set + */ + public void setOnAddDisabledAbility(List onAddDisabledAbility) { + this.onAddDisabledAbility = onAddDisabledAbility; + } + public List getOnRemoveAbility() { return onRemoveAbility; } @@ -175,6 +194,20 @@ public void setOnRemoveAbility(List onRemoveAbility) { this.onRemoveAbility = onRemoveAbility; } + /** + * @return the onRemoveDisabledAbility + */ + public List getOnRemoveDisabledAbility() { + return onRemoveDisabledAbility; + } + + /** + * @param onRemoveDisabledAbility the onRemoveDisabledAbility to set + */ + public void setOnRemoveDisabledAbility(List onRemoveDisabledAbility) { + this.onRemoveDisabledAbility = onRemoveDisabledAbility; + } + public List getOnDeathPreCast() { return onDeathPreCast; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderParser.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderParser.java index 28d8df15..913de7dc 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderParser.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/parser/AbilityBuilderParser.java @@ -20,9 +20,11 @@ public class AbilityBuilderParser { private List extraTargetConditions; private List extraCastConditions; - + private List onAddAbility; + private List onAddDisabledAbility; private List onRemoveAbility; + private List onRemoveDisabledAbility; private List onDeathPreCast; private List onCancelPreCast; private List onOrderIssued; @@ -103,6 +105,20 @@ public void setOnAddAbility(List onAddAbility) { this.onAddAbility = onAddAbility; } + /** + * @return the onAddDisabledAbility + */ + public List getOnAddDisabledAbility() { + return onAddDisabledAbility; + } + + /** + * @param onAddDisabledAbility the onAddDisabledAbility to set + */ + public void setOnAddDisabledAbility(List onAddDisabledAbility) { + this.onAddDisabledAbility = onAddDisabledAbility; + } + public List getOnRemoveAbility() { return onRemoveAbility; } @@ -111,6 +127,20 @@ public void setOnRemoveAbility(List onRemoveAbility) { this.onRemoveAbility = onRemoveAbility; } + /** + * @return the onRemoveDisabledAbility + */ + public List getOnRemoveDisabledAbility() { + return onRemoveDisabledAbility; + } + + /** + * @param onRemoveDisabledAbility the onRemoveDisabledAbility to set + */ + public void setOnRemoveDisabledAbility(List onRemoveDisabledAbility) { + this.onRemoveDisabledAbility = onRemoveDisabledAbility; + } + public List getOnDeathPreCast() { return onDeathPreCast; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/timer/TransformationMorphAnimationTimer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/timer/TransformationMorphAnimationTimer.java index efcd88cb..c08d25f6 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/timer/TransformationMorphAnimationTimer.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/timer/TransformationMorphAnimationTimer.java @@ -20,10 +20,15 @@ public TransformationMorphAnimationTimer(CSimulation game, CUnit unit, boolean a this.setRepeats(false); this.setTimeoutTime(delay); } - + public void onFire(CSimulation game) { - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, - this.addAlternateTagAfter ? SequenceUtils.EMPTY : EnumSet.of(SecondaryTag.ALTERNATE), 1.0f, true); + if (addAlternateTagAfter) { + unit.getUnitAnimationListener().removeSecondaryTagForFutureAnimations(SecondaryTag.ALTERNATE); + unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, SequenceUtils.EMPTY, 1.0f, true); + } else { + unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.MORPH, EnumSet.of(SecondaryTag.ALTERNATE), + 1.0f, true); + } this.unit.getUnitAnimationListener().queueAnimation(PrimaryTag.STAND, this.addAlternateTagAfter ? EnumSet.of(SecondaryTag.ALTERNATE) : SequenceUtils.EMPTY, true); if (this.addAlternateTagAfter) { @@ -32,5 +37,5 @@ public void onFire(CSimulation game) { this.unit.getUnitAnimationListener().removeSecondaryTagForFutureAnimations(SecondaryTag.ALTERNATE); } } - + } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityBuilder.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityBuilder.java index d6c343fc..de140869 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityBuilder.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityBuilder.java @@ -6,6 +6,7 @@ import com.etheller.warsmash.units.GameObject; import com.etheller.warsmash.util.War3ID; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.AbstractCAbilityTypeDefinition; @@ -13,6 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.types.impl.CAbilityTypeAbilityBuilder; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.types.impl.CAbilityTypeAbilityBuilderLevelData; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CUnitData; public class CAbilityTypeDefinitionAbilityBuilder extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { @@ -75,8 +77,18 @@ protected CAbilityTypeAbilityBuilderLevelData createLevelData(final GameObject a } final int manaCost = abilityEditorData.readSLKTagInt(MANA_COST+level); final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); + + int checkDeps = abilityEditorData.readSLKTagInt(CHECK_DEPENDENCIES); + List requirements = null; + if (checkDeps > 0) { + final List requirementsString = abilityEditorData.getFieldAsList(REQUIREMENTS); + final List requirementsLevelsString = abilityEditorData.getFieldAsList(REQUIREMENT_LEVELS); + requirements = CUnitData.parseRequirements(requirementsString, + requirementsLevelsString); + } + return new CAbilityTypeAbilityBuilderLevelData(targetsAllowedAtLevel, area, castRange, castTime, cooldown, - durationHero, durationNormal, buffs, effects, manaCost, data, unitId); + durationHero, durationNormal, buffs, effects, manaCost, data, unitId, requirements); } @Override diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityTemplateBuilder.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityTemplateBuilder.java index 165008b8..d0ac8f69 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityTemplateBuilder.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/definitions/impl/CAbilityTypeDefinitionAbilityTemplateBuilder.java @@ -6,6 +6,7 @@ import com.etheller.warsmash.units.GameObject; import com.etheller.warsmash.util.War3ID; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.AbstractCAbilityTypeDefinition; @@ -13,6 +14,7 @@ import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.types.impl.CAbilityTypeAbilityBuilderLevelData; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.types.impl.CAbilityTypeAbilityTemplateBuilder; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CUnitData; public class CAbilityTypeDefinitionAbilityTemplateBuilder extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { @@ -75,8 +77,18 @@ protected CAbilityTypeAbilityBuilderLevelData createLevelData(final GameObject a } final int manaCost = abilityEditorData.readSLKTagInt(MANA_COST+level); final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); + + int checkDeps = abilityEditorData.readSLKTagInt(CHECK_DEPENDENCIES); + List requirements = null; + if (checkDeps > 0) { + final List requirementsString = abilityEditorData.getFieldAsList(REQUIREMENTS); + final List requirementsLevelsString = abilityEditorData.getFieldAsList(REQUIREMENT_LEVELS); + requirements = CUnitData.parseRequirements(requirementsString, + requirementsLevelsString); + } + return new CAbilityTypeAbilityBuilderLevelData(targetsAllowedAtLevel, area, castRange, castTime, cooldown, - durationHero, durationNormal, buffs, effects, manaCost, data, unitId); + durationHero, durationNormal, buffs, effects, manaCost, data, unitId, requirements); } @Override diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/impl/CAbilityTypeAbilityBuilderLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/impl/CAbilityTypeAbilityBuilderLevelData.java index fb1a9c8b..00b42137 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/impl/CAbilityTypeAbilityBuilderLevelData.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/types/impl/CAbilityTypeAbilityBuilderLevelData.java @@ -4,6 +4,7 @@ import java.util.List; import com.etheller.warsmash.util.War3ID; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; @@ -19,10 +20,11 @@ public class CAbilityTypeAbilityBuilderLevelData extends CAbilityTypeLevelData { private final int manaCost; private final List data; private final War3ID unitId; + private List requirements; public CAbilityTypeAbilityBuilderLevelData(EnumSet targetsAllowed, float area, float castRange, float castTime, float cooldown, float durationHero, float durationNormal, List buffs, - List effects, int manaCost, List data, War3ID unitId) { + List effects, int manaCost, List data, War3ID unitId, List requirements) { super(targetsAllowed); this.area = area; this.castRange = castRange; @@ -35,6 +37,7 @@ public CAbilityTypeAbilityBuilderLevelData(EnumSet targetsAllowed, this.manaCost = manaCost; this.data = data; this.unitId = unitId; + this.requirements = requirements; } public float getArea() { @@ -81,4 +84,18 @@ public War3ID getUnitId() { return unitId; } + /** + * @return the requirements + */ + public List getRequirements() { + return requirements; + } + + /** + * @param requirements the requirements to set + */ + public void setRequirements(List requirements) { + this.requirements = requirements; + } + } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java index eb901ef6..e3396881 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java @@ -1,6 +1,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityDisableType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGenericDoNothing; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; @@ -33,119 +34,119 @@ public class AbilityDisableWhileUnderConstructionVisitor implements CAbilityVisi @Override public Void accept(final CAbilityAttack ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityMove ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityOrcBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityHumanBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityUndeadBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityNightElfBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityGenericDoNothing ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityColdArrows ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityNagaBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityNeutralBuild ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityBuildInProgress ability) { - ability.setDisabled(false); + ability.setDisabled(false, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityQueue ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilitySellItems ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityUpgrade ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityReviveHero ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final AbilityBuilderActiveAbility ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final GenericSingleIconActiveAbility ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @@ -157,28 +158,28 @@ public Void accept(GenericSingleIconPassiveAbility ability) { @Override public Void accept(final CAbilityRoot ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityRally ability) { - ability.setDisabled(false); + ability.setDisabled(false, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final GenericNoIconAbility ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityNeutralBuilding ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @@ -191,14 +192,14 @@ public Void accept(final CBuff ability) { @Override public Void accept(final CAbilityReturnResources ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @Override public Void accept(final CAbilityHero ability) { - ability.setDisabled(true); + ability.setDisabled(true, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(false); return null; } @@ -206,7 +207,7 @@ public Void accept(final CAbilityHero ability) { @Override public Void accept(final CAbilityJass ability) { final boolean enabledWhileUnderConstruction = ability.getType().isEnabledWhileUnderConstruction(); - ability.setDisabled(!enabledWhileUnderConstruction); + ability.setDisabled(!enabledWhileUnderConstruction, CAbilityDisableType.CONSTRUCTION); ability.setIconShowing(enabledWhileUnderConstruction); return null; } diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUpgradingVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUpgradingVisitor.java index be1c46ef..2f4a2588 100644 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUpgradingVisitor.java +++ b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUpgradingVisitor.java @@ -1,6 +1,7 @@ package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; +import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityDisableType; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGenericDoNothing; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; @@ -33,119 +34,119 @@ public class AbilityDisableWhileUpgradingVisitor implements CAbilityVisitor setToLevel); } - public void removeTechtreeUnlocked(final War3ID rawcode) { + public void removeTechtreeUnlocked(CSimulation simulation, final War3ID rawcode) { final Integer techtreeUnlocked = this.rawcodeToTechtreeUnlocked.get(rawcode); if (techtreeUnlocked == null) { this.rawcodeToTechtreeUnlocked.put(rawcode, -1); @@ -197,6 +200,7 @@ public void removeTechtreeUnlocked(final War3ID rawcode) { else { this.rawcodeToTechtreeUnlocked.put(rawcode, techtreeUnlocked - 1); } + fireRequirementUpdateForAbilities(simulation, true); } public void addTechtreeInProgress(final War3ID rawcode) { @@ -626,6 +630,7 @@ public void addTechResearched(final CSimulation simulation, final War3ID techIdR final int setToLevel = previousUnlockCount + levels; setTechToLevel(simulation, techIdRawcodeId, setToLevel); } + fireRequirementUpdateForAbilities(simulation, false); } public void setTechResearched(final CSimulation simulation, final War3ID techIdRawcodeId, final int setToLevel) { @@ -633,12 +638,12 @@ public void setTechResearched(final CSimulation simulation, final War3ID techIdR if ((setToLevel > previousUnlockCount) || (setToLevel < previousUnlockCount)) { setTechToLevel(simulation, techIdRawcodeId, setToLevel); } - + fireRequirementUpdateForAbilities(simulation, false); } private void setTechToLevel(final CSimulation simulation, final War3ID techIdRawcodeId, final int setToLevel) { final int previousLevel = getTechtreeUnlocked(techIdRawcodeId); - setTechtreeUnlocked(techIdRawcodeId, setToLevel); + setTechtreeUnlocked(simulation, techIdRawcodeId, setToLevel); // terminate in progress upgrades of this kind for player final CUpgradeType upgradeType = simulation.getUpgradeData().getType(techIdRawcodeId); if (upgradeType != null) { @@ -676,4 +681,12 @@ public void updateFogModifiers(final CSimulation game) { fogModifier.update(game.getPathingGrid(), this.fogOfWar); } } + + public void fireRequirementUpdateForAbilities(final CSimulation simulation, final boolean disable) { + for(CUnit unit : simulation.getUnits()) { + if (unit.getPlayerIndex() == this.getId()) { + unit.checkDisabledAbilities(simulation, disable); + } + } + } }