How to implement every possible Yanfly Tips & Tricks effect in MZ with VisuStella plugins

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
Hi all. This is by far one of the biggest topics I've seen people asking about, to the point where I've been commissioned twice to make an MZ project containing all of the T&T effects. So I figured I'd make a topic about how to implement them all yourselves. If no other plugins are specified, these can all be done with the free cores.

NOTE: Several effects use functions from the Battle Statistics plugin. Although there isn't a VS equivalent of this, I've added the same values via a global passive state which has the following code:

JavaScript:
<JS Pre-Start Battle>
  user._killCount = user._killCount || 0;
  user._assistCount = user._assistCount || 0;
  user._deathCount = user._deathCount || 0;
</JS Pre-Start Battle>
<JS Post-Damage As User>
  if (target.hp <= 0) {
    user._killCount = (user._killCount || 0) + 1;
    // add assist for each other living party member
    $gameParty.battleMembers().forEach(member =>
      member !== user && member.hp > 0 ? member._assistCount = (member._assistCount || 0) + 1 : member
    );
  }
</JS Post-Damage As User>
<JS Post-Damage As Target>
  if (target.hp <= 0) {
    target._deathCount = (target._deathCount || 0) + 1;
  }
</JS Post-Damage As Target>

Exact
JavaScript:
<JS MP Cost>
  cost -= user.mhp - user.hp
</JS MP Cost>
Percentage
JavaScript:
<JS MP Cost>
  cost *= user.hpRate()
</JS MP Cost>

JavaScript:
<JS Parameters>
  ATK = $gameSystem.escapeCount();
</JS Parameters>

Plugin Manager -> MainMenuCore -> Command Window List -> new entry

Symbol: whatever you want
Icon: whatever you want
STR: Text: "Tonberry Shop" or what you want the menu option to be
JS: Show: "$gameSwitches.value(10)" or whatever condition you want (this will make the shop available if switch 10 is on)
JS: Ext: "return 1;" or replace 1 with a different common event ID.
JS: Run Code: "SceneManager._scene.commandCommonEvent();"

The common event setup will be the same as it was in the original T&T.

Plugin Manager -> EventsMoveCore -> Region Rulings -> Forbid Regions

Set up whatever regions you want to restrict movement, then paint those regions on your map as in the original T&T.

Requires the tier 4 Encounter Effects plugin. Event setup is the same as in the original T&T with the exception of the move route.

Instead of putting this._chaseRange = 5; into the movement route, put <Alert Range: 5> in the event's note. More specific settings are available in the plugin parameters.

JavaScript:
<JS Parameters>
  ATK = user.paramBase(2) * 0.1 + user.level;
</JS Parameters>

This cannot be adapted as VS hasn't ported independent item/upgrade slot functionality.

Taunt effects require the tier 2 Aggro Control System plugin.

JavaScript:
<Magical Taunt>
<JS Pre-Damage As Target>
  if (this.isMagical() && this.isHpEffect() && value > 0) {
    value = 0;
    if (DataManager.isSkill(this.item())) {
      const mp = user.skillMpCost(this.item());
      target.gainMp(mp);
    }
    $gameTemp.requestAnimation([target], 58);
  }
</JS Pre-Damage As Target>

JavaScript:
<JS Post-Damage>
  if (target.hp <= 0) {
    user.gainMp(item.mpCost);
  }
</JS Post-Damage>

Requires the tier 2 Skill Learn System plugin. If you wish to use Job Points for advancement, this will also require the tier 2 Class Change System plugin, but you can achieve the same effect using Skill Points or Ability Points.

JavaScript:
<JS On Learn Skill>
  const id = 0;
  user._paramPlus[id] += 200;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  user._upgradeParam[id] += 1;
  user.forgetSkill(skill.id);
  user.refresh();
</JS On Learn Skill>
<Learn SP Cost: 0>
<JS Learn JP Cost>
  const id = 0;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  cost = 1000 + user._upgradeParam[id] * 200;
</JS Learn JP Cost>

<Hide in Battle>

The code supplied is for adding 200 to HP per upgrade. Adjust the param ID and additional values according to your needs. (1 = MP, 2 = ATK, 3 = DEF, 4 = MAT, 5 = MDF, 6 = AGI, 7 = LUK)

JavaScript:
<JS Pre-Apply>
 if (target.isEnemy()) {
    const id = target._enemyId;
    $gameSystem.registerDefeatedEnemy(id);
  }
  let text = target.name() + '\n';
  text += '\\px[100]\\c[4]HP:\\c[0] ' + target.hp;
  text += '/' + target.mhp;
  text += '\\px[300]\\c[4]MP:\\c[0] ' + target.mp;
  text += '/' + target.mmp;
  text += '\\px[500]\\c[4]TP:\\c[0] ' + target.tp;
  text += '\n';
  text += '\\px[100]\\c[4]ATK:\\c[0] ' + target.atk;
  text += '\\px[300]\\c[4]MAT:\\c[0] ' + target.mat;
  text += '\\px[500]\\c[4]AGI:\\c[0] ' + target.agi;
  text += '\n';
  text += '\\px[100]\\c[4]DEF:\\c[0] ' + target.def;
  text += '\\px[300]\\c[4]MDF:\\c[0] ' + target.mdf;
  text += '\\px[500]\\c[4]LUK:\\c[0] ' + target.luk;
  $gameMessage.add(text);
 
  let weakness = '';
  let resist = '';
  let immune = '';
  let absorb = '';
  let elements = $dataSystem.elements;
  for (let i = 1; i < elements.length; ++i) {
    const name = elements[i];
    const rate = target.elementRate(i);
    if (rate > 1) {
      weakness += name + ' ';
    } else if (rate < 0) {
      absorb += name + ' ';
    } else if (rate === 0) {
      immune += name + ' ';
    } else if (rate < 1) {
      resist += name + ' ';
    }
  }
  if (weakness === '') weakness = 'None';
  if (resist === '') resist = 'None';
  if (immune === '') immune = 'None';
  if (absorb === '') absorb = 'None';
  weakness = '\\c[4]Weakness:\\c[0] ' + weakness + '\n';
  resist = '\\c[4]Resist:\\c[0] ' + resist + '\n';
  immune = '\\c[4]Immune:\\c[0] ' + immune + '\n';
  absorb = '\\c[4]Absorb:\\c[0] ' + absorb;
  text = weakness + resist + immune + absorb;
  $gameMessage.add(text);
</JS Pre-Apply>

JavaScript:
<JS Post-Damage>
if (target.isActor() && target._classId === 9) {
  if (!target.isLearnedSkill(item.id)) {
    target.learnSkill(item.id);
    let text = target.name() + ' has learned '
    text = text + item.name + '!';
    $gameMessage.add(text);
  }
}
</JS Post-Damage>

JavaScript:
<JS Parameters>
  let glory = 0;
  glory += (user._killCount || 0) * 4;
  glory += (user._assistCount || 0) * 2;
  glory -= (user._deathCount || 0) * 10;
  glory = glory.clamp(0, 25);
  MAT = glory * 5;
  if (glory >= 15) {
    AGI = user.paramBase(6) * 0.1;
  }
</JS Parameters>

JavaScript:
<JS Pre-Damage>
  if (user.isStateAffected(34)) {
    user.gainMp(-5);
  }
</JS Pre-Damage>

Replace 34 with the ID of your Spirit Shackles state.

JavaScript:
<JS On Add State>
  this._toxicCounter = 1;
</JS On Add State>
<JS Pre-Regenerate>
  const n = this._toxicCounter / 16;
  const value = Math.floor(n * target.mhp);
  this._toxicCounter++;
  target.gainHp(-value);
</JS Pre-Regenerate>

Add to the death state, replace 101 with the ID of the ring:

JavaScript:
<JS On Add State>
  if (target.isActor()) {
    const ring = $dataArmors[101];
    if (target.hasArmor(ring)) {
      target.discardEquip(ring);
      $gameTemp.requestAnimation([target], 42);
      const hp = Math.floor(target.mhp * 0.25);
      target.gainHp(hp);
    }
  }
</JS On Add State>

JavaScript:
<JS Post-Damage As Target>
  if (value < 0) {
    const heal = Math.floor(value * 0.5);
    origin.gainHp(-heal);
    origin.startDamagePopup();
    origin.clearResult();
  }
</JS Post-Damage As Target>

JavaScript:
<JS Parameters>
  if ($gameParty.inBattle()) {
    const turns = user.turnCount();
    let charges = Math.floor(turns / 2);
    charges = charges.clamp(0, 10);
    MaxHP = 20 * charges;
    MaxMP = 40 * charges;
    MAT = 4 * charges;
  }
</JS Parameters>

JavaScript:
<JS Pre-Damage As Target>
  if (value > 0 && this.isHpEffect()) {
    let mpDamage = Math.floor(value * 0.85);
    mpDamage = mpDamage.clamp(0, target.mp);
    target.gainMp(-mpDamage);
    value -= mpDamage;
    if (target.mp === 0) {
      target.removeState(state.id);
    }
  }
</JS Pre-Damage As Target>

This requires the tier 2 STB battle system for the instant tag and the tier 3 Skill Cooldowns plugin for the cooldown.

JavaScript:
<STB Instant Cast>
<Cooldown: 5>
<JS Pre-Apply>
  let tpGained = 0;
  for (let i = 0; i < user.skills().length; ++i) {
    const skill = user.skills()[i];
    if (skill === this.item()) continue;
    if (skill.stypeId === 4) {
      if (user.cooldown(skill.id) > 0) {
        tpGained += 10;
        user.setCooldown(skill.id, 0);
      }
    }
  }
  user.gainTp(tpGained);
</JS Pre-Apply>

This requires the tier 2 STB battle system for the instant tag on the skill that inflicts the state.

JavaScript:
<JS On Add State>
  target._deathMarkDamage = 0;
</JS On Add State>
<JS Post-Damage As Target>
  if (value > 0 && attacker === origin && this.isHpEffect()) {
    target._deathMarkDamage += value;
  }
</JS Post-Damage As Target>
<JS On Erase State>
  $gameTemp.requestAnimation([target], 101);
  const damage = Math.round(0.50 * target._deathMarkDamage);
  target.gainHp(-damage);
  delete target._deathMarkDamage;
  target.startDamagePopup();
  target.clearResult();
</JS On Erase State>

JavaScript:
<JS Post-Apply>
  if (user.isEnemy()) {
    const successRate = 0.5;
    if (Math.random() < successRate) {
      let items = [];
      const total = $gameParty.items().length;
      for (let i = 0; i < total; ++i) {
        const item = $gameParty.items()[i];
        if (item.itypeId !== 2) {
          items.push(item);
        }
      }
      if (items.length > 0) {
        const random = Math.randomInt(items.length);
        const item = items[random];
        $gameParty.loseItem(item, 1);
        var text = user.name() + ' stole ' + item.name + ' from the party!';
        SoundManager.playEquip();
      }
    } else {
      var text = user.name() + ' failed to steal an item!';
      SoundManager.playBuzzer();
    }
    const window = SceneManager._scene._logWindow;
    if (text) {
      window.addStealText(text + '<CENTER>');
    }
  }
</JS Post-Apply>

This requires the tier 2 STB battle system for the instant tag on the skill that inflicts the state.

