RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
So @TSR has a wonderful plugin that lets you customize the look of your popups in combat. However, it's missing one crucial feature: popups for states being removed/added.

a87MVm1.png


Something like this. (Example image courtesy of LGP Better Damage Popup)

Olivia's Battle Impact sidesteps this problem with the flashing State Icons, but it also halves my framerate even on a fresh project due to how the plugin itself is constructed. So that is not negotiable.

I've looked around and experimented with Victor's, SRD's and LGP's plugins for this kind of thing, but none of my experiments to isolate this exact line of code and still have it work with TSR Popups have worked.

I genuinely don't care if the state added/removed popup is a plain old string call, I'll be happy that it works period.
 
Last edited:

ShadowDragon

Realist
Veteran
Joined
Oct 8, 2018
Messages
7,513
Reaction score
3,022
First Language
Dutch
Primarily Uses
RMMV
it is possible (not tested) as you read teh helpfile though:

Code:
 * STATES POPUPS
 * =========================================================================================
 * Whenever a battler is hit by a skill or item that inflict a
 * state, the Plugin will pop out a 'No Effect' if the battler
 * is resistant to the state.
 *
 * Show States Popups:   
 * ===================
 * You can Enable/Disable this feature with this parameter. It
 * will affect both sprite sheet and string popups.
 *
 *
 * String State Popups:
 * ====================
 * Turn this parameter On if you want to use text string popups
 * for the state response popups.
 *
 *
 * State String:
 * ==============
 * This is the text box for state resistance. Write what you
 * want to show for that popup.

so you can test if its working the way you want too?
 

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
it is possible (not tested) as you read teh helpfile though:

Code:
 * STATES POPUPS
 * =========================================================================================
 * Whenever a battler is hit by a skill or item that inflict a
 * state, the Plugin will pop out a 'No Effect' if the battler
 * is resistant to the state.
 *
 * Show States Popups:  
 * ===================
 * You can Enable/Disable this feature with this parameter. It
 * will affect both sprite sheet and string popups.
 *
 *
 * String State Popups:
 * ====================
 * Turn this parameter On if you want to use text string popups
 * for the state response popups.
 *
 *
 * State String:
 * ==============
 * This is the text box for state resistance. Write what you
 * want to show for that popup.

so you can test if its working the way you want too?

Unfortunately that function is only for State Resist and nothing else.

Unless I somehow missed a notetag function that let's me set custom messages per state but I've looked through the actual code and there doesn't seem to be anything else for it.
 

TSR

The Northern Frog
Veteran
Joined
Nov 14, 2019
Messages
515
Reaction score
666
First Language
French
Primarily Uses
RMMZ
Hello @RCXGaming,
this would require to add an additionnal popup effect through code. I don't use MV anymore since it became very unstable on my Mac. But I can give a look at the code and provide some guidance on how to add that feature to the plugin.
But you have to give me some time since I'm kind if busy with lot of stuff...

Regards,
TSR
 

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
Hello @RCXGaming,
this would require to add an additionnal popup effect through code. I don't use MV anymore since it became very unstable on my Mac. But I can give a look at the code and provide some guidance on how to add that feature to the plugin.
But you have to give me some time since I'm kind if busy with lot of stuff...

Regards,
TSR

Thanks for responding. That said, take as much time as you need. I'm not in a hurry. :kaoluv:
 

TSR

The Northern Frog
Veteran
Joined
Nov 14, 2019
Messages
515
Reaction score
666
First Language
French
Primarily Uses
RMMZ
Hello again @RCXGaming
As discussed, I'll show how to, with a few tweaks to the code, add popups to show states addition and removal. This is just to display the state names as a string with a + or - sign in front to show if the state is added or removed. You're free to edit it as you like afterward; I'm just showing the basic process.

1) add some methods to Game_ActionResult
Simply add these methods somewhere in the plugin.
Code:
//== Game_ActionResult ================================


