Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

MACL - Method and Class Library 2.3

But I still want your ideas there. ;)

I want this a complete group effort. I only want to see this done and the most it can be and I will push it until it is.

Sorry about the delay on the MACL update. So many projects at once and I am working on going through every method, cleaning up as much as possible. Currently stuck at Bitmap.gradient, cleaning up a few methods and adding more. lol
 
FFFF WONDERFUL!!! THE PROJECT WITH ALL THE UPDATES TO THE MACL WAS CORRUPTED! I DONT EVEN KNOW THE LAST TIME I BACKED IT UP! THERE WENT PROBABLY 30 HOURS TO HELL!

SO MAD RIGHT NOW!!!
 
Damnit!!!!!! That sucks man! If I were you, I'd constantly backup my Scripts.rxdata file, daily... weekly... monthly, thats something that I always do.

Have you tried putting just the "Scripts.rxdata" in another project, or a new project? ...Most likely, if that was the last thing you were working on thats probably the only corrupted file, but what if its a stupid Map or something? Ha, I doubt it, you're a scripter not a mapper! But still, not to be Captain Obvious or nothing, but test out just the "Scripts" file on a new project, there's probably a chance thats not the corrupted file (but like I said, I doubt it since that is something you always work on.)

Is there anything we could help you with on re-attempt to update the MACL? I can go through and try and organize the new methods 'n stuff if you would like, leaving you to just proof read and make changes to whatever isn't working. I'm not sure what all you plan on including but I'm down for whatever to help you with it.

*Leaves to backup his current scripts.*
 
I usually do weekly, but just haven't had the time. I haven't had any problems in about 2 years. It was all the .rxdata files. I tried putting it into a new project and putting all the other files into the project. Now luck either way. :(

All I can say is it's a good thing I have about 40% of the updates scattered in my other projects. Now to go through 120 project files and check, add and merge. I will probably end up  not having everything that I did have, but I am going to try. In all cases, the compiler is going to wait for the 2.6 version now. I just don't have the time and patience for it right now.


If you really want to help, can you create a new project, go through this topic and add every addition into the project. Each with its own part, seperated like the MACL would. RGSS.Map, RGSS.Character, etc.

That would save me an hour or 2 and I would greatly appreciate it.
 
One last thing I wrote for the Game_Map class (I origionally wrote it into Event_Spawner, but is more defined now.)

This prints an events commands list, like so...

http://i224.photobucket.com/albums/dd28 ... ntList.png[/img]

I do have to do the parameters though, but here it is so far :P

Code:
class Game_Map
  #-----------------------------------------------------------------------------
  # * Print List
  #-----------------------------------------------------------------------------
  def print_list(event_id)
    list = String.new
    unless $game_map.events[event_id].nil?
      for c in $game_map.events[event_id].list
        code = c.code.to_s
        code.gsub!("0",   "")
        code.gsub!("101", "Show Text")
        code.gsub!("102", "Show Choices")
        code.gsub!("402", "When [**]")
        code.gsub!("403", "When Cancel")
        code.gsub!("103", "Input Number")
        code.gsub!("104", "Change Text Options")
        code.gsub!("105", "Button Input Processing")
        code.gsub!("106", "Wait")
        code.gsub!("111", "Conditional Branch")
        code.gsub!("411", "Else")
        code.gsub!("412", "Branch End")
        code.gsub!("112", "Loop")
        code.gsub!("413", "Repeat Above")
        code.gsub!("113", "Break Loop")
        code.gsub!("115", "Exit Event Processing")
        code.gsub!("116", "Erase Event")
        code.gsub!("117", "Call Common Event")
        code.gsub!("118", "Label")
        code.gsub!("119", "Jump to Label")
        code.gsub!("121", "Control Switches")
        code.gsub!("122", "Control Variables")
        code.gsub!("123", "Control Self Switch")
        code.gsub!("124", "Control Timer")
        code.gsub!("125", "Change Gold")
        code.gsub!("126", "Change Items")
        code.gsub!("127", "Change Weapons")
        code.gsub!("128", "Change Armor")
        code.gsub!("129", "Change Party Member")
        code.gsub!("131", "Change Windowskin")
        code.gsub!("132", "Change Battle BGM")
        code.gsub!("133", "Change Battle End ME")
        code.gsub!("134", "Change Save Access")
        code.gsub!("135", "Change Menu Access")
        code.gsub!("136", "Change Encounter")
        code.gsub!("201", "Transfer Player")
        code.gsub!("202", "Set Event Location")
        code.gsub!("203", "Scroll Map")
        code.gsub!("204", "Change Map Settings")
        code.gsub!("205", "Change Fog Color Tone")
        code.gsub!("206", "Change Fog Opacity")
        code.gsub!("207", "Show Animation")
        code.gsub!("208", "Change Transparent Flag")
        code.gsub!("209", "Set Move Route")
        code.gsub!("210", "Wait for Move's Completion")
        code.gsub!("221", "Prepare for Transition")
        code.gsub!("222", "Execute Transition")
        code.gsub!("223", "Change Screen Color Tone")
        code.gsub!("224", "Screen Flash")
        code.gsub!("225", "Screen Shake")
        code.gsub!("231", "Show Picture")
        code.gsub!("232", "Move Picture")
        code.gsub!("233", "Rotate Picture")
        code.gsub!("234", "Change Picture Color Tone")
        code.gsub!("235", "Erase Picture")
        code.gsub!("236", "Set Weather Effects")
        code.gsub!("241", "Play BGM")
        code.gsub!("242", "Fade Out BGM")
        code.gsub!("245", "Play BGS")
        code.gsub!("246", "Fade Out BGS")
        code.gsub!("247", "Memorize BGM/BGS")
        code.gsub!("248", "Restore BGM/BGS")
        code.gsub!("249", "Play ME")
        code.gsub!("250", "Play SE")
        code.gsub!("251", "Stop SE")
        code.gsub!("301", "Battle Processing")
        code.gsub!("601", "If Win")
        code.gsub!("602", "If Escape")
        code.gsub!("603", "If Lose")
        code.gsub!("302", "Shop Processing")
        code.gsub!("303", "Name Input Processing")
        code.gsub!("311", "Change HP")
        code.gsub!("312", "Change SP")
        code.gsub!("313", "Change State")
        code.gsub!("314", "Recover All")
        code.gsub!("315", "Change EXP")
        code.gsub!("316", "Change Level")
        code.gsub!("317", "Change Parameters")
        code.gsub!("318", "Change Skills")
        code.gsub!("319", "Change Equipment")
        code.gsub!("320", "Change Actor Name")
        code.gsub!("321", "Change Actor Class")
        code.gsub!("322", "Change Actor Graphic")
        code.gsub!("331", "Change Enemy HP")
        code.gsub!("332", "Change Enemy SP")
        code.gsub!("333", "Change Enemy State")
        code.gsub!("334", "Enemy Recover All")
        code.gsub!("335", "Enemy Appearance")
        code.gsub!("336", "Enemy Transform")
        code.gsub!("337", "Show Battle Animation")
        code.gsub!("338", "Deal Damage")
        code.gsub!("339", "Force Action")
        code.gsub!("340", "Abort Battle")
        code.gsub!("351", "Call Menu Screen")
        code.gsub!("352", "Call Save Screen")
        code.gsub!("353", "Game Over")
        code.gsub!("354", "Return to Title Screen")
        code.gsub!("355", "Script")
        code = ("  " * c.indent) + "@>" + code + ": "+c.parameters.to_s+"\n"
        list += code
      end
    end
    print list
  end
end
 
This is a little thing that improves :hwnd, a method used in various scripts which require Win32API structures.  I personally made this to fix my mouse script.  It fixes the "bug" where anything that requires the method fails to work when you press F2 (which displays the frame rate).

Code:
  Findwindow    = Win32API.new('user32',    'FindWindowA',      %w(p p), 'l')
  Readini       = Win32API.new('kernel32',  'GetPrivateProfileStringA', 
                               %w(p p p p l p), 'l')
  #--------------------------------------------------------------------------
  # * Find the game window and return it
  #--------------------------------------------------------------------------
  def self.hwnd
    # Finds Game Name
    game_name = "\0" * 256
    Readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
    game_name.delete!("\0")
    win = Findwindow.call('RGSS Player', game_name)
    if win == 0
      i = 0
      while i <= Graphics.frame_rate
        win = Findwindow.call('RGSS Player', game_name+' - '+i.to_s+' FPS')
        break if win != 0
        i += 1
      end
    end
    # Finds Window
    return win
  end
 
mewsterus":3cil2gpw said:
This is a little thing that improves :hwnd, a method used in various scripts which require Win32API structures.  I personally made this to fix my mouse script.  It fixes the "bug" where anything that requires the method fails to work when you press F2 (which displays the frame rate).

Code:
  Findwindow    = Win32API.new('user32',    'FindWindowA',      %w(p p), 'l')
  Readini       = Win32API.new('kernel32',  'GetPrivateProfileStringA', 
                               %w(p p p p l p), 'l')
  #--------------------------------------------------------------------------
  # * Find the game window and return it
  #--------------------------------------------------------------------------
  def self.hwnd
    # Finds Game Name
    game_name = "\0" * 256
    Readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
    game_name.delete!("\0")
    win = Findwindow.call('RGSS Player', game_name)
    if win == 0
      i = 0
      while i <= Graphics.frame_rate
        win = Findwindow.call('RGSS Player', game_name+' - '+i.to_s+' FPS')
        break if win != 0
        i += 1
      end
    end
    # Finds Window
    return win
  end
Actually, you need to obtain the hwnd index only once, so you can get it using the original name(Without the FPS) of the window when the game starts, so you can do something like this:
Code:
  Findwindow = Win32API.new('user32', 'FindWindowA', 'pp', 'l')
  Readini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'pppplp', 'l')
  def self.hwnd
    if @hwnd.nil?
      game_name = "\0" * 256
      Readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
      game_name.delete!("\0")
      @hwnd = Findwindow.call('RGSS Player', game_name)
    else
      @hwnd
    end
  end
  self.hwnd
 
