Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
181
Reaction score
296
First Language
English
Primarily Uses
RMMZ
I can't figure out how to fix this.

I've put together an 'alpha' version of my Turn Priority Window. The core mechanics of it work, but after awhile it's going to get laggy because the faces for one of the windows is not clearing and redrawing like it should, in fact it's just redrawing and not clearing lol. There are two windows, the Active Actor Window, which displays the actor that is currently able to select commands and the Turn Priority Window which displays the order of the remaining party members in which they can have a turn. The Turn Priority Window is the one that isn't clearing properly.

UpdateTpbChargeTime (core file) Despite 'update' in it's name, it's not one of those "always running non stop" updates. It's up to 2-3 times during charging phase. It doesn't run when a player's turn bar is full.
JavaScript:
Game_Battler.prototype.updateTpbChargeTime = function() {
    if (this._tpbState === "charging") {
        // how fast the turn bar fills is determined by the acceleration rate
        this._tpbChargeTime += this.tpbAcceleration();
        if (this._tpbChargeTime >= 1) {
            // When someone's turn is up, tell the TP Window to redraw the faces for the new order.
            ChargeTracker._hasUpdatedCharge = true;
            this._tpbChargeTime = 1;
            this.onTpbCharged();
        }
    }
};

Update function. "always running for as long as the scene its window is in is active." In this case Scene Battle.
JavaScript:
TurnPriorityWindow.prototype.update = function() {
    Window_Base.prototype.update.call(this)
   
    if (this._drawOnce === false) {
        // draw the initial order of faces at the start of battle(when the Fight/Escape command window appears)
        this.drawFacesByTurn();
        this._drawOnce = true
    } else if (ChargeTracker._hasUpdatedCharge === true) {
        /* This is set to true every time Game_Battler.updatetpbChargeTime is called
        by a character who's turn is up. Choosing to guard always invokes this.
       
        It's suppose to clear the window of the previous faces and then
        draw the faces that reflect the new turn order.
        */
        this.refresh()
       
        // This is suppose to prevent unecessary redrawing.
        ChargeTracker._hasUpdatedCharge = false
    };
};

Refresh and Redraw. I probably could just have Redraw do its thing and then draw the faces and do away with refresh.
JavaScript:
TurnPriorityWindow.prototype.refresh = function() {
    this.redraw();
    this.drawFacesByTurn();
};

TurnPriorityWindow.prototype.redraw = function() {
    // property has the TP Window Rect stored to it.
    const TurnWindow = this._redrawWindow
    this.contents.clearRect(TurnWindow.x, TurnWindow.y,
                            TurnWindow.width, TurnWindow.height)
};

SortBattlersByChargeTime.

JavaScript:
TurnPriorityWindow.prototype.sortBattlersByChargeTime = function() {
    /* Order all actor faces by the current charge time of their respective
    actors. The charge time is actually the fill percentage of their turn
    bars. Order is from largest to smallest. Largest = actor nearing their turn.
    */
    const party = $gameParty.members();
   
    let sortByChargeTime = [];
   
    for (let i = 0; i < party.length; i++) {
       
        /* Sorting the party array directly will cause the order to be static(never changing)
        in the turn priority window for some reason.

        Add only actors who's turn progress bar is not 100%(otherwise they would be in the Active Actor Window).
        */
        if (party[i]._tpbState === "charging") {
            sortByChargeTime.push(party[i]);
           
        };
    };
    return sortByChargeTime.sort((a, b) => b._tpbChargeTime - a._tpbChargeTime);
   
   
};

DrawFaceByTurn
JavaScript:
// this is for actors in the Turn Priority Window.
TurnPriorityWindow.prototype.drawFacesByTurn = function() {
    const actors = this.sortBattlersByChargeTime();
   
    // this is the x position
    let pos = 0;
       
    for (let i = 0; i < actors.length; i++) {
        // faces are scaled down 24x24 (drawFace function had to be changed to allow this)
        this.drawFace(actors[i].faceName(), actors[i].faceIndex(), pos, 0, 144, 144, 24, 24);
        pos += 24
    };
   
       
};

