- Joined
- Apr 12, 2012
- Messages
- 4,969
- Reaction score
- 4,557
- 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:
Molten Giant (skill)
Exact
Percentage
Chicken Knife (weapon)
Tonberry Shop
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.
Parallax Mapping
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.
On Map Encounters
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.
Hestia Knife (weapon)
Regen Scroll
This cannot be adapted as VS hasn't ported independent item/upgrade slot functionality.
Runic (state)
Taunt effects require the tier 2 Aggro Control System plugin.
Disintegrate (skill)
Stat Upgrades
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)
Libra (skill)
Blue Magic (skill)
Mejai's Soulstealer (weapon)
Spirit Shackles (add note to Attack skill)
Replace 34 with the ID of your Spirit Shackles state.
Toxic (state)
Phoenix Ring (armour)
Add to the death state, replace 101 with the ID of the ring:
Healing Link (state)
Rod of Ages (weapon)
Magic Guard (state)
Flourish (skill)
This requires the tier 2 STB battle system for the instant tag and the tier 3 Skill Cooldowns plugin for the cooldown.
Zed's Death Mark (state)
This requires the tier 2 STB battle system for the instant tag on the skill that inflicts the state.
Enemy Thieves
Joint Penalty
This requires the tier 2 STB battle system for the instant tag on the skill that inflicts the state.
The Bloodthirster (weapon)
This requires the tier 3 Anti Damage Barriers plugin.
Absorb state:
Victory Cry
1 is 100% heal. If you want it to be lower, use a smaller decimal value (for example, 0.5 for 50%).
Thornmail (armour)
Sacrificial Bolt
Damage formula: user._allyHp + user._allyMat * 14;
Freeze (state)
Replace 2 with the ID of your fire element.
Second Chance (state)
Warmog's Armor (armour)
<Passive State: 45>
Replace 45 with the ID of the Warmog's Heart state.
Warmog's Heart:
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>
Molten Giant (skill)
Exact
JavaScript:
<JS MP Cost>
cost -= user.mhp - user.hp
</JS MP Cost>
JavaScript:
<JS MP Cost>
cost *= user.hpRate()
</JS MP Cost>
Chicken Knife (weapon)
JavaScript:
<JS Parameters>
ATK = $gameSystem.escapeCount();
</JS Parameters>
Tonberry Shop
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.
Parallax Mapping
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.
On Map Encounters
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.
Hestia Knife (weapon)
JavaScript:
<JS Parameters>
ATK = user.paramBase(2) * 0.1 + user.level;
</JS Parameters>
Regen Scroll
This cannot be adapted as VS hasn't ported independent item/upgrade slot functionality.
Runic (state)
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>
Disintegrate (skill)
JavaScript:
<JS Post-Damage>
if (target.hp <= 0) {
user.gainMp(item.mpCost);
}
</JS Post-Damage>
Stat Upgrades
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)
Libra (skill)
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>
Blue Magic (skill)
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>
Mejai's Soulstealer (weapon)
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>
Spirit Shackles (add note to Attack skill)
JavaScript:
<JS Pre-Damage>
if (user.isStateAffected(34)) {
user.gainMp(-5);
}
</JS Pre-Damage>
Replace 34 with the ID of your Spirit Shackles state.
Toxic (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>
Phoenix Ring (armour)
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>
Healing Link (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>
Rod of Ages (weapon)
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>
Magic Guard (state)
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>
Flourish (skill)
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>
Zed's Death Mark (state)
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>
Enemy Thieves
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>
Joint Penalty
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>
The Bloodthirster (weapon)
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>
Victory Cry
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%).
Thornmail (armour)
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>
Sacrificial Bolt
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;
Freeze (state)
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.
Second Chance (state)
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>
Warmog's Armor (armour)
<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!