Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
Well a work around for us would be to just make every action in the game, which heals mp, also remove the buff.
(pretty much how death should have worked. leave the state removal to us, where we have to manually pick which states get removed from death, rather than it defaulting to removal of all states)
If this wouldnt work for any reason, is it possible to make an adjustment, so manual removal is possible?

EDIT: forgot MP regeneration, which would require an immunity, but doesnt quite work properly this way. (unless you put that in the spells description)

So MP restoration items/abilities naturally remove the state, and the MP regen has an immunity.
Thanks for the suggestions. Weirdly enough, the problem wasn't with making it go away when you gain MP - that was easy and works. The problem was making it block any MP gain unless it goes away at the same time. There's no such thing as "at the same time". Damage is processed first, followed by effects in the order they are defined. If you set damage to MP Recovery and also add a remove state effect, the state would block the MP Recovery even though it's set to be removed immediately afterwards. If you didn't set damage at all and instead added a Remove State effect followed by a Recover MP effect, it would've probably worked, but that's a confusing state of affairs in my opinion.

So I just dropped the idea altogether. You can still set it not to automatically remove the state when you gain MP, but then the result is that you have more than 0 MP yet still have the state.

Am I the only one who finds those settings to be extremely user-unfriendly?

Anyway, I would expect the default draw option code to be sufficient for this option, since my plugin doesn't change anything about how the option is drawn. I could be wrong though.

Similarly, I don't change anything about how options process the OK button, so likely the default Process OK Code is also sufficient. At most you might need to substitute in ConfigManager.autoBattle somewhere in there.

Set Make Option Code to this code:
JavaScript:
this.addCommand(TextManager.optionAutoBattle, 'autoBattle');
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I added SFG_Wait and SFG_EventTriggers to the opening post. Also, SFG_Utils has an update. You won't need it unless you're also downloading SFG_EventTriggers, but it can never hurt to be up-to-date.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I discovered a bug in SFG_AltDeathState that would prevent hidden enemies (those set to "Appear Halfway") from working correctly. Version 1.2 should fix it.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
Updated SFG_Utils and SFG_AltDeathState.

The latter fixes a bug where the "state added" notification kept popping up even though the low MP state was already added.

I also added a new plugin: SFG_SwitchCommand. This adds the equivalent of a switch statement for eventing. Here's some contrived examples of its use:

Code:
◆Control Variables:#0019 += 1
◆Plugin Command:switch @19
◆Show Choices:1, 2, 3, #4~8, 9, 10 (Window, Right, #1, #2)
:When 1
  ◆Text:None, Window, Bottom
  :Text:First time!
  ◆
:When 2
  ◆Text:None, Window, Bottom
  :Text:Second time!
  ◆
:When 3
  ◆Text:None, Window, Bottom
  :Text:Third time!
  ◆
:When #4~8
  ◆Text:None, Window, Bottom
  :Text:Maybe you should stop this...
  ◆
:When 9
  ◆Text:None, Window, Bottom
  :Text:Calm down, that's already nine times!
  ◆
:When 10
  ◆Text:None, Window, Bottom
  :Text:And now it's your tenth time!
  ◆
