FANDOM


Set the Controls Screen
This tutorial was written by -FL-. Please give credit.

This tutorial is related to the following pages:

Click here for more tutorials!


Setcontrolssscreen
#===============================================================================
# * Set the Controls Screen - by FL (Credits will be apreciated)
#===============================================================================
#
# This script is for Pokémon Essentials. It's make a "Set the controls"
# option screen allowing the player to map the actions to the keys in keyboard,
# customizing the controls.
#
#===============================================================================
#
# To this script works, put it between PSystem_Controls and PSystem_System. 
#
# To this screen be displayed in the pause menu, in PScreen_PauseMenu script,
# before line 'commands[cmdDebug=commands.length]=_INTL("Debug") if $DEBUG' add:
#
# cmdControls=-1
# commands[cmdControls=commands.length]=_INTL("Controls")
#
# Before line 'elsif cmdOption>=0 && command==cmdOption' add:
#
# elsif cmdControls>=0 && command==cmdControls
#   scene=PokemonControlsScene.new       
#   screen=PokemonControls.new(scene)
#   pbFadeOutIn(99999) {
#     screen.pbStartScreen
#   }
#
# Using the last five lines you can start this scene in other places like at
# an event.
#
# Note that this script, by default, doesn't allows the player to redefine some
# commands like F8 (screenshot key), but if the player assign an action to
# this key, like the "Run" action, this key will do this action AND take
# screenshots when pressed. Remember that F12 will reset the game.
#
#===============================================================================

