MV - Chrono Engine Bug/Softlock on Victory

● ARCHIVED · READ-ONLY
Started by Slaughty 30 posts Page 2 of 2 View original ↗
  1. roger that. I'm at the house now due to a huge storm that just rolled through so I may sit down here in a little while and tinker with it before I crash out and see if I can't get something working. Let me know if ya find something @bass2yang. @Slaughty roger, just making sure it'd do it just purely based on the scope of the skill alone. That still begs the question why its only the scope of ally that causes it. I may see if I can look into that side first and see if I can determine what the root cause is. Ideally we'd make whatever process we can cobble together work dynamically so it won't matter where in the party the actor is. It'd just act like the default function should and iterate through each battler and essentially hit em with an to forceClearBaseParameters() to cancel any outstanding actions.
    Update: So searching for the root cause hasn't turned up anything as of yet but I'm tired so focus is kind of wavering here. Haven't solved it yet. Power isnt stable here at the moment due to the storm. We'll have to look elsewhere than applyCN. Here's the logic I used
    JavaScript:
    //==============================
    // * apply CN
    //==============================
    Game_Action.prototype.applyCN = function(target, coopUsers) {
        if (Imported.MOG_BossHP) {
            if (target.isEnemy() && target._bosshp_meter) {
                $gameTemp._battler_bhp_temp[1] = target.hp;
                $gameTemp._battler_bhp_temp[3] = 0;
            }
        }
        if (Imported.MOG_Chrono_EnemyHP) {
            $gameTemp._chronoEnemyHP[4] = target.hp;
        }
    
        var oldhp = target.hp;
        var oldmp = target.mp;
        var result = target.result();
        this.subject().clearResult();
        result.clear();
        result.used = this.testApply(target);
        result.missed = (result.used && Math.random() >= this.itemHit(target));
        result.evaded = (!result.missed && Math.random() < this.itemEva(target));
        result.physical = this.isPhysical();
        result.drain = this.isDrain();
        if (result.isHitCR()) {
            if (this.item().damage.type > 0) {
                result.critical = (Math.random() < this.itemCri(target));
                if (coopUsers.length > 0) {
                    var value = 0;
                    for (var i = 0; i < coopUsers.length; i++) {
                        var subject = coopUsers[i].battler();
                        value += this.makeDamageValueCN(target, result.critical, subject);
                    }
                    var realValue = Math.floor(value / coopUsers.length)
                    value = realValue;
                } else {
                    var value = this.makeDamageValue(target, result.critical);
                }
                 // Checking if new HP after value is returned is less than or equal to 0
                if (target.hp <= 0) {
                    // Call custom function to get alive enemies. Not sure who the author is. Flintx's brother maybe?
                    var aliveEnemies = Game_Chrono.prototype.getAliveEnemies();
                    // peeking at the array length for expected value
                    console.log("Number of alive enemies: " + aliveEnemies.length);
                   
                    // Checking if the last enemy is going to die.
                    if (aliveEnemies.length < 1) {
                        const bat1 = $gameMap.players()[0].battler();
                        bat1.action = null;
                        bat1.clearRasCast();
                        const bat2 = $gameMap.players()[1].battler();
                        bat2.action = null;
                        bat2.clearRasCast();
                        const bat3 = $gameMap.players()[2].battler();
                        bat3.action = null;
                        bat3.clearRasCast();
                        const bat4 = $gameMap.players()[3].battler();
                        bat4.action = null;
                        bat4.clearRasCast();
                        console.log("Purging actions from battlers");
                       
                    }
                }
                this.executeDamageCN(target, value);
    
            }
            this.item().effects.forEach(function(effect) {
                this.applyItemEffect(target, effect);
            }, this);
            this.applyItemUserEffect(target);
            this.afterApplyCN(target, result, oldhp, oldmp);
        }
    
        // Get new HP value after damage calculation
        var newHP = target.hp;
        console.log("New HP value: " + newHP);
    };

    commented lines are those I added in. The logic is sound but it doesn't rectify the problem. It also turns out the function I saw for obtaining an array populated to know how many enemies are left alive is custom in the version I obtained in flintx's thread. It returns correctly so it does do as advertised, here is the function
    JavaScript:
    Game_Chrono.prototype.getAliveEnemies = function() {
        const enemies = [];
        for (var i = 0; i < $gameMap.enemiesF().length; i++) {
             var battler = $gameMap.enemiesF()[i].battler();
             if (!battler.isDead()) {
                enemies.push(battler);
             };
        };
        return enemies;
    };

    it appears underneath isAllEnemiesDead function and before Game_Chrono.prototype.update.

    was hoping someone else could test this as I don't have a base version of chrono engine at the moment readily accessible, just my modified one which has also been extended in other areas significantly past what flintx and restart had done. If this doesn't work on base we have 2 options, take a step back in the chain and try and force the same approach there or search out the root cause. I'm gonna hit the sack for the night and I'll mess with it some more tomorrow and see what if I can find a thread to pull or something lol. @bass2yang since you said it worked when moving to the target my next step will probably be falling back in the logic chain and seeing if there's a way to approach predicting the enemy's demise there. anyhoo night to yall!

    edit: I used the straight forward attack you did bass in this before attempting to iterate through each battler to force the reset for testing purposes. When its all said and done I'd rather iterate through an array though.
  2. CHRONO FAM... THIS IS SOLVED! (further testing needed)

    Edited to include issue of enemies charging and allies losing the battle:

    JavaScript:
    Game_Chrono.prototype.checkBattleResult = function() {
        var clearParameters = false
        if (this.isAllPartyDead()) {    
            // Clear out all skills that are hanging over
            $gameMap.enemiesF().forEach(x=>{
                x.battler()._chrono.action = null;
                x.battler().clearRasCast();
            });
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
            // Move the phase change to the bottom so that all things can clear out
            $gameSystem._chronoMode.phase = 6;
        } else if (this.isAllEnemiesDead()) {
            // Clear out all skills that are hanging over
            $gameMap.players().forEach(x=>{
                x.battler()._chrono.action = null;
                x.battler().clearRasCast();
            });
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
            // Move the phase change to the bottom so that all things can clear out
            $gameSystem._chronoMode.phase = 4;
        };
        if (clearParameters) {this.forceClearBaseParameters()}
    };
    This is the code you need. I thought it was weird why I was never able to get the timing so I framed everything up and noticed that it was out of phase... immediately. I pretty much forced the system to walk through the battle phase (phase 3) during the softlock and noticed that it resumed and completed the skill which removed the softlock.

    Then I remembered that the code, even though it all executes at the same time, still has a phase duration as written by the chrono mode. Using that, I was able to re-channel the phase change which was preventing the enemy from fully "dying" and the skill from fully "resetting."

    The phase change needs to occur after the clearance of skills. What was happening was that they were both going on at the same time. Checking for dead enemies needed more time/space to clear and the phase change was too abrupt.

    This should be fixed and should not be limited to any casting skill. Please test thoroughly.

    Thanks!
  3. bass2yang said:
    CHRONO FAM... THIS IS SOLVED! (further testing needed)


    JavaScript:
    Game_Chrono.prototype.checkBattleResult = function() {
        var clearParameters = false
        if (this.isAllPartyDead()) {
            $gameSystem._chronoMode.phase = 6;
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
        } else if (this.isAllEnemiesDead()) {
            // Clear out all skills that are hanging over
            $gameMap.players().forEach(x=>{
                x.battler()._chrono.action = null;
                x.battler().clearRasCast();
            })
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
            // Move the phase change to the bottom so that all things can clear out
            $gameSystem._chronoMode.phase = 4;
        };
        if (clearParameters) {this.forceClearBaseParameters()}
    };
    This is the code you need. I thought it was weird why I was never able to get the timing so I framed everything up and noticed that it was out of phase... immediately. I pretty much forced the system to walk through the battle phase (phase 3) during the softlock and noticed that it resumed and completed the skill which removed the softlock.

    Then I remembered that the code, even though it all executes at the same time, still has a phase duration as written by the chrono mode. Using that, I was able to re-channel the phase change which was preventing the enemy from fully "dying" and the skill from fully "resetting."

    The phase change needs to occur after the clearance of skills. What was happening was that they were both going on at the same time. Checking for dead enemies needed more time/space to clear and the phase change was too abrupt.

    This should be fixed and should not be limited to any casting skill. Please test thoroughly.

    Thanks!

    Edit - if your enemies are also charging and casting and your entire party loses, you may want to do something about isAllPartyDead and phase 6... just in case. haha.
    Lol ignore my comment then. Glad this one is bagged.

    Edit: strange, the forum shows you posted 52 minutes ago but I didnt see the post at all. On my end the posts are out of order as well. The one I posted a few minutes ago with what I had tried shows up before yours even thought there is a huge time difference between them

    Further edit: For those using flintx's version of the code yours will look something like this and this hopefully corrects for the other issue bass mentioned.
    JavaScript:
    Game_Chrono.prototype.checkBattleResult = function() {
        var clearParameters = false;
        if (this.isAllPartyDead()) {
            $gameMap.enemiesF().forEach(enemy => {
                enemy.battler()._chrono.action = null;
                enemy.battler().clearRasCast();
            });
    
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
            $gameSystem._chronoMode.phase = 6;
        } else if (this.isAllEnemiesDead()) {
            $gameMap.players().forEach(x=>{
                x.battler()._chrono.action = null;
                x.battler().clearRasCast();
            });
            this.clearCommandPhase();
            $gameSystem.clearChronoEscape();
            AudioManager.fadeOutBgm(3);
            $gameSystem._chronoMode.phaseDuration = 120;
            $gameSystem._chronoMode.phaseEndPhaseDuration = 120;
            clearParameters = true;
            $gameSystem._chronoMode.phase = 4;
            var eventFight = this.isEventFight();
            if (eventFight) {
                this.executeEventFightVictory();
            } else {
                this.executeThreatCleared();
            }var eventFight = this.isEventFight();
            if (eventFight) {
                this.executeEventFightVictory();
            } else {
                this.executeThreatCleared();
            }
        } else if ($gameSystem._chronoMode.phase !== 11) {
            if (this.isAnyBossDead()) {
                const minionsToKill = this.getMinionsToKill();
                if (minionsToKill.length > 0) {
                    this.clearCommandPhase();
                    this.executeKillMinions(minionsToKill);
                    clearParameters = true;
                }
            }
        }
        if (clearParameters) {
            this.forceClearBaseParameters();
        }
    };

    Kudo's again bass to figuring that one out. If you ever have time I'd like to hear more about where you mentioned forcing the system through each of the phases. As I've mentioned before I'm rather new to all this and I figure just seeing how you went about that process would lend a lot of insight. Anyway's it's off to bed with me, g'nite folks that are probably already asleep like normal people lol
  4. kalian19 said:
    Kudo's again bass to figuring that one out. If you ever have time I'd like to hear more about where you mentioned forcing the system through each of the phases. As I've mentioned before I'm rather new to all this and I figure just seeing how you went about that process would lend a lot of insight. Anyway's it's off to bed with me, g'nite folks that are probably already asleep like normal people lol
    Thank you - all you need is the console log and use the game system chrono mode phase code during battle to cycle through each part of the turn (similar to turn start, select action, battle, check for win/lose/escape, etc.)
    JavaScript:
    $gameSystem._chronoMode.phase = 3
    Go through all the phases. I believe 3 is the actual battle phase which was what prevented the action nulling/clearing from happening since the moment all enemies die, the phase also immediately goes to 4, locking you out of ever completing/canceling the skill properly.
  5. Aw you guys already solved it...

    How did I never catch this? Thanks, everyone.
  6. SundialShark said:
    Aw you guys already solved it...

    How did I never catch this? Thanks, everyone.
    Charging/casting time wasn't a part of my game mechanic so I never had an issue with the battle phase locking up. Glad it was an easy fix (took more time to find than anything).
  7. bass2yang said:
    Thank you - all you need is the console log and use the game system chrono mode phase code during battle to cycle through each part of the turn (similar to turn start, select action, battle, check for win/lose/escape, etc.)
    JavaScript:
    $gameSystem._chronoMode.phase = 3
    Go through all the phases. I believe 3 is the actual battle phase which was what prevented the action nulling/clearing from happening since the moment all enemies die, the phase also immediately goes to 4, locking you out of ever completing/canceling the skill properly.
    Roger that, and appreciate the info. Glad the root issue was found because I was not looking forward to trying what I was going to try and then still hitting a brick wall lol. Welp, I'm off to cut up trees the storm knocked down in my yard last night. Have a good one!
  8. Wow! Wow! Wow! Thanks so much! Y'all are my heroes! I've only done initial testing so far but it seems to have solved this. What a thing to wake up to!

    Kudos!
  9. Awesome. I'll make a note off this bug and link back to the codefix in my Chrono Engine thread.
  10. This thread is being closed due to being reported as solved. If you need it reopened, let us know. Thank you!