I am almost certain it has to do with the way all the faces are being drawn, but I don't know another way of displaying them the way I want.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,659
Reaction score
2,750
First Language
EN
Primarily Uses
RMMZ
If it's not clearing, maybe check this part:
JavaScript:
TurnPriorityWindow.prototype.redraw = function() {
    // property has the TP Window Rect stored to it.
    const TurnWindow = this._redrawWindow
    this.contents.clearRect(TurnWindow.x, TurnWindow.y,
                            TurnWindow.width, TurnWindow.height)
};
What's the value of this._redrawWindow? Where is it set? Are you sure it's using internal/window coordinates rather than external/screen coordinates?
 

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
181
Reaction score
296
First Language
English
Primarily Uses
RMMZ
That is set in the initializer.
JavaScript:
TurnPriorityWindow.prototype.initialize = function(rect) {
    Window_Base.prototype.initialize.call(this, rect)
   
    this._redrawWindow = rect
    this._opening = true
    this._closing = false
    this._drawOnce = false
};
There has to be a reason why I do that as I've done that in all my past scripts before I took that long break, but past me didn't leave an explanation for that. Seems like I was thinking since there's only ever gonna be one window created, just store it and use it where needed.

I'm not sure how to answer your question as I thought there was just one set of coordinates.
The console reports this(sorry, I can't seem to copy paste the entire sheet from the console, feel free to ask for any info that might seem relevant);

  1. redrawWindow: Rectangle
    1. bottom: (...)
    2. height: 48
    3. left: (...)
    4. right: (...)
    5. top: (...)
    6. type: 1
    7. width: 220
    8. x: 62
    9. y: 0
 

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
181
Reaction score
296
First Language
English
Primarily Uses
RMMZ
I have discovered the problem and the fact that the Active Actor Window doesn't have this problem lead me in direction of the culprit:

drawFacesByTurn is constantly running.

It's supposed to draw the new faces once and only once, when someone's turn has been established. When it's charging time, the rect needs to be cleared so that it can display the new turn order of faces.

With it constantely running (including the sorting method that it calls), it doesn't matter if redraw is called. drawActiveFace is called only once per turn, so it's redraw method is given time to clear the rect.

In my tests I've learned I could just use onTbpCharged and not updateTpbChargeTime. i also don't need an initial drawing of the faces before the Fight/Escape menu appears. Cutting down all the unecessary steps will make this as fluid as intended.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,659
Reaction score
2,750
First Language
EN
Primarily Uses
RMMZ
Great! However, I think that _redrawRect might be incorrect:
  • The window initializes with a rectangle describing the window's position in the scene, i.e. "external" coordinates. In this coordinate system, (0, 0) is the top-left corner of the game screen.

  • this.contents, the bitmap being cleared, is a child of a game window. This means its position is defined in terms of its parent. You can confirm this via the console, e.g. here's an example of checking the contents coordinates for the title scene's command window:

    console.table(SceneManager._scene._commandWindow.contents.rect);
    Therefore "internal" coordinates should be used for clearRect, i.e. use (0, 0) for the top-left of the bitmap.
If you want to clear the entire bitmap, there's a Bitmap#clear method (rmmz_core.js). E.g.
JavaScript:
TurnPriorityWindow.prototype.redraw = function() {
    this.contents.clear();
};
 

Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
181
Reaction score
296
First Language
English
Primarily Uses
RMMZ
You are correct and that also explains why the Active Actor Window clears as expected because it is at 0,0 by default but the Turn Priority Window is 62, 0. Though I didn't come back to this thread until today and..didn't realize the whole week had gone by. I was wrong in my last post obviously. I checked everything for days and just couldn't figure it out why it was happening. Thanks for the explanation and both methods work as expected now.
 

Latest Threads

Latest Profile Posts

Couldn't sleep at all so I started working on the topmost deck. I've had to make several deviations from the Imperator/Berengaria's deck-plans to accommodate MV's movement, but 100% accuracy was never my intention.
Still no name for the poor ship...:kaodes:
Screenshot-2022-06-25-053308.png
ScreenShot_6_24_2022_9_20_7.png
Here's Mike when you get a preemptive strike in battle. There's another one for when an enemy sneaks up on you too.
Suddenly, games mean nothing. The money spent was worth it to bring souls towards the light of life. May God bless my path forever. I pray that all are shaken for truth and poured out flat on the table of true understanding, knowledge, and wisdom. Bless you.
Finally I bought OMORI...cant wait to get traumatised!!!
Finished making this pretty ambitious forest map. Was wondering what y'all think of it! :kaopride:
1656136876015.png

Forum statistics

Threads
123,023
Messages
1,153,482
Members
161,367
Latest member
akuakudac
Top