RMMV use Sprite_StateOverlay on MapEvents?

Status
Not open for further replies.

Dopan

Veteran
Veteran
Joined
Mar 27, 2020
Messages
664
Reaction score
342
First Language
German
Primarily Uses
RMMV
i would like to play "Sprite_StateOverlay" (which are the default State Animations) on events outside of Battle..

Spoiler shows where the Functions is located, but i am not sure how the Function get triggered when SV battle happens..

Screenshot_4.png

I think there is a function that disables the "Sprite_StateOverlay"-functions outside of SV Battle.
(yep battleEngineCore)

I got no idea how to script this, i would like a script that allows me to Display The StateOverlay based on The Event Id
(to be displayed over the Event similar how it would be displayed on SV battlers)

The Unit Events that i will use have also a "battler"-part but i couldnt figure out ,how to use that to play the StateOverlay Animations on these UnitEvents..

-> any hints or Ideas are welcome! thx
 
Last edited:

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,219
Reaction score
1,629
First Language
EN
Primarily Uses
RMMZ
These are added as child sprites to instances of Sprite_Actor and setup when a battler is assigned:
JavaScript:
Sprite_Actor.prototype.createStateSprite = function() {
    this._stateSprite = new Sprite_StateOverlay();  // <- initialised
    this.addChild(this._stateSprite);  // <- added as child
};