@mew

Code:
 #--------------------------------------------------------------------------
  # * Get Screen Window Handle
  #--------------------------------------------------------------------------
  def Mouse.hwnd
    game_name = "\0" * 256
    Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l').call('Game','Title','',game_name,255,".\\Game.ini")
    game_name.delete!("\0")
    return Win32API.new('user32', 'FindWindowA', %w(p p), 'l').call('RGSS Player',game_name)
  end

@vgvf,

isn't the handle changed if it is moved or something (not sure - never tried). Oh and not everyone uses that ReadIni ;)
 
@me, no, the window handles are assigned to each window when it is created, so it will never change.
Oh and not everyone uses that ReadIni ;)
I just copied what mewsterus posted and edited it a little.
 
Ok so I've been using the MACL 2.1 and decided to update it to 2.3 and now I get an error on line 5523
Code:
      if conditions[effect]
        # Call Method
        send(effect, *args)
      end

Any idea's or should I just go back to 2.1 which didn't give me problems?
 
it happens before the game starts after you hit "test game" it goes to open the window and bam throws the error up. I'll update my game demo with it in there and make it unencrypted and PM you with it if you like
 
Me(tm)":26a139kp said:
@mew

Code:
 #--------------------------------------------------------------------------
  # * Get Screen Window Handle
  #--------------------------------------------------------------------------
  def Mouse.hwnd
    game_name = "\0" * 256
    Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l').call('Game','Title','',game_name,255,".\\Game.ini")
    game_name.delete!("\0")
    return Win32API.new('user32', 'FindWindowA', %w(p p), 'l').call('RGSS Player',game_name)
  end

@vgvf,

isn't the handle changed if it is moved or something (not sure - never tried). Oh and not everyone uses that ReadIni ;)

The point of the code was to fix the F2 bug, which vgvgf did better than I did methinks. What you posted kind of backtracked over that fix...
 