JavaScript:
<JS Pre-Damage As Target>
  if (value > 0) {
    const members = target.friendsUnit().aliveMembers();
    let affected = [];
    for (let i = 0; i < members.length; ++i) {
      const member = members[i];
      if (member && member.isStateAffected(state.id)) {
        affected.push(member);
      }
    }
    value = Math.ceil(value / affected.length);
    for (let i = 0; i < affected.length; ++i) {
      const member = affected[i];
      if (member !== target) {
        $gameTemp.requestAnimation([member], 12);
        member.gainHp(-value);
        member.startDamagePopup();
        member.clearResult();
        if (member.isDead()) {
          member.performCollapse();
        }
      }
    }
  }
</JS Pre-Damage As Target>

This requires the tier 3 Anti Damage Barriers plugin.

JavaScript:
<JS Pre-Damage as User>
  user._confirmHp = user.hp;
</JS Pre-Damage as User>

<JS Post-Damage as User>
  if (value > 0 && this.isHpEffect() && this.isPhysical()) {
    const lifesteal = Math.ceil(value * 0.2);
    user.gainHp(lifesteal);
    if (user.hp === user.mhp) {
      const result = user.result();
      const overheal = -result.hpDamage + user._confirmHp - user.mhp;
      if (overheal > 0) {
        user._btBarrier = (user._stateDisplay[41] || 0) + overheal;
        user.addState(40);
      }
    }
  }
</JS Post-Damage as User>

Absorb state:

JavaScript:
<All Absorb Barrier: user._btBarrier>

<JS On Erase State>
  delete target._btBarrier;
</JS On Erase State>

JavaScript:
<JS Battle Victory>
  const rate = 1;
  const hpValue = Math.ceil(user.mhp * rate);
  const mpValue = Math.ceil(user.mmp * rate);
  user.gainHp(hpValue);
  user.gainMp(mpValue);
</JS Battle Victory>

1 is 100% heal. If you want it to be lower, use a smaller decimal value (for example, 0.5 for 50%).

JavaScript:
<JS Post-Damage As Target>
  if (value > 0 && this.isPhysical()) {
    const rate = 0.1;
    const recoil = value * rate;
    const defRate = 0.25;
    const bonus = target.def * defRate;
    const damage = Math.ceil(bonus + recoil);
    user.gainHp(-damage);
    if (user.isDead()) {
      user.performCollapse();
    }
  }
</JS Post-Damage As Target>

JavaScript:
<JS Skill Enable>
  const group = user.friendsUnit();
  const allies = group.aliveMembers();
  enabled = allies.length > 1;
</JS Skill Enable>

<Custom Cost Text>
  \i[1]Ally
</Custom Cost Text>

<JS Pre-Start Action>
  const group = user.friendsUnit();
  const allies = group.aliveMembers();
  allies.splice(allies.indexOf(user), 1);
  const ally = allies[Math.randomInt(allies.length)];
  user._allyHp = ally.hp;
  user._allyMat = ally.mat;
  $gameTemp.requestAnimation([ally], 65);
  ally.gainHp(-ally.hp);
  ally.performCollapse();
</JS Pre-Start Action>

<JS Post-End Action>
  delete user._allyHp;
  delete user._allyMat;
</JS Post-End Action>

Damage formula: user._allyHp + user._allyMat * 14;

JavaScript:
<JS Post-Damage As Target>
  const fire = 2;
  if (this.isPhysical() && value > 0) {
    target.setHp(0);
  } else if (this.item().damage.elementId === fire) {
    target.removeState(state.id);
  }
</JS Post-Damage As Target>

Replace 2 with the ID of your fire element.

JavaScript:
<JS Pre-Damage As Target>
  if (value >= target.hp && target.hp > 1) {
    value = target.hp - 1;
    $gameTemp.requestAnimation([target], 49);
  }
</JS Pre-Damage As Target>

<Passive State: 45>

Replace 45 with the ID of the Warmog's Heart state.

Warmog's Heart:

JavaScript:
<JS Passive Condition>
  condition = user.mhp >= 3000;
</JS Passive Condition>

<JS Post-Damage As Target>
  if (value > 0) {
    target._warmogTurns = 0;
  }
</JS Post-Damage As Target>

<JS Pre-Regenerate>
  user._warmogTurns ??= 0;
  user._warmogTurns++;
  if (user._warmogTurns >= 3) {
    const rate = 0.15;
    const value = Math.ceil(rate * user.mhp);
    user.gainHp(value);
    user.startDamagePopup();
  }
</JS Pre-Regenerate>

I'll do these in 30s so the posts don't get too long. Keep your eyes peeled for Unstable Affliction to Actor Transformations!
 
Last edited:

NaosoX

Regular
Regular
Joined
Feb 28, 2013
Messages
696
Reaction score
431
First Language
English
Primarily Uses
RMMZ
I was thinking the same thing..
You beat me to it. I was just typing these up last night. :kaoswt:
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
JavaScript:
<JS Post-Regenerate>
  const elementId = 9;
  let damage = origin.mat;
  damage *= user.elementRate(elementId);
  damage = Math.floor(damage);
  user.gainHp(-damage);
</JS Post-Regenerate>

<JS On Erase State>
  const dispeller = BattleManager._subject;
  if (dispeller) {
    const stateId = 6;
    const elementId = 9;
    let damage = origin.mat;
    damage *= 3;
    damage *= dispeller.elementRate(elementId);
    $gameTemp.requestAnimation([dispeller], 102);
    dispeller.addState(stateId);
    dispeller.gainHp(-damage);
    dispeller.clearResult();
  }
</JS On Erase State>

Replace 9 with the ID of your darkness element, and 6 with the ID of your Silence state.

Damage formula: let value = a.atk * 2; let diff = b.hp - a.hp; if (diff > 0) { diff = Math.floor(diff / 50); let rate = 1 + 0.1 * diff; rate = Math.min(1.50, rate); value *= rate; } value;

JavaScript:
<JS Pre-Regenerate>
  if (origin !== target && origin.isAlive()) {
    let damage = target.hp / 8;
    damage = Math.ceil(damage);
    $gameTemp.requestAnimation([origin], 46);
    origin.gainHp(damage);
    $gameTemp.requestAnimation([target], 59);
    target.gainHp(-damage);
  }
</JS Pre-Regenerate>

JavaScript:
<JS Pre-Damage As User>
  if (this.isAttack()) {
    let turns = user.buffTurns(5);
    turns = Math.max(3, turns);
    user.addBuff(5, turns);
    let tTurns = target.buffTurns(5);
    tTurns = Math.max(3, turns);
    target.addDebuff(5, turns);
    let damage = (user.mat - target.mdf) * 0.4;
    damage = Math.ceil(damage);
    value += Math.max(0, damage);
    const color = [0, 255, 255, 64];
    const duration = 8;
    $gameScreen.startFlash(color, duration);
  }
</JS Pre-Damage As User>

Damage formula: let mp = Math.ceil(b.mp * 0.1); const cap = Math.ceil(a.mmp * 0.2); mp = Math.min(mp, cap); b.gainMp(-mp); Math.ceil(mp * 0.5)

JavaScript:
<Hide State Turns>

<JS On Add State>
  user._bide = 0;
</JS On Add State>

<JS Pre-Damage As Target>
  if (value > 0) {
    target._bide += value;
  }
</JS Pre-Damage As Target>

<JS On Erase State>
  $gameTemp.requestAnimation([user], 97);
  const damage = Math.ceil(user._bide * 2);
  const enemies = user.opponentsUnit().aliveMembers();
  for (let i = 0; i < enemies.length; ++i) {
    const enemy = enemies[i];
    $gameTemp.requestAnimation([enemy], 107);
    enemy.gainHp(-damage);
    enemy.startDamagePopup();
    enemy.clearResult();
  }
  delete user._bide;
</JS On Erase State>

Passive:
JavaScript:
<JS Pre-Damage As User>
  const stage1 = 50;
  const stage2 = 51;
  if (this.isAttack()) {
    if (target.isStateAffected(stage1)) {
      target.setStateTurns(stage1, 3);
    } else if (target.isStateAffected(stage2)) {
      target.setStateTurns(stage2, 3);
    }
  } else if (this.isSkill() && target.isActor() !== user.isActor()) {
    if (!target.isStateAffected(stage1) && !target.isStateAffected(stage2)) {
      target.addState(stage1);
    } else if (target.isStateAffected(stage1)) {
      target.removeState(stage1);
      target.addState(stage2);
    } else if (target.isStateAffected(stage2)) {
      target.removeState(stage2);
      target._deconstructDamage = user.mat * 10;
    }
  }
</JS Pre-Damage As User>

<JS Post-Apply As User>
  if (target._deconstructDamage) {
    if (target.isAlive()) {
      $gameTemp.requestAnimation([target], 101);
      target.startDamagePopup();
      target.gainHp(-target._deconstructDamage);
      target.startDamagePopup();
    }
    delete target._deconstructDamage;
  }
</JS Post-Apply As User>

Replace 50 and 51 with the IDs of your stage 1 and stage 2 states.

This effect can't be adapted as VS didn't port Target Core or Selection Control. It's ostensibly possible with 3rd-party plugins.

JavaScript:
<JS On Add State>
  target._stackingPoison ??= 0;
  target._stackingPoison++;
</JS On Add State>

<JS On Erase State>
  delete target._stackingPoison;
</JS On Erase State>

<JS Pre-Regenerate>
  target._stackingPoison ??= 0;
  const stacks = Math.min(5, target._stackingPoison);
  const damage = stacks * 100;
  $gameTemp.requestAnimation([target], 59);
  target.gainHp(-damage);
</JS Pre-Regenerate>

Damage formula: this._chainMultiplier = this._chainMultiplier || 1.0; let value = user.mat + 1000; value *= this._chainMultiplier; this._chainMultiplier -= 0.2; value

Notebox:
JavaScript:
<Custom Action Sequence>
<JS Targets>
  const foes = this.subject().opponentsUnit();
  const target = foes.members()[this._targetIndex];
  targets.push(target);
  let members = foes.aliveMembers();
  members.splice(members.indexOf(target), 1);
  let extraTargets = 3;
  while (extraTargets--) {
    const member = members[Math.randomInt(members.length)];
    if (member) {
      targets.push(member);
      members.splice(members.indexOf(member), 1);
    }
  }
</JS Targets>

Action Sequence:
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Display Action
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Cast Animation
: :Targets = ["user"]
: :Mirror Animation = false
: :Wait For Animation? = true
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Each Target Action Set
: :Dual/Multi Wield? = false
: :Perform Action = true
: :Wait Count = Sprite_Battler._motionSpeed
: :Action Animation = true
: :Wait Count = Sprite_Battler._motionSpeed * 2
: :Action Effect = true
: :Immortal: Off = true
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

This requires the tier 3 Anti Damage Barriers plugin.

JavaScript:
<JS Pre-Damage As User>
  if (this.isHpEffect() && this.isSkill() && value < 0) {
    const turns = 3;
    const rate = 1.00;
    const barrier = Math.floor(-(value * rate));
    target._spiritShellBarrier = barrier + (target._stateDisplay[54] || 0);
    target.addState(54);
    value += barrier;
  }
</JS Pre-Damage As User>

<JS Post-Damage As User>
  const result = target.result();
  if (result.hpDamage === 0) {
    result.hpAffected = false;
  }
</JS Post-Damage As User>

Absorb state:
JavaScript:
<All Absorb Barrier: user._spiritShellBarrier>

<JS On Erase State>
  delete target._spiritShellBarrier;
</JS On Erase State>

JavaScript:
<No Death Clear>

<JS Post-Damage As Target>
  if (target.hp <= 0) {
    target.removeState(state.id);
    const deathState = user.deathStateId();
    if (user.stateRate(deathState) > 0.01) {
      $gameTemp.requestAnimation([user], 65);
      user.setHp(0);
    }
  }
</JS Post-Damage As Target>

JavaScript:
<Custom Action Sequence>
<JS Targets>
  let hits = Math.floor(user.agi / 34);
  hits = hits.clamp(1, 5);
  this._totalThiefDamage = 0;
  this._currentThiefHits = 0;
  this._totalThiefHits = hits;
</JS Targets>

<JS Post-Apply>
  const result = target.result();
  if (result.isHit()) {
    this._totalThiefDamage += result.hpDamage;
  }
  this._currentThiefHits += 1;
  if (this._currentThiefHits >= this._totalThiefHits) {
    const rate = 0.3;
    const heal = Math.ceil(this._totalThiefDamage * rate);
    $gameVariables.setValue(1, heal);
  }
</JS Post-Apply>

Action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = front base
: :Melee Distance = 20
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 12
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Loop
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Action Animation
: :Targets = ["current target"]
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["current target"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 10
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Movement
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["current target"]
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Jump
: :Targets = ["user"]
: :Desired Height = 100
: :Duration = 20
: :Wait For Jump? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["current target"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 20
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Direction
: :Targets = ["user"]
: :Direction = forward
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Movement
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Wait By Motion Frame
: :Motion Frames to Wait? = 2
◆Script:BattleManager._action._currentThiefHit = BattleManager._action._currentThiefHit || 0;
: :BattleManager._action._currentThiefHit++;
◆If:Script:BattleManager._action._currentThiefHit === BattleManager._action._totalThiefHits
◆Break Loop

:End

:Repeat Above
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Wait By Motion Frame
: :Motion Frames to Wait? = 1
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Jump
: :Targets = ["user"]
: :Desired Height = 100
: :Duration = 60
: :Wait For Jump? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Point
: :Targets = ["user"]
: :Destination Point = home
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 60
: :Face Destination? = false
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["user"]
: :Animation ID = 41
: :Mirror Animation = false
: :Wait For Animation? = true
◆Play SE:Recovery (90, 100, 0)
◆Plugin Command:VisuMZ_1_BattleCore, MECH: HP, MP, TP
: :Targets = ["user"]
: :HP =
: :HP Rate = +0.00
: :HP Flat = +$gameVariables.value(1);
: :MP =
: :MP Rate = +0.00
: :MP Flat = +0
: :TP =
: :TP Rate = +0.00
: :TP Flat = +0
: :Damage Popup? = true

JavaScript:
<Passive State: 56>
<JS Pre-Regenerate>
  const stateId = 56;
  const currentStacks = user.getStateDisplay(stateId) || 0;
  let newStacks = currentStacks + 6;
  newStacks = newStacks.clamp(0, 100);
  user.setStateDisplay(stateId, newStacks);
</JS Pre-Regenerate>

<JS Pre-Damage As User>
  if (this.isAttack() && target.isActor() !== user.isActor()) {
    const stateId = 56;
    const currentStacks = user.getStateDisplay(stateId) || 0;
    let newStacks = currentStacks + 12;
    newStacks = newStacks.clamp(0, 100);
    user.setStateDisplay(stateId, newStacks);
    if (user.getStateDisplay(stateId) >= 100) {
      user.clearStateDisplay(stateId);
      const elementId = 4;
      let damage = user.mat * 2;
      if (target.result().critical) {
        damage = this.applyCritical(damage);
      }
      let members = this.opponentsUnit().aliveMembers();
      members.splice(members.indexOf(target), 1);
      $gameTemp.requestAnimation([target], 77);
      value += Math.ceil(damage * target.elementRate(elementId));
      let extraTargets = 4;
      while (extraTargets--) {
        const member = members[Math.randomInt(members.length)];
        if (member) {
          $gameTemp.requestAnimation([member], 77);
          member.gainHp(-Math.ceil(damage * member.elementRate(elementId)));
          member.startDamagePopup();
          members.splice(members.indexOf(member), 1);
        }
      }
    }
  }
</JS Pre-Damage As User>

Replace 56 with the ID of your Statikk Shiv Stack Counter state. This exists only to display the counter and needs no other settings (it does need an icon)

This requires the tier 4 Weapon Unleash plugin.

JavaScript:
<Replace Attack: 263>

Replace 263 with the ID of your Flare Gun Attack skill.

Skill notebox:
JavaScript:
<Command Text: Attack>
<Custom Action Sequence>

Action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = false
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = false
: :Wait For Animation = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Target(s)
: :Targets (facing) = ["user"]
: :Targets (destination) = ["current target"]
: :Face Away From? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Wait:10 frames
◆If:Script:BattleManager._action.subject().opponentsUnit().members()[BattleManager._action._targetIndex].isStateAffected(57)
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Multipliers
: :Critical Hit% =
: :Rate = 100
: :Flat = +0.00
: :Critical Damage =
: :Rate = 3
: :Flat = +0.00
: :Damage/Healing =
: :Rate = 1.00
: :Flat = +0.00
: :Hit Rate =
: :Rate = 1.00
: :Flat = +0.00
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["current target"]
: :Animation ID = 13
: :Mirror Animation = false
: :Wait For Animation? = false

:Else
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Action Animation
: :Targets = ["current target"]
: :Mirror Animation = false
: :Wait For Animation? = false

:End
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["current target"]
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Multipliers
: :Critical Hit% =
: :Rate = 1.0
: :Flat = +0.00
: :Critical Damage =
: :Rate = 1.00
: :Flat = +0.00
: :Damage/Healing =
: :Rate = 1.00
: :Flat = +0.00
: :Hit Rate =
: :Rate = 1.00
: :Flat = +0.00
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

This can't be adapted as VS didn't port the Augment plugins.

JavaScript:
<No Death Clear>

<JS Post-Apply As Target>
  if (target.hp <= 0 || target.isDead()) {
    $gameTemp.requestAnimation([target], 49);
    const rate = 0.1;
    const heal = Math.floor(target.mhp * rate);
    target.removeState(state.id);
    target.gainHp(heal);
    target.startDamagePopup();
  }
</JS Post-Apply As Target>

This requires the tier 2 STB battle system for the instant tag.

JavaScript:
<STB Instant>

State:
JavaScript:
<JS On Add State>
  user._siphonBonus ??= 1;
  const bonus = user._siphonBonus;
  user.setStateDisplay(state.id, "x" + bonus);
</JS On Add State>

<JS Pre-Damage As User>
  if (this.isAttack()) {
    user._siphonBonus ??= 1;
    value += user._siphonBonus * 100;
    $gameTemp.requestAnimation([target], 102);
    target._lifeState = target.hp > 0;
  }
</JS Pre-Damage As User>

<JS Post-Damage As User>
  if (this.isAttack()) {
    if (target._lifeState && target.hp <= 0) {
      user._siphonBonus ??= 1;
      user._siphonBonus += 1;
    }
  }
  user.removeState(state.id);
  delete target._lifeState;
</JS Post-Damage As User>

JavaScript:
<JS On Add State>
  user.clearActions();
  let text = '<CENTER>' + user.name() + ' will unleash \\c[4]Tsunami\\c[0] in 3 turns.';
  SceneManager._scene._logWindow._lines.push(text);
  text = '<CENTER>Attack ' + user.name() + ' with \\c[6]Lightning\\c[0] to cancel it!';
  SceneManager._scene._logWindow._lines.push(text);
  SceneManager._scene._logWindow.refresh();
</JS On Add State>

<JS On Erase State>
  if (user === origin) {
    const skill = 267;
    const target = -2;
    user.forceAction(skill, target);
  }
</JS On Erase State>

<JS Post-Damage As Target>
  const element = this.item().damage.elementId;
  if (this.isDamage() && element === 4) {
    target.removeState(state.id);
    const text = '<CENTER>' + target.name() + "'s \\c[4]Tsunami\\c[0] is interrupted!";
    SceneManager._scene._logWindow._lines.push(text);
  }
</JS Post-Damage As Target>

Replace 267 with your Tsunami skill and 4 with your Thunder element ID.

JavaScript:
<JS Skill Enable>
  const count = user.totalStateCategoryAffected("Ailment");
  enabled = count > 0;
</JS Skill Enable>

<JS Post-Apply>
  let states = user.states();
  const category = "Ailment";
  while (states.length > 0) {
    const state = states.shift();
    if (state.categories.contains(category.toUpperCase())) {
      const turns = user.stateTurns(state.id);
      user.removeState(state.id);
      target.addState(state.id);
      if (target.isStateAffected(state.id)) {
        target.setStateTurns(state.id, turns);
      }
    }
  }
</JS Post-Apply>

For this to work, you'll have to put <Category: Ailment> on any state you want this to affect.

JavaScript:
<JS On Add State>
  this._roamingMendCharges = 4;
  this._roamingMendHeal = origin.mat * 4;
  this.setStateDisplay(state.id, "x" + 4);
</JS On Add State>

<JS On Erase State>
  delete this._roamingMendCharges;
  delete this._roamingMendHeal;
</JS On Erase State>

<JS Post-Damage As Target>
  if (this.isHpEffect() && this.isDamage() && target.hp > 0) {
    const heal = target._roamingMendHeal || 1;
    $gameTemp.requestAnimation([target], 45);
    target.startDamagePopup();
    target.gainHp(heal);
    target.startDamagePopup();
    const charges = target._roamingMendCharges - 1;
    target.removeState(state.id);
    if (charges > 0) {
      let members = [];
      const aliveMembers = target.friendsUnit().aliveMembers();
      for (let i = 0; i < aliveMembers.length; ++i) {
        const potential = aliveMembers[i];
        if (!potential) continue;
        if (potential === target) continue;
        if (potential.isStateAffected(state.id)) continue;
        if (potential.hp <= 0) continue;
        members.push(potential);
      }
      const member = members[Math.randomInt(members.length)];
      if (member) {
        $gameTemp.requestAnimation([member], 97);
        member.addState(state.id);
        member._roamingMendCharges = charges;
        member._roamingMendHeal = heal;
        member.setStateDisplay(state.id, "x" + charges);
      }
    }
  }
</JS Post-Damage As Target>

For this to work, you'll need the tier 3 Steal Items plugin and a Steal skill with this notebox:
JavaScript:
<Custom Action Sequence>

<Steal>

<JS On Steal Success>
  user._successfulSteals ??= 0;
  user._successfulSteals++;
</JS On Steal Success>

Action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = false
: :Wait For Movement = false
: :Cast Animation = false
: :Wait For Animation = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 20
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = wait
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Movement
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Target(s)
: :Targets (facing) = ["user"]
: :Targets (destination) = ["current target"]
: :Face Away From? = false
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Action Animation
: :Targets = ["current target"]
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = middle center
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 10
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = false
◆Wait:15 frames
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["current target"]
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Jump
: :Targets = ["user"]
: :Desired Height = 50
: :Duration = 10
: :Wait For Jump? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 10
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Direction
: :Targets = ["user"]
: :Direction = forward
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

Thievery skill:

JavaScript:
<Custom Action Sequence>

Damage formula: const steals = a._successfulSteals || 0; const value = (steals * user.agi) / 2; value

Action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 0
: :Duration = 20
: :Opacity Easing = Linear
: :Wait For Opacity? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["current target"]
: :Target Location = back base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 1
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Target(s)
: :Targets (facing) = ["user"]
: :Targets (destination) = ["current target"]
: :Face Away From? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 255
: :Duration = 20
: :Opacity Easing = Linear
: :Wait For Opacity? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Wait:6 frames
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Attack Animation
: :Targets = ["current target"]
: :Mirror Animation = false
: :Wait For Animation? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 0
: :Duration = 20
: :Opacity Easing = Linear
: :Wait For Opacity? = false
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["current target"]
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Action Animation
: :Targets = ["current target"]
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Opacity
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Point
: :Targets = ["user"]
: :Destination Point = home
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 1
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Direction
: :Targets = ["user"]
: :Direction = forward
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 255
: :Duration = 20
: :Opacity Easing = Linear
: :Wait For Opacity? = true

JavaScript:
<JS Pre-Apply>
  target._buffs.forEach(function(buff, index) {
    if (target.isBuffAffected(index) || target.isDebuffAffected(index)) {
      target._buffs[index] *= -1;
    }
  });
</JS Pre-Apply>

JavaScript:
<JS On Add State>
  target.setStateDisplay(state.id, 5);
  target._thornBindDamage = origin.mat * 2;
  target._thornBindDamage.clamp(0, 1000);
</JS On Add State>

<JS Post-Apply As Target>
  const result = target.result();
  if (result.isHit() && !target.isDead() && this.isPhysical() && this.isDamage()) {
    $gameTemp.requestAnimation([target], 12);
    const damage = target._thornBindDamage || 1;
    target.startDamagePopup();
    target.gainHp(-damage);
    target.result().critical = false;
    target.startDamagePopup();
    const currentStacks = target.getStateDisplay(state.id);
    target.setStateDisplay(state.id, currentStacks - 1);
    if (target.getStateDisplay(state.id) <= 0) {
      target.removeState(state.id);
    }
  }
</JS Post-Apply As Target>

JavaScript:
<Reapply Rules: Ignore>
<JS On Erase State>
  const deathState = user.deathStateId();
  if (user.stateRate(deathState) > 0.01 && !user.isStateResist(deathState)) {
    $gameTemp.requestAnimation([user], 65);
    user.setHp(0);
  }
</JS On Erase State>

This requires the tier 2 STB battle system for the instant tag.

JavaScript:
<STB Instant>

<JS Post-Apply>
  let hpRate1 = user.hpRate();
  let hpRate2 = target.hpRate();
  const aniLower = 58;
  const aniUpper = 46;
  if (hpRate1 > hpRate2) {
    hpRate2 = Math.max(0.25, hpRate2);
    $gameTemp.requestAnimation([user], aniLower);
    $gameTemp.requestAnimation([target], aniUpper);
  } else if (hpRate1 < hpRate2) {
    hpRate1 = Math.max(0.25, hpRate1);
    $gameTemp.requestAnimation([user], aniUpper);
    $gameTemp.requestAnimation([target], aniLower);
  }
  const hp1 = Math.ceil(hpRate2 * user.mhp);
  const hp2 = Math.ceil(hpRate1 * target.mhp);
  user.setHp(hp1);
  target.setHp(hp2);
</JS Post-Apply>

This one is a bit of a hack. Technically it has an unwanted animation happening but because the user is off-screen you don't see it. I had to cobble together the targeting part because of not having Selection Control.

Skill notebox:
JavaScript:
<Custom Action Sequence>
<JS Post-Apply>
  $gameTroop.aliveMembers().forEach(member => member.addState(65));
</JS Post-Apply>

Replace 65 with the ID of your Jump Target Redirect state.

Action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Display Action
◆Plugin Command:VisuMZ_1_BattleCore, CAMERA: Focus Target(s)
: :Targets = ["user"]
: :Duration = 60
: :Camera Easing = InOutSine
: :Wait For Camera? = false
◆Plugin Command:VisuMZ_1_BattleCore, ZOOM: Change Scale
: :Scale = 1.5
: :Duration = 60
: :Zoom Easing = InOutSine
: :Wait For Zoom? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Battle Step
: :Targets = ["user"]
: :Wait For Movement? = false
◆Wait:60 frames
◆Play SE:Wind1 (80, 150, 0)
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Float
: :Targets = ["user"]
: :Desired Height = 495
: :Duration = 20
: :Float Easing = Linear
: :Wait For Float? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 0
: :Duration = 20
: :Opacity Easing = Linear
: :Wait For Opacity? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Float
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["current target"]
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Add State
: :Targets = ["user"]
: :States = ["64"]
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Clear Battle Log
◆Plugin Command:VisuMZ_1_BattleCore, CAMERA: Reset
: :Reset Focus? = true
: :Reset Offset? = true
: :Duration = 60
: :Camera Easing = InOutSine
: :Wait For Camera? = false
◆Plugin Command:VisuMZ_1_BattleCore, ZOOM: Reset Zoom
: :Duration = 60
: :Zoom Easing = InOutSine
: :Wait For Zoom? = true

Replace 64 with the ID of your Jump state.

Jump state:
JavaScript:
<JS On Add State>
  target._jumpTurns = 2;
</JS On Add State>

<JS Pre-Damage As Target>
  target.clearResult();
</JS Pre-Damage As Target>

<JS Pre-Regenerate>
  target._jumpTurns--;
  if (target._jumpTurns <= 0) {
    const skill = 277;
    const target = -2;
    user.forceAction(skill, target);
    BattleManager.forceAction(user);
  }
</JS Pre-Regenerate>

Replace 277 with the ID of your Land skill.

Jump Target Redirect state:
JavaScript:
<JS Pre-Start Action>
  if (this.isForOpponent() && this.isForOne()) {
    const possibleTargets = user.opponentsUnit().members().filter(member => !member.isStateAffected(64));
    const target = possibleTargets[Math.randomInt(possibleTargets.length)];
    if (target) {
      this._targetIndex = target.index();
    } else {
      this.setSkill(16);
    }
  }
</JS Pre-Start Action>

This requires that 16 is still the default "Wait and See" skill. If not, set up a skill that does nothing and change 16 to that skill's ID.

Land skill action sequence:
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Clear Battle Log
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Display Action
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Immortal
: :Targets = ["user","all targets"]
: :Immortal = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = middle base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 1
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false
◆Plugin Command:VisuMZ_1_BattleCore, CAMERA: Focus Target(s)
: :Targets = ["current target"]
: :Duration = 60
: :Camera Easing = InOutSine
: :Wait For Camera? = false
◆Plugin Command:VisuMZ_1_BattleCore, ZOOM: Change Scale
: :Scale = 1.5
: :Duration = 60
: :Zoom Easing = InOutSine
: :Wait For Zoom? = false
◆Wait:60 frames
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Opacity
: :Targets = ["user"]
: :Desired Opacity = 255
: :Duration = 1
: :Opacity Easing = Linear
: :Wait For Opacity? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Float
: :Targets = ["user"]
: :Desired Height = 0
: :Duration = 20
: :Float Easing = Linear
: :Wait For Float? = false
◆Wait:10 frames
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["current target"]
: :Animation ID = 2
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["all targets"]
◆Shake Screen:5, 5, 5 frames
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation
◆Plugin Command:VisuMZ_1_BattleCore, CAMERA: Reset
: :Reset Focus? = true
: :Reset Offset? = true
: :Duration = 60
: :Camera Easing = InOutSine
: :Wait For Camera? = false
◆Plugin Command:VisuMZ_1_BattleCore, ZOOM: Reset Zoom
: :Duration = 60
: :Zoom Easing = InOutSine
: :Wait For Zoom? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Jump
: :Targets = ["user"]
: :Desired Height = 100
: :Duration = 30
: :Wait For Jump? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Point
: :Targets = ["user"]
: :Destination Point = home
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 30
: :Face Destination? = false
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = true
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Remove State
: :Targets = ["user"]
: :States = ["64"]

JavaScript:
<JS On Add State>
  if (user.isEnemy()) {
    user._prevEnemyId = user._enemyId;
    const transformEnemyId = 4;
    user.transform(transformEnemyId);
  }
</JS On Add State>

<JS On Erase State>
  if (user.isEnemy()) {
    const transformEnemyId = user._prevEnemyId;
    user.transform(transformEnemyId);
    delete user._prevEnemyId;
  }
</JS On Erase State>

Replace 4 with the ID of the enemy to transform into.

JavaScript:
<JS On Add State>
  if (user.isActor()) {
    user._prevCharName ??= user._characterName;
    user._prevCharIndex ??= user._characterIndex;
    user._prevFaceName ??= user._faceName;
    user._prevFaceIndex ??= user._faceIndex;
    user._prevBattlerName ??= user._battlerName;
    const charName = "SF_Actor1";
    const charIndex = 0;
    const faceName = "SF_Actor1";
    const faceIndex = 0;
    const battlerName = "SF_Actor1_1";
    user.setCharacterImage(charName, charIndex);
    user.setFaceImage(faceName, faceIndex);
    user.setBattlerImage(battlerName);
    user.refresh();
  }
</JS On Add State>

<JS On Erase State>
  const charName = user._prevCharName;
  const charIndex = user._prevCharIndex;
  const faceName = user._prevFaceName;
  const faceIndex = user._prevFaceIndex;
  const battlerName = user._prevBattlerName;
  user.setCharacterImage(charName, charIndex);
  user.setFaceImage(faceName, faceIndex);
  user.setBattlerImage(battlerName);
  delete user._prevCharacterName;
  delete user._prevCharacterIndex;
  delete user._prevFaceName;
  delete user._prevFaceIndex;
  delete user._prevBattlerName;
  user.refresh();
</JS On Erase State>

Replace the graphic filenames and IDs according to your needs.
 
Last edited:

Shaz

Keeper of the Nuts
Global Mod
Joined
Mar 2, 2012
Messages
46,153
Reaction score
16,971
First Language
English
Primarily Uses
RMMV

I've moved this thread to MZ Tutorials. Thank you.



and WOW!!!
 

NeoSoulGamer

Regular
Regular
Joined
Aug 10, 2012
Messages
678
Reaction score
445
First Language
English
Primarily Uses
N/A
NIIIICEEE!!! I was hoping you were going to do this.
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
This works the same way as the original but needs <JS Pre-Apply> instead of <Before Eval>.

JavaScript:
<HRG Rate: 0%>

NOTE: You will need to add an if statement
to all DoT effects which use notetags in
order for this to work properly

For example, the Toxic effect won't be affected because it doesn't use the native regeneration functionality. You could incorporate HRG into such effects rather than using branching logic if you had a lot of them in your game.

JavaScript:
<JS Pre-Apply>
  const stateId = 69;
  if (target.isStateAffected(stateId)) {
    target.removeState(stateId);
  } else {
    target.addState(stateId);
  }
</JS Pre-Apply>

Replace 69 with the ID of your Mending state, which will have the following code:

JavaScript:
<JS Pre-Regenerate>
  const mpUpkeep = 5;
  if (origin.isAlive() && origin.mp >= mpUpkeep) {
    origin.gainMp(-mpUpkeep);
    origin.startDamagePopup();
    const regen = Math.floor(origin.mdf / 2);
    user.gainHp(regen);
    user.startDamagePopup();
  } else {
    origin.removeState(state.id);
  }
</JS Pre-Regenerate>

Just needs a <Custom Action Sequence>. The common event should look like this:
◆If:Script:BattleManager._action.subject().getAttackMotion().type !== 2
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Display Action
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 20
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false

:Else
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = true
: :Wait For Animation = false

:End
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = wait
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Movement
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Target(s)
: :Targets (facing) = ["user"]
: :Targets (destination) = ["current target"]
: :Face Away From? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Wait:10 frames
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Attack Animation
: :Targets = ["all targets"]
: :Mirror Animation = false
: :Wait For Animation? = true
◆If:Script:BattleManager._action.subject().hasWeapon($dataWeapons[1])
◆Plugin Command:VisuMZ_1_BattleCore, ELE: Force Elements
: :Elements = ["2"]
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["all targets"]
: :Animation ID = 8
: :Mirror Animation = false
: :Wait For Animation? = false

:Else
◆If:Script:BattleManager._action.subject().hasWeapon($dataWeapons[2])
◆Plugin Command:VisuMZ_1_BattleCore, ELE: Force Elements
: :Elements = ["3"]
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["all targets"]
: :Animation ID = 9
: :Mirror Animation = false
: :Wait For Animation? = false

:End

:End
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["all targets"]
◆Plugin Command:VisuMZ_1_BattleCore, ELE: Clear Element Changes
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

Modify the ID of the weapon(s) being checked for and IDs of the associated elements according to your needs.

JavaScript:
<JS Pre-Apply>
  if (!this._sharedLifeRate) {
    this._sharedLifeRate = 0;
    const members = this.friendsUnit().aliveMembers();
    for (let i = 0; i < members.length; ++i) {
      const member = members[i];
      this._sharedLifeRate += member.hpRate();
    }
    this._sharedLifeRate /= members.length;
    this._sharedLifeRate += 0.15;
  }
</JS Pre-Apply>

<JS Post-Apply>
  if (target.isAlive()) {
    const targetHp = Math.floor(this._sharedLifeRate * target.mhp);
    const difference = targetHp - target.hp;
    if (difference > 0) {
      $gameTemp.requestAnimation([target], 41);
    } else if (difference < 0) {
      $gameTemp.requestAnimation([target], 54);
    }
    if (difference !== 0) {
      target.gainHp(difference);
      target.startDamagePopup();
    }
  }
</JS Post-Apply>

JavaScript:
<Reapply Rules: Ignore>

<JS On Add State>
  target._promisedDamage ??= 0;
</JS On Add State>

<JS Pre-Damage As Target>
  if (this.isHpEffect()) {
    target._promisedDamage ??= 0;
    if (value > 0) {
      target._promisedDamage += value;
    } else {
      target._promisedDamage += value * 2;
    }
    value = 0;
  }
</JS Pre-Damage As Target>

<JS On Erase State>
  target._promisedDamage ??= 0;
  if (target._promisedDamage > 0) {
    $gameTemp.requestAnimation([target], 11);
  } else {
    $gameTemp.requestAnimation([target], 41);
  }
  target.gainHp(-target._promisedDamage);
  delete target._promisedDamage;
  target.startDamagePopup();
</JS On Erase State>

JavaScript:
<JS Pre-Start Action>
  const paralyzeRate = 0.75;
  if (Math.random() < paralyzeRate) {
    $gameTemp.requestAnimation([user], 64);
    if (user.currentAction()) {
      user.useItem(user.currentAction().item());
    }
    this.setSkill(286);
    const logWindow = SceneManager._scene._logWindow;
    if ($dataStates[71].message3) {
      const msg = '<CENTER>' + user.name() + $dataStates[71].message3;
      logWindow.addText(msg);
      logWindow.refresh();
    }
  }
</JS Pre-Start Action>

This will need a "Paralyzed" skill with scope set to the user which does nothing, which in my project is 286. Adjust the ID as needed. Replace 71 with the ID of the Paralyze state.

Just needs a <Custom Action Sequence>. The common event should look like this:
◆If:Script:BattleManager._action.subject().getAttackMotion().type !== 2
◆Plugin Command:VisuMZ_1_BattleCore, BTLOG: Display Action
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Move To Target(s)
: :Targets (Moving) = ["user"]
: :Targets (Destination) = ["all targets"]
: :Target Location = front base
: :Melee Distance = 24
: :Offset Adjustment = horz
: :Offset: X = 0
: :Offset: Y = 0
: :Duration = 20
: :Face Destination? = true
: :Movement Easing = Linear
: :Movement Motion = walk
: :Wait For Movement? = false

:Else
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = true
: :Wait For Animation = false

:End
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = wait
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Wait For Movement
◆Plugin Command:VisuMZ_1_BattleCore, MOVE: Face Target(s)
: :Targets (facing) = ["user"]
: :Targets (destination) = ["current target"]
: :Face Away From? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = attack
: :Show Weapon? = true
◆Wait:10 frames
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Attack Animation
: :Targets = ["all targets"]
: :Mirror Animation = false
: :Wait For Animation? = true
◆Script:BattleManager._action._targetHp = BattleManager._action.subject().opponentsUnit().members()[BattleManager._action._targetIndex].hp
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Action Effect
: :Targets = ["all targets"]
◆If:Script:BattleManager._action.subject().opponentsUnit().members()[BattleManager._action._targetIndex].hp === BattleManager._action._targetHp
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Add Buff/Debuff
: :Targets = ["user"]
: :Buff Parameters = []
: :Debuff Parameters = ["AGI"]
: :Turns = 5
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["user"]
: :Animation ID = 54
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MOTION: Motion Type
: :Targets = ["user"]
: :Motion Type = dead
: :Show Weapon? = true
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation

:End
◆Script:delete BattleManager._action._targetHp
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

All states involved in this need a <No Death Clear> tag. The code that goes into the death state is the same as in the original, though I used "let" and "const" instead of "var".

JavaScript:
<JS Post-Damage As User>
  if (this.isHpEffect() && value > 0) {
    const actionElements = this.elements();
    const matchingElements = [2, 3, 4, 5, 6, 7, 8, 9];
    let condition = false;
    for (let i = 0; i < actionElements.length; ++i) {
      if (matchingElements.contains(actionElements[i])) {
        condition = true;
        break;
      }
    }
    if (condition) {
      const exposedState = 89;
      target.addState(exposedState);
    }
  }
</JS Post-Damage As User>

Modify matchingElements according to your own element types, and change 89 to the ID of your Expose Weakness state. That state should have the following code:

JavaScript:
<JS On Add State>
  target._exposedWeakness ??= 0;
  target._exposedWeakness = Math.min(4, target._exposedWeakness + 1);
  const counterText = "+" + (target._exposedWeakness * 5) + "%";
  target.setStateDisplay(state.id, counterText);
</JS On Add State>

<JS On Remove State>
  delete target._exposedWeakness;
  target.clearStateDisplay(89);
</JS On Remove State>

<JS Pre-Damage As Target>
  if (this.isHpEffect() && value > 0) {
    target._exposedWeakness = target._exposedWeakness || 0;
    let multiplier = 1;
    multiplier += target._exposedWeakness * 0.05;
    value *= multiplier;
    value = Math.ceil(value);
  }
</JS Pre-Damage As Target>

JavaScript:
<JS Pre-Damage As User>
  if (this.isMagical() && value !== 0) {
    value = Math.ceil(value * 1.5);
  }
</JS Pre-Damage As User>

This effect requires the tier 2 STB battle system for the instant tag.

JavaScript:
<Custom Action Sequence>
<STB Instant>

Action sequence for instant skills:
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = false
: :Wait For Animation = false
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: All Targets Action Set
: :Dual/Multi Wield? = false
: :Perform Action = true
: :Wait Count = Sprite_Battler._motionSpeed
: :Action Animation = true
: :Wait For Animation = false
: :Action Effect = true
: :Immortal: Off = false
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

The action sequence for this is too long and specific to be worth transcribing, but if anyone really wants to see how it's done in VisuStella plugins PM me and I'll paste the common event.

JavaScript:
<JS Post-Damage As Target>
  if (target.result().hpDamage > 0) {
    let elements = this.elements();
    while (elements.length > 0) {
      const element = elements.shift();
      if (element >= 2 && element <= 9) {
        target.addState(element + 89);
        $gameTemp.requestAnimation([target], 53);
      }
    }
  }
</JS Post-Damage As Target>

The way I've set this up requires that all the elemental guard states and element types are in sequence. Change 89 to the ID of your first guard state minus the ID of the first element. If you haven't got yours in sequence, you'll need to modify this slightly.

JavaScript:
<JS Post-Apply>
  if (user.isActor() && target.isEnemy() && (target.isDead() || target.hp <= 0)) {
    const id = target.enemyId();
    const pool = [];
    pool.push($dataItems[7]);
    pool.push($dataItems[8]);
    pool.push($dataItems[9]);
    if (id === 1) {
      pool.push($dataWeapons[1]);
    } else if (id === 2) {
      pool.push($dataWeapons[2]);
      pool.push($dataWeapons[3]);
    } else if (id === 3) {
      pool.push($dataArmors[2]);
      pool.push($dataArmors[3]);
      pool.push($dataArmors[4]);
    }
    const item = pool[Math.randomInt(pool.length)];
    if (item) {
      $gameTemp.requestAnimation([target], 2);
      target.removeImmortal();
      SoundManager.playShop();
      $gameParty.gainItem(item, 1);
      const msg = '<CENTER>' + user.name() + ' acquired \\i[' + item.iconIndex + ']' + item.name + ' from ' + target.name() + '!';
      const logWindow = SceneManager._scene._logWindow;
      logWindow.addStealText(msg);
    }
  }
</JS Post-Apply>

Modify the pool array as necessary for your game.

JavaScript:
<JS On Add State>
  target._earthShieldHeal = Math.floor(origin.mat * 0.5);
  target.setStateDisplay(state.id, 9);
</JS On Add State>

<JS On Erase State>
  delete target._earthShieldHeal;
  target.clearStateDisplay(state.id);
</JS On Erase State>

<JS Pre-Damage As Target>
  if (this.isHpEffect() && value < 0) {
    value = Math.floor(value * 1.2);
    target.setStateDisplay(state.id, target.getStateDisplay(99) - 1);
    if (target.getStateDisplay(state.id) <= 0) {
      target.removeState(state.id);
    }
  }
</JS Pre-Damage As Target>

<JS Post-Apply As Target>
  if (target.isAlive() && target.result().hpDamage > 0) {
    const hpHealed = target._earthShieldHeal || 0;
    target.startDamagePopup();
    target.gainHp(hpHealed);
    target.startDamagePopup();
    target.setStateDisplay(state.id, target.getStateDisplay(99) - 1);
    if (target.getStateDisplay(state.id) <= 0) {
      target.removeState(state.id);
    }
  }
</JS Post-Apply As Target>

JavaScript:
<JS Pre-Start Battle>
  user._criticalProtect = false;
</JS Pre-Start Battle>

<JS Post-End Battle>
  user._criticalProtect = false;
</JS Post-End Battle>

<JS Post-Damage As Target>
  const crisis = 0.25;
  if ($gameParty.inBattle() && target.isAlive() && target.hpRate() <= crisis && !target._criticalProtect) {
    target._criticalProtect = true;
    target._criticalProtectTurns = 5;
    const turns = 5;
    target.addBuff(3, turns);
    $gameTemp.requestAnimation([target], 53);
  }
</JS Post-Damage As Target>

<JS Post-End Turn>
  if (target._criticalProtectTurns) {
    target._criticalProtectTurns--;
    if (target._criticalProtectTurns <= 0) {
      delete target._criticalProtectTurns;
      target._criticalProtect = false;
    }
  }
</JS Post-End Turn>

JavaScript:
<JS Pre-Apply>
  BattleManager.allBattleMembers().forEach(member => member.isStateAffected(102) ? member.removeState(102) : null);
</JS Pre-Apply>

The skill should have an effect to add the "Cyclone Bridge" state. Replace 102 with the ID of your Cyclone state proper. Cyclone Bridge should have the following code:

JavaScript:
<JS On Add State>
  target._cycloneTimes ??= 0;
  const turns = Math.max(5 - target._cycloneTimes * 2, 1);
  target.addState(102);
  target.setStateTurns(102, turns);
  target._cycloneTimes++;
</JS On Add State>

<JS On Erase State>
  delete target_cycloneTimes;
</JS On Erase State>

Again, replace 102 with the ID of your Cyclone state.

JavaScript:
<JS Pre-Apply>
  if (user.isActor()) {
    const allowed = [];
    allowed.push(1, 2, 3, 4);
    const skills = target.skills();
    for (let i = 0; i < skills.length; ++i) {
      const skill = skills[i];
      if (skill && allowed.contains(skill.stypeId) && !user.isLearnedSkill(skill.id)) {
        user.learnSkill(skill.id);
        const text = '<CENTER>' + user.name() + ' has learned \\i[' + skill.iconIndex + ']' + skill.name + ' from ' + target.name() + '!';
        const logWindow = SceneManager._scene._logWindow;
        logWindow._lines.push(text);
        $gameTemp.requestAnimation([user], 119);
      }
    }
  }
</JS Pre-Apply>

Modify the skill type IDs in the allowed array as needed.

JavaScript:
<JS Passive Condition>
  if ($gameParty.inBattle()) {
    condition = user.tp >= 80;
  } else {
    condition = false;
  }
</JS Passive Condition>

Add whatever buffs you wish to the state traits.

JavaScript:
<JS Passive Condition>
  if ($gameParty.inBattle()) {
    user._trance ??= false;
    condition = user._trance || user.tp === user.maxTp();
  } else {
    condition = false;
  }
  if (condition) {
    if (!user._trance) {
      $gameTemp.requestAnimation([user], 120);
    }
    user._trance = true;
  }
</JS Passive Condition>

<JS Pre-Regenerate>
  const tp = 10;
  user.gainTp(-tp);
  if (user.tp === 0) {
    user._trance = false;
  }
</JS Pre-Regenerate>

The setup of the Combo Attack skill should just add the Combo state, which should have the following code:

JavaScript:
<JS On Add State>
  user._comboStacks ??= 0;
  const stacks = user._comboStacks.clamp(0, 10);
  user.setStateDisplay(state.id, 'x' + stacks);
</JS On Add State>

<JS On Erase State>
  user._comboStacks = 0;
  user.setStateDisplay(state.id, 'x' + stacks);
</JS On Erase State>

<JS Pre-Damage As User>
  if (this.isPhysical() && value > 0 && !this.item().name.match('Combo')) {
    user._comboStacks ??= 0;
    let stacks = user._comboStacks.clamp(0, 10);
    const rate = 1 + stacks * 0.1;
    value = Math.ceil(value * rate);
    stacks++;
    stacks = stacks.clamp(0, 10);
    user.setStateDisplay(state.id, 'x' + stacks);
    user._comboStacks = stacks;
  }
</JS Pre-Damage As User>

Skills that use combo points should be set up similarly to this:

JavaScript:
<Custom Cost Text>
  2\i[160]
</Custom Cost Text>

<JS Skill Enable>
  user._comboStacks ??= 0;
  enabled = user._comboStacks >= 2;
</JS Skill Enable>

<JS Pre-start Action>
  user._comboStacks ??= 0;
  let stacks = user._comboStacks;
  stacks -= 2;
  stacks = stacks.clamp(0, 10);
  const comboStateId = 105;
  user.setStateDisplay(comboStateId, 'x' + stacks);
  user._comboStacks = stacks;
</JS Pre-start Action>

Replace 2 with whatever the combo cost is and 105 with the ID of your Combo state.

This requires the tier 3 Auto Skill Triggers plugin.

The state code should be:
JavaScript:
<JS Post-Damage As Target>
  if (value > 0) {
    target._tookDamage = true;
  }
</JS Post-Damage As Target>

<JS Post-End Action>
  target._tookDamage = false;
</JS Post-End Action>

And the skill code should be:

JavaScript:
<Auto Trigger: Certain Hit Enemy>
<Auto Trigger: Physical Enemy>
<Auto Trigger: Magical Enemy>
<Auto Trigger: Item Enemy>

<JS Skill Visible>
  visible = false;
</JS Skill Visible>

<JS Skill Enable>
  enabled = false;
  if (user.isActor()) {
    const potions = [];
    potions.push(7, 8, 9);
    for (let i = 0; i < potions.length; ++i) {
      const id = potions[i];
      if ($gameParty.numItems($dataItems[id]) > 0) {
        enabled = true;
        break;
      }
    }
  } else {
    enabled = true;
  }
</JS Skill Enable>

<JS Pre-Apply>
  if (target._tookDamage) {
    const potions = [];
    potions.push(7, 8, 9);
    for (let i = 0; i < potions.length; ++i) {
      const id = potions[i];
      if ($gameParty.numItems($dataItems[id]) > 0) {
        const item = $dataItems[id];
        if (user.isActor()) {
          $gameParty.loseItem(item, 1);
        }
        this.setItem(id);
        const text = '<CENTER>' + user.name() + ' uses \\i[' + item.iconIndex + ']' + item.name + '!';
        const logWindow = SceneManager._scene._logWindow;
        logWindow._lines.push(text);
        break;
      }
    }
  }
</JS Pre-Apply>

<Custom Action Sequence>

The action sequence is just
◆If:Script:BattleManager._action.subject()._tookDamage
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = false
: :Wait For Animation = false
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: All Targets Action Set
: :Dual/Multi Wield? = false
: :Perform Action = true
: :Wait Count = Sprite_Battler._motionSpeed
: :Action Animation = true
: :Wait For Animation = false
: :Action Effect = true
: :Immortal: Off = false
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Finish Action
: :Immortal: Off = true
: :Wait For New Line = true
: :Wait For Effects = true
: :Clear Battle Log = true
: :Home Reset = true
: :Wait For Movement = true

:End

Note that the state needs the "Add Skill: Auto Potion" trait for this to work. Replace 7, 8, 9 with the IDs of the potions you want to use with the effect, in the order they should be prioritised.

If you want to limit the effect as per the original T&T, you'll also need the tier 3 Limited Skill Uses plugin. Add a <Limited Uses: x> tag to the Auto Potion skill.

JavaScript:
<JS Post-Start Action>
  if (!$gameTemp._chainAction) {
    $gameTemp._chainAction = user.currentAction();
  } else {
    delete $gameTemp._chainAction;
  }
</JS Post-Start Action>

<JS Pre-End Action>
  if ($gameTemp._chainAction) {
    const action = $gameTemp._chainAction;
    if (action && action.isSkill() && action.isMagical()) {
      const skill = action.item();
      if (user.canPaySkillCost(skill)) {
        user.setAction(0, action);
      }
    }
  }
</JS Pre-End Action>

<JS On Erase State>
  delete $gameTemp._chainAction;
</JS On Erase State>

The Living Dead state itself just needs a <No Death Clear> tag. The Walking Dead state's code is:

JavaScript:
<JS Pre-Regenerate>
  if (target.isStateAffected(state.id)) {
    if (target.hp <= 0) {
      target.setHp(1);
    }
  }
</JS Pre-Regenerate>

<JS On Add State>
  target._walkingDeadHp = target.mhp;
  target._walkingDeadFailed = false;
  $gameTemp.requestAnimation([target], 65);
  target.setStateDisplay(state.id, target._walkingDeadHp);
</JS On Add State>

<JS On Erase State>
  target._walkingDeadHp ??= target.mhp;
  if (target._walkingDeadHp > 0) {
    target._walkingDeadFailed = true;
    target.setHp(0);
  }
</JS On Erase State>

<JS Post-Damage As Target>
  target._walkingDeadHp ??= target.mhp;
  if (value < 0) {
    target._walkingDeadHp += value;
    user.setStateDisplay(state.id, Math.max(0, target._walkingDeadHp));
  }
  if (target.hp <= 0) {
    target.setHp(1);
  }
</JS Post-Damage As Target>

And in the Death state:

JavaScript:
<JS On Add State>
  if (target.isStateAffected(108) && !target._walkingDeadFailed) {
    target.removeState(1);
    target.removeState(108);
    target.addState(109);
    user.setHp(1);
  }
</JS On Add State>

Replace 108 with the ID of the Living Dead state, and 109 with the ID of the Walking Dead state.

This effect can't be replicated due to not having the functionality of Selection Control.

The state setup is the same as in the original, as there's no code involved. In any skill which you want Blood Magic to affect, you'd put the following:

JavaScript:
<JS MP Cost>
  if (user.isStateAffected(110)) {
    cost = 0;
  }
</JS MP Cost>
<JS HP Cost>
  if (user.isStateAffected(110)) {
    cost = skill.mpCost * 2;
  }
</JS HP Cost>

JavaScript:
<JS On Add State>
  target._healingFateDamage = 0;
</JS On Add State>

<JS On Erase State>
  delete target._healingFateDamage;
</JS On Erase State>

<JS Post-Damage As Target>
  if (this.isHpEffect() && value > 0) {
    target._healingFateDamage += value;
    if (target._healingFateDamage >= target.mhp * 0.2) {
      target.removeState(state.id);
      const members = origin.friendsUnit().aliveMembers();
      const hpHealed = origin.mdf * 2;
      for (let i = 0; i < members.length; ++i) {
        const member = members[i];
        if (member) {
          member.gainHp(hpHealed);
          $gameTemp.requestAnimation([member], 46);
          member.startDamagePopup();
        }
      }
    }
  }
</JS Post-Damage As Target>

The skill code should be:

JavaScript:
<JS Pre-Damage>
  target._currentHp = target.hp;
</JS Pre-Damage>

<JS Post-Damage>
  if (target._currentHp && target.hp <= 0) {
    const damage = value - target._currentHp;
    if (damage > 0) {
      const overkillStateId = 112;
      user.addState(overkillStateId);
      user._overkillBonus = damage;
      $gameTemp.requestAnimation([user], 51);
    }
  }
  delete target._currentHp;
</JS Post-Damage>

Replace 112 with the ID of your Overkill state, which should have the following code:

JavaScript:
<JS Pre-Damage As User>
  if (this.isHpEffect() && value > 0) {
    user._overkillBonus ??= 0;
    value += Math.min(value * 5, user._overkillBonus);
    $gameTemp.requestAnimation([target], 13);
  }
</JS Pre-Damage As User>

JavaScript:
<JS Pre-Start Action>
  user._reverenceMp = user.mp;
</JS Pre-Start Action>

<JS Pre-Apply As User>
  if (user._reverenceMp) {
    const difference = user._reverenceMp - user.mp;
    if (difference > 0) {
      const hp = Math.ceil(difference * 20);
      user.gainHp(hp);
      user.startDamagePopup();
    }
  }
</JS Pre-Apply As User>
 
Last edited:

AeroPergold

RPG Maker Nutcase
Regular
Joined
Feb 3, 2014
Messages
353
Reaction score
415
First Language
English
Primarily Uses
RMMZ
This is a fantastic resource! I have a folder in my bookmarks for RPG Maker stuff and its in there. Now...to make something that uses this....
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
Apologies for the delay in the next one, it's been a busy week. :D

This effect can't be adapted due to having no plugins offering lifesteal functionality.

Note that the selection restriction can't be done with VS plugins, but caethyril's battle effects plugin can add it if you want to put it in yourself.

Damage formula: const states = b._states.length; a.mdf * 2 * states;

Skill notebox:
JavaScript:
<JS Pre-Damage>
  while (target._states.length > 0) {
    const stateId = target._states.shift();
    target.removeState(stateId);
  }
</JS Pre-Damage>

This effect can't be adapted due to having no plugins with item augmentation.

JavaScript:
<JS Pre-Start Action>
  const clericStanceId = 114;
  if (user.isStateAffected(clericStanceId)) {
    user.removeState(clericStanceId);
  } else {
    user.addState(clericStanceId);
  }
</JS Pre-Start Action>

Replace 114 with the ID of your Cleric Stance state.

State notebox:
JavaScript:
<JS Pre-Damage As User>
  if (this.isMagical() && this.isHpEffect() && value > 0) {
    value = Math.ceil(value * 1.2);
  } else if (this.isMagical() && this.isHpEffect() && value < 0) {
    value = Math.ceil(value * 0.8);
  }
</JS Pre-Damage As User>

Note that this T&T requires the tier 3 Anti Damage Barriers plugin for the barrier effect.

JavaScript:
<JS Pre-Regenerate>
  user._hexdrinkerCooldown ??= 0;
  if (user._hexdrinkerCooldown > 0) {
    user._hexdrinkerCooldown--;
  }
</JS Pre-Regenerate>

<JS Pre-Damage As Target>
  target._hexdrinkerCooldown ??= 0;
  if (this.isMagical() && value > 0 && target.hpRate() <= 0.3 && target.hp >= 0 && target._hexdrinkerCooldown <= 0) {
    target.addState(116);
    target._hexdrinkerCooldown = 5;
    $gameTemp.requestAnimation([target], 53);
  }
</JS Pre-Damage As Target>

Replace 116 with the ID of your Hexdrinker Barrier state, which will have:

JavaScript:
<All Absorb Barrier: 250>

JavaScript:
<JS Pre-Damage As Target>
  if (this.isPhysical() && this.isHpEffect() && value > 0) {
    target._staggerDamage ??= 0;
    const reduce = Math.ceil(value * 0.35);
    value -= reduce;
    target.addState(118);
    target._staggerDamage += reduce;
  }
</JS Pre-Damage As Target>

Replace 118 with the ID of your Staggered Damage state, which has the following notebox:

JavaScript:
<JS Pre-Regenerate>
  user._staggerDamage ??= 0;
  if (user.isAlive() && user._staggerDamage > 0) {
    const turns = Math.max(1, user.stateTurns(118));
    const damage = Math.ceil(user._staggerDamage / turns);
    user._staggerDamage -= damage;
    user.gainHp(-damage);
    $gameTemp.requestAnimation([user], 2);
    user.startDamagePopup();
  }
</JS Pre-Regenerate>

<JS On Erase State>
  delete user._staggerDamage;
</JS On Erase State>

No targeting plugins are needed to target everybody as this is now a native option in the database.

Damage formula: let damage = 0; if (target.isActor() === user.isActor()) { damage = user.mdf * 6; } else { damage = user.mat * 4; } damage

Skill note:
JavaScript:
<JS Pre-Damage>
  if (target.isActor() === user.isActor()) {
    value = -value;
  }
</JS Pre-Damage>

Biotic Blast state note:
JavaScript:
<JS Pre-Damage As Target>
  if (this.isHpEffect() && value < 0) {
    if (target.isActor() === origin.isActor()) {
      value = Math.ceil(value * 2);
    } else {
      value = 0;
    }
  }
</JS Pre-Damage As Target>

JavaScript:
<JS Pre-Apply>
  if (this.item() && DataManager.isSkill(this.item()) && this.isForOpponent()) {
    const blockedTypes = [];
    blockedTypes.push(1, 2);
    const blockedSkills = [];
    blockedSkills.push(294);
    if (blockedTypes.contains(this.item().stypeId) || blockedSkills.contains(this.item().id)) {
      this._formerItemSuccessRate = this.item().successRate;
      this.item().successRate = 0;
      $gameTemp.requestAnimation([target], 53);
    }
  }
</JS Pre-Apply>

<JS Post-Apply>
  if (this._formerSuccessRate) {
    this.item().successRate = this._formerItemSuccessRate;
    target.removeState(state.id);
  }
</JS Post-Apply>

Replace the values in blockedTypes and blockedSkills with whatever skill type IDs or skill IDs you want the spell shield to block.

This can't be adapted due to no augment plugins.

This can't be adapted as there are no row formation plugins.

JavaScript:
<JS Post-Damage As User>
  if (this.isHpEffect() && value < 0 && target.isAlive()) {
    target.addState(122);
    const healing = Math.abs(Math.ceil(value * 0.2));
    target._echoHealing ??= 0;
    target._echoHealing += healing;
  }
</JS Post-Damage As User>

Replace 122 with the ID of your EoL Healing state, which has the following note:

JavaScript:
<JS Pre-Regenerate>
  user._echoHealing ??= 0;
  if (user.isAlive() && user._echoHealing > 0) {
    const turns = Math.max(1, user.stateTurns(state.id));
    const damage = Math.ceil(user._echoHealing / turns);
    user._echoHealing -= damage;
    user.gainHp(damage);
    $gameTemp.requestAnimation([user], 45);
    user.startDamagePopup();
  }
</JS Pre-Regenerate>

<JS On Erase State>
  delete user._echoHealing;
</JS On Erase State>

Power Charge:
JavaScript:
<JS Post-Start Action>
  if (action.isPhysical() && action.isAttack() && action.isHpEffect()) {
    $gameTemp.requestAnimation([user], 2);
  }
</JS Post-Start Action>

<JS Pre-Damage As User>
  if (this.isPhysical() && this.isAttack() && this.isHpEffect() && value > 0) {
    value *= 2;
    value = Math.ceil(value);
    user.removeState(state.id);
  }
</JS Pre-Damage As User>

Mind Charge:
JavaScript:
<JS Post-Start Action>
  if (action.isMagical() && action.isHpEffect()) {
    $gameTemp.requestAnimation([user], 2);
  }
</JS Post-Start Action>

<JS Pre-Damage As User>
  if (this.isMagical() && this.isHpEffect() && value > 0) {
    value *= 2;
    value = Math.ceil(value);
    user.removeState(state.id);
  }
</JS Pre-Damage As User>

JavaScript:
<JS Pre-Start Action>
  if (action && action.isItem() && action.isForFriend()) {
    const index = user.index();
    action.setTarget(index);
  }
</JS Pre-Start Action>

JavaScript:
<JS On Add State>
  target._antiHealBarrier = 3000;
  target.setStateDisplay(state.id, 3000);
</JS On Add State>

<JS On Erase State>
  delete target._antiHealBarrier;
  target.setStateDisplay(state.id, 0);
</JS On Erase State>

<JS Pre-Damage As Target>
  if (this.isHpEffect() && value < 0) {
    target._antiHealBarrier ??= 0;
    const offset = Math.min(target._antiHealBarrier, Math.abs(value));
    value += offset;
    target._antiHealBarrier -= offset;
    target.setStateDisplay(state.id, target._antiHealBarrier);
    if (target._antiHealBarrier <= 0) {
      target.removeState(state.id);
    }
    $gameTemp.requestAnimation([target], 5);
    const text = '<CENTER>\\c[4]\\i[' + $dataStates[state.id].iconIndex + ']' + $dataStates[state.id].name + '\\c[0] blocked \\c[4]\\i[' + this.item().iconIndex + ']' + this.item().name + '\\c[0] from healing \\c[6]' + target.name() + '\\c[0]!';
    const logWindow = SceneManager._scene._logWindow;
    logWindow._lines.push(text);
    logWindow.refresh();
  }
</JS Pre-Damage As Target>

JavaScript:
<JS Post-Apply>
  let hp = 0;
  for (let i = 0; i < 8; ++i) {
    if (target._buffs[i] > 0) {
      hp -= user.mat * 2;
    }
    if (target._buffs[i] < 0) {
      hp += user.mdf * 2;
    }
    target._buffs[i] = 0;
  }
  if (hp > 0) {
    $gameTemp.requestAnimation([target], 41);
  } else if (hp < 0) {
    $gameTemp.requestAnimation([target], 56);
  }
  if (hp !== 0) {
    target.gainHp(hp);
    target.startDamagePopup();
  }
</JS Post-Apply>

Note that due to lack of selection control, I've had to modify the damage formula slightly to ensure that if the user uses it on themselves, they only heal for their current HP (in other words, it's a wasted turn and not exploitable).

Damage formula: b === a ? a.hp : a.hp * 2

Skill note:
JavaScript:
<JS HP Cost>
  cost = Math.ceil(user.hp / 2);
</JS HP Cost>

JavaScript:
<JS On Learn Skill>
  const id = 0;
  user._paramPlus[id] += 200;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  user._upgradeParam[id] += 1;
  user.forgetSkill(skill.id);
  user.refresh();
</JS On Learn Skill>
<Learn SP Cost: 0>
<JS Learn JP Cost>
  const id = 0;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  cost = 1000 + user._upgradeParam[id] * 200;
</JS Learn JP Cost>

<Hide in Battle>

Replace id with the ID of the param you wish to upgrade with the skill (0 = Max HP, 1 = Max MP, 2 = Atk, 3 = Def, 4 = Mat, 5 = Mdf, 6 = Agi, 7 = Luk). Feel free to customise the amounts raised, base cost and multiplicative cost increase according to your needs.

JavaScript:
<JS Pre-End Action>
  $gameTemp.requestAnimation([user], 45);
  user.gainMp(user.mmp - user.mp);
  user.startDamagePopup();
</JS Pre-End Action>

<JS On Erase State>
  const manaNerfID = 128;
  user.addState(manaNerfID);
  user.setMp(0);
  $gameTemp.requestAnimation([user], 54);
</JS On Erase State>

Replace 128 with the ID of your ManaNerf state, which has the following note:

JavaScript:
<MRG Rate: 0%>

There's no need to adapt this as VisuStella's Aggro Control plugin has native functionality for provokes and taunts.

The skill itself just has <Custom Action Sequence>. The sequence is:

◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Setup Action Set
: :Display Action = true
: :Immortal: On = true
: :Battle Step = true
: :Wait For Movement = true
: :Cast Animation = true
: :Wait For Animation = true
◆Plugin Command:VisuMZ_1_BattleCore, ACSET: Each Target Action Set
: :Dual/Multi Wield? = false
: :Perform Action = true
: :Wait Count = Sprite_Battler._motionSpeed
: :Action Animation = true
: :Wait Count = Sprite_Battler._motionSpeed * 2
: :Action Effect = true
: :Immortal: Off = true
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["user"]
: :Animation ID = 51
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Add Buff/Debuff
: :Targets = ["user"]
: :Buff Parameters = ["MAT"]
: :Debuff Parameters = []
: :Turns = 5
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Show Animation
: :Targets = ["user"]
: :Animation ID = 101
: :Mirror Animation = false
: :Wait For Animation? = false
◆Plugin Command:VisuMZ_1_BattleCore, MECH: Add State
: :Targets = ["user"]
: :States = ["63"]
◆Plugin Command:VisuMZ_1_BattleCore, ANIM: Wait For Animation

Replace 63 with the ID of your Doom state.

JavaScript:
<JS Pre-Damage>
  const doom = 63;
  if (user.isStateAffected(doom)) {
    value = Math.ceil(value * 1.5);
  }
</JS Pre-Damage>

Replace 63 with the ID of your Doom state.

JavaScript:
<JS Post-Damage As User>
  if (this.isPhysical() && value > 0 && target.result().critical) {
    let param = 2;
    let turns = 5;
    user.addBuff(param, turns);
    param = 6;
    user.addBuff(param, turns);
    if (target.isAlive()) {
      param = 3;
      target.addDebuff(param, turns);
      param = 6;
      target.addDebuff(param, turns);
    }
  }
</JS Post-Damage As User>

Replace param IDs and turns for buffs/debuffs as needed.

JavaScript:
<JS Post-Damage As Target>
  if (target.isAlive() && target.hp > 0) {
    if (this.isHpEffect() && this.isPhysical() && user.isActor() !== target.isActor()) {
      const damage = Math.ceil(target.mat * 0.5);
      user.gainHp(-damage);
      user.startDamagePopup();
      const result = JsonEx.makeDeepCopy(target._result);
      const heal = Math.ceil(damage * 0.5);
      target.gainHp(heal);
      target.startDamagePopup();
      target._result = result;
    }
  }
</JS Post-Damage As Target>

JavaScript:
<JS Post-Apply>
  const barrierStates = [40, 54, 116];
  let barrier = 0;
  for (let i = 0; i < barrierStates.length; ++i) {
    const barrierPoints = parseInt(target.getStateDisplay(barrierStates[i]));
    if (!isNaN(barrierPoints)) {
      barrier += barrierPoints;
    }
    target.removeState(barrierStates[i], 0);
  }
  target.gainHp(barrier);
  target.startDamagePopup();
</JS Post-Apply>

Add barrier states to the barrierStates array as needed. For the purposes of my T&T project, the states included are the Bloodthirster absorb, Spirit Shell absorb and Hexdrinker barrier.

JavaScript:
<JS Post-Apply>
  const barrierStates = [40, 54, 116];
  let barrier = 0;
  for (let i = 0; i < barrierStates.length; ++i) {
    const barrierPoints = parseInt(target.getStateDisplay(barrierStates[i]));
    if (!isNaN(barrierPoints)) {
      barrier += barrierPoints;
    }
    target.removeState(barrierStates[i], 0);
  }
  const mpLoss = Math.ceil(barrier * 0.5);
  target.gainMp(-mpLoss);
  target.startDamagePopup();
</JS Post-Apply>

Again, add to or modify barrierStates as required.

JavaScript:
<JS Passive Condition>
  if ($gameParty.inBattle()) {
    const background1 = ['Wasteland'];
    const background2 = ['Wasteland'];
    const spriteset = SceneManager._scene._spriteset;
    if (spriteset) {
      condition = background1.contains(spriteset._back1Sprite.battleback1Name()) && background2.contains(spriteset._back2Sprite.battleback2Name());
    } else {
      condition = false;
    }
  } else {
    condition = false;
  }
</JS Passive Condition>

This example passive is for the Wasteland state and just has a trait that puts water element at 200% effectiveness. Replace Wasteland with the appropriate battle back name(s) for the terrain you're making a state for.

JavaScript:
<Reapply Rules: Ignore>

<JS On Add State>
  user._frenzyA = 5;
  user._frenzyB = 5;
</JS On Add State>

<JS On Erase State>
  delete user._frenzyA;
  delete user._frenzyB;
</JS On Erase State>

<JS Post-Damage As Target>
  target._frenzyA ??= 5;
  if (value > 0) {
    target._frenzyA--;
  }
  if (target._frenzyA <= 0) {
    target.removeState(state.id);
    target.addState(133);
  }
</JS Post-Damage As Target>

<JS Post-Damage As User>
  user._frenzyB ??= 5;
  if (value > 0) {
    user._frenzyB--;
  }
  if (user._frenzyB <= 0) {
    user.removeState(state.id);
    user.addState(134);
  }
</JS Post-Damage As User>

Replace 133 with the ID of your Venom Virus state, and 134 with the ID of your Booster Virus state.

Undo HP skill note:
JavaScript:
<JS Pre-Apply>
  const undo2 = 136;
  const undo3 = 137;
  let range = 0;
  if (user.isStateAffected(undo3)) {
    range = target._undoHp3;
  } else if (user.isStateAffected(undo2)) {
    range = target._undoHp2;
  } else {
    range = target._undoHp1;
  }
  const hp = range - target.hp;
  target.gainHp(hp);
  target.startDamagePopup();
</JS Pre-Apply>

Replace 136 with the ID of your Un Deux state and 137 with the ID of your Undo Trois state.

Undo Tracker state note:
JavaScript:
<JS Pre-Start Battle>
  user._undoHp0 = user.hp;
  user._undoHp1 = user.hp;
  user._undoHp2 = user.hp;
  user._undoHp3 = user.hp;
</JS Pre-Start Battle>

<JS Post-End Turn>
  user._undoHp3 = user._undoHp2;
  user._undoHp2 = user._undoHp1;
  user._undoHp1 = user._undoHp0;
  user._undoHp0 = user.hp;
</JS Post-End Turn>

The Un Deux skill just adds the Un Deux state and removes the Undo Trois state, while Undo Trois adds the Undo Trois state and removes the Un Deux one. The Un Deux and Undo Trois states have no function of their own and only exist as markers for Undo HP.

Mirror Move skill note:
JavaScript:
<JS Post-Apply>
  const id = target._lastUsedSkill || 1;
  user.forceAction(id, target.index());

Mirror Move Tracker state note:
[CODE=javascript]<JS Pre-Start Action>
  user._lastUsedSkill ??= 1;
  if (action && action.isSkill()) {
    user._lastUsedSkill = action.item().id;
  }
</JS Pre-Start Action>

Passive note:
JavaScript:
<JS Pre-Damage As User>
  if (this.isHpEffect() && this.isMagical() && value > 0) {
    const atonement = 140;
    const group = user.friendsUnit().aliveMembers();
    const hpHealed = Math.floor(value * 0.401);
    for (let i = 0; i < group.length; ++i) {
      const ally = group[i];
      if (ally && ally.isStateAffected(atonement) && ally.getStateOrigin(atonement) === user) {
        ally.gainHp(hpHealed);
        ally.startDamagePopup();
      }
    }
  }
</JS Pre-Damage As User>
</JS Post-Apply>[/CODE]

Replace 140 with the ID of your Atonement state.
 
Last edited:

BeanCanDev

A Can of Beans?
Regular
Joined
May 12, 2020
Messages
50
Reaction score
20
First Language
English
Primarily Uses
RMMZ
All of this is really nice! Quick thing I do want to alert other too is that states like Doom and Auto heal are part of the VIZ Life state effects plug-in as notetags. Other than that, keep up the good work!
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
All of this is really nice! Quick thing I do want to alert other too is that states like Doom and Auto heal are part of the VIZ Life state effects plug-in as notetags. Other than that, keep up the good work!
That's a good point. I did those ones before Life State Effects came out, so I forgot to mention it.
 

Jenova

Because you are...a puppet!
Regular
Joined
Nov 29, 2017
Messages
480
Reaction score
317
First Language
English
Primarily Uses
RMMV
Are the Stat Upgrades and Stat Upgrades with Increasing Cost literally the same code? I can't get it to work....

Edit: I finally got it to work.

So, here's the case:

JavaScript:
<JS On Learn Skill>
  const id = 0;
  user._paramPlus[id] += 200;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  user._upgradeParam[id] += 1;
  user.forgetSkill(skill.id);
  user.refresh();
</JS On Learn Skill>
<Learn SP Cost: 0>

This is for basic Stat Upgrades.

JavaScript:
<JS Learn SP Cost>
  const id = 0;
  user._upgradeParam ??= [];
  user._upgradeParam[id] ??= 0;
  cost = 1000 + user._upgradeParam[id] * 200;
</JS Learn SP Cost>

This is for Increasing Costs (notice how it says SP and not JP). Make sure you remove <Learn SP Cost: 0> If you want to use this.
 
Last edited:

Cyberhawk

Bravelion Leader
Regular
Joined
Jan 9, 2019
Messages
151
Reaction score
109
First Language
English
Primarily Uses
RMMZ
Love to see this. I can now actually do a project i wanted to do in MZ now thanks to this.
Though in Libra, some of the text & Numbers in libra skill don't line up. (I'm trying to figure that one out currently.)
This is fantastic, Ty for all that.

