Yanfly Action Sequence - Frame Selection/Control?

Discussion in 'JS Plugin Requests' started by AsuranFish, May 27, 2018.

  1. AsuranFish

    AsuranFish Veteran Veteran

    Messages:
    115
    Likes Received:
    83
    First Language:
    English
    If I was to put "motion swing: user" into an action sequence, the battler would go through a three frame motion to swing their sword
    Basically what I'm looking for is a way to control sideview battler motions beyond simply cycling through the standard three frames.

    Example:

    For one action sequence, I would like to have the following happen:

    1: The user draws their bow (motion missile: user, frame 1)
    2: The user readies their attack (motion missile: user, frame 2)
    3: The user stays in frame 2 for "x" number of frames, rather than immediately progressing to frame 3.
    4: The user fires their attack, completing the motion (motion missile: user, frame 3)

    The delay in step 3 would allow for some pretty neat stuff to occur, such as an animation on the weapon, sound effects of the bowstring being pulled back, animations on the target illustrating that the user is carefully lining up their attack (think crosshairs, etc).

    There's plenty of other possibilities, such as cleave abilities, defensive stances, poses, and so on.

    Ideally, this would work as an extension to Yanfly's action sequence system, and would allow users to:

    1: start a motion from a specific frame
    2: hold a motion on a specific image for X frames
    3: ensure the weapon remains visible during the "hold", if the motion is either "thrust", "swing", or "missile"

    The image below illustrates an example of a pose I would like to be able to hold a character in for several frames.

    ranged.png


    If anyone is able to accomplish this - I'd greatly appreciate it! :)
     
    #1
    Kike, alcreator440 and Sauteed_Onion like this.
  2. Sauteed_Onion

    Sauteed_Onion Mmm Tasty Veteran

    Messages:
    554
    Likes Received:
    3,660
    Location:
    Perhaps on a steak or cheeseburger
    First Language:
    English
    Primarily Uses:
    RMMV
    Sorry to derail, but I love that battle back meow.
     
    #2
  3. AsuranFish

    AsuranFish Veteran Veteran

    Messages:
    115
    Likes Received:
    83
    First Language:
    English
    It's actually part of the default graphics, but I adjusted the brightness/hue/contrast, to make it darker and more cave-like.
     
    #3
    Sauteed_Onion likes this.
  4. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    This sparked my interest so I gave it a quick look and came up with something.
    Paste this in a .js file name it whatever and import it in your projet.

    Code:
    (function() {
    Sprite_Actor.prototype.updateMotionCount = function() {
        if (this._motion && ++this._motionCount >= this.motionSpeed()) {
            if (this.hasOwnProperty("_maxPattern") && this._pattern === this._maxPattern) {this.refreshMotion(); return}
            if (this._motion.loop) {
                this._pattern = (this._pattern + 1) % 4;
            } else if (this._pattern < 2) {
                this._pattern++;
            } else {
                this.refreshMotion();
            }
            this._motionCount = 0;
        }
    };
    
    var alias2 = Sprite_Weapon.prototype.updatePattern
    Sprite_Weapon.prototype.updatePattern = function() {
        if (this.parent.hasOwnProperty("_maxPattern") && this._pattern === this.parent._maxPattern) {return}
       alias2.call(this);
    };
    
    var alias = Sprite_Actor.prototype.refreshMotion
    Sprite_Actor.prototype.refreshMotion = function() {
        var actor = this._actor;
        if (actor) {
            if (this.hasOwnProperty("_maxPattern") && this._pattern === this._maxPattern) {return}
        }
        alias.call(this)
    }
    
    Sprite_Actor.prototype.setMaxFrame = function(num) {
        this._maxPattern = num;
    }
    
    Sprite_Actor.prototype.removeMaxFrame = function() {
        delete this._maxPattern
    }
    
    Sprite_Actor.prototype.setFrame = function(motion,num) {
        if (motion === "attack") {this._actor.performAttack()} else {this._actor.requestMotion(motion)}
       if (motion === "attack" && this.hasOwnProperty("_weaponSprite")) {
           var wpn = this._weaponSprite;
           wpn._pattern = num - 1;
           wpn._motionCount = 0;
           wpn.updatePattern();
       }
       this._pattern = num;
       this._motionCount = 0;
       this.setMaxFrame(num)
    }
    
    })()
    
    You can then do what you want by using the eval function of action sequences:
    Eval: user.battler().setMaxFrame(1)
    This will block the animation in the middle. Animations are 3 frames long: 1,2,3. A limit of 0 is the same as no limit.

    Eval: user.battler().removeMaxFrame()
    This will resume the animation.

    Full warning: this overrides the counting process and may create incompatibilities with other plugins that modify animation frames.

    Edit: it also may require 1.6.1 because that's the version I've been working with and I didn't check for others.
     
    Last edited: Jul 3, 2018
    #4
    CoryH, Critcap, caethyril and 2 others like this.
  5. AsuranFish

    AsuranFish Veteran Veteran

    Messages:
    115
    Likes Received:
    83
    First Language:
    English
    This works perfectly! Thanks so much! :)

    One rushed action sequence in, and I already love you.

    Edit: Wanted to add, this works fine for me in 1.5.2
     
    Last edited: May 29, 2018
    #5
    Sauteed_Onion likes this.
  6. Kenode

    Kenode Veteran Veteran

    Messages:
    66
    Likes Received:
    24
    First Language:
    Spanish
    Primarily Uses:
    RMMV
    I was looking at this script because I need a very similar function. However it seems that "Eval: user.battler().setMaxFrame(1)" locks the sprite on the second frame instead of the first. Is there a way to make it locked on the first frame? Because:
    Eval: user.battler().setMaxFrame(0) restores the motion
    Eval: user.battler().setMaxFrame(1) locks the sprite on the second frame
    Eval: user.battler().setMaxFrame(2) locks the sprite on the third frame
    Eval: user.battler().setMaxFrame(3) restores the motion

    I can't figure out how to lock the sprite on the first frame of the sprite animation.
     
    #6
  7. alcreator440

    alcreator440 Veteran Veteran

    Messages:
    199
    Likes Received:
    88
    First Language:
    English
    Primarily Uses:
    RMMV
    A potential work around for the first frame is to do this:
    motion attack: user
    wait: 7
    motion attack: user
    wait: 7
    etc.

    That's what I use and it gets the job done for now.
     
    #7
  8. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    Hmm I guess I missed that.
    I'll look into it soon when I have some time.
     
    #8
  9. Kenode

    Kenode Veteran Veteran

    Messages:
    66
    Likes Received:
    24
    First Language:
    Spanish
    Primarily Uses:
    RMMV
    I'll try that. It's a bit crude for whenever you have to do long waits, though, haha.

    Alright, thanks!
    [EDIT]: Forgot to mention, I left a message at Yanfly's Suggestion Box requesting manual frame control/calling. However I'm not sure how difficult would it be to add that feature to his plugins.
     
    #9
  10. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    I've updated my previous post with the correct code that fixes the above issue.

    This will now work like this:
    Frame limits:
    frame 0 first frame
    frame 3 last frame before resuming motion and after weapon disappears
    frame 4 same as no limit

    Enjoy, and happy making!

    For the curious I used a check to see if my max pattern property existed that incorrectly passed because if something is equal to 0 it evaluates as false so I had to use the "has own property" method instead.
     
    Last edited: Jul 2, 2018
    #10
    Kenode likes this.
  11. Kenode

    Kenode Veteran Veteran

    Messages:
    66
    Likes Received:
    24
    First Language:
    Spanish
    Primarily Uses:
    RMMV
    Sweet! I just gave it a short test and it works pretty well. Thank you!

    [EDIT] Forgot to ask, is there a way to also freeze the gun frame? Not sure if it could be me, though, since I am using:
    because Yanfly's "Weapon Animation" plugin won't let me use any motion in a skill other than the one set to the gun unless I do this.

    [EDIT (again)] Nevermind, it was me being a dummy. I had to move down your plugin. Now it freezes the weapon frame too and works exactly the way it's supposed to. Thank you again!
     
    Last edited: Jul 2, 2018
    #11
  12. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    Another small update to the above plugin:
    You can now request animation frames directly with this command:

    $gameActor.actor(id).battler().setFrame(motion,number);
    Ex: $gameActor.actor(id).battler().setFrame("attack", 1);

    This will make the sprite jump to that frame directly instead of playing all previous frames.

    List of motions: "attack", "missile", "thrust", "swing", "guard", "walk", "wait", "chant", "damage", "evade", "skill", "spell", "item", "escape", "victory", "dying", "abnormal", "sleep", "dead".
    Only "attack" will use the weapon sprite and it will choose depending on weapon type. If you use missile thrust or swing the weapon sprite will not appear.

    This should be all, barring any major bug, I will not be returning to this snippet.
    Take care, and happy making.
     
    #12
  13. AsuranFish

    AsuranFish Veteran Veteran

    Messages:
    115
    Likes Received:
    83
    First Language:
    English
    Quick question @Astfgl66 :

    I'm getting an error message using the newer version of your snippet - it apparently doesn't like line #42...

    Code:
    Uncaught SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    Here's the line in question:
    Code:
           let wpn = this._weaponSprite; 
    Is the "let" declaration not supported in 1.5.x, or could something else be causing this issue?


    Either way - the new snippet doesn't seem to work for me suddenly.
     
    #13
  14. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    I'll replace it with var for older version compatibilty. It's not really important in that case, I just used it for good practice.
    Replace the snippet, I fixed it.
     
    #14
  15. AsuranFish

    AsuranFish Veteran Veteran

    Messages:
    115
    Likes Received:
    83
    First Language:
    English
    Thank you so much! You’ve been so helpful!
     
    #15
  16. RK DracoRoy

    RK DracoRoy Fire Emblem RPG Gamer Veteran

    Messages:
    153
    Likes Received:
    20
    First Language:
    English
    Primarily Uses:
    RMMV
    @Astfgl66

    The script itself appears to make SV_Actors stay at Frame 1 of each motion they take in battle, and this was with no eval commands used at all.

    They will stay in Frame 1 of a motion indefinitely unless each actor uses a skill with this eval inserted in action sequence, making them finally abide by the frame count as usual.

    Code:
    eval: user.battler().removeMaxFrame()
    The whole plugin works as I expected it to, but this is the only glaring problem I have with it. Is there a possible fix to the plugin to make them abide by frame count in battle?

    ===========
    Update
    ===========
    I added a "this.removeMaxFrame()" that resolves this issue though partially.

    Code:
    Sprite_Actor.prototype.setFrame = function(motion,num) {
        if (motion === "attack") {this._actor.performAttack()} else {this._actor.requestMotion(motion)}
       if (motion === "attack" && this.hasOwnProperty("_weaponSprite")) {
           var wpn = this._weaponSprite;
           wpn._pattern = num - 1;
           wpn._motionCount = 0;
           wpn.updatePattern();
       }
       this._pattern = num;
       this._motionCount = 0;
       this.setMaxFrame(num)
       this.removeMaxFrame()
    }
    With the addition at the bottom, the issue is almost gone. However, the player actors will still unintentionally stay at Frame 1 only in the beginning of battle (much more noticeable when you have a Battle Event set at Turn 0 + 0).

    Wish there was a fix to this part of the issue, and then I'll be all set with the plugin that you made.
     
    Last edited: Nov 17, 2018
    #16
  17. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    I've never had any issues like that. I checked in an empty project with just my plugin and this didn't happen.
    The issue is probably a conflict with another plugin.
     
    #17
  18. RK DracoRoy

    RK DracoRoy Fire Emblem RPG Gamer Veteran

    Messages:
    153
    Likes Received:
    20
    First Language:
    English
    Primarily Uses:
    RMMV
    @Astfgl66

    I see what the problem is on my end, it's YEP_BattleEngineCore but mainly, I'm using MV 1.0.1 project files.

    And as I said, this no longer happens when I use a skill with the eval code I've mentioned above (unless I restart a battle in-game).

    http://yanfly.moe/2015/10/10/yep-3-battle-engine-core/

    I can only stay with that project version as it gives me the best in-game performance. Updating to 1.3.2 or higher will unfortunately cause significant in-game lag, due to that timestamp implemented.

    If a small workaround to this can be done, it'd be much appreciated. I understand otherwise.
     
    #18
  19. Astfgl66

    Astfgl66 Veteran Veteran

    Messages:
    661
    Likes Received:
    511
    First Language:
    French
    It's working with an up to date battle engine core on my end. And a whole set of yanfly plugins, except animated sv enemies and dragonbones, which I haven't tested.
    If the problem lies with compatibility with anterior versions of MV I'm afraid I can't help you. I don't even have the files needed to test with.
     
    #19
  20. RK DracoRoy

    RK DracoRoy Fire Emblem RPG Gamer Veteran

    Messages:
    153
    Likes Received:
    20
    First Language:
    English
    Primarily Uses:
    RMMV
    I do have the MV 1.0.1 files in this small demo I've tested it on. I can PM you the download link to it along with the plugin.
     
    #20

Share This Page