Disable Movement In A Direction

Discussion in 'RGSS3 Script Requests' started by DumbPomelo, Jun 19, 2019.

  1. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    I'm looking to enable/disable player's movement in a specific direction with a script call.
    But they should still be able to turn in that direction and interact with things. Just not move.

    So disabling the whole input, like this script here...
    Code:
    #==============================================================================
    #  @> Disable Move to Direction ~ Karin's Soulkeeper, 2015
    #------------------------------------------------------------------------------
    #   v1.0 - May 23 : Started & finished.
    #------------------------------------------------------------------------------
    #  * Description:
    #    This script disables movement in a specified direction.
    #------------------------------------------------------------------------------
    #  * To Use:
    #    Put this script below Materials and above Main.
    #
    #    To enable/disable a direction, perform the script call:
    #        enable_move(:SYMBOL)
    #        disable_move(:SYMBOL)
    #    ~ Where :SYMBOL is any of the symbols specified in the module below.
    #------------------------------------------------------------------------------
    #  * Compatibility:
    #    This script aliases Game_Player.move_by_input
    #------------------------------------------------------------------------------
    #  * Terms:
    #    Free to use in any kind of project, with or without credit. I wouldn't
    #    really mind. Though I'd appreciate it! (^w^)/
    #    Just don't, you know, claim that you made this here script yourself,
    #    Because that's just mean (._.)
    #==============================================================================
    
    #CUSTOMIZATION OPTIONS
    module KS
      module Disabled_Dirs
      #--------------------------------------------------------------------------
      # Set the symbol names and their corresponding direction.
      #--------------------------------------------------------------------------
      # - No need to change, unless if you have Diagonal Movement, or something.
      #--------------------------------------------------------------------------
      INPUT = {
         :DOWN  => 2,
         :LEFT  => 4,
         :RIGHT => 6,
         :UP    => 8
      }# FFS, DO NOT REMOVE
    
    # END OF CUSTOMIZATION OPTIONS
      Disabled = []
      end
    end
    
    #==============================================================================
    # ** Modified Class: Game_Interpreter
    #==============================================================================
    class Game_Interpreter
      #--------------------------------------------------------------------------
      # * New: Disable Direction
      #--------------------------------------------------------------------------
      def disable_move(dir)
        dir = KS::Disabled_Dirs::INPUT[dir]
        KS::Disabled_Dirs::Disabled.push(dir) unless KS::Disabled_Dirs::Disabled.include?(dir)
      end
    
      #--------------------------------------------------------------------------
      # * New: Enable Direction
      #--------------------------------------------------------------------------
      def enable_move(dir)
        dir = KS::Disabled_Dirs::INPUT[dir]
        KS::Disabled_Dirs::Disabled.delete(dir) if KS::Disabled_Dirs::Disabled.include?(dir)
      end
    end
    
    #==============================================================================
    # ** Aliased Class: Game_Player
    #==============================================================================
    class Game_Player < Game_Character
      #--------------------------------------------------------------------------
      # * Alias: Processing of Movement via Input from Directional Buttons
      #--------------------------------------------------------------------------
      alias move_by_input_orig move_by_input
      def move_by_input
        return if KS::Disabled_Dirs::Disabled.include?(Input.dir4)
        move_by_input_orig
      end
    end
    is not suitable.

    Also, I'm planning to use this to circumvent autotile's lack of directional passability, so if you know of any solutions to that specifically, that would also be helpful.
    Thanks.
     
    Last edited: Jun 19, 2019
    #1
  2. Bex

    Bex Veteran Veteran

    Messages:
    1,167
    Likes Received:
    259
    First Language:
    German
    Primarily Uses:
    RMMV
    Your Link gives me a Attack Warning when i click it in Firefox.
     
    #2
  3. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    Code:
    #==============================================================================
    #  @> Disable Move to Direction ~ Karin's Soulkeeper, 2015
    #------------------------------------------------------------------------------
    #   v1.0 - May 23 : Started & finished.
    #------------------------------------------------------------------------------
    #  * Description:
    #    This script disables movement in a specified direction.
    #------------------------------------------------------------------------------
    #  * To Use:
    #    Put this script below Materials and above Main.
    #
    #    To enable/disable a direction, perform the script call:
    #        enable_move(:SYMBOL)
    #        disable_move(:SYMBOL)
    #    ~ Where :SYMBOL is any of the symbols specified in the module below.
    #------------------------------------------------------------------------------
    #  * Compatibility:
    #    This script aliases Game_Player.move_by_input
    #------------------------------------------------------------------------------
    #  * Terms:
    #    Free to use in any kind of project, with or without credit. I wouldn't
    #    really mind. Though I'd appreciate it! (^w^)/
    #    Just don't, you know, claim that you made this here script yourself,
    #    Because that's just mean (._.)
    #==============================================================================
    
    #CUSTOMIZATION OPTIONS
    module KS
      module Disabled_Dirs
      #--------------------------------------------------------------------------
      # Set the symbol names and their corresponding direction.
      #--------------------------------------------------------------------------
      # - No need to change, unless if you have Diagonal Movement, or something.
      #--------------------------------------------------------------------------
      INPUT = {
         :DOWN  => 2,
         :LEFT  => 4,
         :RIGHT => 6,
         :UP    => 8
      }# FFS, DO NOT REMOVE
     
    # END OF CUSTOMIZATION OPTIONS
      Disabled = []
      end
    end
    
    #==============================================================================
    # ** Modified Class: Game_Interpreter
    #==============================================================================
    class Game_Interpreter
      #--------------------------------------------------------------------------
      # * New: Disable Direction
      #--------------------------------------------------------------------------
      def disable_move(dir)
        dir = KS::Disabled_Dirs::INPUT[dir]
        KS::Disabled_Dirs::Disabled.push(dir) unless KS::Disabled_Dirs::Disabled.include?(dir)
      end
     
      #--------------------------------------------------------------------------
      # * New: Enable Direction
      #--------------------------------------------------------------------------
      def enable_move(dir)
        dir = KS::Disabled_Dirs::INPUT[dir]
        KS::Disabled_Dirs::Disabled.delete(dir) if KS::Disabled_Dirs::Disabled.include?(dir)
      end
    end
    
    #==============================================================================
    # ** Aliased Class: Game_Player
    #==============================================================================
    class Game_Player < Game_Character
      #--------------------------------------------------------------------------
      # * Alias: Processing of Movement via Input from Directional Buttons
      #--------------------------------------------------------------------------
      alias move_by_input_orig move_by_input
      def move_by_input
        return if KS::Disabled_Dirs::Disabled.include?(Input.dir4)
        move_by_input_orig
      end
    end
     
    #3
  4. Bex

    Bex Veteran Veteran

    Messages:
    1,167
    Likes Received:
    259
    First Language:
    German
    Primarily Uses:
    RMMV
    Nice Script. Sadly if you need a extra Parallel Event to check for direction input to let a turn happen, than you could not use
    the Script and make a Parallel Event which contains these Eventcommands:
    ◆If:Button Left is pressed down
    ◆Set Movement Route:Player
    :Set Movement Route:◇Turn Left
    :Set Movement Route:◇Wait:4 frames

    :End
    Now you can turn left but you are not able to move into that direction. Or if you need it as Script i hope a Scripter drops by.
    Sorry iam not one of them.​
     
    #4
  5. Kes

    Kes Global Moderators Global Mod

    Messages:
    20,393
    Likes Received:
    10,410
    First Language:
    English
    Primarily Uses:
    RMVXA
    @DumbPomelo That site is also flagged up by Chrome and Vivaldi.
    I am, therefore, removing the link.
     
    #5
  6. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    I'll just slap the code there I guess
     
    #6
  7. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    Player can still move in that direction, albeit with some delays and after a few button presses.
    Ticking or unticking "wait for completion" didn't make a difference.

    I tried to do the same branch before, but with the script calls that would disable direction after the player had already turned. Didn't work.
    It seems that processing the input and setting player in motion happens before the parallel process can kick in.


    <edit>
    Sorry for double post I was going to merge them but I can't delete my own post it appears
     
    #7
  8. Bex

    Bex Veteran Veteran

    Messages:
    1,167
    Likes Received:
    259
    First Language:
    German
    Primarily Uses:
    RMMV
    Ah sorry i forgot that you use vxace and not mv^^ in vx ace eventpages were not executed every frame. Therfor if timing is wrong player still moved.
    But there is also a Solution for that, you can solve it this way:

    Parallell Event with this Code:
    Eventcommand Loop
    The Code from Above
    1Frame Wait
    Repeat Loop

    Now it works like i intended it to work. in mv i dont need this extra loop, in vx ace i used them all the time for zelda like gamestuff. I just forgot about it.
     
    #8
  9. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    Changing amount of frames to 1 didn't help, can still move after a few button presses or after holding and releasing it.
    ...But putting a loop inside of a parallel process actually just freezes the game!
    If the parallel process event is on the map, the game won't even load it. It freezes right on the black screen fadein.

    What am I doing wrong?
    upload_2019-6-19_19-33-51.png
     
    Last edited: Jun 20, 2019
    #9
  10. Bex

    Bex Veteran Veteran

    Messages:
    1,167
    Likes Received:
    259
    First Language:
    German
    Primarily Uses:
    RMMV
    You forgot the regular 1Frame Wait Event Command after the Conditional Branch. Without that we create a endless loop which freeze the game. thats why i wonder why you get the result you are describing.
    Edit:
    And in the Moveroute keep it 4Frames and dont change it to 1.
    Will test in VX-Ace and let you know if it works in praxis.

    Edit2: Tested it in a fresh Project, and its working fine on my end.
    noleftruntest.PNG
    I should have posted a Picture in the first place, my fault =).
     
    Last edited: Jun 20, 2019
    #10
  11. Heirukichi

    Heirukichi Veteran Veteran

    Messages:
    1,134
    Likes Received:
    420
    Location:
    Italy
    First Language:
    Italian
    Primarily Uses:
    RMVXA
    Code:
    module HRK_MDS
      module CONFIG
        #================================================================
        # Set the following value to be the ID of the variable where you want to store the blocked direction
        #================================================================
        DIRECTION_BLOCK_VARIABLE = 50
      end # end of CONFIG module
      def self.block_var_id
        CONFIG::DIRECTION_BLOCK_VARIABLE
      end
      def self.block_switch
        return false unless blocked_dir.is_a?(Array)
        blocked_dir.length > 0
      end
      def self.blocked_dir
        $game_variables[block_var_id]
      end
      def self.block_direction(dir)
        $game_variables[block_var_id] = [] unless blocked_dir.is_a?(Array)
        blocked_dir << dir unless blocked?(dir)
      end
      def self.remove_block(dir)
        return unless blocked_dir.is_a?(Array)
        blocked_dir.delete(dir)
      end
      def self.blocked?(dir)
        return false unless blocked_dir.is_a?(Array)
        blocked_dir.include?(dir)
      end
    end # end of HRK_MDS module
    class Game_Player < Game_Character
      #--------------------------------------------------------------------------
      # * Processing of Movement via Input from Directional Buttons
      #--------------------------------------------------------------------------
      alias hrk_mds_move_by_input_old move_by_input
      def move_by_input
        return if !movable? || $game_map.interpreter.running?
        mdir = Input.dir4
        if HRK_MDS.block_switch
          if HRK_MDS.blocked?(mdir)
            set_direction(mdir)
          else
            move_straight(mdir) if mdir > 0
          end
        else
          move_straight(mdir) if mdir > 0
        end
      end
    end
    This should do the trick. Just use HRK_MDS.block_direction(direction) when you want to block a particular direction (direction in VX Ace are 2, 4, 6, 8 for down, left, right, up). Use HRK_MDS.remove_block(direction) to remove a direction block you previously set.
     
    Last edited: Jun 20, 2019
    #11
  12. Trihan

    Trihan Speedy Scripter Veteran

    Messages:
    1,483
    Likes Received:
    976
    Location:
    Buckie, Scotland
    First Language:
    English
    @Heirukichi Out of curiosity, is there a particular reason you don't use class_eval?
     
    #12
  13. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    Script call gives this error. On a fresh project too.
    upload_2019-6-19_20-59-2.png
    This what I was supposed to do, right?
    upload_2019-6-19_20-58-48.png


    Yes, I didn't quite get what you meant by "1 frame" at first. It works fine now, thank you!
     
    #13
  14. Heirukichi

    Heirukichi Veteran Veteran

    Messages:
    1,134
    Likes Received:
    420
    Location:
    Italy
    First Language:
    Italian
    Primarily Uses:
    RMVXA
    @DumbPomelo I modified the previous script to add the missing part that was causing an error. Sorry for that, I wrote it directly here from mobile, with no syntax highlighting and no automatic word completion, it makes coding harder.

    @Trihan do you mean other than trying to avoid all the "eval" methods (class_eval, eval, method_eval, instance_eval) unless they are absolutely necessary because they are bad coding etiquette? Not really, that is the only reason.

    As long as another way to handle that exists, I usually go for the one that adheres to the etiquette. If the OP does not want to use any script and wants to do that with a script call, using a method of the eval family is a good option, I will never disregard those options. It is true that they are considered bad etiquette, but they are there for a reason, and they are indeed useful sometimes.
     
    #14
  15. DumbPomelo

    DumbPomelo Villager Member

    Messages:
    18
    Likes Received:
    1
    First Language:
    English
    Primarily Uses:
    RMVXA
    Works now, thank you.
     
    #15
  16. Trihan

    Trihan Speedy Scripter Veteran

    Messages:
    1,483
    Likes Received:
    976
    Location:
    Buckie, Scotland
    First Language:
    English
    Why are they bad coding etiquette?
     
    #16
  17. TheoAllen

    TheoAllen Self-proclaimed jack of all trades Veteran

    Messages:
    4,212
    Likes Received:
    4,668
    Location:
    Riftverse
    First Language:
    Indonesian
    Primarily Uses:
    RMVXA
    @Heirukichi here is another question. Why would you bother to alias move_by_input if you never recall the aliased method?
     
    #17
  18. Heirukichi

    Heirukichi Veteran Veteran

    Messages:
    1,134
    Likes Received:
    420
    Location:
    Italy
    First Language:
    Italian
    Primarily Uses:
    RMVXA
    @Trihan honestly I cannot answer your question. I suppose it is because they can all get a string to evaluate and writing code using strings does not make the code easy to read. In fact, there is an explicit rule that states that you should avoid evaluating strings as much as possible and use blocks instead. Another reason might be because you call the method on the object itself to change how the class behaves, and if you want to change the class is more readable to change the class itself.
    However, this does not change the fact that they are particularly useful sometimes. As a matter of fact, I use them sometimes, and I even made a tutorial on how to use instance_eval to achieve complex things with script calls in VX Ace.
    Even so, passing a block to them does not make the code particularly hard to read to be honest, even the style guide to ruby states that it is fine if you use a block and not a string. So I guess it is just a matter of personal preference in that case.

    However there are things I don't really get in ruby coding etiquette to be honest, like avoid using return at the end of a method. Why is using return at the end of a method bad coding etiquette when every other language uses it? It does not make the code easier to read, it actually makes it harder to read for people who do not use ruby very often...but well, not using it does not bring any harm so...

    @TheoAllen this way the old method is not lost, and if the OP ever wants to restore it somehow (by disabling my method with a switch or so) it is still possible to use it.
     
    #18
  19. Trihan

    Trihan Speedy Scripter Veteran

    Messages:
    1,483
    Likes Received:
    976
    Location:
    Buckie, Scotland
    First Language:
    English
    I only ever use them with blocks; the reason I use class_eval and instance_eval is so that I only need to know which class I'm extending and don't have to faff about with looking up what it inherits from and any other nuances of its implementation.

    I can actually answer your second point! It's considered redundant to use return in Ruby since it automatically returns the last evaluated expression anyway (I've noticed etiquette is often "what can we get rid of?" without any consideration for readability when comparing with other languages)
     
    #19
    Heirukichi likes this.

Share This Page