Edit: Libra is likely a bit messy due to me changing the window & UI size to 1280 x 720 and that's why the text is out of place.

Edit edit: It's the auto message word wrap from Visu Message Core doing it.
 
Last edited:

desertbriar

Regular
Regular
Joined
Jan 30, 2018
Messages
51
Reaction score
29
First Language
English
Primarily Uses
RMMV
You are a true saint! I'll keep this in mind whenever I pick up MZ on a sale
 

AeroPergold

RPG Maker Nutcase
Regular
Joined
Feb 3, 2014
Messages
353
Reaction score
415
First Language
English
Primarily Uses
RMMZ
Ok, so Bide, Toxic, and Leech Seed all work so long they are being used by a party member. Is there a way to have a variant of these three state-based attacks so that enemies could use them. I tested the attacks as if they were enemy attacks and all three didn't work in that fashion.
 

Trihan

Speedy Scripter
Regular
Joined
Apr 12, 2012
Messages
6,879
Reaction score
7,965
First Language
English
Primarily Uses
RMMZ
Ok, so Bide, Toxic, and Leech Seed all work so long they are being used by a party member. Is there a way to have a variant of these three state-based attacks so that enemies could use them. I tested the attacks as if they were enemy attacks and all three didn't work in that fashion.
That's kinda weird, they should work for enemies as well. How did you test them?
 

