Deriving Max Hit Points?

Khulse

Villager
Member
Joined
Jan 2, 2019
Messages
16
Reaction score
6
First Language
English
Primarily Uses
RMMV
Hi! I've lurked here for a while. Now I've joined. I'll introduce myself and so forth another time, though.

My question is simple enough. Most of the stats work well enough with a little tweaking, renaming, and plunging them into damage formulas and so forth. What I'd like to do is add another layer of value to some of them by having them determine Max HP and Max MP.

I can certainly just calculate the bases from the bases of the stats in question and then enter that into the class, but I'd like to set things up so that changes to those stats -such as from equipment and spells - also effect the max HP and MP values for both enemies and party members.

I prefer to avoid plugins if at all possible, simply for compatibility sake- it's a pain to wind up having issues with a plugin that's the only way to do something because of a plugin that's doing something I could have done another way.

I have found a couple of plugins that modify how stats work, such as Yanfly's base parameter's control, but it doesn't specify whether stats can be entered as variables in the formula. The examples only use level and numbers.

I'm sure this has been asked and answered before, since it's such a fundamental sort of thing, but I just can't find it.
 

bgillisp

Global Moderators
Global Mod
Joined
Jul 2, 2014
Messages
13,522
Reaction score
14,255
First Language
English
Primarily Uses
RMVXA
If you want to modify how HP and MP stats work and have it update with equipment changes, then plug-ins are the only option.

I've moved this thread to Plug-In Requests. Please be sure to post your threads in the correct forum next time. Thank you.

 

Khulse

Villager
Member
Joined
Jan 2, 2019
Messages
16
Reaction score
6
First Language
English
Primarily Uses
RMMV
/sigh
I was afraid of that. I'd prefer another way, but if that's the only way...

I guess this has turned into a 'what plugin?' thread, then. If anyone can point me in the right direction, I'd appreciate it.

I'd like something that works on both enemies and actors and has at least a decent chance of being compatible with other plugins I'm using or might decide to use. Thanks in advance.
 
Last edited:

Weremole

Veteran
Veteran
Joined
Jan 22, 2016
Messages
260
Reaction score
214
First Language
Swedish
Primarily Uses
Yanflys "Base Parameter Control" allows you to have formulas influence those values. So you could check that out to start with.
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
640
Reaction score
353
First Language
English
Primarily Uses
RMMV
Can you clarify what you're asking for with some examples? Are you saying that, for example, if someone increases their ATK with a new weapon, their MHP should increase by a percentage of their ATK?
 

Khulse

Villager
Member
Joined
Jan 2, 2019
Messages
16
Reaction score
6
First Language
English
Primarily Uses
RMMV
Yes, precisely.
Specifically, I'd like to use defense and luck to calculate hit points, and magic defense and luck to calculate magic points (luck is being used as something else, by the way).
For example:
The player finds a magic ring that increases his luck. When his luck goes up, so does his magic points and hit points. Then he puts on a helmet that increases his defense. His max hit points go up, but his magic points don't. If he swaps that for a helmet that increases magic defense as well as defense, he gets both hit points and magic points.
In the next fight, he casts a spell that reduces his targets defense. The targets max hit points are reduced until the effect wears off as well.

Then he fights a stupidly overpowered boss that casts a spell on him that drops his magic defense to 0. His max mp is now cut in half, because he lost half the points being used to calculate it. He still has the half of them that come from luck. Then the same boss casts another spell that drops his luck to 0. Now he has no mp (max mp at 0) and half his max hp.
Then the boss casts a third spell that drops his defense to 0. He's dead.
Not that I'd ever make a boss that could do that with this kind of mechanic in the game lol.

It is, of course, possible for me to just calculate the base mhp and base mmp using the numbers for def, mdf, and luk, then just bake mhp and mmp bonuses or penalties of the right proportion into anything that affects those stats. At this point, I suspect that's what I'm going to do. It looks like that'll be much simpler than trying to figure out how to use Base Parameter Control to do what I want.

PS: Do Yanfly's plugin descriptions have to that abstruse?
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
640
Reaction score
353
First Language
English
Primarily Uses
RMMV
Here's a plugin you can try. Make sure you save it as "LinkedStats.js" (alternatively, I've attached it as a file to this post):

Code:
/*:
* @plugindesc This plugin allows a user to modify stats on Classes or Enemies based on other stats.
* For example, raising maximum HP by a percentage of their defense.
* @author Zevia
*
* @help In a class or enemy's note box, put <link firstStat: x secondStat>,
* where firstStat is the stat you want to increase, secondStat is the stat you
* want to reference to increase the first stat by, and x is the percentage you
* want to increase based on the secondStat.
*
* As an example, <link mhp: 50 def> would translate to "increase this class's
* maximum hp by 50% of the class's defense".
*
* You can tie multiple stats to one stat by separating them with commas.
* For example, <link mhp: 50 def, 40 luk> would mean, "increase this
* class's maximum hp by 50% of the class's defense and 40% of the class's
* luck".
*
* If you want to be able to define a class or enemy's entire stat in relation
* to another stat, you can change the minimums of their stats. As an example,
* if you want a class's maximum HP to be solely dependent on their DEF and
* LUK, you can change the minimum HP parameter to 0, then do <link mhp: x def, y luk>
*
* @param mhp
* @text HP minimum
* @type number
* @desc The minimum value for HP. By default, it's 1.
* @default 1
*
* @param mmp
* @text MP minimum
* @type number
* @desc The minimum value for MP. By default, it's 0.
* @default 0
*
* @param atk
* @text ATK minimum
* @type number
* @desc The minimum value for ATK. By default, it's 1.
* @default 1
*
* @param def
* @text DEF minimum
* @type number
* @desc The minimum value for DEF. By default, it's 1.
* @default 1
*
* @param mat
* @text MAT minimum
* @type number
* @desc The minimum value for MAT. By default, it's 1.
* @default 1
*
* @param mdf
* @text MDF minimum
* @type number
* @desc The minimum value for MDF. By default, it's 1.
* @default 1
*
* @param agi
* @text AGI minimum
* @type number
* @desc The minimum value for AGI. By default, it's 1.
* @default 1
*
* @param luk
* @text LUK minimum
* @type number
* @desc The minimum value for LUK. By default, it's 1.
* @default 1
*/

(function(module) {
    'use strict';

    
    // Polyfill for older versions of RPG Maker MV
    Array.prototype.find = Array.prototype.find || function(finderFunction) {
        for (var i = 0; i < this.length; i++) {
            var element = this[i];
            if (finderFunction(element, i, this)) { return element; }
        }
    };

    module.Zevia = module.Zevia || {};
    var LinkedStats = module.Zevia.LinkedStats = {};
    var LINK_MATCH = 'link\\s+';

    var params = ['mhp', 'mmp', 'atk', 'def', 'mat', 'mdf', 'agi', 'luk'];
    var parameters = PluginManager.parameters('LinkedStats');
    var minimums = params.reduce(function(paramMinimums, param) {
        var minimumParam = parseInt(parameters[param]);
        if (isNaN(minimumParam)) {
            if (param === 'mmp') { paramMinimums[param] = 0; }
            else { paramMinimums[param] = 1; }
        } else {
            paramMinimums[param] = minimumParam;
        }

        return paramMinimums;
    }, {});

    LinkedStats.getLinkedStats = function(meta, paramId) {
        if (!meta || !params[paramId]) { return; }

        var regExp = new RegExp(LINK_MATCH + params[paramId], 'i');
        return meta[Object.keys(meta).find(function(key) {
            return key.match(regExp);
        })];
    };

    LinkedStats.getValues = function(values) {
        if (!values) { return; }

        return values.split(',').map(function(value) {
            var percentage = value.match(/\d+/);
            if (!percentage) { return; }

            var linkedMatch = value.match(/[a-zA-Z]+/);
            if (!linkedMatch) { return; }

            var linkedStat = params.find(function(param) {
                return param === linkedMatch[0];
            });
            if (!linkedStat) { return; }

            return {
                stat: linkedStat,
                percentage: percentage[0]
            };
        });
    };

    LinkedStats.getMinimumValue = function(value, paramId) {
        if (value === 1 && minimums[params[paramId]] === 0) { return 0; }
        return value;
    };

    LinkedStats.paramMin = Game_BattlerBase.prototype.paramMin;
    Game_BattlerBase.prototype.paramMin = function(paramId) {
        return minimums[params[paramId]];
    };

    LinkedStats.actorParamBase = Game_Actor.prototype.paramBase;
    Game_Actor.prototype.paramBase = function(paramId) {
        return LinkedStats.getMinimumValue(LinkedStats.actorParamBase.call(this, paramId), paramId);
    };

    LinkedStats.enemyParamBase = Game_Enemy.prototype.paramBase;
    Game_Enemy.prototype.paramBase = function(paramId) {
        return LinkedStats.getMinimumValue(LinkedStats.enemyParamBase.call(this, paramId), paramId);
    };

    LinkedStats.param = Game_BattlerBase.prototype.param;
    Game_BattlerBase.prototype.param = function(paramId) {
        var meta = this instanceof Game_Actor ? this.currentClass().meta : $dataEnemies[this._enemyId].meta;
        var value = LinkedStats.param.call(this, paramId);

        var linkedStats = LinkedStats.getLinkedStats(meta, paramId);
        if (!linkedStats || !linkedStats.length) { return value; }

        var linkedValues = LinkedStats.getValues(linkedStats);
        if (!linkedValues || !linkedValues.length) { return value; }

        return value + linkedValues.reduce(function(total, linkedValue) {
            if (!linkedValue.stat || !linkedValue.percentage) { return total; }
            return total += Math.round((this[linkedValue.stat] * (parseInt(linkedValue.percentage) / 100)));
        }.bind(this), 0);
    };

    LinkedStats.actorParam = Game_Actor.prototype.param;
    Game_Actor.prototype.param = Game_BattlerBase.prototype.param;

    LinkedStats.enemyParam = Game_Enemy.prototype.param;
    Game_Enemy.prototype.param = Game_BattlerBase.prototype.param;
})(window);
You should be able to make any of the default 8 stats (mhp, mmp, atk, def, mat, mdf, agi, luk) gain increased values from other stats using notetags for a class or an enemy along the lines of:
Code:
<link stat: x dependentStat>
where stat is the stat you want to adjust according to dependentStat, with x being the percentage of the dependentStat you want to use. As an example:
Code:
<link mhp: 50 def>
means that a class's maximum HP should be increased by 50% of the Actor's defense. So, if the Actor has 100 MHP and 50 DEF, then their MHP will be 125. You can tie multiple stats to a stat by separating them with commas, such as:

Code:
<link mhp: 50 def, 50 luk>
You can also adjust the minimums of any of the 8 parameters, since the default is that every stat has a minimum of 1 except MMP. As an example, if you want your Actor's MHP to be solely dependent on their DEF and LUK, you can change the "Minimum HP" parameter to 0, then in the Actor's Class, put:

Code:
<link mhp: 100 def, 100 luk>
Their MHP will now be the total of their DEF plus their LUK, so that if DEF and LUK are reduced to 0, they should die.

I have not confirmed that it's compatible with any other scripts, so if you run into issues, let me know.

EDIT: To specifically get what you want, I believe you should adjust the parameters for the plugin for HP Minimum, Defense Minimum, Luck Minimum, and Magic Defense minimum to be 0, then add this notetag to your classes:

Code:
<link mhp: 100 def, 100 luk>
<link mmp: 100 mdf, 100 luk>
 

Attachments

Last edited:

Astfgl66

Veteran
Veteran
Joined
Jan 5, 2016
Messages
722
Reaction score
578
First Language
French
Primarily Uses
You can also use my flat stat bonus state plugin for this.
The link is in my signature.
 

Khulse

Villager
Member
Joined
Jan 2, 2019
Messages
16
Reaction score
6
First Language
English
Primarily Uses
RMMV
@Zevia That almost works perfectly! When I tested, the max hp was indeed changed based on the stats.
Unfortunately, it appears that it only uses the last stat listed per stat effected. For example, if I put both <link mhp: 100 def> and <link mhp: 100 luk> in the note box for a class (in that order), max hp is only changed by luck. If I add magic attack (for testing purposes), it uses magic attack, but ignores luck and defense. If I have tags for both hp and mp, both hp and mp are changed by whatever I put in the appropriate note tag, but only uses the last the last tag listed for each respective stat. If I take out all but defense, it uses defense just fine.

Short version: it only uses the last note to change a particular stat, not all of them.

I did test both using equipment and using buffs and debufs in combat, and that works just the way it should, with the max hp increasing or decreasing based on the change to the affected stat (defense is the one I tested, just to be specific about it.)

I hope you followed all that. I just got off work and my brain is tired.
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
640
Reaction score
353
First Language
English
Primarily Uses
RMMV
@Khulse Should be fixed now. RPG Maker MV builds an object out of each note tag, using the part before the colon as a key. So if you have <link stat> twice, like you mentioned, it's just going to keep replacing the key with whatever the last key was.

I've edited my post with the Plugin and re-uploaded the file to the same post. Should be good if you replace the old version with the new one. If you want to tie multiple stats to one stat, now you should comma-separate the linked stats. As an example:

Code:
<link mhp: 100 def, 100 luk>
 

Khulse

Villager
Member
Joined
Jan 2, 2019
Messages
16
Reaction score
6
First Language
English
Primarily Uses
RMMV
Awesome! Beautiful! It works perfectly!
I can't believe you took the time to do that for me. Thank you very, very much. I'm sure other people will find it very useful too.
I can verify at least somewhat that it works as intended on monsters too.

As an added bonus, I tested it with Hime's parameter tables, which I'm also considering using. If your not familiar with it, it lets you use a spreadsheet file to set base parameters for a class. It works just fine that way too- it used the base defense and base luck provided by the table and added them to the base mhp also provided by the table. Again ditto for the enemies using enemy levels and classes, also from Hime.

Again. Thank you very much.

@Astfgl66 Sorry, I didn't mean to ignore you in my previous post. I meant to reply, but it slipped my mind. Having the effect just on states isn't quite what I was looking for, though that does look like a good mod. Thanks for the suggestion, though.
 

Zevia

Veteran
Veteran
Joined
Aug 4, 2012
Messages
640
Reaction score
353
First Language
English
Primarily Uses
RMMV
Awesome! Beautiful! It works perfectly!
I can't believe you took the time to do that for me. Thank you very, very much. I'm sure other people will find it very useful too.
No problem, glad it works for you - and glad it's compatible with at least one other tool you're using.

Let me know if you run across any other issues with it, I've got it over on the Plugins In Development board.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,860
Messages
1,017,040
Members
137,569
Latest member
Shtelsky
Top