Sprite_Actor.prototype.setBattler = function(battler) {
    Sprite_Battler.prototype.setBattler.call(this, battler);
    var changed = (battler !== this._actor);
    if (changed) {
        this._actor = battler;
        if (battler) {
            this.setActorHome(battler.index());
        }
        this.startEntryMotion();
        this._stateSprite.setup(battler);  // <- setup
    }
};
In this case, "setup" just means telling the overlay sprite who to reference (e.g. actor 1) so it knows what frames it should be showing. After setup, the sprite updates itself. (This is how most of RMMV's sprites work.)

Map events have their walking sprites stored in the map's spriteset:
JavaScript:
Spriteset_Map.prototype.createCharacters = function() {
    this._characterSprites = [];
    $gameMap.events().forEach(function(event) {
        this._characterSprites.push(new Sprite_Character(event));
    }, this);
// ... //
So by default I think the sprite for event ID x is stored under the spriteset's _characterSprites array at index x-1 (because indexing starts at 0).

So if you have a battler for each of these events, you could try something vaguely like this (untested):
JavaScript:
var spriteset = SceneManager._scene._spriteset;
var eventId = 9;
var battler = $gameActors.actor(11);
var sprChar = spriteset._characterSprites[eventId - 1];
sprChar._stateSprite = new Sprite_StateOverlay();  // init
sprChar.addChild(sprChar._stateSprite);            // add
sprChar._stateSprite.setup(battler);               // setup
Could probably be done a lot more neatly in an appropriate context; this is just a hopefully-functional example to explain what I'm talking about~ :kaoslp:
 

Dopan

Veteran
Veteran
Joined
Mar 27, 2020
Messages
664
Reaction score
342
First Language
German
Primarily Uses
RMMV
So if you have a battler for each of these events, :kaoslp:
at the moment i still didnt figure out all of your posting but thx anyway i will work with that
(but i am trying to give more information ,perhaps that might help somehow)

well the UnitEvents contain a battler aswell as an actor OR enemy ID..
perhaps using these Actor/Enemy IDs would be better=?
->the problem on enemy IDs is that, several Enemys can be a cloned version (same id),.. that doesnt happen on Actors..
=> however thats why i thought event ID is the best way to go..

Also i will probably need to use a "If condition" to ask about if the Unit is affected?
-> or is this handled with the state setup, where i can choose the overlay for a state..?

EDIT// it will always trigger the state overlay with the state that has the highest priority
=> i wanted to use a script that checks all events if they are "actor/enemy".. this script can adress both types.. the map event aswell as the battler..

here the Script to adress those events for better understanding:
JavaScript:
                //0U_Add Test: THIS IF FOR TESTING NEW FUNCTIONS "this.allUxTest();"
                Game_Interpreter.prototype.allUxTest = function() {
                    // this below checks all Events on Map
                    for (var i = 1; i <= $gameMap.events().length; i++) {
                    // this below is the battler part
                    var battleunit = $gameSystem.EventToUnit([i]);
                    // this below is the mapEvent part
                    var eventunit = $gameMap.event([i]);
                    // this below checks if Battler and Event are the same Unit,and
                    // If the Unit is an Actor or Enemy    ,..and
                    // if the Unit is not death
                    if (battleunit && eventunit && (battleunit[0] === 'actor' || battleunit[0] === 'enemy') && (!battleunit[1].isDead())) {
                        // <-insert test code here
                    }

                    }
                    return true;
                };
Example IMGs for an EventUnit. This one use Event ID 9 and stores the Actor(img1),which stores the battler(img2) at the bottom
Screenshot_1.png--
Screenshot_2.png
---
Another approach..
i dont know if that is helpfull but there is also allready a function that display char frame over the normal event char frame.. in order to add the turn end sprite
(i edited that function to be able to use more frames without conflicts,, basicly by changing the loaded img..)
Screenshot_3.png
Screenshot_4.pngScreenshot_5.png

But i think this is different because it uses the char animations and not the system state img
 
Last edited:

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,219
Reaction score
1,629
First Language
EN
Primarily Uses
RMMZ
Globally, it looks like $gameSystem.EventToUnit([eventId])[1] might work for the battler reference? Remember to replace eventId with the event's ID (or use it as a local var like I have done in my example). :kaophew:

Edit @Dopan: this "add state overlay sprite" stuff would have to be done when arriving on the map, either via a Script command in an event or a plugin. I'm not concerned about the enemy thing...they must be separate battler instances otherwise you'd have problems with them sharing HP etc. :kaoslp:
 
Last edited:

Dopan

Veteran
Veteran
Joined
Mar 27, 2020
Messages
664
Reaction score
342
First Language
German
Primarily Uses
RMMV
JavaScript:
var spriteset = SceneManager._scene._spriteset;
var eventId = 9;
var battler = $gameActors.actor(9);
var sprChar = spriteset._characterSprites[eventId - 1];
sprChar._stateSprite = new Sprite_StateOverlay();  // init
sprChar.addChild(sprChar._stateSprite);            // add
sprChar._stateSprite.setup(battler);               // setup
@caethyril
i tried this, but it seems my main Problem is, that the "_spriteset" part is "undefined" outside of sideview battle..
(using "SceneManager._scene._spriteset" in F8 console will return undefined because the scene wont have it outside of SV)
=> using "SceneManager._scene._spriteset" while a sideview action is active will show all related data in console..


I think i have to figure out how to make the "_spriteset"-Part active on Map.. but perhaps that might provoke other problems .. idk
edit // the reason was , i used "scene menu" before opening the console.. more info in the next post
 
Last edited:

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,219
Reaction score
1,629
First Language
EN
Primarily Uses
RMMZ
i tried this, but it seems my main Problem is, that the "_spriteset" part is "undefined" outside of sideview battle..
I just tested in a project without plugins, and on the map SceneManager._scene._spriteset returns an instance of Spriteset_Map, as expected. It's the container for all character sprites (player, followers, events, vehicles) etc.

I'm guessing you either mistyped when checking the console, or one (or more) of your plugins completely overhauls all of that...? :kaoswt2:
 

Dopan

Veteran
Veteran
Joined
Mar 27, 2020
Messages
664
Reaction score
342
First Language
German
Primarily Uses
RMMV
I just tested in a project without plugins, and on the map SceneManager._scene._spriteset returns an instance of Spriteset_Map, as expected. It's the container for all character sprites (player, followers, events, vehicles) etc.

I'm guessing you either mistyped when checking the console, or one (or more) of your plugins completely overhauls all of that...? :kaoswt2:
deleted old post
edit
my bad, it was because i always go to scene menu before i open console f8 ..
( i am doing this to avoid "request animationFrame" issue.. info img)
Screenshot_1.png

thx for double checking with an empty/clean project

@caethyril
you are a Genius!
, your code works fine.. i tried this without going in "scene menu" & ignoring the "violation" info..:
JavaScript:
var spriteset = SceneManager._scene._spriteset;
var eventId = 9; // in my testing project each actor ID is the same like the event ID..
var battler = $gameActors.actor(9); //.. i used event placeholders to make that sure
var sprChar = spriteset._characterSprites[eventId - 1];
sprChar._stateSprite = new Sprite_StateOverlay();  // init
sprChar.addChild(sprChar._stateSprite);            // add
sprChar._stateSprite.setup(battler);               // setup
so actor 9 with event ID 9 will indeed display the poison State if affected!
(after puting your code in console and closing console)

.. I am pretty sure i can do that on all Units without help..
Screenshot_1.png
The only issues left (no real Issues):
1.
This will always just display the state with the highest Priority,there are Plugin requests for rotate trough states or display several states, but i couldnt find a plugin that does it^^
(not even for the default SV battles)

2.This will Stop/End as soon the "Scene menu" was opened.. and has to be refreshed after going back to "map Scene"..
(i am not sure why, but that should be no problem, i can refresh the function..)


about 1:
i think the best way would be to add a rotation betwen the states, but i think thats not so easy because i couldnt find any plugin that does that.. even not for SV.
Or using StateNote tags that decide if this state is a "rotation state" or a "parrallel state".. without StateNote it would be a "Default state" that only shows up if its the highest priority
(i got no idea how this could be solved , i think i can use normal animations as walkaround for "special states" like "aura".. also i think displaying to much states could get laggy.. i already tried that with animations for all states and rotation via CE.. instead of using state overlays)

about 2:
I think when i make a function that "returns true" on battlemap whenever active.. i can easyly refresh it whenever its "NOT true" outside of "scene menu" on Battlemap.
( i am pretty sure i can figure this out myself.. aswell as adding all Units on map to the Function.. not just actor 9 )

*Battlemap means , when SRPG battle is active.. which is the same like "map scene" but only with the battle modus active.. where Events become Units ect..

Edit the 3rd
i think i solved "about 2"
here is my test function which can be used for SRPG projects

JavaScript:
Game_Interpreter.prototype.srpgStateOverlay = function() {
    for (var i = 1; i <= $gameMap.events().length; i++) {
         var battleunit = $gameSystem.EventToUnit([i]);
         var eventunit = $gameMap.event([i]);
         var spriteset = SceneManager._scene._spriteset;
         var eventId = [i];
         var sprChar = spriteset._characterSprites[eventId - 1];
         if (battleunit && eventunit && (battleunit[0] === 'actor' || battleunit[0] === 'enemy') && (!battleunit[1].isDead())) {
             sprChar._stateSprite = new Sprite_StateOverlay();  // init
             sprChar.addChild(sprChar._stateSprite);            // add
             sprChar._stateSprite.setup(battleunit[1]);               // setup
         }
         return true;
    }
};

Game_Interpreter.prototype.srpgStateOverlay(); // can be used to refresh
i tried to use a Game battler prototype at first to get the event id of every Unit, but that didnt worked well..

Here the proof that it works on All Units Now^^
(enemys have "enemy state" , actors have "friend State", actor9/nymphe has "poison state" with higher priority)
Screenshot_3.png
--
Screenshot_2.png
hearts = friend state
fireface = enemy state
green bubbles = poison state (higher priority)

This thread will be reported as Solved,..to be closed
if "about 1" should be solved or needs more questions,.. this can be made in an Extra Thread
 
Last edited:

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,219
Reaction score
1,629
First Language
EN
Primarily Uses
RMMZ
:kaojoy: Good to hear it's working! For your questions:
  1. By default the state overlay sprite gets its row index from the battler's stateOverlayIndex method:
    JavaScript:
    Game_BattlerBase.prototype.stateOverlayIndex = function() {
        var states = this.states();
        if (states.length > 0) {
            return states[0].overlay;
        } else {
            return 0;
        }
    };
    As you can see, it simply returns the overlay index of the first state in the list, which will be the one with highest priority (because the states get sorted by priority when a new one is added). You could alias or override this in a plugin to change the behaviour. If you want it to cycle through, one option would be to also create an alias/override for the overlay sprite's update method:
    JavaScript:
    Sprite_StateOverlay.prototype.update = function() {
        Sprite_Base.prototype.update.call(this);
        this._animationCount++;
        if (this._animationCount >= this.animationWait()) {
            this.updatePattern();
            this.updateFrame();
            this._animationCount = 0;
        }
    };
    It already counts frames, to update the column of the overlay sheet it is referencing. You could simply add another counter in a similar way for "state index", to change the row when appropriate.

  2. When you leave the map scene, it and all its elements (sprites, etc) are unloaded to make way for the next scene (e.g. menu or battle): that's simply how the SceneManager works, one scene at a time. The map data, e.g. character locations, is stored in $gameMap, which is preserved.

    If you added the overlay sprites in a plugin it could be a non-issue. Perhaps by aliasing the setCharacter method of Sprite_Character? Untested example:
    JavaScript:
    (function(alias) {
      Sprite_Character.prototype.setCharacter = function(char) {
        alias.apply(this, arguments);
        var battler;
        if (char instanceof Game_Player) {
          battler = $gameParty.leader();
        } else if (char instanceof Game_Follower) {
          battler = char.actor();
        } else if (char instanceof Game_Event) {
          /* if (event is a map enemy) {
            battler = enemy reference     // THIS PART NEEDS EDITING
          } */
        }
        if (!battler) return;  // don't add overlay unless appropriate
        this._stateSprite = new Sprite_StateOverlay();  // init
        this.addChild(this._stateSprite);               // add
        this._stateSprite.setup(battler);               // setup
      };
    })(Sprite_Character.prototype.setCharacter);
 

Dopan

Veteran
Veteran
Joined
Mar 27, 2020
Messages
664
Reaction score
342
First Language
German
Primarily Uses
RMMV
:kaojoy: Good to hear it's working! For your questions:
  1. By default the state overlay sprite gets its row index from the battler's stateOverlayIndex method:
    JavaScript:
    Game_BattlerBase.prototype.stateOverlayIndex = function() {
    var states = this.states();
    if (states.length > 0) {
    return states[0].overlay;
    } else {
    return 0;
    }
    };
    As you can see, it simply returns the overlay index of the first state in the list, which will be the one with highest priority (because the states get sorted by priority when a new one is added). You could alias or override this in a plugin to change the behaviour. If you want it to cycle through, one option would be to also create an alias/override for the overlay sprite's update method:
    JavaScript:
    Sprite_StateOverlay.prototype.update = function() {
    Sprite_Base.prototype.update.call(this);
    this._animationCount++;
    if (this._animationCount >= this.animationWait()) {
    this.updatePattern();
    this.updateFrame();
    this._animationCount = 0;
    }
    };
    It already counts frames, to update the column of the overlay sheet it is referencing. You could simply add another counter in a similar way for "state index", to change the row when appropriate.

  2. When you leave the map scene, it and all its elements (sprites, etc) are unloaded to make way for the next scene (e.g. menu or battle): that's simply how the SceneManager works, one scene at a time. The map data, e.g. character locations, is stored in $gameMap, which is preserved.

    If you added the overlay sprites in a plugin it could be a non-issue. Perhaps by aliasing the setCharacter method of Sprite_Character? Untested example:
    JavaScript:
    (function(alias) {
    Sprite_Character.prototype.setCharacter = function(char) {
    alias.apply(this, arguments);
    var battler;
    if (char instanceof Game_Player) {
    battler = $gameParty.leader();
    } else if (char instanceof Game_Follower) {
    battler = char.actor();
    } else if (char instanceof Game_Event) {
    /* if (event is a map enemy) {
    battler = enemy reference // THIS PART NEEDS EDITING
    } */
    }
    if (!battler) return; // don't add overlay unless appropriate
    this._stateSprite = new Sprite_StateOverlay(); // init
    this.addChild(this._stateSprite); // add
    this._stateSprite.setup(battler); // setup
    };
    })(Sprite_Character.prototype.setCharacter);
about 1
thx i will look into that,..perhaps that might be helpfull for more Plugin Functions

about 2
I think thats not needed because SRPG has Phases and Subphases that tell me where we are..
i can use them to make "if conditions" which controll when a refresh should happen
( to be honest .. again i dont understand half of it yet anyway^^ but i will look into it anyway to learn more^^)
=> i allready solved most of it.. shown in the "3rd Edit" in the posting above^^

Thank you very much for all the help! @caethyril
 
Last edited:

slimmmeiske2

Little Red Riding Hood
Global Mod
Joined
Sep 6, 2012
Messages
8,010
Reaction score
5,320
First Language
Dutch
Primarily Uses
RMXP

This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.

 
Status
Not open for further replies.

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

Latest Threads

Latest Profile Posts

My computer broke yesterday, so no RPG maker for at least a week until I can get it repaired. :(
Just wanted to share how my game won 1st place in a game jam for itch.io. Everyone else used Unreal, Unity, GMS2, Godot, etc but I used RPG Maker 2003 :guffaw: It just shows that you can create a good game and it doesn't matter which engine you use
Working on cutscenes~

if your game is the first (or ONLY) in a series and still has a colon in its title, you are a bad person and I hate you...... jk.

who could ever hate BETWEEN: TWO SOULS?

Forum statistics

Threads
107,404
Messages
1,029,443
Members
139,503
Latest member
cheesepot
Top