I rewrote the Mouse Module based off Aleworks::API (yes, it should be MACL standard its fuckin' awesome), and checked my CPU and it used about 8-14% less (varies), probably because its using less memory by not redefining the constants in the module. A single module to handle all API is great, Aleworks does it just fine! Also, vgvgf is correct, set the 'hwnd' to an instance (if nil) then return that baby and frame rate got WAY better!

I also re-wrote your 'Mouse Selectable Windows' script, it runs pretty fast now. I like my version of the setup better, because you can individually enable/disable windows that use mouse via {'Window_XXX' => true/false, ...}, then Selectable_Objects.default = true/false to set all undefined windows mouse enabled.

Code:
#============================================================================== 
# ** Modules.Mouse Input (7.0)              By Near Fantastica & SephirothSpawn
#------------------------------------------------------------------------------
# * Description :
#
#   The Mouse Input Module defines mouse input. It will retrieve the cursor
#   x and y position, as well as grid locations. This script updates
#   itself when the input module updates.
#------------------------------------------------------------------------------
# * Customization :
#
#   Turning Windows Cursor off when opening Game
#    - Hide_Mouse_Cursor = true (turn off) or false (leave alone)
#
#   Mouse triggers that cause Input triggers
#    - Mouse_to_Input_Triggers = { mouse_key => Input::KeyConstant, ... }
#------------------------------------------------------------------------------
# * Syntax :
#
#   Get Mouse Position :
#    - position = Mouse.position
#
#   Get Mouse Grid Position :
#    - grid_position = Mouse.grid
#
#   Trigger Status
#    - Mouse.trigger?
#
#   Repeat Status
#    - Mouse.repeat?
#==============================================================================

MACL::Loaded << 'Modules.Mouse Module'

#==============================================================================
# ** Mouse
#==============================================================================

module Mouse
  #--------------------------------------------------------------------------
  # * Include Aleworks::API module
  #--------------------------------------------------------------------------
  include Aleworks::API
  #--------------------------------------------------------------------------
  # * Show Windows Cursor Setting
  #--------------------------------------------------------------------------
  Hide_Mouse_Cursor = false
  #--------------------------------------------------------------------------
  # * Mouse to Input Triggers
  #
  #   key => Input::KeyCONSTANT (key: 0 - Left, 1 - Middle, 2 - Right)
  #--------------------------------------------------------------------------
  Mouse_to_Input_Triggers = {0 => Input::C, 1 => Input::B, 2 => Input::A}
  #--------------------------------------------------------------------------
  # * API Declaration
  #--------------------------------------------------------------------------
  FindWindowA    = Win32API.new('user32', 'FindWindowA', %w(p p), 'l')
  ShowCursor.call(Hide_Mouse_Cursor ? 0 : 1)
  @triggers     =   [[0, 1], [0, 2], [0, 4]] 
  #--------------------------------------------------------------------------
  # * Mouse Grid Position
  #--------------------------------------------------------------------------
  def self.grid
    # Return Nil if Position is Nil
    return nil if @pos.nil?
    # Return X & Y Locations
    x = (@pos[0] + $game_map.display_x / 4) / 32
    y = (@pos[1] + $game_map.display_y / 4) / 32
    return [x, y]
  end
  #--------------------------------------------------------------------------
  # * Mouse X
  #--------------------------------------------------------------------------
  def self.x
    return position[0]
  end
  #--------------------------------------------------------------------------
  # * Mouse Y
  #--------------------------------------------------------------------------
  def self.y
    return position[1]
  end
  #--------------------------------------------------------------------------
  # * Moving Down?
  #--------------------------------------------------------------------------
  def self.moving_down?
    return (@last_y.nil? ? false : self.position[1] > @last_y)
  end
  #--------------------------------------------------------------------------
  # * Moving Up?
  #--------------------------------------------------------------------------
  def self.moving_up?
    return (@last_y.nil? ? false : self.position[1] < @last_y)
  end
  #--------------------------------------------------------------------------
  # * Moving Left?
  #--------------------------------------------------------------------------
  def self.moving_left?
    return (@last_x.nil? ? false : self.position[0] < @last_x)
  end
  #--------------------------------------------------------------------------
  # * Moving Right?
  #--------------------------------------------------------------------------
  def self.moving_right?
    return (@last_x.nil? ? false : self.position[0] > @last_x)
  end
  #--------------------------------------------------------------------------
  # * Mouse Position
  #--------------------------------------------------------------------------
  def self.position
    return @pos == nil ? [0, 0] : @pos
  end
  #--------------------------------------------------------------------------
  # * Mouse Global Position
  #--------------------------------------------------------------------------
  def self.global_pos
    # Packs 0 Position
    pos = [0, 0].pack('ll')
    # Returns Unpacked Cursor Position Call
    return GetCursorPos.call(pos) == 0 ? nil : pos.unpack('ll')
  end
  #--------------------------------------------------------------------------
  # * Mouse Position
  #--------------------------------------------------------------------------
  def self.pos
    # Gets X & Y Position
    x, y = self.screen_to_client(*self.global_pos)
    # Gets Width & Height of Game Window
    width, height = self.client_size
    # Begins Test
    begin
      # Return X & Y or Nil Depending on Mouse Position
      if (x >= 0 && y >= 0 && x < width && y < height)
        return x, y
      end
      return nil
    rescue
      # Return nil
      return nil
    end
  end
  #--------------------------------------------------------------------------
  # * Update Mouse Position
  #--------------------------------------------------------------------------
  def self.update
    # Update Position
    @pos = self.pos
    # Update Triggers
    for i in @triggers
      # Gets Async State
      n = GetAsyncKeyState.call(i[1])
      # If 0 or 1
      if [0, 1].include?(n)
        i[0] = (i[0] > 0 ? i[0] * -1 : 0)
      else
        i[0] = (i[0] > 0 ? i[0] + 1 : 1)
      end
    end
    @last_x, @last_y = self.position[0], self.position[1]
  end
  #--------------------------------------------------------------------------
  # * Trigger?
  #     id : 0:Left, 1:Right, 2:Center
  #--------------------------------------------------------------------------
  def self.trigger?(id = 0)
    return @triggers[id][0] == 1
  end
  #--------------------------------------------------------------------------
  # * Repeat?
  #     id : 0:Left, 1:Right, 2:Center
  #--------------------------------------------------------------------------
  def self.repeat?(id = 0)
    if @triggers[id][0] <= 0
      return false
    else
      return @triggers[id][0] % 5 == 1 && @triggers[id][0] % 5 != 2
    end
  end
  #--------------------------------------------------------------------------
  # * Screen to Client
  #--------------------------------------------------------------------------
  def self.screen_to_client(x, y)
    # Return nil if X & Y empty
    return nil unless x and y
    # Pack X & Y
    pos = [x, y].pack('ll')
    # Return Unpacked Position or Nil
    return ScreenToClient.call(self.window, pos) == 0 ? nil : pos.unpack('ll')
  end
  #--------------------------------------------------------------------------
  # * Hwnd
  #--------------------------------------------------------------------------
  def self.window
    if @game_window.nil?
      # Finds Game Name
      game_name = "\0" * 256
      GPPSA.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
      game_name.delete!("\0")
      # Finds Window
      @game_window = FindWindowA.call('RGSS Player', game_name)
    end
    return @game_window
  end
  #--------------------------------------------------------------------------
  # * Client Size
  #--------------------------------------------------------------------------
  def self.client_size
    # Packs Empty Rect
    rect = [0, 0, 0, 0].pack('l4')
    # Gets Game Window Rect
    GetClientRect.call(self.window, rect)
    # Unpacks Right & Bottom
    right, bottom = rect.unpack('l4')[2..3]
    # Returns Right & Bottom
    return right, bottom
  end
end

#==============================================================================
# ** Input
#==============================================================================

class << Input
  #------------------------------------------------------------------------
  # * Alias Listings
  #------------------------------------------------------------------------
  unless self.method_defined?(:seph_mouse_input_update)
    alias_method :seph_mouse_input_update,   :update
    alias_method :seph_mouse_input_trigger?, :trigger?
    alias_method :seph_mouse_input_repeat?,  :repeat?
  end
  #------------------------------------------------------------------------
  # * Frame Update
  #------------------------------------------------------------------------
  def update
    # Update Mouse
    Mouse.update
    # Original Update
    seph_mouse_input_update
  end
  #--------------------------------------------------------------------------
  # * Trigger? Test
  #--------------------------------------------------------------------------
  def trigger?(constant)
    # Return true if original test is true
    return true if seph_mouse_input_trigger?(constant)
    # If Mouse Position isn't Nil
    unless Mouse.pos.nil?
      # If Mouse Trigger to Input Trigger Has Constant
      if Mouse::Mouse_to_Input_Triggers.has_value?(constant)
        # Return True if Mouse Triggered
        mouse_trigger = Mouse::Mouse_to_Input_Triggers.index(constant)
        return true if Mouse.trigger?(mouse_trigger)
      end
    end
    # Return False
    return false
  end
  #--------------------------------------------------------------------------
  # * Repeat? Test
  #--------------------------------------------------------------------------
  def repeat?(constant)
    # Return true if original test is true
    return true if seph_mouse_input_repeat?(constant)
    # If Mouse Position isn't Nil
    unless Mouse.pos.nil?
      # If Mouse Trigger to Input Trigger Has Constant
      if Mouse::Mouse_to_Input_Triggers.has_value?(constant)
        # Return True if Mouse Triggered
        mouse_trigger = Mouse::Mouse_to_Input_Triggers.index(constant)
        return true if Mouse.repeat?(mouse_trigger)
      end
    end
    # Return False
    return false
  end
end

Code:
#===============================================================================
# ** Mouse Selectables
#-------------------------------------------------------------------------------
# Revised by  : SephirothSpawn / Lambchop / Kain Nobel
# Version     : 2.5
# Last Update : 11.10.2008
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log Script
#-------------------------------------------------------------------------------
SDK.log('Mouse Selectable Windows', 'MACL Authors', 2.5, '11.10.2008')
SDK.check_requirements(2.0, [], {'Method & Class Library' => 2.1}) 

#-------------------------------------------------------------------------------
# * Begin SDK Enable Test
#-------------------------------------------------------------------------------
if SDK.enabled?('Mouse Selectable Windows')

#===============================================================================
# ** Mouse
#-------------------------------------------------------------------------------
#   This module contains extra constants for selectable windows.
#===============================================================================

module Mouse
  #-----------------------------------------------------------------------------
  # * Selectable_Objects
  #-----------------------------------------------------------------------------
  Selectable_Objects = {
    'Window_PartyMain'    => false,
    'Window_PartyReserve' => false
  }
  Selectable_Objects.default = true
  #-----------------------------------------------------------------------------
  # * Selectable_Padding
  #-----------------------------------------------------------------------------
  Selectable_Padding = {}
  Selectable_Padding.default = 16
  #-----------------------------------------------------------------------------
  # * Selectable_Switch
  #-----------------------------------------------------------------------------
  Selectable_Key = Keys::N0
end

#===============================================================================
# ** Window_Selectable
#-------------------------------------------------------------------------------
#   This class has been enhanced to utilizes the mouse to handle selections.
#===============================================================================

class Window_Selectable < Window_Base
  #-----------------------------------------------------------------------------
  # * Public Instance Variables
  #-----------------------------------------------------------------------------
  attr_accessor :mouse_enabled
  #-----------------------------------------------------------------------------
  # * Alias Listings
  #-----------------------------------------------------------------------------
  alias_method :mouse_win_select_initialize,  :initialize
  alias_method :mouse_win_select_update,      :update
  #-----------------------------------------------------------------------------
  # * Mouse Enabled?
  #-----------------------------------------------------------------------------
  def mouse_enabled?
    if @mouse_enabled.nil?
      @mouse_enabled = Mouse::Selectable_Objects[self.class.to_s] == true
    end
    return @mouse_enabled == true
  end
  #-----------------------------------------------------------------------------
  # * Mouse Padding
  #-----------------------------------------------------------------------------
  def mouse_padding
    return Mouse::Selectable_Padding[self.class.to_s]
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    if Input.trigger?(Mouse::Selectable_Key)
      self.mouse_enabled = !self.mouse_enabled?
      return
    end
    if self.mouse_enabled? && self.active && @item_max > 0 && @index >= 0
      mx, my = *Mouse.position
      if mx.between?(self.x, self.x + self.width) && 
      my.between?(self.y, self.y + self.height)
        mx -= (self.x + self.mouse_padding) ; my -= (self.y + self.mouse_padding)
        for i in 0...@item_max
          x = i % @column_max * (cursor_width + 32)
          y = i / @column_max * cursor_height - self.oy
          if mx.between?(x, x + cursor_width) && 
             my.between?(y, y + cursor_height)
            @index = i
            break
          end
        end
      end
    end
    mouse_win_select_update
  end
end

#===============================================================================
# ** Arrow_Enemy
#-------------------------------------------------------------------------------
#   ...
#===============================================================================

class Arrow_Base < Sprite
  #-----------------------------------------------------------------------------
  # * Alias Listings
  #-----------------------------------------------------------------------------
  alias_method :mouse_arrow_base_update, :update
  #-----------------------------------------------------------------------------
  # * Mouse Enabled?
  #-----------------------------------------------------------------------------
  def mouse_enabled?
    if @mouse_enabled.nil?
      @mouse_enabled = Mouse::Selectable_Objects[self.class.to_s] == true
    end
    return @mouse_enabled == true
  end
  #-----------------------------------------------------------------------------
  # * Update
  #-----------------------------------------------------------------------------
  def update
    mouse_arrow_base_update
    update_mouse($game_troop.enemies) if self.is_a?(Arrow_Enemy)
    update_mouse($game_party.actors)  if self.is_a?(Arrow_Actor)
  end
  #-----------------------------------------------------------------------------
  # * Update Mouse
  #-----------------------------------------------------------------------------
  def update_mouse(battlers)
    if self.mouse_enabled?
      mx, my = *Mouse.position
      for index in 0...battlers.size
        battler = battlers[index]
        bitmap = RPG::Cache.battler(battler.battler_name, 0)
        width, height = bitmap.width, bitmap.height
        x, y = (battler.screen_x - width / 2), (battler.screen_y - height)
        if mx.between?(x, x + width) && my.between?(y, y + height)
          break if @index == index
          @index = index
          $game_system.se_play($data_system.cursor_se)
          break
        end
      end
    end
  end
end

#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end

EDIT: I just made another feature for it, I'll update it tonight/tomorrow, but now you can set scene-based cursors (for instance, set "001-Weapon01" for Scene_Battle and "Mouse" for default scenes) via Hash constant. I'm gonna make a Window-based setting constant for it too before I post it maybe. Also gotta keep in mind Arrow_Actor, Arrow_Enemy, events, etc... I'll figure it out, hopefully I can keep it simple.
 
I have some work on class Hash.  No comments, unfortunately.  This allows you to sort Hashes and have them evaluate as sorted via :each, :each_key, and :each_value :)each_pair is untouched):

Code:
class Hash
  alias_method :meu_hash_clear, :clear
  def sort
    begin
      sorted = super {|a, b| yield(a[0], a[1], b[0], b[1])}
    rescue LocalJumpError
      sorted = super
    end
    output = {}
    sorted.each {|ar| output.set(ar[0], ar[1])}
    return output
  end
  def sort!
    begin
      sorted = self.sort {|k1, v1, k2, v2| yield(k1, v1, k2, v2)}
    rescue LocalJumpError
      sorted = self.sort
    end
    self.clear
    sorted.each {|key, value| self.set(key, value)}
    return self
  end
  def set(key, value)
    key_order.push(key) unless self.has_key?(key)
    self[key] = value
  end
  def each
    key_order.each {|key| yield(key, self[key])}
  end
  def each_key
    key_order.each {|key| yield(key)}
  end
  def each_value
    key_order.each {|key| yield(self[key])}
  end
  def key_order
    @key_order = self.keys if @key_order == nil
    return @key_order
  end
  def clear
    meu_hash_clear
    @key_order = self.keys
  end
  def to_s
    series = '{'
    # Run Through Each Item with index
    each do |key, value|
      series += ', ' unless series == '{'
      # Add String to Series
      series += key.to_s + ' => ' + value.to_s
    end
    series += '}'
    return series
  end