Game_ActionResult.prototype.isStateChanged = function() {
    return (
        this.addedStates.length > 0 ||
        this.removedStates.length > 0
    );
};

Game_ActionResult.prototype.damageAffected = function() {
  return (
      this.hpDamage ||
      this.mpDamage ||
      this.tpDamage
  );
};

2) Edit Game_Battler.prototype.startDamagePopup
Find the method in the plugin and add last part:
Code:
if (Imported.YEP_BattleEngineCore) {
  Game_Battler.prototype.startDamagePopup = function() {
    var result = this.result();
    if (result.missed || result.evaded) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }
    if (result._StateResistRequest && !result.hpAffected) {
      var copyResult = JsonEx.makeDeepCopy(result);
      this._damagePopup.push(copyResult);
    }
    if (result.tpDamage !== 0) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }
    if (result.mpDamage !== 0) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.tpDamage = 0;
      this._damagePopup.push(copyResult);
    }   
    if (result.hpAffected) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }

    /// ADD THIS PART ///////
    if (result.isStateChanged() && !result.damageAffected()) { 
       var copyResult = JsonEx.makeDeepCopy(result);
       this._damagePopup.push(copyResult);
    }
    ////////////////////////

  };
};
*this is to create a popup even if the action doesn't have a damage type.


3) Edit Sprite_Damage.prototype.setup
Find the method and to the following change:
Code:
if (Imported.YEP_BattleEngineCore) {
  Sprite_Damage.prototype.setup = function(target) {
    this._result = target.shiftDamagePopup();
    let result = this._result;
    let dam = result.tpDamage || 0;
    let damm = result.mpDamage || 0;
    let critical = result.critical;
    let overkill = this.CheckOverkill(target, result)
    let alive = target.isAlive() && target.hp > 0;
    if (result.missed || result.evaded) {
        if (TSR.Popups.sheet_enable || TSR.Popups.string_enable) {
          this.createEffects('miss');
        } else {
          this.createMiss();
        }
    } else {
    
    ///////// THIS IS THE PART TO CHANGE /////////////
      if (this.isStateElementVisible(critical, overkill) && alive) {
        if (result._StateResistRequest && TSR.Popups.state_show) {
          this.createEffects('state');
        } 
        if (result.isStateChanged()) {
          const changedStates = [];
          for (const as of result.addedStates) {
            changedStates.push([as, true]);
          }
          for (const rs of result.removedStates) {
            changedStates.push([rs, false]);
          }
          this.createEffects('state', changedStates.sort((a, b) => a[0] - b[0]));
        }
      }
      ///////////////////////////////////////
      
      if (result.hpAffected) {
          this......  ////
*The state add/remove popups use the same condition than the state resist (action is not a critical hit, not an overkill and target is still alive). But they are created independently from the resist popup and will appear even if the state resist popup is disabled with the plugin parameter.
Basically, the added and removed states are pushed in the changedStates array as smal arrays with first entry being the state Id, and second entry is true if state was added and false if the state was removed.
Then the changedStates array is send to the createEffect method as a second arguments.


4) Edit Sprite_Damage.prototype.createEffects
Code:
Sprite_Damage.prototype.createEffects = function(info, chgStates) {
           let w = this.digitWidth(),
               h = this.digitHeight(),
             col = TSR.Popups.effectInfo[info].col,
             row = TSR.Popups.effectInfo[info].row,
             wid = TSR.Popups.effectInfo[info].wid,
          string = TSR.Popups.effectInfo[info].string,
    enableString = TSR.Popups.effectInfo[info].enb;
    if (chgStates) {
      for (let s = 0; s < chgStates.length; s++) {
        const prefix = chgStates[s][1] ? '+' : '-';
        string = prefix + $dataStates[chgStates[s][0]].name;
        info = chgStates[s][1] ? 'addedState' : 'removedState'
        for (var i = 0; i < string.length; i++) {
          let sprite = this.createStringChildSprite(string[i], 0, info);
          let w = sprite.bitmap.measureTextWidth(string[i])
          sprite.x = (i - (string.length - 1) / 2) * w;
          sprite.anchor.y -= 0.5 * s;
          sprite.dy = -i;
        }   
      }
    } else {
      if (!enableString) {
        if (TSR.Popups.sheet_enable) {
          let sprite = this.createChildSprite(info);
          sprite.setFrame(col * w, row * h, wid * w, h);
          sprite.dy = 0;
        }
      } else if (string) {
        for (var i = 0; i < string.length; i++) {
            let sprite = this.createStringChildSprite(string[i], 0, info);
            let w = sprite.bitmap.measureTextWidth(string[i])
            sprite.x = (i - (string.length - 1) / 2) * w;
            sprite.dy = -i;
        }     
      }
    }
  };
Don't forget to add the second argument chgStates. Make the conditional branch that check if chgStates exist and in the Else part, you paste the 'default' code.
When chgStates is defined (true) the code above will create an popup for each of the added and removed states, with a + or - in front accordingly. Note that the sprite.anchor.y is increased for each states so the states popups won't overlap and will stack down.
Also the info value is changed to 'added/removedState' so the popup type can be recognized in further methods.


5) Edit Sprite_Damage.prototype.createStringChildSprite
Code:
Sprite_Damage.prototype.createStringChildSprite = function(string, row, info) {
    let color;
    if (TSR.Popups.digitInfo[info]) {
      color = (row === 0 || row === 2 || row === 5)?
                       TSR.Popups.digitInfo[info].damage.color || '':
                     TSR.Popups.digitInfo[info].recovery.color || '';
    } else if (TSR.Popups.effectInfo[info]) {
      color = TSR.Popups.effectInfo[info].color || '';
    } else {
      color = '';
    }
    let fontSize = TSR.Popups.string_fontSize;
    let pad = fontSize * 0.36;
    let height = fontSize + pad;
    let sprite = new Sprite(new Bitmap(190, height));
    sprite.bitmap.fontSize = fontSize;
    sprite.bitmap.fontFace = TSR.Popups.string_fontFace || 'GameFont';
    sprite.bitmap.textColor = this.getPopupDefaultColor(row, info)
    sprite.bitmap.outlineColor = '#000000';
    sprite.bitmap.outlineWidth = 5;
    sprite.anchor.x = 0;
    sprite.anchor.y = this.getAnchor(info);
    sprite.y = -1 * TSR.Popups.popup_drop;
    sprite.ry = sprite.y;
    sprite.bitmap.drawText(color + string, 10, 0, 200, height);
    this.addChild(sprite);
    return sprite;
  };
Here, only the top conditionnal is to be changed because 'added/removedState' isn't declared in the digitInfo and effectInfo objects.


6) Edit Sprite_Damage.prototype.getPopupDefaultColor and
Sprite_Damage.prototype.getAnchor
Code:
Sprite_Damage.prototype.getPopupDefaultColor = function(row, info) {
    if (info === 'mp') {
      return (row === 0 || row === 2 || row === 5)? '#E9967a' : '#ba55d3';
    } else if (info === 'tp') {
      return (row === 0 || row === 2 || row === 5)? '#f0e68c' : '#87cefa';
    } else if (info === 'critical') {
      return '#ff4500';
    } else if (info === 'overkill') {
      return '#ffa500';
    } else if (info === 'immune') {
      return '#ba55d3';
    } else if (info === 'resist') {
      return '#3cb371';
    } else if (info === 'weak') {
      return '#f0e68c';
    } else if (info === 'addedState') {
      return '#ccffcc';
    } else if (info === 'removedState') {
      return '#ffcccc';
    } else {
      return (row % 2 === 0)? '#ffffff' : '#7fff00';
    }
  };
 
  Sprite_Damage.prototype.getAnchor = function(info) {
    let anc = TSR.Popups.popup_anchor;
    let anchor = 1;
    let result = this._result;
    if (info === 'mp') {
      if (result.ReceivedHpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
    } else if (info === 'tp') {
      if (result.ReceivedHpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
      if (result.ReceivedMpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
    } else if (info === 'critical' ||
               info === 'resist'   ||
               info === 'weak'     ||
               info === 'immune'   ) {
      anchor -= anc;
    } else if (info === 'overkill') {
      anchor -= anc;
      if (this._result.critical) anchor -= anc;
    } else if (info.toLowerCase().includes('state')) {
      anchor -= anc;
      if (this._result._haveElementEffect) anchor -= anc;
    }
    return anchor;   
  };
Change the color of the added/removed state popups by adding a condition for both (optional).
For the anchor method, for now it use the same anchor point than the state resist popup, which mean that if you use it the popups might overlap if both condition occurs. But that can be a later fix if needed.

That's pretty much it. Hope you'll find that useful. This, of course if just the general process, once you got it to work, you can edit it to your liking.

Good luck.
Regards,
TSR
 

Attachments

  • Capture d’écran, le 2023-04-01 à 13.37.17.png
    Capture d’écran, le 2023-04-01 à 13.37.17.png
    129.5 KB · Views: 1

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
Hello again @RCXGaming
As discussed, I'll show how to, with a few tweaks to the code, add popups to show states addition and removal. This is just to display the state names as a string with a + or - sign in front to show if the state is added or removed. You're free to edit it as you like afterward; I'm just showing the basic process.

1) add some methods to Game_ActionResult
Simply add these methods somewhere in the plugin.
Code:
//== Game_ActionResult ================================


Game_ActionResult.prototype.isStateChanged = function() {
    return (
        this.addedStates.length > 0 ||
        this.removedStates.length > 0
    );
};

Game_ActionResult.prototype.damageAffected = function() {
  return (
      this.hpDamage ||
      this.mpDamage ||
      this.tpDamage
  );
};

2) Edit Game_Battler.prototype.startDamagePopup
Find the method in the plugin and add last part:
Code:
if (Imported.YEP_BattleEngineCore) {
  Game_Battler.prototype.startDamagePopup = function() {
    var result = this.result();
    if (result.missed || result.evaded) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }
    if (result._StateResistRequest && !result.hpAffected) {
      var copyResult = JsonEx.makeDeepCopy(result);
      this._damagePopup.push(copyResult);
    }
    if (result.tpDamage !== 0) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }
    if (result.mpDamage !== 0) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.hpAffected = false;
      copyResult.tpDamage = 0;
      this._damagePopup.push(copyResult);
    } 
    if (result.hpAffected) {
      var copyResult = JsonEx.makeDeepCopy(result);
      copyResult.mpDamage = 0;
      this._damagePopup.push(copyResult);
    }

    /// ADD THIS PART ///////
    if (result.isStateChanged() && !result.damageAffected()) {
       var copyResult = JsonEx.makeDeepCopy(result);
       this._damagePopup.push(copyResult);
    }
    ////////////////////////

  };
};
*this is to create a popup even if the action doesn't have a damage type.


