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

What I did with making a battler is basically this:
Code:
class Game_Character
  attr_accessor :battler
  def initialize
    [..]
    @battler = Game_Battler.new
  end
end

class Game_Event
  def setup_battler #In the event name, make [xx] where xx is the two-digit index of the battler
    if @event.name =~ /\[[ ]*([00-99]+)\]/i
      @battler = Game_Battler.new($1)
    end
  end
end

class Game_Player
  #--------------------------------------------------------------------------
  # * Setup Battler : Connect Battler to Player
  #--------------------------------------------------------------------------
  def setup_battler
    @battler = $game_party.actors[0]
  end
end
I did not actually provide for calling setup_battler; not sure where it does get called, actually.  Just went into the project to find it, the only place I used it is in Scene_Title:
Code:
  #-------------------------------------------------------------------------- #****
  # * Command: New Game : Party Setup
  #--------------------------------------------------------------------------
  def commandnewgame_partysetup
    # Set up initial party
    $game_player.setup_battler
  end
Because, since I only have one party member, ever, I'm getting rid of $game_party and migrating all its functions to Game_Battler (also getting rid of the Actor/Enemy distinction, but I've made sure all the functions I just gave you correlate to the default script setup)
 
Ok. I'll check into Window Sprites and Moveable.

It was in RGSS.Character under Game_Character, the update method, it also calls refresh. Silly.

@mew: Pretty cool stuff.
 
SephirothSpawn":25gk8d79 said:
@Charlie Lee: Not a bad idea. I might modify that to make it more dynamic and customizable.
[...]
How's that work?

:straightthumb:
As a development of my initial idea i was thinking about creating two types of shortcuts. The first one is this one, which only moves the cursor; a second one could even trigger the command. However the command selection is usually done within the scenes code, so what could be done in the MACL would be only to provide a support for it... maybe a variable to be checked by the scene code. Opinions?
 

e

Sponsor

I skimmed through the text file and I couldn't anything related to this; and obviously I shouldn't post this in the request forum...anyhow:

A Geometry module containing basic data structures would be appreciated. Sure, there are some draw methods, but that's about it. Having a nicely contained, basic module would be nice; things like Point, Line, Polygon, Ellipse, Circle (yes, I know, it's an Ellipse, but I think the equations are computed in a more efficient manner than with the ellipse), etc.

It's not necessary, I suppose, but it eases development, handling and code logic.
 
I was actually thinking of going through my old college math books and adding some things to the MACL, but it's not really a priority right now, so that will probably be in the 2.5 version.
 
Y'know what you should throw into the 2.5 version? I think the main section of the MACL you should add some re-writes to the SDK (if defined), namely the .check_requirements() method. I want to be able to use SDK.check_requirements() to check for MACL scripts. So if MACL.loaded?('RGSS.Map'), then it'll execute the script as long as we've got 'RGSS.Map' loaded. It' should obviously still work like it normally does, but the overwrite would check MACL scripts in question too.
 