end

Also, at the end is a nifty :to_s method based off of Array.series_string.
 

Zeriab

Sponsor

I don't really like the idea of changing the Hash to being sorted. At least not the general class being sorted.
I am pretty sure they are currently being placed in a red-black tree accordingly to their hash-values. (Object.hash)

I suggest you create a SortedHash subclass of the Hash class since having the sorted property is by no means requires for the general hash. I know you'll lose some syntactic sugar on this, but I really think this is a better style since a Hash represents an unsorted mapping from one object to another.

*hugs*
- Zeriab
 
How about this then?  It still adds the :sort method to Hash, but that method returns a SortedHash instead of a Hash.  Hash.sort! has been taken out, although it's still in SortedHash (I felt like it, even though with type uncertainties it's unlikely to get good use).  I still get to use all my sugar since I can declare a hash and get a SortedHash with :sort, rather than needing to specifically declare a SortedHash first.

I added comments too:
Code:
#============================================================================== 
# ** Hash    
#==============================================================================

class Hash
  #--------------------------------------------------------------------------
  # * Sort the hash according to |k1, v1, k2, v2| and return a SortedHash
  #--------------------------------------------------------------------------
  def sort
    # Pass the block to Enumerable.sort
    begin
      sorted = super {|a, b| yield(a[0], a[1], b[0], b[1])}
    rescue LocalJumpError # If no block was provided
      sorted = super
    end
    # Initialize the output object
    output = SortedHash.new
    # Set each key in order
    sorted.each {|ar| output[ar[0]] = ar[1]}
    return output
  end
  #--------------------------------------------------------------------------
  # * Turn the hash into a string "{key => value, key => value}"
  #--------------------------------------------------------------------------
  def to_s
    series = '{'
    # Run Through Each Item with index
    each do |key, value|
      series += ', ' unless series == '{'
      # Add String to Series
      series += key.to_s + ' => ' + value.to_s
    end
    series += '}'
    return series
  end