module Keys  
  # Available keys
  CONTROLSLIST = {
    # Mouse buttons
    _INTL("Backspace") => 0x08,
    _INTL("Tab") => 0x09,
    _INTL("Clear") => 0x0C,
    _INTL("Enter") => 0x0D,
    _INTL("Shift") => 0x10,
    _INTL("Ctrl") => 0x11,
    _INTL("Alt") => 0x12,
    _INTL("Pause") => 0x13,
    _INTL("Caps Lock") => 0x14,
    # IME keys
    _INTL("Esc") => 0x1B,
    # More IME keys
    _INTL("Space") => 0x20,
    _INTL("Page Up") => 0x21,
    _INTL("Page Down") => 0x22,
    _INTL("End") => 0x23,
    _INTL("Home") => 0x24,
    _INTL("Left") => 0x25,
    _INTL("Up") => 0x26,
    _INTL("Right") => 0x27,
    _INTL("Down") => 0x28,
    _INTL("Select") => 0x29,
    _INTL("Print") => 0x2A,
    _INTL("Execute") => 0x2B,
    _INTL("Print Screen") => 0x2C,
    _INTL("Insert") => 0x2D,
    _INTL("Delete") => 0x2E,
    _INTL("Help") => 0x2F,
    _INTL("0") => 0x30,
    _INTL("1") => 0x31,
    _INTL("2") => 0x32,
    _INTL("3") => 0x33,
    _INTL("4") => 0x34,
    _INTL("5") => 0x35,
    _INTL("6") => 0x36,
    _INTL("7") => 0x37,
    _INTL("8") => 0x38,
    _INTL("9") => 0x39,
    _INTL("A") => 0x41,
    _INTL("B") => 0x42,
    _INTL("C") => 0x43,
    _INTL("D") => 0x44,
    _INTL("E") => 0x45,
    _INTL("F") => 0x46,
    _INTL("G") => 0x47,
    _INTL("H") => 0x48,
    _INTL("I") => 0x49,
    _INTL("J") => 0x4A,
    _INTL("K") => 0x4B,
    _INTL("L") => 0x4C,
    _INTL("M") => 0x4D,
    _INTL("N") => 0x4E,
    _INTL("O") => 0x4F,
    _INTL("P") => 0x50,
    _INTL("Q") => 0x51,
    _INTL("R") => 0x52,
    _INTL("S") => 0x53,
    _INTL("T") => 0x54,
    _INTL("U") => 0x55,
    _INTL("V") => 0x56,
    _INTL("W") => 0x57,
    _INTL("X") => 0x58,
    _INTL("Y") => 0x59,
    _INTL("Z") => 0x5A,
    # Windows keys
    _INTL("Numpad 0") => 0x60,
    _INTL("Numpad 1") => 0x61,
    _INTL("Numpad 2") => 0x62,
    _INTL("Numpad 3") => 0x63,
    _INTL("Numpad 4") => 0x64,
    _INTL("Numpad 5") => 0x65,
    _INTL("Numpad 6") => 0x66,
    _INTL("Numpad 7") => 0x67,
    _INTL("Numpad 8") => 0x68,
    _INTL("Numpad 9") => 0x69,
    _INTL("Multiply") => 0x6A,
    _INTL("Add") => 0x6B,
    _INTL("Separator") => 0x6C,
    _INTL("Subtract") => 0x6D,
    _INTL("Decimal") => 0x6E,
    _INTL("Divide") => 0x6F,
    _INTL("F1") => 0x70,
    _INTL("F2") => 0x71,
    _INTL("F3") => 0x72,
    _INTL("F4") => 0x73,
    _INTL("F5") => 0x74,
    _INTL("F6") => 0x75,
    _INTL("F7") => 0x76,
    _INTL("F8") => 0x77,
    _INTL("F9") => 0x78,
    _INTL("F10") => 0x79,
    _INTL("F11") => 0x7A,
    _INTL("F12") => 0x7B,
    _INTL("F13") => 0x7C,
    _INTL("F14") => 0x7D,
    _INTL("F15") => 0x7E,
    _INTL("F16") => 0x7F,
    _INTL("F17") => 0x80,
    _INTL("F18") => 0x81,
    _INTL("F19") => 0x82,
    _INTL("F20") => 0x83,
    _INTL("F21") => 0x84,
    _INTL("F22") => 0x85,
    _INTL("F23") => 0x86,
    _INTL("F24") => 0x87,
    _INTL("Num Lock") => 0x90,
    _INTL("Scroll Lock") => 0x91,
    # Multiple position Shift, Ctrl and Menu keys
    _INTL(";:") => 0xBA,
    _INTL("+") => 0xBB,
    _INTL(",") => 0xBC,
    _INTL("-") => 0xBD,
    _INTL(".") => 0xBE,
    _INTL("/?") => 0xBF,
    _INTL("`~") => 0xC0,
    _INTL("{") => 0xDB,
    _INTL("\|") => 0xDC,
    _INTL("}") => 0xDD,
    _INTL("'\"") => 0xDE,
    _INTL("AX") => 0xE1, # Japan only
    _INTL("\|") => 0xE2
    # Disc keys
  }
  
  # Here you can change the number of keys for each action and the
  # default values
  def self.defaultControls
    return [
      ControlConfig.new(_INTL("Down"),_INTL("Down")),
      ControlConfig.new(_INTL("Left"),_INTL("Left")),
      ControlConfig.new(_INTL("Right"),_INTL("Right")),
      ControlConfig.new(_INTL("Up"),_INTL("Up")),
      ControlConfig.new(_INTL("Action"),_INTL("C")),
      ControlConfig.new(_INTL("Action"),_INTL("Enter")),
      ControlConfig.new(_INTL("Action"),_INTL("Space")),
      ControlConfig.new(_INTL("Cancel"),_INTL("X")),
      ControlConfig.new(_INTL("Cancel"),_INTL("Esc")),
      ControlConfig.new(_INTL("Run"),_INTL("Z")),
      ControlConfig.new(_INTL("Scroll down"),_INTL("Page Down")),
      ControlConfig.new(_INTL("Scroll up"),_INTL("Page Up")),
      ControlConfig.new(_INTL("Registered/Sort"),_INTL("F5"))
    ]
  end  
  
  def self.getKeyName(keyCode)
    ret  = CONTROLSLIST.index(keyCode) 
    return ret ? ret : (keyCode==0 ? _INTL("None") : "?")
  end  
  
  def self.getKeyCode(keyName)
    ret  = CONTROLSLIST[keyName] 
    raise "The button #{keyName} no longer exists! " if !ret
    return ret
  end  
  
  def self.detectKey
    loop do
      Graphics.update
      Input.update
      for keyCode in CONTROLSLIST.values
        return keyCode if Input.triggerex?(keyCode)
      end
    end 
  end  
