Arctica

Veteran
Veteran
Joined
Jul 19, 2021
Messages
186
Reaction score
302
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,807
Reaction score
2,867
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
186
Reaction score
302
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
186
Reaction score
302
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,807
Reaction score
2,867
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
186
Reaction score
302
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 Posts

Latest Profile Posts

uOy9Wjc.png

Something something.
Dev be like: "I'll make the character goes amnesia so I could explain the world and the lore better and immersive to the players"
Whoever decided that the 5th area of Xenoblade 3 had to be THAT big and be explored in the manner it does needs to be shot. My OCD cannot leave a tiny shard of the map hidden and those controls can go right on and f*** themselves. -.-

/rant off
Raggon wrote on NoPatience's profile.
:kaohi:

Forum statistics

Threads
124,435
Messages
1,163,622
Members
163,247
Latest member
renice
Top