Action Sequence Rotation Extension

● ARCHIVED · READ-ONLY
Started by ATT_Turan 58 posts Page 1 of 3 View original ↗
  1. Action Sequence Rotation
    ATT_Turan

    Introduction
    This plugin adds a command to rotate battlers within action sequences. This allows them to tilt, spin, etc. Thanks to @SGHarlekin for the inspiration!

    I have tested the basic functionality, please let me know if you encounter any errors. I will consider making compatibility patches if the other plugin is free to use (or one I own, such as a Yanfly product) and unobfuscated. Otherwise, other authors are free to modify this code to make it compatible with theirs so long as I am still credited.

    rotate3.gif

    Features
    Code:
     *=============================================================================
     * ROTATE target: args
     * ----------------------------------------------------------------------------
     * ROTATE target: degrees, (direction), (frames)
     * ----------------------------------------------------------------------------
     *
     * Degrees is an integer value representing how many clockwise degrees to
     * rotate the sprite. Entering 0 from no rotation will do a circle.
     *
     * The direction argument can be RIGHT or LEFT, indicating a clockwise or
     * counterclockwise rotation. Omitting it defaults to clockwise (RIGHT).
     *
     * The frames argument is optional; omitting it will make the rotation
     * instantaneous.
     *
     * Example: rotate user: 90, right, 15

    Rotation is considered to be movement for the purposes of WAIT FOR MOVEMENT.

    How to Use
    This plugin is plug 'n' play. Install it below all Yanfly plugins in your plugin manager and you'll be able to use the above action sequence command.

    Please feel free to offer any suggestions for further target types you'd find useful.

    Terms and Credits
    Free for non-commercial and commercial use. Credit ATT_Turan.

    Plugin Code
    Code:
    //=============================================================================
    // Action Sequence Rotation
    // TUR_X_ActSeqRot.js
    //=============================================================================
    
    window.Imported = window.Imported || {};
    Imported.TUR_X_ActSeqRot = true;
    
    window.TUR = window.TUR || {};
    TUR.ActSeqRot = TUR.ActSeqRot || {};
    TUR.ActSeqRot.version = 1.3;
    
    /*:
     * @plugindesc Provides a rotate command for Yanfly's Action Sequences.
     * @author ATT_Turan
     * @url https://forums.rpgmakerweb.com/index.php?threads/action-sequence-rotation-extension.166579/
     * @version 1.3
     * @help
     * ============================================================================
     * Introduction
     * ============================================================================
     *
     * This plugin provides a command for rotating battlers to users of Yanfly's
     * Action Sequences plugins.
     *
     *=============================================================================
     *
     *=============================================================================
     * ROTATE target: args
     * ----------------------------------------------------------------------------
     * ROTATE target: degrees, (direction), (frames)
     * ----------------------------------------------------------------------------
     *
     * Degrees is an integer value representing how many clockwise degrees to
     * rotate the sprite. Entering 0 from no rotation will do a circle.
     *
     * The direction argument can be RIGHT or LEFT, indicating a clockwise or
     * counterclockwise rotation. Omitting it defaults to clockwise (RIGHT).
     *
     * The frames argument is optional; omitting it will make the rotation
     * instantaneous.
     *
     * ============================================================================
     * Changelog
     * ============================================================================
     *
     * Version 1.3:
     * - Fixed more facing and prevented users from breaking their sprites with bad
     *   timing.
     *
     * Version 1.2:
     * - Adjusted for facing commands
     *
     * Version 1.1:
     * - Corrected positioning issues
     *
     * Version 1.0:
     * - Release version
     *
     */
     
    if (Imported.YEP_BattleEngineCore)
    {
        TUR.processActionSequence = BattleManager.processActionSequence;
        BattleManager.processActionSequence = function(actionName, actionArgs)
        {
            if (actionName.match(/ROTATE[ ](.*)/i))
            {
                let string = String(RegExp.$1);
                if (this.makeActionTargets(string).length > 0)
                    return this.actionRotate(string, actionArgs);
            }
            return TUR.processActionSequence.call(this, actionName, actionArgs);
        };
     
        BattleManager.actionRotate = function(name, actionArgs)
        {
            let spinners = this.makeActionTargets(name);
    
            if (!spinners.length)
                return true;
    
            if (!spinners[0].battler()._mainSprite)
                return true;
    
            let degrees = Number(actionArgs[0]);
    
            if (isNaN(degrees) || degrees < 0)
                return true;
    
            let frames = 0;
        
            if (actionArgs[1] && isNaN(actionArgs[1]))
            {
                if (actionArgs[1].toUpperCase() == "LEFT")
                    spinners.forEach(spinner => spinner.battler()._mainSprite.rotateDir = "left");
                else if (actionArgs[1].toUpperCase() == "RIGHT")
                    spinners.forEach(spinner => spinner.battler()._mainSprite.rotateDir = "right");
                else
                    return true;
            
                frames = Number(actionArgs[2]) || 0;
            }
            else
            {
                spinners.forEach(spinner => spinner.battler()._mainSprite.rotateDir = "right");
                frames = Number(actionArgs[1]) || 0;
            }
    
            if (!frames)
                spinners.forEach(spinner => spinner.battler()._mainSprite.rotation = degrees * (Math.PI / 180));
            else
                spinners.forEach(spinner => {let sprite = spinner.battler()._mainSprite;
                    if (sprite.rotateTo == undefined)
                    {
                        sprite.rotateTo = degrees;
                        sprite.rotateFrames = frames;
                        sprite.oldPivot = sprite.pivot.y;
                        sprite.pivot.y = -sprite.height / 2;
                        sprite.y += sprite.pivot.y
                    }});
        
            return true;
        };
     
        Sprite_Base.prototype._refresh = function()
        {
            var frameX = Math.floor(this._frame.x);
            var frameY = Math.floor(this._frame.y);
            var frameW = Math.floor(this._frame.width);
            var frameH = Math.floor(this._frame.height);
            var bitmapW = this._bitmap ? this._bitmap.width : 0;
            var bitmapH = this._bitmap ? this._bitmap.height : 0;
            var realX = frameX.clamp(0, bitmapW);
            var realY = frameY.clamp(0, bitmapH);
            var realW = (frameW - realX + frameX).clamp(0, bitmapW - realX);
            var realH = (frameH - realY + frameY).clamp(0, bitmapH - realY);
    
            this._realFrame.x = realX;
            this._realFrame.y = realY;
            this._realFrame.width = realW;
            this._realFrame.height = realH;
            this.pivot.x = frameX - realX;
            if (this.rotateTo == undefined)
                this.pivot.y = frameY - realY;
    
            if (realW > 0 && realH > 0)
            {
                if (this._needsTint())
                {
                    this._createTinter(realW, realH);
                    this._executeTint(realX, realY, realW, realH);
                    this._tintTexture.update();
                    this.texture.baseTexture = this._tintTexture;
                    this.texture.frame = new Rectangle(0, 0, realW, realH);
                }
                else
                {
                    if (this._bitmap)
                        this.texture.baseTexture = this._bitmap.baseTexture;
                    this.texture.frame = this._realFrame;
                }
            }
            else if (this._bitmap)
                this.texture.frame = Rectangle.emptyRectangle;
            else
            {
                this.texture.baseTexture.width = Math.max(this.texture.baseTexture.width, this._frame.x + this._frame.width);
                this.texture.baseTexture.height = Math.max(this.texture.baseTexture.height, this._frame.y + this._frame.height);
                this.texture.frame = this._frame;
            }
            this.texture._updateID++;
        };
     
        Sprite_Battler.prototype.updateFloat = function()
        {
            if (!this._battler) return;
            if (this._floatDur > 0) this._floatDur--;
            if (this._jumpDur > 0) this._jumpDur--;
            var baseY = this._battler.anchorY();
            var floatHeight = this.getFloatHeight();
            var jumpHeight = this.getJumpHeight();
            var height = floatHeight + jumpHeight;
            if (this._mainSprite && this._mainSprite.bitmap)
            {
                var rate = this._battler.spriteHeight() / this._mainSprite.height;
                this._mainSprite.anchor.y = (baseY + height * rate);
                if (this._mainSprite.rotateTo != undefined)
                {
                    let oldPivot = this._mainSprite.pivot.y;
                    this._mainSprite.pivot.y = (0.5 - this._mainSprite.anchor.y) * this._mainSprite.height;
                    this._mainSprite.y += this._mainSprite.pivot.y - oldPivot;
                }
            this._weaponSprite.anchor.y = this._mainSprite.anchor.y;
            }
            else
                this.anchor.y = (baseY + height);
        };
     
        TUR.updateMove = Sprite_Battler.prototype.updateMove;
        Sprite_Battler.prototype.updateMove = function()
        {
            TUR.updateMove.call(this);
    
            if (this._mainSprite && this._mainSprite.rotateTo != undefined)
            {
                let sprite = this._mainSprite;
                sprite.rotateFrames--;
            
                if (sprite.rotateFrames <= 0)
                {
                    sprite.rotation = sprite.rotateTo * (Math.PI / 180);
    
                    sprite.y -= sprite.pivot.y;
                    sprite.pivot.y = sprite.oldPivot;
                    delete sprite.oldPivot;
                    delete sprite.rotateTo;
                    delete sprite.rotateFrames;
                }
                else
                {
                    let toDegrees = sprite.rotateTo;
                    let currDegrees = sprite.rotation * (180 / Math.PI);
                    if (sprite.rotateDir == "right" && this.scale.x >= 0 || sprite.rotateDir == "left" && this.scale.x < 0)
                    {
                        let degrees = toDegrees > currDegrees ? toDegrees - currDegrees : 360 + toDegrees - currDegrees;
                        degrees = Math.round(degrees / sprite.rotateFrames);
                        sprite.rotation += degrees * (Math.PI / 180);
                    }
                    else
                    {
                        let degrees = currDegrees > toDegrees ? currDegrees - toDegrees : 360 + toDegrees - currDegrees;
                        degrees = Math.round(degrees / sprite.rotateFrames);
                        sprite.rotation = ((currDegrees > 0 ? currDegrees : 360) - degrees) * (Math.PI / 180);
                    }
                }
            }
            else if (this._mainSprite && this._mainSprite.oldPivot != undefined)
            {
                this._mainSprite.y -= this._mainSprite.pivot.y;
                this._mainSprite.pivot.y = this._mainSprite.oldPivot;
                delete this._mainSprite.oldPivot;
            }
        };
     
        TUR.isMoving = Sprite_Battler.prototype.isMoving;
        Sprite_Battler.prototype.isMoving = function()
        {
            if (!TUR.isMoving.call(this))
                return !!this._mainSprite && this._mainSprite.oldPivot != undefined;
            else
                return true;
        };
    }
  2. Good work! Gonna report any bugs I may or may not find.
  3. Please, only report the bugs you do find :stickytongue:
  4. Where's the fun in that? I wouldn't put it past me to report some stuff that's totally my bad xD
  5. Just tried downloading it but curiously enough it's blocked by windows defender (browser is chrome). That's a first on this site so not sure why it does that. Would it be possible to put the code in a spoiler tag, or change the extension to txt?

    1709868197599.png

    Tested it with another of yours and this one downloaded normally, so perhaps there is something in the code that Defender does not like...?
  6. both edge and chrome block the download for me as well
  7. That's bizarre. I'll run it through a scan. I've removed the download until I check it out.

    I dunno, @werzaque.

    I scanned my whole system and the file individually, BitDefender says it's clean. I don't know why Windows Defender is flagging it when downloaded through specific browsers, but as far as I can see the file is safe.

    I've reattached the file to the original post and included the code in a spoiler for copy and paste.
  8. Wow, thanks @ATT_Turan! This looks really cool and I'm looking forward to testing this out when I'm back at my PC.

    The main plugin I want to find out if it works with this is Yami Sideview Enhancement: More Frames. I'm curious if / how the extra frames will mess up the rotation.

    If it works though with it, the timing is great.
  9. @PersistentDreamerGames Rotating doesn't interact with motions at all, so anything that has to do with frames/cels should function normally. But, of course, I haven't tried.
  10. Updated with some fixes for positioning and to accommodate action sequence facing commands.
  11. I might try, but rather than reporting the bugs, is throwing bugs at you allowed too?
  12. @ShadowDragon You can try, but I can't write code to fix things if I have beetle juice in my eyes.
  13. Made a little test skill with the plugin. Think it looks pretty dope for a test :D


    This is just a little showcase how well this extension works, so everybody go and grab it and get on making some dope skills!
  14. that looks really sick @SGHarlekin keep it up.

  15. Another skill using this extension. This time, no beyblade.
    Grab it grab it grab it.
    :D
  16. Updated to correct the placement of animations when the battler is moving and jumping and rotating.

    For the action sequencer who needs to do all the things!
  17. I wish, nay demand the Beyblade-strike to be included as end-game content!
  18. As always, it doesn't work for me. I put it in the skill notes, but nothing happens, what am I doing wrong?

    Skill Notes:

    <setup action>
    clear battle log
    display action
    immortal: targets, true
    </setup action>

    <whole action>
    perform start
    motion standby: user
    wait for movement
    face user: target
    </whole action>

    <target action>
    move type: user, InOutBack
    move type: target, OutBounce
    ROTATE target: 0, (LEFT)
    motion attack: user
    wait: 10
    attack animation: target
    wait: 10
    action effect
    wait: 10
    </target action>



    <follow action>
    wait for animation
    </follow action>
  19. I use MZ so sorry if I’m saying something irrelevant, but isn’t LEFT supposed to be without parentheses?
  20. Lionheart_84 said:
    ROTATE target: 0, (LEFT)
    werzaque said:
    isn’t LEFT supposed to be without parentheses?
    That's correct. The parentheses are to match the style of all of Yanfly's action sequence instructions, indicating an optional argument.

    They are not to be typed.