end  

class ControlConfig
  attr_reader :controlAction
  attr_accessor :keyCode
  
  def initialize(controlAction,defaultKey)
    @controlAction = controlAction
    @keyCode = Keys.getKeyCode(defaultKey)
  end
  
  def keyName
    return Keys.getKeyName(@keyCode)
  end  
end

module Input
  class << self
    alias :buttonToKeyOldFL :buttonToKey
    # Here I redefine this method with my controlAction.
    # Note that I don't declare action for all commands.
    def buttonToKey(button)
      $PokemonSystem = PokemonSystem.new if !$PokemonSystem
      case button
        when Input::DOWN
          return $PokemonSystem.getGameControlCodes(_INTL("Down"))
        when Input::LEFT
          return $PokemonSystem.getGameControlCodes(_INTL("Left"))
        when Input::RIGHT
          return $PokemonSystem.getGameControlCodes(_INTL("Right"))
        when Input::UP
          return $PokemonSystem.getGameControlCodes(_INTL("Up"))
        when Input::A # Z, Shift
          return $PokemonSystem.getGameControlCodes(_INTL("Run"))
        when Input::B # X, ESC 
          return $PokemonSystem.getGameControlCodes(_INTL("Cancel"))
        when Input::C # C, ENTER, Space
          return $PokemonSystem.getGameControlCodes(_INTL("Action"))
        when Input::L # Page Up
          return $PokemonSystem.getGameControlCodes(_INTL("Scroll up"))
        when Input::R # Page Down
          return $PokemonSystem.getGameControlCodes(_INTL("Scroll down"))
#        when Input::SHIFT
#          return [0x10] # Shift
#        when Input::CTRL
#          return [0x11] # Ctrl
#        when Input::ALT
#          return [0x12] # Alt
        when Input::F5 # F5
          return $PokemonSystem.getGameControlCodes(_INTL("Registered/Sort"))
#        when Input::F6
#          return [0x75] # F6
#        when Input::F7
#          return [0x76] # F7
#        when Input::F8
#          return [0x77] # F8
#        when Input::F9
#          return [0x78] # F9
        else
          return buttonToKeyOldFL(button)
      end
    end
  end
end

class Window_PokemonControls < Window_DrawableCommand
  attr_reader :readingInput
  attr_reader :controls
  attr_reader :changed
  
  def initialize(controls,x,y,width,height)
    @controls=controls
    @nameBaseColor=Color.new(88,88,80)
    @nameShadowColor=Color.new(168,184,184)
    @selBaseColor=Color.new(24,112,216)
    @selShadowColor=Color.new(136,168,208)
    @readingInput=false
    @changed=false
    super(x,y,width,height)
  end
  
  def setNewInput(newInput)
    @readingInput = false
    return if @controls[@index].keyCode==newInput
    for control in @controls # Remove the same input for the same array
      control.keyCode = 0 if control.keyCode==newInput
    end  
    @controls[@index].keyCode=newInput
    @changed = true
    refresh
  end

  def itemCount
    return @controls.length+2
  end

  def drawItem(index,count,rect)
    rect=drawCursor(index,rect)
    optionname = ""
    if index==(@controls.length+1)
      optionname = _INTL("Exit")
    elsif index==(@controls.length)
      optionname = _INTL("Default")
    else
      optionname = @controls[index].controlAction
    end  
    optionwidth=(rect.width*9/20)
    pbDrawShadowText(self.contents,rect.x,rect.y,optionwidth,rect.height,
      optionname,@nameBaseColor,@nameShadowColor)
    self.contents.draw_text(rect.x,rect.y,optionwidth,rect.height,optionname)
    return if index>=@controls.length
    value=@controls[index].keyName
    xpos=optionwidth+rect.x
    pbDrawShadowText(self.contents,xpos,rect.y,optionwidth,rect.height,value,
       @selBaseColor,@selShadowColor)
    self.contents.draw_text(xpos,rect.y,optionwidth,rect.height,value)
  end

  def update
    dorefresh=false
    oldindex=self.index
    super
    dorefresh=self.index!=oldindex
    if self.active && self.index<=@controls.length
      if Input.trigger?(Input::C)
        if self.index == @controls.length # Default
          @controls = Keys.defaultControls
          @changed = true
          dorefresh = true
        else
          @readingInput = true
        end  
      end
    end
    refresh if dorefresh
  end
