3131import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .GetAbilityByRawcodeVisitor ;
3232import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .build .CAbilityBuildInProgress ;
3333import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .cargohold .CAbilityCargoHold ;
34+ import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .generic .AbilityGenericSingleIconPassiveAbility ;
3435import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .generic .CBuff ;
3536import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .generic .CLevelingAbility ;
3637import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .harvest .CAbilityHarvest ;
4445import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .targeting .AbilityTarget ;
4546import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilities .targeting .AbilityTargetVisitor ;
4647import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilitybuilder .buff .ABGenericTimedBuff ;
48+ import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .abilitybuilder .buff .ABTimedTickingPausedBuff ;
4749import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .behaviors .CBehavior ;
4850import com .etheller .warsmash .viewer5 .handlers .w3x .simulation .behaviors .CBehaviorAttack ;
4951import 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 ();
0 commit comments