- 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:
Replace 34 with the ID of your Spirit Shackles state.
1 is 100% heal. If you want it to be lower, use a smaller decimal value (for example, 0.5 for 50%).
Damage formula: user._allyHp + user._allyMat * 14;
Replace 2 with the ID of your fire element.
I'll do these in 30s so the posts don't get too long. Keep your eyes peeled for Unstable Affliction to Actor Transformations!
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
Percentage
JavaScript:
<JS MP Cost>
cost -= user.mhp - user.hp
</JS MP Cost>
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.
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.
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.
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.
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 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.
Absorb state:
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:
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: