Passive state application + Creating makeshift state menu?

kjorteo

Act with love and sincerity
Regular
Joined
Jun 19, 2023
Messages
57
Reaction score
40
First Language
English
Primarily Uses
RMMZ
Good evening, all! Two questions this time.

1) Passive state application
Is there a way to give actors whatever chance to apply states automatically across all physical attacks? We know that you can do it per weapon--for example, that you could make a Poison Sword (wielder has a 25% chance to poison the enemy on strike) and edit the Poison Sword's Traits --> Attack --> Attack Skill --> Have it use a cloned version of the regular 0001 Attack skill, one that includes the chance to poison. However, that's not what we're after. We're looking for a trait elsewhere (perhaps a Poisoner state, a wearable Poisoner's Ring, etc.) that applies this effect to all physical attacks with any weapon, even those that wouldn't have it otherwise.

Perhaps entire... like... custom-created "chance to inflict each particular state" stats/parameters, perhaps? elsewhere in the chain, which the attack skills can then take into account? You'd need a way to tie the Add State value in skills to a variable instead of a hard number, though. But if there's any way that's feasible, it might just solve question 2 below.

2) Makeshift state menu
So, we're using VisuStella's Element/Status Core, which has a very beautiful screen to display a given party member's elemental strengths/weaknesses and bonus damage they inflict.
states1.png

The neat thing about the VS cores is that the plugin management screen just lets you dive right into the full JS code of exactly what's being drawn here, where it gets it from, how it aligns and displays everything, everything. This is what appears to be the complete code of how this screen was generated:
JavaScript:
// Declare Constants
const lineHeight = this.lineHeight();
const actor = this._actor;
const padding = this.itemPadding();
const labelFmt = '\\C[16]%1: \\C[0]%2';
const traitType1 = DataManager.traitSetType('Element');
const traitSet1 = actor.traitSet('Element');
const traitType2 = DataManager.traitSetType('SubElement');
const traitSet2 = actor.traitSet('SubElement');
const traitHeight = (this.innerHeight / Math.max(Window_StatusData.traitCol1.length, Window_StatusData.traitCol2.length)) - lineHeight;
let x = 0;
let y = 0;
let width = this.innerWidth / 2;

// Draw Actor Graphic
this.drawActorGraphic(0, width);

// Draw Element Trait Sets
if (traitType1.Visible || traitType2.Visible) {
    this.drawItemDarkRect(x, y, width, lineHeight, 2);
    this.drawItemDarkRect(width, y, width, lineHeight, 2);
    if (traitType1.Visible) {
        this.drawTextEx(labelFmt.format(traitType1.Label, traitSet1.Display), padding, y, width - padding * 2);
    }
    if (traitType2.Visible) {
        this.drawTextEx(labelFmt.format(traitType2.Label, traitSet2.Display), width + padding, y, width - padding * 2);
    }
    y += lineHeight;
    this.setDescriptionFontSizeToTraitSet();
    this.drawItemDarkRect(x, y, width, traitHeight);
    this.drawItemDarkRect(width, y, width, traitHeight);
    if (traitType1.Visible) {
        this.drawTextEx(traitSet1.Description, padding, y, width - padding * 2);
    }
    if (traitType2.Visible) {
        this.drawTextEx(traitSet2.Description, width + padding, y, width - padding * 2);
    }
    this.resetDescriptionFontSize();
    this.resetFontSettings();
    y += traitHeight;
}
const topY = y;

// Prepare Elemental Data
const elementCol1 = this.getElementIDsCol1();
const elementCol2 = this.getElementIDsCol2();
let columnData;
if (elementCol2.length > 0) {
    columnData = ['Resist','Resist','Bonus','Bonus'];
} else {
    columnData = ['Resist','Bonus'];
}
const dataRows = Math.max(elementCol1.length, elementCol2.length, 1);
const dataCols = columnData.length;

// Draw Elemental Data
this.drawItemDarkRect(width * 0, y, width, lineHeight, 2);
this.drawItemDarkRect(width * 1, y, width, lineHeight, 2);
this.changeTextColor(ColorManager.systemColor());
this.drawText(TextManager.statusMenuDmgReceive, width * 0, y, width, 'center');
this.drawText(TextManager.statusMenuDmgDealt, width * 1, y, width, 'center');
y += lineHeight;
this.setDescriptionFontSizeToTraitSet();
const smallLineHeight = this.textSizeEx(' ').height;