:End
◆Show Choices:#(value % 5 == 1), 20, >30 (Window, Right, #1, -)
:When #(value % 5 == 1)
  ◆Text:None, Window, Bottom
  :Text:I'm really at a loss for words.
  ◆Plugin Command:switch @19
  ◆Show Choices:>100, >45 (Window, Right, #1, #2)
  :When >100
    ◆Text:None, Window, Bottom
    :Text:Are you serious!? You've exceeeded one hundred!!!
    ◆
  :When >45
    ◆Text:None, Window, Bottom
    :Text:No really, stop it!
    ◆
  :End
  ◆
:When 20
  ◆Text:None, Window, Bottom
  :Text:Twentieth time already!? Are you mad!?
  ◆
:When >30
  ◆Text:None, Window, Bottom
  :Text:More than thirty times! Just... just stop!
  ◆
:When Cancel
  ◆Text:None, Window, Bottom
  :Text:This is starting to get crazy...
  ◆
:End

Works for string values too:
Code:
◆Name Input Processing:Harold, 8 characters
◆Plugin Command:switch $gameActors.actor(1).name()
◆Show Choices:"Harold", #"x"~"zzzzzzz", ~"[aeiou]{3,}" (Window, Right, #1, -)
:When "Harold"
  ◆Text:None, Window, Bottom
  :Text:The default, good choice!
  ◆
:When #"x"~"zzzzzzz"
  ◆Text:None, Window, Bottom
  :Text:That's quite a rare name...
  ◆
:When ~"[aeiou]{3,}"
  ◆Text:None, Window, Bottom
  :Text:So many vowels!
  ◆
:When Cancel
  ◆Text:None, Window, Bottom
  :Text:Not a bad choice!
  ◆
:End

More detail on all the possible options can be found in the plugin's documentation.

EDIT: Snuck in a fix for SFG_SwitchCommand - some of the documented examples didn't actually work (although the posted example did, at least), so now that's fixed.
 
Last edited:

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I added SFG_MapHierarchy to the opening post, which makes use of the map hierarchy in the editor to inherit optional properties such as background music from parent maps. The idea for this was partly due to @Warilized's plugin request.

I also added SFG_ExtraMaps to the opening post. I'd already posted it in another thread but hadn't gotten around to adding it here.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
Latest updates:

  • Fixed bug in SFG_MapHierarchy that prevented event tests from working. (Event tests are when you select some event commands in the event editor and press Ctrl+R.)
  • Fixed bug in SFG_Wait - only the plugin commands that took an argument were working. The ones that had no argument would not work unless you added a dummy 0 on the end. Now they all work as intended.
EDIT: Also snuck in a tiny change to SFG_SwitchCommand - no change in functionality, just an extra note in the help section.
 
Last edited:

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I added SFG_BattleBalloons and SFG_NewAnimTimings to the opening post. The first is pretty self-explanatory, while NewAnimTimings allows playing screen shakes or weather effects as part of a battle animation.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I updated a new version of SFG_Wait with some new features.

Part of this is that I noticed SRD had a similar (but not quite the same) plugin, so I added those wait commands to my plugin so that if someone wanted my plugin for one of the commands that it adds that SRD's plugin doesn't have, they could just replace his with mine. (I didn't look at SRD's source code, but the code is quite simple, so I would imagine his implementation of most of these is nearly the same as mine.)

The other part is that I wanted a way to wait for a background music track to finish playing. Then once I got that working, I thought I might as well support all four categories of audio assets. (SRD's plugin supports two of them, for what it's worth.) Since BGM and BGS loop, you might think it's not worth waiting for them, but you could use this as a way to make them not loop if you so desire, or you could use the track as a sort of timer so that some event triggers every time it loops.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
Discovered a major bug in the last version of SFG_Wait, so I uploaded a fix.

Also added to the terms of use regarding MZ.
 
Last edited:

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
Updated SFG_Wait with a new command allowing you to wait for a keypress.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
New release: SFG_ExpandedTP.js, which basically allows you to do with TP anything that's already possible with MP and HP, plus some extra things specific to TP like customizing what it's set to at the beginning and end of battle.

I'm not sure why the forum won't let me upload the file, but here's the full source code:

JavaScript:
/*:
@plugindesc [v1.0] Expanded TP settings
@author Solar Flare Games

@param effectId
@text Effect ID
@desc Effect ID for the TP Recover effect.
@type number
@min 100
@max 999
@default 100

@param showTpInStatus
@text Show In Status
@desc Whether to show a TP bar in the status window. Only enable if you're using no other status window customization.
@type boolean
@default false

@param TP Icons

@param buffIcon
@text Buff Icon
@desc Icon shown when an actor or enemy has a buff to max TP. Right-click and choose IconSet Viewer.
@parent TP Icons
@type text

@param greaterBuffIcon
@text Greater Buff Icon
@desc Icon shown when an actor or enemy has a greater buff to max TP. Right-click and choose IconSet Viewer.
@parent TP Icons
@type text

@param debuffIcon
@text Debuff Icon
@desc Icon shown when an actor or enemy has a debuff to max TP. Right-click and choose IconSet Viewer.
@parent TP Icons
@type text

@param greaterDebuffIcon
@text Greater Debuff Icon
@desc Icon shown when an actor or enemy has a greater debuff to max TP. Right-click and choose IconSet Viewer.
@parent TP Icons
@type text

@param Preserve TP

@param invertTp
@text Invert
@desc Turn on to make all actors preserve TP by default. When turned on, actors with the Preserve TP will not preserve TP.
@parent Preserve TP
@type boolean
@default false
@on Inverted
@off Normal

@param initTp
@text Init Value
@desc Initial TP value for battlers who do not preserve TP. This is an eval where a is the battler.
@parent Preserve TP
@type text
@default Math.randomInt(25)

@param clearTp
@text Clear Value
@desc TP after battle ends for battlers who do not preserve TP. This is an eval where a is the battler.
@parent Preserve TP
@type text
@default 0

@param Charge TP by Damage

@param chargeTpFromHp
@text HP Damage
@desc Whether to enable gaining TP whenever you take HP damage.
@parent Charge TP by Damage
@type boolean
@default true
@on Enabled
@off Disabled

@param chargeTpFromMp
@text MP Damage
@desc Whether to enable gaining TP whenever you take MP damage.
@parent Charge TP by Damage
@type boolean
@default false
@on Enabled
@off Disabled

@param tpChargeFormula
@text Formula
@desc The formula for gaining TP from damage, where a is the battler, type is 'hp' or 'mp', rate is cur/max.
@parent Charge TP by Damage
@type text
@default 50 * rate * a.tcr * critBonus * superBonus

@param TP Gain Bonuses

@param tpCriticalBonus
@text Critical Bonus
@desc Multiply TP gain by this percent if you score a critical hit. Also available as critBonus in the TP Charge formula.
@parent TP Gain Bonuses
@type number
@min 0
@max 1000
@default 150

@param tpSuperBonus
@text Super Bonus
@desc Multiply TP gain by this percent if the enemy is weak to the element. Available as superBonus in the TP Charge formula.
@parent TP Gain Bonuses
@type number
@min 0
@max 1000
@default 150

@help
This gives TP functionality to match everything that HP and MP already has.

- Max TP can grow as you level up
- Modify max TP with traits
- TP damage, recovery, and drain
- TP percent+fixed recovery
- Buffs/debuffs to max TP
- Permanently grow max TP with items
- Customize TP charge behaviour with formulas
- Customize TP settings when battle begins and ends (without Preserve TP)
- Boost TP gain for critical hits or elemental weaknesses

If using SFG_ParamAdd, place this plugin below it.

Configuration
=============

The Effect ID can be ignored unless you have other SFG plugins with an
Effect ID parameter, in which case you just need to make sure it has a
different value for each plugin.

If you're using the default status panel, you can show a TP bar in the
status panel by enabling Show In Status. However, this can conflict with
other status screen customizations, so if you are using another status
screen plugin it's better to configure it to add the TP bar instead.
This option also shows it in the actor select screen.

TP Icons
--------

If you are using buffs or debuffs for max TP, you will need to configure the
icon to display for these. Just as with standard buffs and debuffs, they
come in two levels, so there are a total of four icons.

You can select an icon by right-clicking the empty text field and choosing
IconSet Viewer from the menu.

Preserve TP
-----------

This section controls the behaviour of Preserve TP.

If you turn on Invert, then all actors will preserve TP by default.
However, an actor with the Preserve TP trait will exhibit the default behaviour.

For actors that do not preserve TP, you can also set their initial TP when
a battle begins, and how much TP they retain when the battle ends.

In the Init Value and Clear Value formulas, you can access the following
variables:
a - the current actor
v - game variables
s - game switches

Charge TP by Damage
-------------------

This section customizes the TP gain when an actor or enemy takes damage.
It can be disabled entirely, or you can customize the amount of TP gained
based on the damage. You can even enable gaining TP when the battler takes
MP damage.

In the TP Charge formula, you can access the following variables:
a - the actor or enemy currently being targeted
b - the opponent actor or enemy
item - the item or skill being used
v - game variables
s - game switches
rate - the rate of TP gain based on current and max HP or MP
type - either 'hp' or 'mp'
critBonus - the value from Critical Bonus, as a ratio (divided by 100)
superBonus - the value from Super Bonus, as a ratio (divided by 100)

TP Gain Bonuses
---------------

In this section you can specify a percentage bonus to TP gain if scoring a
critical hit or attacking an elemental weakness. TP gain from skill use is
automatically multiplied by this value. If you wish, you can also include it
in the TP charge formula.

Note Tags
=========

<base_mtp:56> (classes, enemies, weapons, armours)
  Specifies the base max TP for this class or enemy.
  Used on a weapon or armour, it specifies a bonus to max TP.

<base_mtp:12,34,67,98> (classes)
  Specify the base max TP for each level, starting from 1. Any missing levels
  will be set equal to the last specified level.

<base_mtp:formula> (classes)
  Specify the base TP as a formula. You can reference the following variables:
    level, mhp, mmp, atk, def, mat, mdf, agi, luk
  The parameters refer to that parameter's value at the current level.
  For example, set the formula to "luk" to make it grow at the same rate
  as the class's luck.

<init_tp:formula> (classes, enemies, actors)
  Override the default Init Value for this battler's TP.
  If both an actor and a class have this tag, the actor's formula is used.

<clear_tp:formula> (classes, enemies, actors)
  Override the default Clear Value for this battler's TP.
  If both an actor and their class have this tag, only the actor's formula is
  used.

<mtp_rate:22> (anything with traits)
  Maximum TP will be multiplied by this value.

<add_mtp:12> (anything with traits) -- requires SFG_ParamAdd
  Adds this value to the maximum TP.

<tp_formula> (skills, items)
  Specifies that the damage formula box should affect TP instead of MP or HP.
  Whether it does damage, recovery, or drain is based on the type selection.

<tp_recover:12%> (skills, items)
  Recover 12% of your maximum TP.

<tp_recover:+12> (skills, items)
  Recover 12 TP. This is identical to the Gain TP effect.

<tp_recover:12% + 12> (skills, items)
  Recover 12% of your maximum TP, plus an additional 12 TP.

<buff_mtp:5> (skills, items)
  Add a buff to max TP for 5 turns.

<buff_mtp:remove> (skills, items)
  Remove any buff to max TP.

<debuff_mtp:5> (skills, items)
  Add a debuff to max TP for 5 turns.

<debuff_mtp:remove> (skills, items)
  Remove any debuff to max TP.

<grow_mtp:5> (skills, items)
  Permanently increase the target's max TP by 5.

<require_mtp:5> (armours, weapons) -- requires SFG_EquipParams
  Require a max TP of at least 5 to equip this item.
*/

(function() {
    var params = PluginManager.parameters("SFG_ExpandedTP");
    const PRESERVE_TP = JSON.parse(params.invertTp);
    const CHARGE_TP_FROM_HP = JSON.parse(params.chargeTpFromHp);
    const CHARGE_TP_FROM_MP = JSON.parse(params.chargeTpFromMp);
    const TP_DAMAGE = 7, TP_RECOVER = 8, TP_DRAIN = 9;
    const PARAM_MTP = 8;
    const TRAIT_PARAM_PLUS = PluginManager.isEnabled('SFG_ParamAdd') ? (Number(PluginManager.parameters('SFG_ParamAdd').traitId) || 100) : 0;
    const HAVE_EQUIP_PARAMS = PluginManager.isEnabled('SFG_EquipParams');
    const EFFECT_TP_RECOVER = Number(params.effectId) || 100;
    const TP_BUFF_ICONS = {
        [-2]: Number(params.greaterDebuffIcon) || 0,
        [-1]: Number(params.debuffIcon) || 0,
        0: 0,
        1: Number(params.buffIcon) || 0,
        2: Number(params.greaterBuffIcon) || 0,
    };
    const tp_recover_pat = /(\d+%)\s*(?:\+\s*(\d+))/, int_list_pat = /^\s*\d+(\s*,\s*\d+)*\s*$/;
    Object.defineProperty(Game_BattlerBase.prototype, 'mtp', {get: function() {return this.param(PARAM_MTP);}, configurable: true});

    const parseTpBase = function(obj, dflt) {
        if(!obj) return;
        var base_mtp = obj.meta ? obj.meta.base_mtp : dflt;
        if(base_mtp === undefined) base_mtp = dflt;
        // Are we a class or an enemy?
        if(typeof(obj.params[0]) === 'number') {
            // Enemy
            if(Number(base_mtp)) {
                obj.params[PARAM_MTP] = Number(base_mtp);
            } else {
                obj.params[PARAM_MTP] = dflt;
            }
        } else {
            // Class
            obj.params[PARAM_MTP] = [1];
            if(Number(base_mtp)) {
                for(let i = 1; i < 100; i++) {
                    obj.params[PARAM_MTP][i] = Number(base_mtp) || 100;
                }
            } else if(typeof(base_mtp) === 'string' && base_mtp.match(int_list_pat)) {
                obj.params[PARAM_MTP] = [1].concat(Utils.parseIntList(base_mtp));
                if(obj.params[PARAM_MTP].length > 100) {
                    obj.params[PARAM_MTP] = obj.params[PARAM_MTP].slice(0, 100);
                } else {
                    for(let i = obj.params[PARAM_MTP].length; i < 100; i++) {
                        obj.params[PARAM_MTP][i] = obj.params[PARAM_MTP][i - 1];
                    }
                }
            } else for(let level = 1; level < 100; level++) {
                let mhp = obj.params[0][level], mmp = obj.params[1][level], atk = obj.params[2][level], def = obj.params[3][level];
                let mat = obj.params[4][level], mdf = obj.params[5][level], agi = obj.params[6][level], luk = obj.params[7][level];
                try {
                    obj.params[PARAM_MTP][level] = eval(base_mtp);
                } catch(e) {
                    obj.params[PARAM_MTP][level] = 100;
                }
            }
        }
    };
  
    const parseTpInitClear = function(obj) {
        if(!obj || !obj.meta) return;
        if(obj.meta.init_tp) {
            obj.initTp = obj.meta.init_tp;
        }
        if(obj.meta.clear_tp) {
            obj.clearTp = obj.meta.clear_tp;
        }
    };

    const parseTpTraits = function(obj) {
        if(!obj || !obj.meta) return;
        if(obj.meta.mtp_rate) {
            let trait = {
                code: Game_BattlerBase.TRAIT_PARAM,
                dataId: PARAM_MTP,
                value: (Number(obj.meta.mtp_rate) || 0) / 100,
            };
            obj.traits.push(trait);
        }
        if(TRAIT_PARAM_PLUS && obj.meta.add_mtp) {
            let trait = {
                code: TRAIT_PARAM_PLUS,
                dataId: PARAM_MTP,
                value: Number(obj.meta.add_mtp) || 0,
            };
            obj.traits.push(trait);
        }
    };

    const parseTpDamage = function(obj) {
        if(!obj || !obj.meta || !obj.meta.tp_formula) return;
        switch(obj.damage.type) {
            case 1: case 2:
                obj.damage.type = TP_DAMAGE;
                break;
            case 3: case 4:
                obj.damage.type = TP_RECOVER;
                break;
            case 5: case 6:
                obj.damage.type = TP_DRAIN;
                break;
        }
    };
  
    const parseTpEffects = function(obj) {
        if(!obj || !obj.meta) return;
        if(obj.meta.tp_recover) {
            let m = obj.meta.tp_recover.match(tp_recover_pat);
            if(m) {
                let effect = {
                    code: EFFECT_TP_RECOVER,
                    dataId: 0,
                    value1: 0,
                    value2: 0,
                };
                if(m[1]) {
                    effect.value1 = Number(m[1]) / 100;
                }
                if(m[2]) {
                    effect.value2 = Number(m[2]);
                }
                obj.effects.push(effect);
            }
        }
        if(obj.meta.buff_mtp) {
            let effect = {
                dataId: PARAM_MTP,
                value1: 0,
                value2: 0,
            };
            if(obj.meta.buff_mtp.trim().toLowerCase() == 'remove') {
                effect.code = Game_Action.EFFECT_REMOVE_BUFF;
                obj.effects.push(effect);
            } else if(Number(obj.meta.buff_mtp)) {
                effect.code = Game_Action.EFFECT_ADD_BUFF;
                effect.value1 = Number(obj.meta.buff_mtp);
                obj.effects.push(effect);
            }
        }
        if(obj.meta.debuff_mtp) {
            let effect = {
                dataId: PARAM_MTP,
                value1: 0,
                value2: 0,
            };
            if(obj.meta.debuff_mtp.trim().toLowerCase() == 'remove') {
                effect.code = Game_Action.EFFECT_REMOVE_DEBUFF;
                obj.effects.push(effect);
            } else if(Number(obj.meta.debuff_mtp)) {
                effect.code = Game_Action.EFFECT_ADD_DEBUFF;
                effect.value1 = Number(obj.meta.debuff_mtp);
                obj.effects.push(effect);
            }
        }
        if(Number(obj.meta.grow_mtp)) {
            let effect = {
                code: Game_Action.EFFECT_GROW,
                dataId: PARAM_MTP,
                value1: Number(obj.meta.grow_mtp),
                value2: 0,
            };
            obj.effects.push(effect);
        }
    }

    var old_startup = DataManager.createGameObjects;
    DataManager.createGameObjects = function() {
        for(var i = 1; i < $dataStates.length; i++) {
            parseTpTraits($dataStates[i]);
        }
        for(var i = 1; i < $dataActors.length; i++) {
            parseTpTraits($dataActors[i]);
            parseTpInitClear($dataActors[i]);
        }
        for(var i = 1; i < $dataClasses.length; i++) {
            parseTpBase($dataClasses[i], 100);
            parseTpTraits($dataClasses[i]);
            parseTpInitClear($dataClasses[i]);
        }
        for(var i = 1; i < $dataWeapons.length; i++) {
            parseTpBase($dataWeapons[i], 0);
            parseTpTraits($dataWeapons[i]);
        }
        for(var i = 1; i < $dataArmors.length; i++) {
            parseTpBase($dataArmors[i], 0);
            parseTpTraits($dataArmors[i]);
        }
        for(var i = 1; i < $dataEnemies.length; i++) {
            parseTpBase($dataEnemies[i], 100);
            parseTpTraits($dataEnemies[i]);
            parseTpInitClear($dataEnemies[i]);
        }
        for(var i = 1; i < $dataItems.length; i++) {
            parseTpDamage($dataItems[i]);
            parseTpEffects($dataItems[i]);
        }
        for(var i = 1; i < $dataSkills.length; i++) {
            parseTpDamage($dataSkills[i]);
            parseTpEffects($dataSkills[i]);
        }
        old_startup.call(this);
    };
  
    // Overwrite, not alias
    Game_BattlerBase.prototype.maxTp = function() {
        return this.mtp;
    };
  
    // Overwrite, not alias
    Game_Battler.prototype.regenerateTp = function() {
        var value = Math.floor(this.mtp * this.trg);
        this.gainSilentTp(value);
    };
  
    const old_clearPlus = Game_BattlerBase.prototype.clearParamPlus;
    Game_BattlerBase.prototype.clearParamPlus = function() {
        old_clearPlus.call(this);
        this._paramPlus.push(0);
    };
  
    const old_clearBuffs = Game_BattlerBase.prototype.clearBuffs;
    Game_BattlerBase.prototype.clearBuffs = function() {
        old_clearBuffs.call(this);
        this._buffs.push(0);
        this._buffTurns.push(0);
    };
  
    // Overwrite, not alias
    Game_BattlerBase.prototype.isPreserveTp = function() {
        return this.specialFlag(Game_BattlerBase.FLAG_ID_PRESERVE_TP) !== PRESERVE_TP;
    };
  
    const old_buffIcon = Game_BattlerBase.prototype.buffIconIndex;
    Game_BattlerBase.prototype.buffIconIndex = function(level, param) {
        if(param == PARAM_MTP) return TP_BUFF_ICONS[level];
        else return old_buffIcon.call(this, level, param);
    };
  
    Game_Battler.prototype.initTpFormula = function() {
        return params.initTp;
    };
  
    Game_Enemy.prototype.initTpFormula = function() {
        return this.enemy().initTp || Game_Battler.prototype.initTpFormula.call(this);
    };
  
    Game_Actor.prototype.initTpFormula = function() {
        return this.actor().initTp || this.currentClass().initTp || Game_Battler.prototype.initTpFormula.call(this);
    };
  
    const old_initTp = Game_Battler.prototype.initTp;
    Game_Battler.prototype.initTp = function() {
        let a = this;
        let v = $gameVariables._data, s = $gameSwitches._data;
        try {
            this.setTp(Math.round(eval(this.initTpFormula())));
        } catch(e) {
            old_initTp.call(this);
        }
    };
  
    Game_Battler.prototype.clearTpFormula = function() {
        return params.clearTp;
    };
  
    Game_Enemy.prototype.clearTpFormula = function() {
        return this.enemy().clearTp || Game_Battler.prototype.clearTpFormula.call(this);
    };
  
    Game_Actor.prototype.clearTpFormula = function() {
        return this.actor().clearTp || this.currentClass().clearTp || Game_Battler.prototype.clearTpFormula.call(this);
    };
  
    const old_clearTp = Game_Battler.prototype.clearTp;
    Game_Battler.prototype.clearTp = function() {
        let a = this;
        let v = $gameVariables._data, s = $gameSwitches._data;
        try {
            this.setTp(Math.round(eval(this.clearTpFormula())));
        } catch(e) {
            old_clearTp.call(this);
        }
    };
  
    const old_chargeTp = Game_Battler.prototype.chargeTpByDamage;
    Game_Battler.prototype.chargeTpByDamage = function(rate, type = 'hp') {
        if(type == 'hp' && !CHARGE_TP_FROM_HP) return;
        if(type == 'mp' && !CHARGE_TP_FROM_MP) return;
        try {
            var item = this._opponentAction.item();
            var a = this, b = this._opponentAction.subject();
            let v = $gameVariables._data, s = $gameSwitches._data;
            var critBonus = 1, superBonus = 1;
            if(this.result().critical) {
                critBonus *= params.tpCriticalBonus / 100;
            }
            if(this._opponentAction.calcElementRate(this) > 1) {
                superBonus *= params.tpSuperBonus / 100;
            }
            var value = Math.round(eval(params.tpChargeFormula));
            if(value > 0) this.gainSilentTp(value);
        } catch(e) {
            old_chargeTp.call(this, rate);
        }
    };
  
    const old_execMpDmg = Game_Action.prototype.executeMpDamage;
    Game_Action.prototype.executeMpDamage = function(target, value) {
        old_execMpDmg.call(this, target, value);
        if(value > 0) {
            target.chargeTpByDamage(value / target.mmp, 'mp');
        }
    };
  
    const old_execDmg = Game_Action.prototype.executeDamage;
    Game_Action.prototype.executeDamage = function(target, value) {
        target._opponentAction = this;
        old_execDmg.call(this, target, value);
        if(this.isTpEffect()) {
            this.executeTpDamage(target, value);
        }
        delete target._opponentAction;
    };

    Game_Action.prototype.isTpEffect = function() {
        return this.checkDamageType([TP_DAMAGE, TP_RECOVER, TP_DRAIN]);
    };

    Game_Action.prototype.isTpRecover = function() {
        return this.checkDamageType([TP_RECOVER]);
    };
  
    const old_isDmg = Game_Action.prototype.isDamage;
    Game_Action.prototype.isDamage = function() {
        return old_isDmg.call(this) || this.checkDamageType([TP_DAMAGE]);
    };
  
    const old_isHeal = Game_Action.prototype.isRecover;
    Game_Action.prototype.isRecover = function() {
        return old_isHeal.call(this) || this.checkDamageType([TP_RECOVER]);
    };
  
    const old_isDrain = Game_Action.prototype.isDrain;
    Game_Action.prototype.isDrain = function() {
        return old_isDrain.call(this) || this.checkDamageType([TP_DRAIN]);
    };
  
    Game_Action.prototype.executeTpDamage = function(target, value) {
        if (!this.isTpRecover()) {
            value = Math.min(target.tp, value);
        }
        if (value !== 0) {
            this.makeSuccess(target);
        }
        target.gainTp(-value);
        this.gainDrainedTp(value);
    };

    Game_Action.prototype.gainDrainedTp = function(value) {
        if (this.isDrain()) {
           var gainTarget = this.subject();
           if (this._reflectionTarget !== undefined) {
               gainTarget = this._reflectionTarget;
           }
           gainTarget.gainTp(value);
        }
    };
  
    // Overwrite, not alias
    Game_Action.prototype.applyItemUserEffect = function(target) {
        var value = this.item().tpGain * this.subject().tcr;
        if(target.result().critical) {
            value *= params.tpCriticalBonus / 100;
        }
        if(this.calcElementRate(target) > 1) {
            value *= params.tpSuperBonus / 100;
        }
        this.subject().gainSilentTp(Math.floor(value));
    };
  
    if(params.showTpInStatus) {
        // These are overwrites, not aliases
        Window_Status.prototype.drawBlock1 = function(y) {
            this.drawActorName(this._actor, 6, y);
            this.drawActorClass(this._actor, 192, y);
            this.drawActorNickname(this._actor, 432, y);
            this.drawActorIcons(this._actor, 568, y, 192);
        };

        Window_Status.prototype.drawBasicInfo = function(x, y) {
            var lineHeight = this.lineHeight();
            this.drawActorLevel(this._actor, x, y + lineHeight * 0);
            this.drawActorHp(this._actor, x, y + lineHeight * 1);
            this.drawActorMp(this._actor, x, y + lineHeight * 2);
            this.drawActorTp(this._actor, x, y + lineHeight * 3, 186);
        };
      
        Window_Base.prototype.drawActorSimpleStatus = function(actor, x, y, width) {
            var lineHeight = this.lineHeight();
            var x2 = x + 180;
            var width2 = Math.min(200, width - 180 - this.textPadding());
            this.drawActorName(actor, x, y);
            this.drawActorLevel(actor, x, y + lineHeight * 1);
            this.drawActorIcons(actor, x, y + lineHeight * 2);
            this.drawActorClass(actor, x2, y, width2);
            this.drawActorHp(actor, x2, y + lineHeight * 1, width2);
            this.drawActorMp(actor, x2, y + lineHeight * 1.8, width2);
            this.drawActorTp(actor, x2, y + lineHeight * 2.6, width2);
        };
    }
  
    if(HAVE_EQUIP_PARAMS) {
        var old_equip_ok = Game_BattlerBase.prototype.canEquip;
        Game_BattlerBase.prototype.canEquip = function(item) {
            if(!old_equip_ok.call(this, item)) return false;
            var bravery = parseInt(item.meta.require_mtp);
            if(!isNaN(bravery) && bravery > this.mtp)
                return false;
            return true;
        };
    }
})();

Be sure to name the file SFG_ExpandedTP.js, otherwise it won't be able to load the plugin parameters.
 
Last edited:

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
I've uploaded all the plugins from this thread to makerdevs.com. If there was anyone who couldn't use them because the forum (if I recall correctly) doesn't allow guests to download attachments… now you can!
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
MZ was usable for free this week, so got a chance to try a few of my plugins in it. As a result, I can say that SFG_MapHierarchy and SFG_AutoBattle are fully-functional in MZ, while SFG_EventTriggers also works except for the <relativeTransfer> note tag.

I didn't get a chance to test them, but I suspect SFG_ExpandedTP, SFG_ParamAdd, and SFG_Wait may be compatible, but most of the others probably aren't. Even those ones may not be.
 

LuKo

Noob
Member
Joined
Mar 31, 2012
Messages
18
Reaction score
48
First Language
Portuguese
Primarily Uses
N/A
Hello, first off... nice scripts! :kaocry:

anyway...
I noticed a weird behavior on it (AltDeathState) that for the enemies, the custom status effect for 0 MP only works when the player character was the last one to hit the enemy, if it is the opposite (the enemy acting last in the turn and getting 0 MP) it wont activate.
(You are the first one who actually had exactly what I wanted with the MP=0 state when EVERYONE recommended the yanfly passive states one when that one simply removed the state the moment it wasn't 0 anymore x.x not what I wanted)


It's nothing serious, and its quite possible that there is a conflict with some of my scripts or maybe I did something wrong... , I just wanted to report that xD

It is a battle with one player character and one monster, I am using the in-built sideview battle, the status effect is exaustion that last 3 turns with turn end timing.
When the enemy is the last one to act with the action reducing its mp to 0, the effect wont appear, and it is quite possible that it is the same for the player character (I am not entirely sure)
For scripts i'm currently only using:
Yanfly_core engine,
your SFG_Utils,
YR_NewParameters (this one messes with max mp values, but I made sure to test with this one off),
and CTB_LevelUpEx (that one just call a event when i level up).
For the Alt Death state, both of the last options are on False.

Thats it, sorry in advance for the bother and see you later :kaopride:
 

BoneCollectors

Villager
Member
Joined
Dec 6, 2017
Messages
26
Reaction score
8
First Language
Portuguese-BR
Primarily Uses
RMMV
Thank you for your autobattle plugin!

Is there a way to control autobattle on/off by script command?

I tried "old_cfgSave.autoBattle = true;" but it didn't work.
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
If you mean you want to turn the setting in the options menu on or off, you can use ConfigManager.autoBattle = true and ConfigManager.autoBattle = false. Fiddling with the user's preferences is never a good idea though, so if your goal is to force auto-battle on or off for key fights, you should save their previous setting before the fight and put it back afterwards. That would look something like this:

  • Control Variables: {1} = Script ConfigManager.autoBattle
  • Script call: ConfigManager.autoBattle = true (or false)
  • Start battle
  • Script call: ConfigManager.autoBattle = $gameVariables.value(1)
Also: There was no need to post the exact same question in four different places. Just one would have been fine.
 
Last edited:

BoneCollectors

Villager
Member
Joined
Dec 6, 2017
Messages
26
Reaction score
8
First Language
Portuguese-BR
Primarily Uses
RMMV
Thank you very MUCH, @Solar_Flare

The best idea would be to be able to switch on/off during battles as well, using common event key press. Like in the new Final Fantasy remake.

This plugin integrates my game Dino Hazard on Steam, now.

Please, send me a PM if you would like a steamkey to play it.

Best.
 
Last edited:

Maldra

Veteran
Veteran
Joined
May 31, 2017
Messages
88
Reaction score
10
First Language
English
Primarily Uses
RMMV
Can you advise how to do a TP Drain skill with the plugin? I have the plugin placed above all other plugins and have <tp_formula> in the Note section of the skill I'm testing, but it continues to drain HP instead of TP. Am I missing something?

1632702312343.png
 

Solar_Flare

Veteran
Veteran
Joined
Jun 6, 2020
Messages
656
Reaction score
269
First Language
English
Primarily Uses
RMMV
That looks correct. Could you please test it in a new project with no other plugins enabled? If it does work in a new project, I'd like to see your plugins list for the real project. There could be a conflict with another plugin.
 

Latest Threads

Latest Posts

Latest Profile Posts

For some reason, I found this is kinda stylist
ready to fall into another development hell...
Mega has been giving me a lot of problems as of late, so I think I'll need to switch to another cloud service. I'm considering Dropbox.
Rough week, but in the end there's light in the darkness.
Mental health is an issue I wish was taken more seriously.
Take care.
1638421271905.jpeg
By the power of timezones! This picture shall still be posted on december 1st!!!
7xI2Gc2.jpg

Forum statistics

Threads
117,126
Messages
1,104,789
Members
153,175
Latest member
SylviaGaming
Top