3) Edit Sprite_Damage.prototype.setup
Find the method and to the following change:
Code:
if (Imported.YEP_BattleEngineCore) {
  Sprite_Damage.prototype.setup = function(target) {
    this._result = target.shiftDamagePopup();
    let result = this._result;
    let dam = result.tpDamage || 0;
    let damm = result.mpDamage || 0;
    let critical = result.critical;
    let overkill = this.CheckOverkill(target, result)
    let alive = target.isAlive() && target.hp > 0;
    if (result.missed || result.evaded) {
        if (TSR.Popups.sheet_enable || TSR.Popups.string_enable) {
          this.createEffects('miss');
        } else {
          this.createMiss();
        }
    } else {
  
    ///////// THIS IS THE PART TO CHANGE /////////////
      if (this.isStateElementVisible(critical, overkill) && alive) {
        if (result._StateResistRequest && TSR.Popups.state_show) {
          this.createEffects('state');
        }
        if (result.isStateChanged()) {
          const changedStates = [];
          for (const as of result.addedStates) {
            changedStates.push([as, true]);
          }
          for (const rs of result.removedStates) {
            changedStates.push([rs, false]);
          }
          this.createEffects('state', changedStates.sort((a, b) => a[0] - b[0]));
        }
      }
      ///////////////////////////////////////
    
      if (result.hpAffected) {
          this......  ////
*The state add/remove popups use the same condition than the state resist (action is not a critical hit, not an overkill and target is still alive). But they are created independently from the resist popup and will appear even if the state resist popup is disabled with the plugin parameter.
Basically, the added and removed states are pushed in the changedStates array as smal arrays with first entry being the state Id, and second entry is true if state was added and false if the state was removed.
Then the changedStates array is send to the createEffect method as a second arguments.


4) Edit Sprite_Damage.prototype.createEffects
Code:
Sprite_Damage.prototype.createEffects = function(info, chgStates) {
           let w = this.digitWidth(),
               h = this.digitHeight(),
             col = TSR.Popups.effectInfo[info].col,
             row = TSR.Popups.effectInfo[info].row,
             wid = TSR.Popups.effectInfo[info].wid,
          string = TSR.Popups.effectInfo[info].string,
    enableString = TSR.Popups.effectInfo[info].enb;
    if (chgStates) {
      for (let s = 0; s < chgStates.length; s++) {
        const prefix = chgStates[s][1] ? '+' : '-';
        string = prefix + $dataStates[chgStates[s][0]].name;
        info = chgStates[s][1] ? 'addedState' : 'removedState'
        for (var i = 0; i < string.length; i++) {
          let sprite = this.createStringChildSprite(string[i], 0, info);
          let w = sprite.bitmap.measureTextWidth(string[i])
          sprite.x = (i - (string.length - 1) / 2) * w;
          sprite.anchor.y -= 0.5 * s;
          sprite.dy = -i;
        } 
      }
    } else {
      if (!enableString) {
        if (TSR.Popups.sheet_enable) {
          let sprite = this.createChildSprite(info);
          sprite.setFrame(col * w, row * h, wid * w, h);
          sprite.dy = 0;
        }
      } else if (string) {
        for (var i = 0; i < string.length; i++) {
            let sprite = this.createStringChildSprite(string[i], 0, info);
            let w = sprite.bitmap.measureTextWidth(string[i])
            sprite.x = (i - (string.length - 1) / 2) * w;
            sprite.dy = -i;
        }   
      }
    }
  };
Don't forget to add the second argument chgStates. Make the conditional branch that check if chgStates exist and in the Else part, you paste the 'default' code.
When chgStates is defined (true) the code above will create an popup for each of the added and removed states, with a + or - in front accordingly. Note that the sprite.anchor.y is increased for each states so the states popups won't overlap and will stack down.
Also the info value is changed to 'added/removedState' so the popup type can be recognized in further methods.


5) Edit Sprite_Damage.prototype.createStringChildSprite
Code:
Sprite_Damage.prototype.createStringChildSprite = function(string, row, info) {
    let color;
    if (TSR.Popups.digitInfo[info]) {
      color = (row === 0 || row === 2 || row === 5)?
                       TSR.Popups.digitInfo[info].damage.color || '':
                     TSR.Popups.digitInfo[info].recovery.color || '';
    } else if (TSR.Popups.effectInfo[info]) {
      color = TSR.Popups.effectInfo[info].color || '';
    } else {
      color = '';
    }
    let fontSize = TSR.Popups.string_fontSize;
    let pad = fontSize * 0.36;
    let height = fontSize + pad;
    let sprite = new Sprite(new Bitmap(190, height));
    sprite.bitmap.fontSize = fontSize;
    sprite.bitmap.fontFace = TSR.Popups.string_fontFace || 'GameFont';
    sprite.bitmap.textColor = this.getPopupDefaultColor(row, info)
    sprite.bitmap.outlineColor = '#000000';
    sprite.bitmap.outlineWidth = 5;
    sprite.anchor.x = 0;
    sprite.anchor.y = this.getAnchor(info);
    sprite.y = -1 * TSR.Popups.popup_drop;
    sprite.ry = sprite.y;
    sprite.bitmap.drawText(color + string, 10, 0, 200, height);
    this.addChild(sprite);
    return sprite;
  };
Here, only the top conditionnal is to be changed because 'added/removedState' isn't declared in the digitInfo and effectInfo objects.


6) Edit Sprite_Damage.prototype.getPopupDefaultColor and
Sprite_Damage.prototype.getAnchor
Code:
Sprite_Damage.prototype.getPopupDefaultColor = function(row, info) {
    if (info === 'mp') {
      return (row === 0 || row === 2 || row === 5)? '#E9967a' : '#ba55d3';
    } else if (info === 'tp') {
      return (row === 0 || row === 2 || row === 5)? '#f0e68c' : '#87cefa';
    } else if (info === 'critical') {
      return '#ff4500';
    } else if (info === 'overkill') {
      return '#ffa500';
    } else if (info === 'immune') {
      return '#ba55d3';
    } else if (info === 'resist') {
      return '#3cb371';
    } else if (info === 'weak') {
      return '#f0e68c';
    } else if (info === 'addedState') {
      return '#ccffcc';
    } else if (info === 'removedState') {
      return '#ffcccc';
    } else {
      return (row % 2 === 0)? '#ffffff' : '#7fff00';
    }
  };
 
  Sprite_Damage.prototype.getAnchor = function(info) {
    let anc = TSR.Popups.popup_anchor;
    let anchor = 1;
    let result = this._result;
    if (info === 'mp') {
      if (result.ReceivedHpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
    } else if (info === 'tp') {
      if (result.ReceivedHpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
      if (result.ReceivedMpDamage && !Imported.YEP_BattleEngineCore) anchor += anc;
    } else if (info === 'critical' ||
               info === 'resist'   ||
               info === 'weak'     ||
               info === 'immune'   ) {
      anchor -= anc;
    } else if (info === 'overkill') {
      anchor -= anc;
      if (this._result.critical) anchor -= anc;
    } else if (info.toLowerCase().includes('state')) {
      anchor -= anc;
      if (this._result._haveElementEffect) anchor -= anc;
    }
    return anchor; 
  };
Change the color of the added/removed state popups by adding a condition for both (optional).
For the anchor method, for now it use the same anchor point than the state resist popup, which mean that if you use it the popups might overlap if both condition occurs. But that can be a later fix if needed.

That's pretty much it. Hope you'll find that useful. This, of course if just the general process, once you got it to work, you can edit it to your liking.

Good luck.
Regards,
TSR

Wow! Thank you so much for your time, TSR.

It's a great fix/addon because now I don't have to fiddle with other peoples' scripts just to have state popups anymore. :LZScheeze:

Any of you all watching the thread who are also using his script should do what he outlines here to get the same effect.

Safe to say this is Solved.
 

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
... Is what I like to say but as you know, things are NEVER that simple with me.

While it works, there's a pretty bizarre bug:

YHn4Jyu.png


The popup shows up twice for some reason when you use Normal Attacks that apply states specifically. Like if a weapon inflicts Paralysis on it, it will do this - but if a Skill/Item applies a state, it only shows the message one time.

Edit: Yeah, it's something about the "Normal Attack" state that does something weird with the popup.

It also lags horribly when multiple "state applied" messages show up, like it chugs the game to a crawl whenever it happens. Perhaps a limit on how many popups can be shown should be put in place - maybe only the highest rating states should get popups. (And that popups shouldn't show up if the target already has that state.)

That or the text bouncing makes it act funny.

You have any idea what that's all about @TSR ?
 
Last edited:

ShadowDragon

Realist
Veteran
Joined
Oct 8, 2018
Messages
7,513
Reaction score
3,022
First Language
Dutch
Primarily Uses
RMMV
I think there was a bug report before on the double text, which was fixed,
I dont know if you miss something, or messed something up, will test it
later today how it works on my end, also make sure you got the latest version
when you made the edits though, if you are 1-2 versions behind, you need
to redo it...!

so if the version matches to the last version available, than he might have an
idea, but I will test it later anyway :)

as it seems a nice add :)

@RCXGaming the edit I made show it correctly, not double.
and it doesn't lag either, but there was also a minor issue TSR made,
even if it shouldn't affect the code as well.

Untitled-2.png
while +silence is only as a test (didn't test -Silence) but was more spark and fire
I used for a quick test (for your TOD edit).

but if it still lags, here is the plugin, so you might have somewhere a mistake,
even if you used the latest one, it doesn't have the double thing :)
 
Last edited:

TSR

The Northern Frog
Veteran
Joined
Nov 14, 2019
Messages
515
Reaction score
666
First Language
French
Primarily Uses
RMMZ
Hello again @RCXGaming.

First, I'm unable to reproduce that bug. No matter if I use the 'add state' skill/item trait or the 'Attack state' actor/class/enemies/weapons trait, a single popup is shown. Even when the skill add a state and the user have the attack state of the same state, only one popup appear...

Now about the lag, how many popups can you possibly show at the same time? I tested a skill that add 10 states + damage and elemental effects, and there's not even a glimpse of lag... That said, limiting the number of state popups might be a godd idea, not because of the lag, but to avoid a barage of popups which looks silly...

To do that, go in the createEffect method and replace the limit of the loop that iterate the chgStates array:
for (let s = 0; s < chgStates.length; s++) { //replace chgStates.length by the max popups to be shown.

(And that popups shouldn't show up if the target already has that state.)
Well, add condition when building the addedStates array:
for (const as of result.addedStates) {
if (!target.isStateAffected(as)) changedStates.push([as, true]); //push only if not already affected
}

Hope that help.
Regards.
 

ShadowDragon

Realist
Veteran
Joined
Oct 8, 2018
Messages
7,513
Reaction score
3,022
First Language
Dutch
Primarily Uses
RMMV
I set it, but test tomorrow, I didn't test double state for keep coming :)
 

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
@TSR @ShadowDragon Thanks for all the help, you guys! :LZScheeze:

I figured out what was causing the bug - it was a section of Yanfly's Battle Engine Core that controlled popups. (To be precise, setupDamagePopup and pushDamageSprite).

For some reason it was super-interfering with TSR's script and commenting it out only proved to be a good thing. So if nobody ever uses Yanfly Battle Engine Core they won't have this problem. ( :p :p)

I should also mention that I forgot how intensive my testing was - I was using the maximum amount of players/enemies on screen at once at any given time (5 actors, 8 enemies).

This is to see how the game performs when it's under maximum stress, and even then it wound up working completely fine.

There were also a few other scripts that made the combat screen a little slower and weren't really helping me, so I just got rid of them outright.

Well, add condition when building the addedStates array:
for (const as of result.addedStates) {
if (!target.isStateAffected(as)) changedStates.push([as, true]); //push only if not already affected
}

Hope that help.
Regards.

One thing though about this. It makes the "state added" popup not function since it doesn't distinguish the time before the state is applied and after it is applied.

So it just looks like it doesn't apply at all.
 

ShadowDragon

Realist
Veteran
Joined
Oct 8, 2018
Messages
7,513
Reaction score
3,022
First Language
Dutch
Primarily Uses
RMMV
@RCXGaming I use the BattleEngineCore when testing, probably the setting
of it might be false of the PushDamageSprite, but it might interfer, not sure,
as I place it in 2 instance, maybe it should be only 1 instance (will double check),
as for the last one, I test it a bit later on, and see what cause it, as I use the basic
popup layout (and no idea about the lunatic code for popups).

so a sample code might help me on my end (simple one).
 

RCXGaming

Champion of Brightmoon Tor
Veteran
Joined
Jan 4, 2019
Messages
909
Reaction score
2,056
First Language
English
Primarily Uses
RMMV
I have come in with two fixes and two problems!

FIX 1: TSR Popups is fundamentally incompatible with Yanfly State Protection, which for me is a disaster because a lot of my states revolve around it. However, I figured out how to fix it!

Go over to Game_Action.prototype.executeDamage in TSR_Popups and comment it out. Then, replace it with this:

JavaScript:
//----
// Comment out executeDamage & put this below it!
//----

TSR.Popups.Game_Action_executeDamage = Game_Action.prototype.executeDamage;
Game_Action.prototype.executeDamage = function(target, value) {
    TSR.Popups.Game_Action_executeDamage.call(this, target, value);
    var result = target.result();
    result._haveElementEffect = (value < 0)? false : this.checkElementalResponse(target);
    let immune = result.ElementImmune
    if (value === 0 || !this.isHpEffect() || immune) {
        result.critical = false;
    }
    if (result.critical && TSR.Popups.critical_show) {
        result._StateResistRequest = false
        result._haveElementEffect = false;
    }
};

This will allow TSR Popups to show weak/resisted/immune popups like normal while still allowing Yanfly State Protection to function.

FIX 2: The State function will display the names of all states, including filler ones the player is not meant to see. My fix, however, is very simple!

In Sprite_Damage.prototype.createEffects, add this conditional branch under var stateId = chgStates;:

JavaScript:
if ($dataStates[chgStates[s][0]].iconIndex === 0)  {
        string = '';
      } else {
        string = prefix + $dataStates[chgStates[s][0]].name;
      }

What this does is prevent the names of states with no icon (icon index 0) from having their names displayed, giving you the developer control on how which states are shown.

FIX 2.5: State names bounce the longer the name is, which is extremely annoying. The fix for this is easy too.

Change sprite.dy = -i; in the same section to be -
JavaScript:
sprite.dy = 0;

So it doesn't bounce out of control if the state name is super long.

PROBLEM 1: It doesn't show the element pop-ups when enemies/actors take lethal blows, aka. a super-effective/resisted attack KO's them.

PROBLEM 2: And the reason I made this post to begin with - when an actor/enemy take an elemental hit (resisted/weak/immune, whatever) and then they get hit with a damage over time state...

The element pop-up will still be attached to damage-over-time effect. It doesn't clear properly until you get hit with another attack.

EX. Johnny is afflicted by Poison. He shows damage over time normally when the turn ends.

Then he gets hit by a Super Effective dark attack. The "weak" pop-up will stay stuck under his damage over time pop-up, so a prospective player will probably think "did he get hit with another super effective attack when I wasn't looking" when in reality it's just poison.

It's very bizarre. It seems the element function only updates properly when you take damage from attacks, not damage over time. @TSR , do you have any idea how to fix this?
 
Last edited:

Latest Threads

Latest Posts

Latest Profile Posts

This could probably be an entire thread, but it’s really interesting how replaying a game several years later can change how you relate to a character. I think Tidus from FFX got such a bad rap. I getchu. Completely different reaction as an adult now.
As you see, I still enjoy writing tutorials. Is there anything specific you want to see? (I know mapping and editing/resource making is usually popular, but those are very broad topics)
Well, I wanted to expand player battlers visually and now have 3 sheets and counting for each of my players party.
1. Regular sheet
2. The character has turned stone sheet.
3. Using potions sheet.

Technically the main hero has 4 since he starts with a wooden sword, and I felt that the battler should reflect that until he gets a metal one.

Right back to the RM game dev grind in about 15 minutes. :LZSexcite:
Days ago I gave someone the sage advice not to steer away from your main project or take up another one to abandon the first. After figuring a way that would save me years of development, I am forced to redo a lot of stuff on my own turf, near to remake half of what I have already made.
Somewhere down the line I must have crossed paths with bad karma.
:kaomad2:

Forum statistics

Threads
131,733
Messages
1,222,759
Members
173,485
Latest member
taquing
Top