// Draw Elemental Table
for (let i = 0; i < dataRows; i++) {
    for (let j = 0; j < dataCols; j++) {
        // Draw Dark Rect
        const colWidth = this.innerWidth / dataCols;
        this.drawItemDarkRect(colWidth * j, y, colWidth, smallLineHeight);

        // Draw Element Name
        let elementID = elementCol1[i];
        if (dataCols === 4) {
            elementID = (j % 2 === 0) ? elementCol1[i] : elementCol2[i];
        }
        if (!elementID) continue;
        const name = $dataSystem.elements[elementID];
        this.drawTextEx(name, colWidth * (j + 1/3) + padding, y, colWidth*2/3);
        const type = columnData[j];

        // Draw Resistance Data
        this.resetFontSettings();
        let drawText = '';
        if (type === 'Resist') {
            const rate = actor.elementRate(elementID);
            const flippedRate = (rate - 1) * -1;
            this.changeTextColor(ColorManager.paramchangeTextColor(flippedRate));
            drawText = '%1%'.format(Math.round(flippedRate * 100));
            if (actor.getAbsorbedElements().includes(elementID)) {
                this.changeTextColor(ColorManager.powerUpColor());
                drawText = TextManager.statusMenuDmgAbsorb.format(Math.round(rate * 100));
            } else if (rate > 1) {
                drawText = '%1'.format(drawText);
            } else if (rate <= 1) {
                drawText = '+%1'.format(drawText);
            }

        // Draw Bonus Damage Data
        } else if (type === 'Bonus') {
            const dealtPlus = actor.getDealtElementPlus(elementID);
            const dealtRate = actor.getDealtElementRate(elementID);
            const dealtFlat = actor.getDealtElementFlat(elementID);
            const dealt = ((1 + dealtPlus) * dealtRate + dealtFlat) - 1;
            this.changeTextColor(ColorManager.paramchangeTextColor(dealt));
            drawText = '%1%'.format(Math.round(dealt * 100));
            if (dealt >= 0) drawText = '+%1'.format(drawText);
        }

        // Draw Value
        this.contents.drawText(drawText, colWidth * j, y, (colWidth/3) - padding, smallLineHeight, 'right');
    }
    y += smallLineHeight;
}

// Closing the Table
for (let j = 0; j < dataCols; j++) {
    const colWidth = this.innerWidth / dataCols;
    this.drawItemDarkRect(colWidth * j, y, colWidth, this.innerHeight - y);
}

We're not using the "Traits" tab on the above screen for anything important, and we could rename it and change the code to put basically whatever we want in there. So, to that end, maybe we could put state info there instead. Like, is there a way to copy but modify the above code for the two elemental columns (resistance + bonus damage) and turn them into something that displays the same kind of information but for states, with two state columns (state resistance + chance to inflict state?) Something that would show up if, say wearing a ring that adds a +5% Sleep and +5% Deep Sleep chance to their outgoing attacks and makes them +25% more resistant to Silence on incoming ones, at the cost of being more vulnerable to Fear (-50% resistance or so.) A screen that can just compile and display all total resistances and infliction chances for whichever select states we're including here, like the elements screen above, possibly even using the same code but just getting it to point at different stats/parameters instead.

We could make custom stats/parameters if the code needs something to point at to display them (I suppose "Actor's innate chance to inflict Poison" isn't really a thing if the game is used to that being calculated per Skill instead) but then we'd need to know how to make those stats/parameters actually affect the things they're supposed to be affecting.

Thank you so much for all your help, as always! :yhappy:
 

Robro33

Weeb Cringe Incarnate
Regular
Joined
Oct 15, 2022
Messages
260
Reaction score
219
First Language
English
Primarily Uses
RMMV
you are able to make passives with visustella buffs. youll just have to make the poisoner state where on a physical hit, theres a 25% to apply poison through the pre/post damage tags, then add the state to your equipment/characters/etc with the passive state tag. Alternatively, if youre willing to add normal attack states to all your physical skills, you wouldnt need to even add the pre/post damage tags and use the attack state trait in the poisoner state

Cant help with the 2nd question though. All i know about visustella is from whats available on the plugin pages. I dont use them and im fairly certain that its all obfuscated anyways, so you cant make edits to them beyond what plugin parameters allow. (EDIT: didnt see the spoilered text letting you use js to interact with the ui elements)
if it helps, you could pull the state affliction chance from attack state traits with attackStatesRate(). But if you used the pre/post damage notetags to apply states through more than just normal attacks, youd need to add more steps to be able to accurately display it if the plugin allows you to
 
Last edited:

Andar

Regular
Regular
Joined
Mar 5, 2013
Messages
39,952
Reaction score
11,893
First Language
German
Primarily Uses
RMMV
1) traits are not bound to weapons - if you give the actor or class such an add state trait, then all skills that give a normal attack state will use that state data.
 

kjorteo

Act with love and sincerity
Regular
Joined
Jun 19, 2023
Messages
57
Reaction score
40
First Language
English
Primarily Uses
RMMZ
1) traits are not bound to weapons - if you give the actor or class such an add state trait, then all skills that give a normal attack state will use that state data.
Aha. We didn't notice there's a Rates -> State Rate and Attack -> Attack State. We just saw the one, weren't sure which of those two things it did, and whichever it was, we weren't sure how to do the other. Now I feel like I just asked a silly question (sorry :yswt:) but I'm glad it has such an easy and simple answer.

you are able to make passives with visustella buffs. youll just have to make the poisoner state where on a physical hit, theres a 25% to apply poison through the pre/post damage tags, then add the state to your equipment/characters/etc with the passive state tag. Alternatively, if youre willing to add normal attack states to all your physical skills, you wouldnt need to even add the pre/post damage tags and use the attack state trait in the poisoner state
Or... does it? Are you still saying one needs the VS passive state tags?

Let's say we wanted to include a passive effect that gives the actor plantlike properties. This would mean that (among other effects) an actor in this state should be 50% move vulnerable to receiving the "Frozen" condition when attacked with it, but in exchange, all of their outgoing physical attacks have a 10% chance to inflict poison. Based on Andar's answer, this looks like we could do this with either a "plant-person" State or a "plant ring" Armor somewhere, and either way we do it, it appears that we simply would edit the Traits of the State/Armor to add Rates -> State Rate -> Frozen: 150% and Attack -> Attack State -> Poison: 10%. Would that not work? Is doing it with the VS tags still necessary?

Anyway, whichever of the two methods posted here we go with, thank both of you so much for your help!! Now we just need to figure out how to hack a display screen together (I'm thinking we might just be able to take the code for the Elements tab posted above, find which part of that is the actual data, and change it to... whatever the syntax is for the state-related chance parameters instead, but we're not exactly JS experts) and we should be set. :LZSjoy:
 

Robro33

Weeb Cringe Incarnate
Regular
Joined
Oct 15, 2022
Messages
260
Reaction score
219
First Language
English
Primarily Uses
RMMV
Is doing it with the VS tags still necessary?
you can do poisoner from earlier with or without the VS tags or states at all. it just depends on how close to the initial intended function you want the effect to be. for poisoner, you could have it be a trait on a weapon or armor directly since you can use attack states to do it.

the main reasons i brought up the VS damage tags and making it a passive state are that:
1) its an easy way to make it work so that all physical hits can inflict poison without finding all your physical skills and adding normal attack states to them. Remember that by default, attack states only apply to normal attacks and skills with normal attack states.

2) they let you apply your own formula for affliction chance into itself instead of letting it be a set %. Default state application only uses the state affliction rate, the target's state rate, and some factor based on luck iirc. you can make the formula be whatever you want directly with the damage tags

and 3) it lets you have one place where you can make changes to the effects to then update on every enemy, actor, and equipment its on. I wasnt sure how often you'd be reusing the effect or if you'd also be giving the effect to enemies, but its useful for making sweeping adjustments. as an example, if you didnt make plantlike a state and only used traits, then later on if you wanted to do anything like change the % on the ice weakness, add a fire weakness, add a water resistance, or increase the poison chance, youd have to find everything in the database that you made "plantlike" and change them all manually
 

Latest Threads

Latest Posts

Latest Profile Posts

So in my SRPG, when kill monsters, they leave an aura that grants +20% Crit, +20% PDMG MDMG. Aura lasts only for 1 turn, it forces players when and where to last hit.

1702177938686.png
So frustrating when you just wanna work on your game but people want to do stuff in RL... :p
Day #9 of Advent is all ready in one spot! Do you prefer doing your shopping way before Xmas, or…do you like the chaos? Are you done shopping and/or crafting for Xmas?
Fast test with Wagon and horse no animation. yes it looks strange horse is Ralph and wagon is follower xDDDD
Should first boss be easy or maybe little medium, I don't want to be overwhelmingly hard

Forum statistics

Threads
136,887
Messages
1,271,059
Members
180,663
Latest member
brendancamarillo
Top