end

#============================================================================== 
# ** Sorted Hash    
#==============================================================================

class SortedHash < Hash
  #--------------------------------------------------------------------------
  # * Create the hash; initialize @key_order
  #--------------------------------------------------------------------------
  def initialize(*args)
    super
    @key_order = self.keys
  end
  #--------------------------------------------------------------------------
  # * Sort the hash according to |k1, v1, k2, v2| and return self
  #--------------------------------------------------------------------------
  def sort!
    # Pass the block to Enumerable.sort
    begin
      sorted = super {|a, b| yield(a[0], a[1], b[0], b[1])}
    rescue LocalJumpError # If no block was provided
      sorted = super
    end
    # Clear existing entries and sorted order
    self.clear
    # Set each key in order
    sorted.each {|ar| self[ar[0]] = ar[1]}
    return self
  end
  #--------------------------------------------------------------------------
  # * Set a value in the hash; add the key to the sort order if it is unique
  #--------------------------------------------------------------------------
  def []=(key, value)
    key_order.push(key) unless self.has_key?(key)
    super
  end
  #--------------------------------------------------------------------------
  # * Run a block on keys and values in the sorted order
  #--------------------------------------------------------------------------
  def each
    key_order.each {|key| yield(key, self[key])}
  end
  #--------------------------------------------------------------------------
  # * Run a block on keys only in the sorted order
  #--------------------------------------------------------------------------
  def each_key
    key_order.each {|key| yield(key)}
  end
  #--------------------------------------------------------------------------
  # * Run a block on values only in the sorted order
  #--------------------------------------------------------------------------
  def each_value
    key_order.each {|key| yield(self[key])}
  end
  #--------------------------------------------------------------------------
  # * Returns an array of keys in the sorted order
  #--------------------------------------------------------------------------
  def key_order
    @key_order = [] if @key_order == nil
    return @key_order
  end
  #--------------------------------------------------------------------------
  # * Return an array of keys in the sorted order
  #--------------------------------------------------------------------------
  def keys
    return key_order
  end
  #--------------------------------------------------------------------------
  # * Return an array of values in the sorted order
  #--------------------------------------------------------------------------
  def values
    vals = []
    key_order.each {|key| vals.push(self[key])}
    return vals
  end
  #--------------------------------------------------------------------------
  # * Clear the hash and its sorted order
  #--------------------------------------------------------------------------
  def clear
    super
    @key_order = self.keys
  end
end
 
I have a simple bitmap negative effect, but it's very slow when the bitmap's more than 100x100.
Anyone has an idea how to improve this?

Code:
class Bitmap
  def negative
    for i in 0...(self.width)
      for j in 0...(self.height)
        pix = self.get_pixel(i, j)
        pix.red = (pix.red - 255) * -1
        pix.blue = (pix.blue - 255) * -1
        pix.green = (pix.green - 255) * -1
        self.set_pixel(i, j, pix)
      end
    end
  end
end
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top