MZ - I need help with UP/Down Diagonal Slopes

● ARCHIVED · READ-ONLY
Started by GustoSerpe 14 posts View original ↗
  1. RMMZ

    So, I'm using the plugin "Cae_SlopeMove" to have forced diagonal movement in certain parts of my game. This plugin seems to have been designed with the idea of slopes or stairs in mind, and makes the player move diagonally down or up when moving left/right, based on region IDs. It's great. This plugin works exactly how I need it to when the player is moving left or right, but I wanted to have this same effect while moving up and down too. Is there a way to edit the code of this plugin to have the effect expanded?

    Link to Caethyril's plugin list

    Link to the plugin in question
  2. It would make the most sense to actually ask your question in the plugin's thread that you linked to - that way the author will see it.
  3. ATT_Turan said:
    It would make the most sense to actually ask your question in the plugin's thread that you linked to - that way the author wil
    Right, it's my first time actually posting something in here, I didn't even know I could do that. Thanks
  4. (Another option is to write the author's username with an @ in front, e.g. @GustoSerpe. That sends them a notification that they've been mentioned, unless they've disabled that in account settings.)

    Since you already have a thread, I'll respond here. :kaohi:

    It should be possible to write such an extension (maybe just edits of getSlopeNext, isSlopeMove, and getYMove?). It is set up as-is to account for wide slopes. E.g. how do you want the character to move in these situations?
    1. Move ↑ on an "up" slope;
    2. Move ↑ on a "down" slope.
    Edit - actually, let me rephrase that: do you want it to convert ↕ moves to diagonal slope moves only when the normal up/down movement would be blocked, or always?
  5. caethyril said:
    (Another option is to write the author's username with an @ in front, e.g. @GustoSerpe. That sends them a notification that they've been mentioned, unless they've disabled that in account settings.)

    Since you already have a thread, I'll respond here. :kaohi:

    It should be possible to write such an extension (maybe just edits of getSlopeNext, isSlopeMove, and getYMove?). It is set up as-is to account for wide slopes. E.g. how do you want the character to move in these situations?
    1. Move ↑ on an "up" slope;
    2. Move ↑ on a "down" slope.
    Edit - actually, let me rephrase that: do you want it to convert ↕ moves to diagonal slope moves only when the normal up/down movement would be blocked, or always?
    Thanks for responding and for the tips!

    I hadn't thought of changing to diagonal moves only when movement is blocked, but actually that would be much better for my intended use. Both for up/down movements and for left/right movements. My idea is to "course correct" the player movement when walking straight towards a diagonal wall. So, forcing the diagonal movement only when the normal movement is blocked would be optimal.

    I’m a noob with javascript, so I’m not sure but, would it be possible to do this with some edits to your plugin?
  6. I haven't had a chance to test this, so it may not work, but in case you want to try:
    plugin code
    JavaScript:
    /*:
     * @target MZ
     * @plugindesc Patch for Cae_SlopeMove - blocked up/down moves can go up/down slopes.
     * @author Caethyril
     * @url https://forums.rpgmakerweb.com/threads/165597/
     * @base Cae_SlopeMove
     * @orderAfter Cae_SlopeMove
     * @help Free to use and/or modify for any project, no credit required.
     */
    
    // Override - allow up/down to be slope moves as well.
    CAE.SlopeMove.isSlopeMove = function(d, m) {
      return m !== 0 && d % 2 === 0;
    };
    
    // Override - get X-offset for slope move.
    CAE.SlopeMove.getXMove = function(d, m) {
      switch (d) {
        case 1: case 2: case 3:
          return m > 0 ? 4 : 6;
        case 7: case 8: case 9:
          return m < 0 ? 4 : 6;
      }
      return 0;
    };
    
    // Override - rewrite because now we can receive directions 2 & 8.
    CAE.SlopeMove.getYMove = function(d, m) {
      switch (d) {
        case 1: case 4: case 7:
          return m > 0 ? 2 : 8;
        case 3: case 6: case 9:
          return m < 0 ? 2 : 8;
      }
      return 0;
    };
    
    // Override - also offset target X if appropriate.
    Game_CharacterBase.prototype.getSlopeNext = function(d, m) {
      const dx = this.canPass(this.x, this.y, d) ? d : CAE.SlopeMove.getXMove(d, m);
      const dy = CAE.SlopeMove.getYMove(d, m);
      return {
        x: $gameMap.roundXWithDirection(this.x, dx),
        y: $gameMap.roundYWithDirection(this.y, dy)
      };
    };
    This should be saved as a .js file (Save As -> File Type: All Files, Filename: anything.js), then imported as a plugin, placed below (i.e. after) Cae_SlopeMove in the Plugin Manager list.
  7. caethyril said:
    I haven't had a chance to test this, so it may not work, but in case you want to try:
    plugin code
    JavaScript:
    /*:
     * @target MZ
     * @plugindesc Patch for Cae_SlopeMove - blocked up/down moves can go up/down slopes.
     * @author Caethyril
     * @url https://forums.rpgmakerweb.com/threads/165597/
     * @base Cae_SlopeMove
     * @orderAfter Cae_SlopeMove
     * @help Free to use and/or modify for any project, no credit required.
     */
    
    // Override - allow up/down to be slope moves as well.
    CAE.SlopeMove.isSlopeMove = function(d, m) {
      return m !== 0 && d % 2 === 0;
    };
    
    // Override - get X-offset for slope move.
    CAE.SlopeMove.getXMove = function(d, m) {
      switch (d) {
        case 1: case 2: case 3:
          return m > 0 ? 4 : 6;
        case 7: case 8: case 9:
          return m < 0 ? 4 : 6;
      }
      return 0;
    };
    
    // Override - rewrite because now we can receive directions 2 & 8.
    CAE.SlopeMove.getYMove = function(d, m) {
      switch (d) {
        case 1: case 4: case 7:
          return m > 0 ? 2 : 8;
        case 3: case 6: case 9:
          return m < 0 ? 2 : 8;
      }
      return 0;
    };
    
    // Override - also offset target X if appropriate.
    Game_CharacterBase.prototype.getSlopeNext = function(d, m) {
      const dx = this.canPass(this.x, this.y, d) ? d : CAE.SlopeMove.getXMove(d, m);
      const dy = CAE.SlopeMove.getYMove(d, m);
      return {
        x: $gameMap.roundXWithDirection(this.x, dx),
        y: $gameMap.roundYWithDirection(this.y, dy)
      };
    };
    This should be saved as a .js file (Save As -> File Type: All Files, Filename: anything.js), then imported as a plugin, placed below (i.e. after) Cae_SlopeMove in the Plugin Manager list.
    I've just tried it, and sadly it didn't work. All it did was forbid up/down movement while on the "slope" region.
  8. :kaoslp: Yep, I must be missing something. I tried a few things but can't seem to figure it out at the moment. I'll let you know if/when I find a working solution~
  9. caethyril said:
    :kaoslp: Yep, I must be missing something. I tried a few things but can't seem to figure it out at the moment. I'll let you know if/when I find a working solution~
    No worries! Ideally, I'd like to be able to have some regions in the game where I use your original plugin for stairs and slopes, as well as regions with this version of left/right/up/down that forces diagonals only when regular movement is blocked, for diagonal walls and such.

    Anyway, thanks so much for taking the time to even try this out and help me! I appreciate it a lot!
  10. GustoSerpe said:
    regions with this version of left/right/up/down that forces diagonals only when regular movement is blocked, for diagonal walls and such.
    Wait, do you want this kind of thing everywhere, even when not on a slope? E.g. triacontane's HalfMove plugin has an Avoid Corner parameter for that:
    I haven't tested it with Cae_SlopeMove, though. There may be other, similar plugins available.
  11. caethyril said:
    Wait, do you want this kind of thing everywhere, even when not on a slope? E.g. triacontane's HalfMove plugin has an Avoid Corner parameter for that:
    I haven't tested it with Cae_SlopeMove, though. There may be other, similar plugins available.
    I’ve just tried it now. This plugin can actually be used to implement what I want, with the special collision regions it provides. It seems like it would be a perfect solution, but it’s clashing with other plugins I’m using and fully crashing the game.

    r88_ProximitySensor, VisuMZ_1_EventsMoveCore, and EliMZ_ButtonCommonEvents all stop working with Halfmove.
  12. Ah, OK. HalfMove does a lot of other things, so I'm not surprised it conflicts. I was mostly just asking to see if that's the kind of thing you wanted, since Cae_SlopeMove is for something a bit different.

    You could try this as a standalone plugin (save as a .js file, import as a plugin):
    plugin code
    JavaScript:
    /*:
     * @target MZ
     * @plugindesc Attempting to walk onto a marked tile makes you move diagonally.
     * @author Caethyril
     * @url https://forums.rpgmakerweb.com/threads/165597/
     * @help Edit the marked tile region ID and/or terrain tag in the plugin code.
     *
     * Free to use and/or modify for any project, no credit required.
     */
    void (() => {
    'use strict';
    
        /**
         * Region ID for "marked" tiles.
         * If `0`, region ID will not be checked.
         */
        const REGION_ID = 1;
    
        /**
         * Terrain tag for "marked" tiles.
         * If `0`, terrain tag will not be checked.
         */
        const TERRAIN_TAG = 0;
    
        /**
         * @param {number} x
         * Map tile coordinate X.
         * @param {number} y
         * Map tile coordinate Y.
         * @returns {boolean}
         * `true` iff map tile at given coordinates is "marked".
         */
        const isMarkedTile = function(x, y) {
            return (REGION_ID   && $gameMap.regionId(x, y)   === REGION_ID  )
                || (TERRAIN_TAG && $gameMap.terrainTag(x, y) === TERRAIN_TAG);
        };
    
        /**
         * @param {function} f
         * Function checking diagonal passability: `(dx, dy) => true|false`.
         * @param {number} d
         * Numpad direction of predicted arrival into marked tile.
         * @returns {[dx:number,dy:number]}
         * Valid diagonal move numpad directions (horz, vert), or `[0, 0]`.
         */
        const getDirection = function(f, d) {
            switch (d) {
                case 2: case 8:
                    for (const dx of [4, 6])
                        if (f(dx, d))
                            return [dx, d];
                    break;
                case 4: case 6:
                    for (const dy of [2, 8])
                        if (f(d, dy))
                            return [d, dy];
                    break;
            }
            return [0, 0];
        };
    
        // Patch - replace straight moves onto marked tiles with diagonals, where available.
        const alias = Game_Player.prototype.moveStraight;
        Game_Player.prototype.moveStraight = function(d) {
            const x = $gameMap.roundXWithDirection(this.x, d);
            const y = $gameMap.roundYWithDirection(this.y, d);
            if (isMarkedTile(x, y)) {
                const [dx, dy] = getDirection(
                    this.canPassDiagonally.bind(this, this.x, this.y), d
                );
                if (dx && dy)
                    this.moveDiagonally(dx, dy);
            } else
                alias.apply(this, arguments);
        };
    
    })();
    It's designed so that if the player tries to walk straight into a tile marked with the specified region ID or terrain tag, and there is a passable adjacent tile, they'll move to that tile instead.

    I haven't tested it with Cae_SlopeMove, but I think it should be compatible~
  13. caethyril said:
    Ah, OK. HalfMove does a lot of other things, so I'm not surprised it conflicts. I was mostly just asking to see if that's the kind of thing you wanted, since Cae_SlopeMove is for something a bit different.

    You could try this as a standalone plugin (save as a .js file, import as a plugin):
    plugin code
    JavaScript:
    /*:
     * @target MZ
     * @plugindesc Attempting to walk onto a marked tile makes you move diagonally.
     * @author Caethyril
     * @url https://forums.rpgmakerweb.com/threads/165597/
     * @help Edit the marked tile region ID and/or terrain tag in the plugin code.
     *
     * Free to use and/or modify for any project, no credit required.
     */
    void (() => {
    'use strict';
    
        /**
         * Region ID for "marked" tiles.
         * If `0`, region ID will not be checked.
         */
        const REGION_ID = 1;
    
        /**
         * Terrain tag for "marked" tiles.
         * If `0`, terrain tag will not be checked.
         */
        const TERRAIN_TAG = 0;
    
        /**
         * @param {number} x
         * Map tile coordinate X.
         * @param {number} y
         * Map tile coordinate Y.
         * @returns {boolean}
         * `true` iff map tile at given coordinates is "marked".
         */
        const isMarkedTile = function(x, y) {
            return (REGION_ID   && $gameMap.regionId(x, y)   === REGION_ID  )
                || (TERRAIN_TAG && $gameMap.terrainTag(x, y) === TERRAIN_TAG);
        };
    
        /**
         * @param {function} f
         * Function checking diagonal passability: `(dx, dy) => true|false`.
         * @param {number} d
         * Numpad direction of predicted arrival into marked tile.
         * @returns {[dx:number,dy:number]}
         * Valid diagonal move numpad directions (horz, vert), or `[0, 0]`.
         */
        const getDirection = function(f, d) {
            switch (d) {
                case 2: case 8:
                    for (const dx of [4, 6])
                        if (f(dx, d))
                            return [dx, d];
                    break;
                case 4: case 6:
                    for (const dy of [2, 8])
                        if (f(d, dy))
                            return [d, dy];
                    break;
            }
            return [0, 0];
        };
    
        // Patch - replace straight moves onto marked tiles with diagonals, where available.
        const alias = Game_Player.prototype.moveStraight;
        Game_Player.prototype.moveStraight = function(d) {
            const x = $gameMap.roundXWithDirection(this.x, d);
            const y = $gameMap.roundYWithDirection(this.y, d);
            if (isMarkedTile(x, y)) {
                const [dx, dy] = getDirection(
                    this.canPassDiagonally.bind(this, this.x, this.y), d
                );
                if (dx && dy)
                    this.moveDiagonally(dx, dy);
            } else
                alias.apply(this, arguments);
        };
    
    })();
    It's designed so that if the player tries to walk straight into a tile marked with the specified region ID or terrain tag, and there is a passable adjacent tile, they'll move to that tile instead.

    I haven't tested it with Cae_SlopeMove, but I think it should be compatible~
    You're amazing! I can easly get the effect I want now, thanks a lot!
  14. Great, happy RPG Making! :kaohi: