Skip to content

Commit 24ee927

Browse files
committed
Fix to stun, and update to ability and regen behavior around pausing
* AB: Added specific buff that ticks during pause (for regeneration, maybe others) * AB: Changed timed buffs to maintain remaining duration after pausing * AB: Fixed stun to remember the previous action * Core: Changed command card rendering to hide icons during pause * Core: Changed life/mana regen during pause to match WC3 (uses base+ability+buff values, but not str/int)
1 parent 3a74634 commit 24ee927

14 files changed

+205
-465
lines changed

core/assets/abilityBehaviors/nightElfUnitActives.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@
572572
"type": "isFlexAbilityTargeted"
573573
},
574574
"thenActions": [{
575-
"type": "createTimedTickingBuff",
575+
"type": "createTimedTickingPausedBuff",
576576
"buffId": {
577577
"type": "getFirstBuffId"
578578
},
@@ -838,7 +838,7 @@
838838
}
839839
},
840840
"thenActions": [{
841-
"type": "createTimedTickingBuff",
841+
"type": "createTimedTickingPausedBuff",
842842
"buffId": {
843843
"type": "getFirstBuffId"
844844
},
@@ -1065,7 +1065,7 @@
10651065
}]
10661066
}],
10671067
"elseActions": [{
1068-
"type": "createTimedTickingBuff",
1068+
"type": "createTimedTickingPausedBuff",
10691069
"buffId": {
10701070
"type": "getFirstBuffId"
10711071
},

core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
2828
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
2929
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility;
30+
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbilityGenericSingleIconPassiveAbility;
31+
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CBuff;
3032

3133
public class RenderUnit implements RenderWidget {
3234
public static final Quaternion tempQuat = new Quaternion();
@@ -167,7 +169,10 @@ public void populateCommandCard(final CSimulation game, final GameUI gameUI,
167169
.reset(game, gameUI, this.simulationUnit, commandButtonListener, abilityDataUI, subMenuOrderId,
168170
multiSelect, localPlayerIndex);
169171
for (final CAbility ability : this.simulationUnit.getAbilities()) {
170-
ability.visit(commandCardPopulatingVisitor);
172+
if (!this.simulationUnit.isPaused() || ability instanceof CBuff ||
173+
ability instanceof AbilityGenericSingleIconPassiveAbility) {
174+
ability.visit(commandCardPopulatingVisitor);
175+
}
171176
}
172177
}
173178

core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.GetAbilityByRawcodeVisitor;
3232
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress;
3333
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.cargohold.CAbilityCargoHold;
34+
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbilityGenericSingleIconPassiveAbility;
3435
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CBuff;
3536
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.CLevelingAbility;
3637
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest;
@@ -44,6 +45,7 @@
4445
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget;
4546
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor;
4647
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.buff.ABGenericTimedBuff;
48+
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.buff.ABTimedTickingPausedBuff;
4749
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
4850
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack;
4951
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener;
@@ -201,6 +203,7 @@ public class CUnit extends CWidget {
201203
private boolean autoAttack = true;
202204
private boolean moveDisabled = false;
203205
private CBehavior defaultBehavior;
206+
private CBehavior interruptedBehavior;
204207
private COrder lastStartedOrder = null;
205208
private CUnit workerInside;
206209
private final War3ID[] buildQueue = new War3ID[WarsmashConstants.BUILD_QUEUE_SIZE];
@@ -459,7 +462,7 @@ public void computeUnitState(CSimulation game, StateModBuffType type) {
459462
if (!this.damageTakenModificationListeners.contains(CUnitDefaultEtherealDamageModListener.INSTANCE)) {
460463
this.addDamageTakenModificationListener(CUnitDefaultEtherealDamageModListener.INSTANCE);
461464
}
462-
//Disable physical skills
465+
// Disable physical skills
463466
// for (CAbility ability : this.abilities) {
464467
// if (ability.isPhysical()) {
465468
// ability.setDisabled(true);
@@ -469,7 +472,7 @@ public void computeUnitState(CSimulation game, StateModBuffType type) {
469472
if (this.damageTakenModificationListeners.contains(CUnitDefaultEtherealDamageModListener.INSTANCE)) {
470473
this.removeDamageTakenModificationListener(CUnitDefaultEtherealDamageModListener.INSTANCE);
471474
}
472-
//Enable physical skills
475+
// Enable physical skills
473476
// for (CAbility ability : this.abilities) {
474477
// if (ability.isPhysical()) {
475478
// ability.setDisabled(false);
@@ -527,19 +530,24 @@ public void computeUnitState(CSimulation game, StateModBuffType type) {
527530
}
528531
}
529532
if (isSleeping || isStun) {
530-
if (this.currentBehavior != null) {
531-
this.currentBehavior.end(game, true);
533+
if (this.currentBehavior == null || this.currentBehavior.getHighlightOrderId() != OrderIds.stunned) {
534+
if (this.currentBehavior != null) {
535+
this.interruptedBehavior = this.currentBehavior;
536+
}
537+
this.currentBehavior = new CBehaviorStun(this);
538+
this.currentBehavior.begin(game);
539+
this.setAcceptingOrders(false);
540+
this.stateNotifier.ordersChanged();
532541
}
533-
this.currentBehavior = new CBehaviorStun(this);
534-
this.currentBehavior.begin(game);
535-
this.setAcceptingOrders(false);
536-
this.stateNotifier.ordersChanged();
537542
} else {
538-
this.setAcceptingOrders(true);
539-
this.currentBehavior = this.pollNextOrderBehavior(game);
540-
this.stateNotifier.ordersChanged();
543+
if (this.currentBehavior != null && this.currentBehavior.getHighlightOrderId() == OrderIds.stunned) {
544+
this.setAcceptingOrders(true);
545+
this.currentBehavior = this.pollNextOrderBehavior(game);
546+
this.interruptedBehavior = null;
547+
this.stateNotifier.ordersChanged();
548+
}
541549
}
542-
550+
543551
if (isSleeping) {
544552
if (!this.damageTakenListeners.contains(CUnitDefaultSleepListener.INSTANCE)) {
545553
this.addDamageTakenListener(CUnitDefaultSleepListener.INSTANCE);
@@ -1616,12 +1624,63 @@ public boolean update(final CSimulation game) {
16161624
autoAcquireAttackTargets(game, false);
16171625
}
16181626
}
1627+
for (int i = this.abilities.size() - 1; i >= 0; i--) {
1628+
// okay if it removes self from this during onTick() because of reverse
1629+
// iteration order
1630+
this.abilities.get(i).onTick(game, this);
1631+
}
1632+
}
1633+
} else if (!this.constructing) {
1634+
// Paused units only allow passives to function. Buffs don't tick (except a few)
1635+
// Base and bonus life/mana regen function, but regen from Str/Int doesn't
1636+
if (this.life < this.maximumLife) {
1637+
final CRegenType lifeRegenType = getUnitType().getLifeRegenType();
1638+
boolean active = false;
1639+
switch (lifeRegenType) {
1640+
case ALWAYS:
1641+
active = true;
1642+
break;
1643+
case DAY:
1644+
active = game.isDay();
1645+
break;
1646+
case NIGHT:
1647+
active = game.isNight();
1648+
break;
1649+
case BLIGHT:
1650+
active = PathingFlags.isPathingFlag(game.getPathingGrid().getPathing(getX(), getY()),
1651+
PathingFlags.BLIGHTED);
1652+
break;
1653+
default:
1654+
active = false;
1655+
}
1656+
if (active) {
1657+
float lifePlusRegen = this.life + this.currentLifeRegenPerTick
1658+
- this.lifeRegenStrengthBonus * WarsmashConstants.SIMULATION_STEP_TIME;
1659+
if (lifePlusRegen > this.maximumLife) {
1660+
lifePlusRegen = this.maximumLife;
1661+
}
1662+
this.life = lifePlusRegen;
1663+
this.stateNotifier.lifeChanged();
1664+
}
1665+
}
1666+
if (this.mana < this.maximumMana) {
1667+
float manaPlusRegen = this.mana + this.currentManaRegenPerTick
1668+
- this.manaRegenIntelligenceBonus * WarsmashConstants.SIMULATION_STEP_TIME;
1669+
if (manaPlusRegen > this.maximumMana) {
1670+
manaPlusRegen = this.maximumMana;
1671+
}
1672+
this.mana = manaPlusRegen;
1673+
this.stateNotifier.manaChanged();
1674+
}
1675+
1676+
for (int i = this.abilities.size() - 1; i >= 0; i--) {
1677+
// okay if it removes self from this during onTick() because of reverse
1678+
// iteration order
1679+
if (this.abilities.get(i) instanceof AbilityGenericSingleIconPassiveAbility ||
1680+
this.abilities.get(i) instanceof ABTimedTickingPausedBuff) {
1681+
this.abilities.get(i).onTick(game, this);
1682+
}
16191683
}
1620-
}
1621-
for (int i = this.abilities.size() - 1; i >= 0; i--) {
1622-
// okay if it removes self from this during onTick() because of reverse
1623-
// iteration order
1624-
this.abilities.get(i).onTick(game, this);
16251684
}
16261685
}
16271686
return false;
@@ -2602,7 +2661,8 @@ private AutoAttackTargetFinderEnum reset(final CSimulation game, final CUnit sou
26022661
@Override
26032662
public boolean call(final CUnit unit) {
26042663
if (!this.game.getPlayer(this.source.getPlayerIndex()).hasAlliance(unit.getPlayerIndex(),
2605-
CAllianceType.PASSIVE) && !unit.isDead() && !unit.isInvulnerable() && !unit.isUnitType(CUnitTypeJass.SLEEPING)) {
2664+
CAllianceType.PASSIVE) && !unit.isDead() && !unit.isInvulnerable()
2665+
&& !unit.isUnitType(CUnitTypeJass.SLEEPING)) {
26062666
for (final CUnitAttack attack : this.source.getCurrentAttacks()) {
26072667
if (this.source.canReach(unit, this.source.acquisitionRange)
26082668
&& unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed())
@@ -2680,6 +2740,9 @@ public CBehaviorHoldPosition getHoldPositionBehavior() {
26802740
}
26812741

26822742
public CBehavior pollNextOrderBehavior(final CSimulation game) {
2743+
if (this.interruptedBehavior != null) {
2744+
return this.interruptedBehavior;
2745+
}
26832746
if (this.defaultBehavior != this.stopBehavior) {
26842747
// kind of a stupid hack, meant to align in feel with some behaviors that were
26852748
// observed on War3
@@ -2741,6 +2804,9 @@ public void setHidden(final boolean hidden) {
27412804
public void setPaused(final boolean paused) {
27422805
this.paused = paused;
27432806
}
2807+
public boolean isPaused() {
2808+
return this.paused;
2809+
}
27442810

27452811
public void setAcceptingOrders(final boolean acceptingOrders) {
27462812
this.acceptingOrders = acceptingOrders;
@@ -3725,7 +3791,7 @@ public void setDefenseType(final CDefenseType defenseType) {
37253791
}
37263792

37273793
public void updateFogOfWar(final CSimulation game) {
3728-
if (!isDead() && !this.paused && !this.hidden) {
3794+
if (!isDead() && !this.hidden) {
37293795
final float sightRadius = game.isDay() ? this.unitType.getSightRadiusDay()
37303796
: this.unitType.getSightRadiusNight();
37313797
final CPlayerFogOfWar fogOfWar = game.getPlayer(this.playerIndex).getFogOfWar();

core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilitybuilder/ability/CAbilityAbilityBuilderPassive.java

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,13 @@
66
import com.etheller.warsmash.util.War3ID;
77
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
88
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
9-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
10-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconActiveAbility;
11-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget;
9+
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbilityGenericSingleIconPassiveAbility;
1210
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.core.ABAction;
1311
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.core.ABLocalStoreKeys;
1412
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.parser.AbilityBuilderConfiguration;
1513
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilitybuilder.types.impl.CAbilityTypeAbilityBuilderLevelData;
16-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior;
17-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver;
18-
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver;
1914

20-
public class CAbilityAbilityBuilderPassive extends AbstractGenericSingleIconActiveAbility {
15+
public class CAbilityAbilityBuilderPassive extends AbilityGenericSingleIconPassiveAbility {
2116

2217
List<CAbilityTypeAbilityBuilderLevelData> levelData;
2318
private AbilityBuilderConfiguration config;
@@ -26,7 +21,7 @@ public class CAbilityAbilityBuilderPassive extends AbstractGenericSingleIconActi
2621
public CAbilityAbilityBuilderPassive(int handleId, War3ID alias,
2722
List<CAbilityTypeAbilityBuilderLevelData> levelData, AbilityBuilderConfiguration config,
2823
Map<String, Object> localStore) {
29-
super(handleId, alias);
24+
super(alias, handleId);
3025
this.levelData = levelData;
3126
this.config = config;
3227
this.localStore = localStore;
@@ -78,69 +73,4 @@ public void onDeath(CSimulation game, CUnit unit) {
7873
}
7974
}
8075

81-
@Override
82-
public int getBaseOrderId() {
83-
return 0;
84-
}
85-
86-
@Override
87-
public boolean isToggleOn() {
88-
return false;
89-
}
90-
91-
// Unneeded Methods
92-
@Override
93-
public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) {
94-
}
95-
96-
@Override
97-
public CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target) {
98-
return null;
99-
}
100-
101-
@Override
102-
public CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point) {
103-
return null;
104-
}
105-
106-
@Override
107-
public CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId) {
108-
return null;
109-
}
110-
111-
@Override
112-
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target,
113-
AbilityTargetCheckReceiver<CWidget> receiver) {
114-
receiver.orderIdNotAccepted();
115-
}
116-
117-
@Override
118-
protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, CWidget target,
119-
AbilityTargetCheckReceiver<CWidget> receiver) {
120-
receiver.orderIdNotAccepted();
121-
}
122-
123-
@Override
124-
protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target,
125-
AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
126-
receiver.orderIdNotAccepted();
127-
}
128-
129-
@Override
130-
protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target,
131-
AbilityTargetCheckReceiver<AbilityPointTarget> receiver) {
132-
receiver.orderIdNotAccepted();
133-
}
134-
135-
@Override
136-
protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId,
137-
AbilityTargetCheckReceiver<Void> receiver) {
138-
receiver.orderIdNotAccepted();
139-
}
140-
141-
@Override
142-
protected void innerCheckCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver) {
143-
receiver.notAnActiveAbility();
144-
}
145-
14676
}

0 commit comments

Comments
 (0)