showActivatedModifier(modifier, action, suppressChanges, continuousFXFadeDuration) {
    let showDuration = 0.0;

    if (modifier != null) {
      const sdkCard = this.getSdkCard();

      // show changes
      if (!suppressChanges && this.canShowModifier(modifier, action)
        // don't show changes if for removal
        && (action == null || action.getMatchingAncestorAction(SDK.RemoveAction, null, sdkCard) == null)
        // don't show changes if for apply to board
        && (action == null || action.getMatchingAncestorAction(SDK.ApplyCardToBoardAction, null, sdkCard) == null)) {
        showDuration += this.showModifierChanges(modifier, action);
      }

      // wait for resources to load
      Promise.all([
        this.loadModifierResources(modifier),
        this.whenResourcesReady(this.getCardResourceRequestId()),
      ]).spread((modifierLoadId, cardResourceRequestId) => {
        // ensure that modifier load and resources are valid
        if (!this.getAreModifierResourcesValid(modifierLoadId) || !this.getAreResourcesValid(cardResourceRequestId)) return;

        // update resources
        if (modifier.getAnimResource() != null) {
          this.updateAnimResource();
        }
        if (modifier.getSoundResource() != null) {
          this.updateSoundResource();
        }

        // inject modifier cardFXResource into sdk object
        const cardFXResource = modifier.getCardFXResource();
        if (cardFXResource) {
          this.sdkCard.addFXResource(cardFXResource);
        }

        // show continuous fx for modifier
        const stackType = modifier.getStackType();
        if (!this.getChildByTag(stackType)) {
          var continuousFXSprites = this.showContinuousFX(DATA.dataForIdentifiersWithFilter(modifier.getFXResource(), SDK.FXType.ModifierFX), stackType);
          if (continuousFXSprites && _.isNumber(continuousFXFadeDuration) && continuousFXFadeDuration > 0.0) {
            for (var i = 0, il = continuousFXSprites.length; i < il; i++) {
              var fxSprite = continuousFXSprites[i];
              var opacity = fxSprite.getOpacity();
              fxSprite.setOpacity(0.0);
              fxSprite.fadeTo(continuousFXFadeDuration, opacity);
            }
          }
        }

        // show continuous fx for artifacts
        if (modifier.getIsFromArtifact()) {
          const artifactStackType = modifier.getArtifactStackType();

          if (!this.getChildByTag(artifactStackType)) {
            var continuousFXSprites = this.showContinuousFX(DATA.dataForIdentifiersWithFilter(modifier.getFXResource(), SDK.FXType.ArtifactFX), artifactStackType);
            if (continuousFXSprites && _.isNumber(continuousFXFadeDuration) && continuousFXFadeDuration > 0.0) {
              for (var i = 0, il = continuousFXSprites.length; i < il; i++) {
                var fxSprite = continuousFXSprites[i];
                var opacity = fxSprite.getOpacity();
                fxSprite.setOpacity(0.0);
                fxSprite.fadeTo(continuousFXFadeDuration, opacity);
              }
            }
          }
        }
      });
    }

    return showDuration;
  }
Shows a modifier being activated.
@param {SDK.Modifier} modifier
@param {SDK.Action} action
@param {Boolean} [suppressChanges=false] whether to suppress showing changes and just show continuous fx
@param {Number} [continuousFXFadeDuration=0.0] fade duration of continuous fx
@returns {Number} show duration