AeroPergold

RPG Maker Nutcase
Regular
Joined
Feb 3, 2014
Messages
353
Reaction score
415
First Language
English
Primarily Uses
RMMZ
That's kinda weird, they should work for enemies as well. How did you test them?
I recreated the attacks as per the forum post and I gave a generic enemy each attack, testing the attacks one by one and looking at their behavior. What happened was this:

Leech seed worked as intended, Toxic would heal the player at a constant rate as opposed to how its supposed to behave, and Bide would fire off once before making the enemy invincible (I gave it 200 HP and after Bide's attack that enemy soaked up more than 200 HP in damage).
 

Indinera

Indie Dev
Regular
Joined
Mar 13, 2012
Messages
2,548
Reaction score
1,281
First Language
French
I've added the same values via a global passive state which has the following code:

So correct me if I'm wrong but this will count kills and defeats for each actor?
But then how can I make these stats appear somewhere in the vs menu? Like somewhere in the status page for instance?
 

Dark_Ansem

Regular
Regular
Joined
Jun 16, 2020
Messages
654
Reaction score
162
First Language
English
Primarily Uses
RMMZ
How flexible can global passive states be?
 

Latest Threads

Latest Profile Posts

Huge breakthrough! I finally fixed the dimensions on the WEBM used in the cinematic that ends the demo and introductory segment in MC:RIS, around the one-minute mark:



(There's some audio desync because the capture is an MP4.)
Kudos to everyone making game jam games, because this month has been hell for my development time. I have made a cutscene, 2 sprites, and 1 tile.

I guess I've made conceptual progress in hammering out combat roles and having fixes to be implemented (though I haven't done that yet)
Yeah, it’s a status #3, but it’s just to let y’all know I think I’m gonna have to do a twofer on the Advent compilation tomorrow. I feel like butt. Have a fever. I want to descend into my crypt.
I hope Baldur's Gate 3 wins BIG at TGA tonight. Tales of Arise was the last game to inspire me and BG3 has MASSIVELY surpassed that!
One day someone will build independent items for MZ. ONE DAY!

Forum statistics

Threads
136,819
Messages
1,270,388
Members
180,580
Latest member
GameturtleInk
Top