end

class PokemonControlsScene
  def pbUpdate
    pbUpdateSpriteHash(@sprites)
  end

  def pbStartScene
    @sprites={}
    @viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
    @viewport.z=99999
    @sprites["title"]=Window_UnformattedTextPokemon.newWithSize(
       _INTL("Controls"),0,0,Graphics.width,64,@viewport)
    @sprites["textbox"]=Kernel.pbCreateMessageWindow
    @sprites["textbox"].letterbyletter=false
    gameControls = []
    for control in $PokemonSystem.gameControls
      gameControls.push(control.clone)
    end  
    @sprites["controlwindow"]=Window_PokemonControls.new(gameControls,0,
    @sprites["title"].height,Graphics.width,
    Graphics.height-@sprites["title"].height-@sprites["textbox"].height)
    @sprites["controlwindow"].viewport=@viewport
    @sprites["controlwindow"].visible=true
    @changed = false
    pbDeactivateWindows(@sprites)
    pbFadeInAndShow(@sprites) { pbUpdate }
  end

  def pbMain
    pbActivateWindow(@sprites,"controlwindow"){
    loop do
      Graphics.update
      Input.update
      pbUpdate
      exit = false
      if @sprites["controlwindow"].readingInput
        @sprites["textbox"].text=_INTL("Press a new key.")
        @sprites["controlwindow"].setNewInput(Keys.detectKey)
        @sprites["textbox"].text=""
        @changed = true
      else
        if Input.trigger?(Input::B) || (Input.trigger?(Input::C) && 
           @sprites["controlwindow"].index==(
           @sprites["controlwindow"].itemCount-1))
          exit = true  
          if(@sprites["controlwindow"].changed && 
              Kernel.pbConfirmMessage(_INTL("Save changes?")))
            @sprites["textbox"].text = "" # Visual effect
            newControls = @sprites["controlwindow"].controls 
            emptyCommand = false
            for control in newControls
              emptyCommand = true if control.keyCode == 0
            end
            if emptyCommand
              @sprites["textbox"].text=_INTL("Fill all fields!")
              exit = false  
            else
              $PokemonSystem.gameControls = newControls
            end
          end
        end
       end
       break if exit
     end
    }
  end

  def pbEndScene
    pbFadeOutAndHide(@sprites) { pbUpdate }
    Kernel.pbDisposeMessageWindow(@sprites["textbox"])
    pbDisposeSpriteHash(@sprites)
    @viewport.dispose
  end
end

class PokemonControls
  def initialize(scene)
    @scene=scene
  end

  def pbStartScreen
    @scene.pbStartScene
    @scene.pbMain
    @scene.pbEndScene
  end
end

class PokemonSystem
  attr_accessor :gameControls
  def gameControls
    @gameControls = Keys.defaultControls if !@gameControls
    return @gameControls
  end
  
  def getGameControlCodes(controlAction)
    ret = []
    for control in gameControls
      ret.push(control.keyCode) if control.controlAction == controlAction
    end
    return ret
  end  
end

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.