I have thought of this in the past. The only thing is, every part of the MACL is included. Unlike the SDK, the MACL is a collection of methods. The SDK is method splits. So including individual methods would be a ton of work. So as is right now, every method is included, so of course MACL.loaded.include?('RGSS.Map') (which isn't much longer than what you suggested) will return true.

Unless I am missing what you are saying. I will add some SDK-typed methods in there, but in all honesty I don't think they will be very useful. The only thing I can see anyone not including, would be the modules/systems (like if someone uses a different keyboard).
 
SephirothSpawn":3cdladhb said:
I have thought of this in the past. The only thing is, every part of the MACL is included.

...I hope you weren't thinking I was talking about checking for every method did you? That'd be tedious, I'm just talking about checking something like "Do you have 'RGSS.Whatever' in your project"? If not, then it would return some kinda error message like...

"'Your Script' was disabled for the following reason.
You are missing these parts of the Method & Class Library :

['RGSS.Example']"

Whenever something like the following example is called...

MACL::Loaded << "RGSS.Whatever"

Then it is loaded, but if somebody doesn't have that section it is never called into the MACL::Loaded array, because obviously MACL::Loaded << is called within the script itself, so it'll return false. All it needs is to disable the script then print a formatted error message, telling you that you need "RGSS.Example" to run "Your Script".

Since SDK is primarily something in which methods like this are already used, and since MACL Libraries are placed below SDK, you could overwrite the methods directly, if defined?(SDK) like so...

Code:
if defined?(:SDK)

module SDK
  # Overwrite check_requirements
end

end

...and be able to check both SDK Enabled Scripts and MACL sections simultaneously.

^^I've actually started something like this earlier, and it sorta works like what I was trying to describe but its not ready yet. However, while I'm still tinkering with it I'll submit some other stuff you might enjoy.

Code:
#===============================================================================
# ~** Character Move Test **~
#-------------------------------------------------------------------------------
# Written By  : Kain Nobel
# Version     : 2.0
# Last Update : 09.02.2008
#===============================================================================
# Description
# -----------
#
#   This is a special set of methods, that will tell you which direction a
#   character or event is moving, and supports both 4 and 8 directional movement
#   checking.
#
#   When checking something like $game_map.events[1].moving_down?, you have the
#   optional argument 'diag'. If you set this argument as 'true' and a player is
#   moving_lower_left, then it'll return false, else it'll return true for both.
#
#   Also, for Game_Player, we've got additional methods for checking if player
#   is 'attempting' to move a certain direction. This is for scripts that want
#   to know, "Is he just 'attempting' to move left, or is he 'really' moving
#   left? So, it doesn't check for Input, rather it'll check for Movement AND
#   Input.
#
# Methods List
# -------------
# Game_Character
#   moving_down?
#   moving_left?
#   moving_right?
#   moving_up?
#   moving_upper_left?
#   moving_upper_right?
#   moving_lower_left?
#   moving_lower_right?
#   move_direction
#   moving_diagonal?
#
# Game_Player (< Game_Character)
#   attempt_down?
#   attempt_left?
#   attempt_right?
#   attempt_up?
#   attempt_upper_left?
#   attempt_upper_right?
#   attempt_lower_left?
#   attempt_lower_right?
#   attempt_moving?
#   attempt_direction?
#   attempt_diagonal?
#
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('RGSS.Character.MoveTest', 'Kain Nobel', 2.0, '09.21.2008')
#-------------------------------------------------------------------------------
# * SDK Enabled Test - BEGIN
#-------------------------------------------------------------------------------
if SDK.enabled?('RGSS.Character.MoveTest')
#===============================================================================
# ** Game_Character
#-------------------------------------------------------------------------------
#   The parent superclass of Game_Player and Game_Event has been modified to
# return detailed information on which direction a character is moving.
#===============================================================================
class Game_Character
  #-----------------------------------------------------------------------------
  # * Moving Down?
  #-----------------------------------------------------------------------------
  def moving_down?(diag = false)
    if diag ; return (self.real_y < self.y*128) && (self.real_x == self.x*128)
    end ; return (self.real_y < self.y * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Left?
  #-----------------------------------------------------------------------------
  def moving_left?(diag = false)
    if diag ; return (self.real_x > self.x*128) && (self.real_y == self.y*128)
    end ; return (self.real_x > self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Right?
  #-----------------------------------------------------------------------------
  def moving_right?(diag = false)
    if diag ; return (self.real_x < self.x*128) && (self.real_y == self.y*128)
    end ; return (self.real_x < self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Left?
  #-----------------------------------------------------------------------------
  def moving_up?(diag = false)
    if diag ; return (self.real_y > self.y*128) && (self.real_x == self.x*128)
    end ; return (self.real_y > self.y * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Lower Left?
  #-----------------------------------------------------------------------------
  def moving_lower_left?
    return (self.real_y < self.y * 128) && (self.real_x > self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Lower Right?
  #-----------------------------------------------------------------------------
  def moving_lower_right?
    return (self.real_y < self.y * 128) && (self.real_x < self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Lower Left?
  #-----------------------------------------------------------------------------
  def moving_upper_left?
    return (self.real_y > self.y * 128) && (self.real_x > self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Moving Lower Right?
  #-----------------------------------------------------------------------------
  def moving_upper_right?
    return (self.real_y > self.y * 128) && (self.real_x < self.x * 128)
  end
  #-----------------------------------------------------------------------------
  # * Move Direction?
  #-----------------------------------------------------------------------------
  def move_direction
    return 2 if moving_down?
    return 4 if moving_left?
    return 6 if moving_right?
    return 8 if moving_up?
    return 1 if moving_lower_left?
    return 3 if moving_lower_right?
    return 7 if moving_upper_left?
    return 9 if moving_upper_right?
    return 0
  end
  #-----------------------------------------------------------------------------
  # * Moving Diagonal?
  #-----------------------------------------------------------------------------
  def moving_diagonal?
    return true if moving_upper_left? or moving_upper_right?
    return true if moving_lower_left? or moving_lower_right?
    return false
  end
end

#===============================================================================
# ** Game_Player
#-------------------------------------------------------------------------------
#   The child class of Game_Character, returns user's directional input to tell
# you if they're 'attemtping' to move a certain direction.
#===============================================================================
class Game_Player < Game_Character
  #-----------------------------------------------------------------------------
  # * Attempt Down?
  #-----------------------------------------------------------------------------
  def attempt_down?(diag = false)
    unless Input.press?(Input::LEFT) || Input.press?(Input::RIGHT)
      return Input.press?(Input::DOWN)
    end ; return false
  end
  #-----------------------------------------------------------------------------
  # * Attempt Left?
  #-----------------------------------------------------------------------------
  def attempt_left?(diag = false)
    unless Input.press?(Input::UP) || Input.press?(Input::DOWN)
      return Input.press?(Input::LEFT)
    end ; return false
  end
  #-----------------------------------------------------------------------------
  # * Attempt Right?
  #-----------------------------------------------------------------------------
  def attempt_right?(diag = false)
    unless Input.press?(Input::UP) || Input.press?(Input::DOWN)
      return Input.press?(Input::RIGHT)
    end ; return false
  end
  #-----------------------------------------------------------------------------
  # * Attempt Up?
  #-----------------------------------------------------------------------------
  def attempt_up?(diag = false)
    unless Input.press?(Input::LEFT) || Input.press?(Input::RIGHT)
      return Input.press?(Input::UP)
    end ; return false
  end
  #-----------------------------------------------------------------------------
  # * Attempt Upper Left?
  #-----------------------------------------------------------------------------
  def attempt_upper_left?
    m = Input.press?(Input::UP) && Input.press?(Input::LEFT)
    if defined?(Aleworks) && !m ; m = Input.press?(Input::UPPER_LEFT)
    end ; return m
  end
  #-----------------------------------------------------------------------------
  # * Attempt Upper Right?
  #-----------------------------------------------------------------------------
  def attempt_upper_right?
    m = Input.press?(Input::UP) && Input.press?(Input::RIGHT)
    if defined?(Aleworks) && !m ; return Input.press?(Input::UPPER_RIGHT)
    end ; return m
  end
  #-----------------------------------------------------------------------------
  # * Attempt Lower Left?
  #-----------------------------------------------------------------------------
  def attempt_lower_left?
    m = Input.press?(Input::DOWN) && Input.press?(Input::LEFT)
    if defined?(Aleworks) && !m ; return Input.press?(Input::LOWER_LEFT)
    end ; return m
  end
  #-----------------------------------------------------------------------------
  # * Attempt Lower Right?
  #-----------------------------------------------------------------------------
  def attempt_lower_right?
    m = Input.press?(Input::DOWN) && Input.press?(Input::RIGHT)
    if defined?(Aleworks) && !m ; return Input.press?(Input::LOWER_RIGHT)
    end ; return m
  end
  #-----------------------------------------------------------------------------
  # * Attempt Moving?
  #-----------------------------------------------------------------------------
  def attempt_moving?(diag = false)
    return true if attempt_down?(diag)
    return true if attempt_left?(diag)
    return true if attempt_right?(diag)
    return true if attempt_up?(diag)
    return attempt_diagonal?
  end
  #-----------------------------------------------------------------------------
  # *  Attempt Direction
  #-----------------------------------------------------------------------------
  def attempt_direction?
    if    attempt_down?         ; return 2
    elsif attempt_left?         ; return 4
    elsif attempt_right?        ; return 6
    elsif attempt_up?           ; return 8
    elsif attempt_lower_left?   ; return 1
    elsif attempt_lower_right?  ; return 3
    elsif attempt_upper_left?   ; return 7
    elsif attempt_upper_right?  ; return 9
    else                        ; return 0
    end
  end
  #-----------------------------------------------------------------------------
  # * Attempt Diagonal?
  #-----------------------------------------------------------------------------
  def attempt_diagonal?
    return true if attempt_upper_left?
    return true if attempt_upper_right?
    return true if attempt_lower_left?
    return true if attempt_lower_right?
    return false
  end
  #-----------------------------------------------------------------------------
  # * Attempt Print Test
  #-----------------------------------------------------------------------------
  def attempt_print_test(diag = false)
    print("Down : "+attempt_down?(diag).to_s+
    "\nLeft : "+attempt_left?(diag).to_s+
    "\nRight : "+attempt_right?(diag).to_s+
    "\nUp : "+attempt_up?(diag).to_s+
    "\nUpRight : "+attempt_upper_right?.to_s+
    "\nUpLeft : "+attempt_upper_left?.to_s+
    "\nDownRight : "+attempt_lower_right?.to_s+
    "\nDownLeft : "+attempt_lower_left?.to_s)
  end
end
#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end

Code:
#===============================================================================
# ** RGSS.RTP
#-------------------------------------------------------------------------------
# Written by  : Kain Nobel
# Version     : 1.0
# Last Update : 08/19/2008
# Created On  : 08/16/2008
#-------------------------------------------------------------------------------
# * Description :
#
#   This script reads the GameINI and the Window's Registry to return the data
#   information of the Run Time Package(s) the game has assigned. You can list
#   files from a single RTP, or all RTP files, with ease.
#-------------------------------------------------------------------------------
# * Requirements :
#
#   This script requires the Aleworks Library to read the Window's Registry.
#   You can find what you need by visiting this topic
#
#   - http://www.rmxp.org/forums/index.php?topic=28392.0
#-------------------------------------------------------------------------------
# * Instructions :
#
#   Place The Script Below the SDK and Above Main.
#===============================================================================

MACL::Loaded << 'RGSS.RTP'

#===============================================================================
# ** GameINI
#-------------------------------------------------------------------------------
#   This module simply reads Game.ini file located in the parent Game folder.
#===============================================================================

module GameINI
  def self.read(entry)
    File.open("Game.ini").each{ |row|
    if row =~ Regexp.new("^" + entry + "=.*$")
      str = (row.scan(Regexp.new("^" + entry + "=(.*)$"))[0]).to_s
      return str == "" ? '(none)' : str
    end
    }
    File.close("Game.ini")
  end
end

#===============================================================================
# ** RTP
#-------------------------------------------------------------------------------
#   This class simply sets up RTP information for use in other scripts.
#===============================================================================

module RTP
  #-----------------------------------------------------------------------------
  # * Public Instance Variables
  #-----------------------------------------------------------------------------
  attr_reader :files
  #-----------------------------------------------------------------------------
  # * RTP.files(n)
  #-----------------------------------------------------------------------------
  def RTP.files(n = 1)
    requirement_test
    return if !n.is_a?(Numeric)
    filepaths = []
    n = n.to_s unless n.is_a?(String)
    key = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Enterbrain\\RGSS\\RTP\\'
    data = Aleworks::Registry.read_entry(key, GameINI.read('RTP'+n))
    data.gsub!('\\', '/') unless data.nil?
    return data
  end
  #-----------------------------------------------------------------------------
  # * RTP.list_all(directory)
  #-----------------------------------------------------------------------------
  def RTP.list(directory)
    requirement_test
    return if !directory.is_a?(String)
    files = Dir.new(directory).entries
    files[0,2] = nil, nil
    for i in 1...3
      unless RTP.files(i).nil?
        dir = Dir.new(RTP.files(i)+directory).entries
        dir[0,2] = nil, nil
        files += dir
      end
    end
    files.compact!
  end
  #-----------------------------------------------------------------------------
  # * RTP.requirement_test
  #-----------------------------------------------------------------------------
  def RTP.requirement_test
    unless defined?(Aleworks) && Aleworks.is_a?(Module)
      print("Please install the Aleworks Library to read the Windows Registry,",
      "you can find it @\n http://www.rmxp.org/forums/index.php?topic=28392.0")
      exit
    end
  end
end

^^As basic as this is, and even though this requires Aleworks libraries to read the Windows Registry, this module has came in useful to me for a couple times, bust mostly listing RTP Audio files. To sum it all up, it reads files from both the Game directory, and its assigned RTP directories (and sub-directories) and can return a list of files 'n stuff.

Although this module is small at the moment, I will be expanding this for the future RTP File Manager (if I ever get around to doing it), which will be used for pre-launch of games who use seperate RTPs which cuts/copies your graphics and audio into your game folder if it has been logged. (Please note, this doesn't do that yet, this is just something I've been thinking about for awhile.)

If you need, I'll add the proper heading for the 'RGSS.RTP' module methods tomorrow, and explain what they do so far, which isn't a whole lot yet.
 
A single module what holds all the API declaration, vs. putting a bunch of API into modules. This will prevent multiple scripts creating and using the same API, creating multiple objects.

Code:
module API
  Function_Name = WinAPI.new(.....)
  Funciton_Name = WinAPI.new(...)
end

I actually had a code, that generated this automatically, reading all the win32 api functions, but it ended up as one big ass code. I need to dig that up again.
 
I don't know how much of that to include because there are so many dll/dll functions in there. I kinda want to just include it all (better to have too much that too little, as the Compiler I am working will remove un-needed parts anyways). But if I do include it all (I probably will unless someone has a better suggestion), I will divide each dll into it's own module

Code:
module API
  module Digest
    # functions
  end
  module User32
    # functions
  end
end

That should make calling and organization easier.
Code:
API::User32.MessageBox(0, 'Message', 'Title', 0)

A little simpler than
Code:
api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
api.call(0, 'Message', 'Title', 0)
 

e

Sponsor

Yeah, most likely. Also, is there a list of missing stuff from the MACL? I've got a couple of utility things that could be of use, like a Collections module (queues, deques, stacks, lists, etc.), a Sort module (quicksort, heapsort, shellsort, etc.) and a bunch of Geometry classes that could be modularized (Geometry, Geometry::Point, Geometry::Polygon, Geometry::Ellipse, etc.).

We could also include a Physics module to calculate stuff like projectile arcs, velocity, free falls, etc.
 
I'm guessing I'm probably the only person that has utilized 'Modules.Event_Spawner' thus far, but it is a really great concept yet needs alot of other things debugged from it, that and 'RGSS.Map', because RGSS gives me so much crap about deleting events and changing maps and spawning events and the such. I've prettymuch had to start my own SDK portions for it, and alias my private 'SDK' method splits later on and check if 'event.nil?' everywhere I go in the editor that has to do with events.

I know this isn't the SDK topic, but since this has to do with the SDK-ish method splits I've had to do to overcome problems, I'll already tell you some of the stuff I had to split and alias just to use these two systems together, just because I don't want to overwrite everything...

Game_Map
  #passable?
    -events_passable?(event, x, y, self_event, bit)
    -tiles_passable?(tile_id, x, y, bit)

Interpeter
  #setup_starting_event
    -setup_starting_event_refresh
    -setup_starting_event_common_reserve
    -setup_starting_event_map(event)
    -setup_starting_event_common(common_event)

I've also had to alias Sprite_Character#update (unless @character.nil? ; rgss_map_sprite_char_update ; end) since updating a nil @character pops error as well.

Yet, I still get errors in other event-related places, because of nil events, which really sucks because I want to use both of these together without having to worry about the nil event errors. If it isn't a total loss, I'd still like to use 'RGSS.Map' and 'Event_Spawner' together in future scripts, even if I have to SDK-ize everything to prevent overwritting (and to prevent saving a bunch of spawned events and using a bunch of self switches). So, let me know if you're going to fix everything or if you would like my help, or if I should just do everything myself and try 'n fix it.

I guess there could be other work arounds, but since its all your origional work I figured I should share all this with you, and I'll post everything I've done which has resolved some issues so far if you would like me to, but like I said some of it involves its own SDK type splits just to overcome unless you want to start overwritting stuff...

I donno, unless you've got your own way you want to overcome these issues, its definately something you'll really have to sit down and tinker with! I hope to still be able to use it in the future without worry of game-crashing bugs (like NilClass errors with deleted events).
 
The next SDK will have the Sprite_Character#update method split up.

The passable? method diffently needs split up. I'll look into the setup_starting_event as well.

If you find any errors with anything in the SDK/MACL, let me know, and I'll fix 'em.
 
http://www.owainc.net/scripts/modules.api.txt


Ok. That's what I have done with API so far. Right now, I have it divided into 7 different parts to keep it under 10,000 lines. Which means the API addition alone is about 4 times larger than the rest of the MACL. :p

Code:
#==============================================================================
# ** API
#==============================================================================

module API
  #-------------------------------------------------------------------------
  # * Name      : Current API Module Version
  #   Author    : SephirothSpawn
  #   Call Info : API Arguments, Function Arguments
  #-------------------------------------------------------------------------
  def self.call(api_arguments, function_arguments)
    # Gets instance name
    instance_name = "@#{api_arguments[1]}"
    # Gets instance variable
    instance = eval instance_name
    # If nil instance variable
    if instance.nil?
      p 'create'
      # Create instance variable
      eval "#{instance_name} = Win32API.new(*api_arguments)"
    end
    # Get instance variable
    instance = eval instance_name
    # Call Instance
    instance.call(*function_arguments)
  end
end

All the instances will be created in the base API module, and every other sub-module just calls the method with the parameters involved. That cut down the
Code:
if @instance.nil?
  @instance = 
end
@instance.call

Down to
Code:
API.call(api_arguments, function_arguments)

A little bit shorter when there are I believe 6140-6150 methods.

The list is organized by API name, and each method is organized by function name, in alphabetical order.
 

e

Sponsor

Pretty neat. All that's missing now is a builder. Actually, we should probably do a web builder for the MACL (along with the API), a la Mootools or something.

You go on a given page, select the sections you want, and you download the generated file which contains only the sections you wanted. That'd be kinda cool.

I could do it if you want.
 

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