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

Notify me before you post an update of the MACL, I've got my own library of new stuff to submit but I'm just gonna wait 'til last minute so I can just submit it all.

EDIT: Speaking of which...

Code:
#===============================================================================

# ** RGSS.BattleAction

#-------------------------------------------------------------------------------

# Description:

# ------------

#

#   Makes setting battle actions faster and easier, from both the Game_Battler

#   or directly to a Game_BattleAction object itself.

#

# Method List:

# ------------

#

#   Game_BattleAction

#   -----------------

#   do_attack

#   do_skill

#   do_defend

#   do_item

#   do_escape

#   do_nothing

#

#   Game_Battler

#   ------------

#   do_attack

#   do_skill

#   do_defend

#   do_item

#   do_escape

#   do_nothing

#===============================================================================

 

MACL::Loaded << 'RGSS.BattleAction'

 

#===============================================================================

# ** Game_BattleAction

#===============================================================================

 

class Game_BattleAction

  #-----------------------------------------------------------------------------

  # * Name      : Do Attack

  #   Info      : Sets Battle Action for Attack

  #   Author    : Kain Nobel

  #   Call Info : Target (Optional) is a type of Game_Battler

  #-----------------------------------------------------------------------------

  def do_attack

    @basic    = 0

    @kind     = 0

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Skill

  #   Info      : Sets Battle Action for Skill

  #   Author    : Kain Nobel

  #   Call Info : Skill ID (Numeric) is ID of skill (Optional)

  #               Target (Optional) is a type of Game_Battler

  #-----------------------------------------------------------------------------

  def do_skill(skill_id = 0)

    unless $data_skills[skill_id].is_a?(RPG::Skill)

      clear

      return

    end

    @kind     = 1

    @skill_id = skill_id

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Defend

  #   Info      : Sets Battle Action for Defend

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_defend

    @basic    = 1

    @kind     = 0

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Item

  #   Info      : Sets Battle Action for Item

  #   Author    : Kain Nobel

  #   Call Info : Item ID (Numeric) is ID of item (Optional)

  #               Target (Optional) is a type of Game_Battler

  #-----------------------------------------------------------------------------

  def do_item(item_id = 0, target = nil)

    unless $data_items[item_id].is_a?(RPG::Item)

      clear

      return

    end

    @kind     = 2

    @skill_id = item_id

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Escape

  #   Info      : Sets Battle Action for Escape

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_escape

    @kind   = 0

    @basic  = 2

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Nothing

  #   Info      : Sets Battle Action for Nothing

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_nothing

    @kind   = 0

    @basic  = 3

  end

end

 

#===============================================================================

# ** Game_Battler

#===============================================================================

 

class Game_Battler

  #-----------------------------------------------------------------------------

  # * Name      : Do Attack

  #   Info      : Current Action Does Attack and Selects Target

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_attack

    self.current_action.do_attack

    if $scene.respond_to?(:set_target_battlers)

      $scene.set_target_battlers(1)

    end

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Skill

  #   Info      : Current Action Does Skill and Selects Target

  #   Author    : Kain Nobel

  #   Call Info : Skill ID (Numeric) Representing Skill from Database

  #-----------------------------------------------------------------------------

  def do_skill(skill_id)

    skill = $data_skills[skill_id]

    self.current_action.do_skill(skill.id)

    if $scene.respond_to?(:set_target_battlers) && !skill.nil?

      $scene.set_target_battlers(skill.scope)

    end

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Defend

  #   Info      : Current Action Does Defend

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_defend

    self.current_action.do_defend

    if $scene.respond_to?(:set_target_battlers)

      $scene.set_target_battlers(0)

    end

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Item

  #   Info      : Current Action Does Item and Selects Target

  #   Author    : Kain Nobel

  #   Call Info : Item ID (Numeric) Representing Item from Database

  #-----------------------------------------------------------------------------

  def do_item(item_id)

    item = $data_items[item_id]

    self.current_action.do_item(item.id)

    if $scene.respond_to?(:set_target_battlers) && !item.nil?

      $scene.set_target_battlers(item.scope)

    end

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Defend

  #   Info      : Current Action Does Escape

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_escape

    self.current_action.do_escape

    if $scene.respond_to?(:set_target_battlers)

      $scene.set_target_battlers(0)

    end

  end

  #-----------------------------------------------------------------------------

  # * Name      : Do Nothing

  #   Info      : Current Action Does Nothing

  #   Author    : Kain Nobel

  #   Call Info : None

  #-----------------------------------------------------------------------------

  def do_nothing

    self.current_action.do_nothing

    if $scene.respond_to?(:set_target_battlers)

      $scene.set_target_battlers(0)

    end

  end

end

 

#===============================================================================

# ** Scene_Battle

#===============================================================================

 

class Scene_Battle

  #-----------------------------------------------------------------------------

  # * Public Instance Variables

  #-----------------------------------------------------------------------------

  attr_reader :target_battlers

  #-----------------------------------------------------------------------------

  # * Alias Listings

  #-----------------------------------------------------------------------------

  alias_method :macl_snbattle_settargetbattlers, :set_target_battlers

  #-----------------------------------------------------------------------------

  # * Set Target Battlers

  #-----------------------------------------------------------------------------

  def set_target_battlers(scope)

    @target_battlers ||= Array.new

    macl_snbattle_settargetbattlers(scope)

  end

end

 

...I just happened to develop this 'on accident' kind of when making my FFXII-ish Gambit system, it speeds up setting common methods for battlers and their actions (do_attack, do_skill, do_escape, do_wait, etc...)

I still need to add an escape method to Game_Actor class, because simply calling actor.do_escape won't hold any merit, only for enemies would that work. Basically, what I mean is methods which will make actors able to escape idependantly rather than all at once. I'll add that and update the script later this week if I have time, but everything else works.
 
Well, nobody answered my post. :(

Does the Macl script have a licence ?
Can we use it in the games we want ? (crediting the authors)

Can we use it in commercial projects ? (crediting the authors too)


I'm using part of Macl in all of my projects :

yhsjjie-9.png


If the authors don't agree, just tell me. ;)
 

Zeriab

Sponsor

I am afraid MACL does not have a license which contributors have to agree to, so it would be normal copyright rules for each part of MACL. Joint copyright where applicable.
The intention has definitely been to allow commercial use, but intention doesn't hold in court.

I give permission to use any part I have copyright for however you see fit and allow you to modify and distribute out however you like naturally without you being able to hold me accountable in any way.

*hugs*
 
I'm using only one function, so I don't really care about licence (I could delete this function).
But MACL have a very good purpose (prevent other scripters from "reinventing the wheel"), so I decided to include its Ruby part in my scripts.

If I'm not using MACL, people who are using my scripts could be interested by it. ;)


And thanks for your permission. :D
 
I've made modifications to the Png_File class. It was using gigantic amounts of memory writing to two separate temporary files, reading back the entirety of those files, then writing them again to the final file. I have also used the Zlib::Deflate class more effectively as a stream rather than a single function, so that instead of caching the data to hoge.gz in method 0, it simply streams it into the deflater (using deflater << [...].pack("C*")). I did all of this because Bitmap#make_png was sometimes choking on large images, encountering a NoMemoryError at the point where make_bitmap_data0 reads from hoge.gz (and getting that error more frequently when using mode 1 instead).

Code:
#============================================================================== 

# ** RGSS.Bitmap.misc

#------------------------------------------------------------------------------

# Description:

# ------------

# Miscellaneous New stuff for the Bitmap class.

#

# Method List:

# ------------

# make_png

#==============================================================================

 

#============================================================================== 

# ** Bitmap

#==============================================================================

 

class Bitmap

  #-------------------------------------------------------------------------

  # * Name      : Make PNG

  #   Info      : Saves Bitmap to File

  #   Author    : ??? - [url=http://www.66rpg.com/htm/news624.htm]http://www.66rpg.com/htm/news624.htm[/url]

  #   Call Info : Zero to Three Arguments

  #               Name : Name of filenam

  #               Path : Directory in Game Folder

  #               Mode : Mode of Writing

  #-------------------------------------------------------------------------

  def make_png(name = 'like', path = '', mode = 0)

    Dir.make_dir(path) if path != ''

    f = Png_File.new(path + name + '.png', 'wb')

    f.make_png(self)

    f.close

  end

end

 

#============================================================================== 

# ** Class Png_File

#------------------------------------------------------------------------------

# Description:

# ------------

# Adds PNG_File class to save Bitmap's to PNG Files

#

# Class List:

# -----------

# Png_File

#==============================================================================

 

#============================================================================== 

# ** Png_File

#==============================================================================

 

class Png_File < File

  #--------------------------------------------------------------------------

  # * Make PNG

  #--------------------------------------------------------------------------

  def make_png(bitmap)

    # Save Bitmap & Mode

    @bitmap = bitmap

    # Create & Save PNG

    self.write(make_header)

    self.write(make_ihdr)

    self.write(make_idat)

    self.write(make_iend)

  end

  #--------------------------------------------------------------------------

  # * Make Header

  #--------------------------------------------------------------------------

  def make_header

    return [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].pack('C*')

  end

  #--------------------------------------------------------------------------

  # * Make IHDR

  #--------------------------------------------------------------------------

  def make_ihdr

    ih_size               = [13].pack("N")

    ih_sign               = 'IHDR'

    ih_width              = [@bitmap.width].pack('N')

    ih_height             = [@bitmap.height].pack('N')

    ih_bit_depth          = [8].pack('C')

    ih_color_type         = [6].pack('C')

    ih_compression_method = [0].pack('C')

    ih_filter_method      = [0].pack('C')

    ih_interlace_method   = [0].pack('C')

    string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +

             ih_compression_method + ih_filter_method + ih_interlace_method

    ih_crc = [Zlib.crc32(string)].pack('N')

    return ih_size + string + ih_crc

  end

  #--------------------------------------------------------------------------

  # * Make IDAT

  #--------------------------------------------------------------------------

  def make_idat

    header  = "\x49\x44\x41\x54"

    data    = make_bitmap_data

    size    = [data.length].pack('N')

    crc     = [Zlib.crc32(header + data)].pack('N')

    return size + header + data + crc

  end

  #--------------------------------------------------------------------------

  # * Make bitmap data

  #--------------------------------------------------------------------------

  def make_bitmap_data

    deflater = Zlib::Deflate.new(8)

    t_Fx = 0

    for y in 0...@bitmap.height

      deflater << [0].pack("C*")

      for x in 0...@bitmap.width

        Graphics.update if (t_Fx += 1) % 10000 == 0

        color = @bitmap.get_pixel(x, y)

        deflater << [color.red, color.green, color.blue, color.alpha].pack("C*")

      end

    end

    return deflater.flush(Zlib::FINISH)

  end

  #--------------------------------------------------------------------------

  # * Make IEND

  #--------------------------------------------------------------------------

  def make_iend

    ie_size = [0].pack('N')

    ie_sign = 'IEND'

    ie_crc  = [Zlib.crc32(ie_sign)].pack('N')

    return ie_size + ie_sign + ie_crc

  end

end

EDIT: I improved my modifications further, removing data = [] completely and streaming the color data directly into the deflater.
 
Here's a new function for the Bitmap class. plane_blt functions just like stretch_blt (where it calls blt instead if the width and height are the same on both dest_rect and src_rect) except that if it comes to the edge of the source bitmap, it wraps around. You could use this to, say, draw a fog to a very large bitmap, starting at any x,y offset. If bmp has dimensions 50x50, and src_rect = Rect.new(25, 25, 100, 200) then the bmp will tile over those dimensions, resulting in something like this:

Code:
,.,

|M|

|M|

`*`

I made this function for the Map Image Maker to draw panoramas and fogs to the full size bitmap, as well as small 32x32 tiles offset the correct amount so that if you drew the tiles individually, then pieced them together, the plane bitmap continuously loops as if you had only called the function once (though of course calling the function many times instead of once is not optimal, but in this case only done when necessary)

[rgss]class Bitmap
  #-----------------------------------------------------------------------------
  # * Draw bitmap to self; if rect goes outside, loop around
  #-----------------------------------------------------------------------------
  def plane_blt(dest_rect, bmp, src_rect = bmp.rect, op = 255)
    # Flag to stretch bitmap or not
    stretch = (dest_rect.width != src_rect.width or
               dest_rect.height != src_rect.height)
    # Starting coordinates
    sx = src_rect.x % bmp.width
    dx = dest_rect.x
    # Source width remaining
    swr = src_rect.width
    while (swr > 0)
      # Starting coordinates
      sy = src_rect.y % bmp.height
      dy = dest_rect.y
      # Source height remaining
      shr = src_rect.height
      # Width for this column
      sw = [bmp.width - sx, swr].min
      dw = dest_rect.width * sw / src_rect.width
      while (shr > 0)
        # Height for this column
        sh = [bmp.height - sy, shr].min
        dh = dest_rect.height * sh / src_rect.height
        # Draw bitmap using stretch function if necessary
        if stretch
          self.stretch_blt(Rect.new(dx,dy,dw,dh), bmp, Rect.new(sx,sy,sw,sh),op)
        else
          self.blt(dx, dy, bmp, Rect.new(sx, sy, sw, sh), op)
        end
        sy = 0    # Set Y value to wrap around
        shr -= sh # Reduce height remaining
        dy += dh  # Increase destination coordinate
      end
      sx = 0    # Set X value to wrap around
      swr -= sw # Reduce width remaining
      dx += dw  # Increase destination coordinate
    end
  end
end
[/rgss]
 
Nice additions.

I am currently spending most of my time working on a re-write of the default scripts all together. Working on including most of our MACL/SDK elements, as well as a few tricks I have yet to even release. It will be easier for me to convert that back into the MACL once it is completed. I have a lot of scripts to go through (250+ project folders, and half of them have snippets I've been collecting over the years) so I hope to have lots and lots of things to go through to get all methods updated. Going to re-do some formatting on methods and such.

Still working on that php system I started long ago. Luckily my php/mySQL skills are at the level where I can complete this. Run down on system plans so far.

Login System (Required to submit or propose modification)
- Registered users can add methods to a class, submit a modification and note behind a modification to be approved by myself (and selected admin), or submit a new class or mod. All additions require approval. Any setup constants can be added as well.
- Validation and IP address tracking to avoid abuse.

Build your owm MACL!
- Choose what script elements to build your owm MACL file. A selectable list will be generated for each addition to the macl. You'll see something like this:

[ ] 1.0: Ruby Additions (Classes)
[ ] - 1.1: Object
[ ] -- 1.1.1 <method_name>
[ ] -- 1.1.2 <method_name>
[ ] -- 1.1.3 <method_name>
[ ] - 1.2: Module
[ ] -- 1.2.1 <method_name>
[ ] -- 1.2.2 <method_name>

Select your parts, press submit and a .txt and .rb file will be generated. The text file will be what is placed in the editor and include documentation (credits) and setup (constants) as well as the code to include the .rb file. Rb file will be built for all selected elements.

- Instead of parts (MACL::Loaded << 'Ruby.array.misc'), methods will be logged (or new class and modules). More work to check for script dependencies, but will cut down size of MACL file (of course, will leave easier methods for scripters to just require complete MACL or bigger parts).

With all this re-vamping, I plan to actually break away from the MACL altogether. Planning on renaming this project all together, and going back to a 1.0 version. Each method will have its own version as well, starting from 1.0. This will help keep track of the most updated version (as people like me have 5 versions of the same method lol). All updates will be tracked automatically. So when we (admins) approve modifications and additions, a log is generated and the project version number updates itself. 1.0.1, 1.0.2, etc. It will updated to 1.1, 1.2 when I perform huge updates personally. This will allow users and scripters to track updates a lot easier than versions in the MACL.

I am up for a new project name here. Plan on breaking away for RMXP specifically and making this a Ruby project (Rails, Wx::Ruby, etc.). So for now, main sections stand at:

Ruby Library (Classes)
Ruby Library (Modules)
User Library (Classes)
User Library (Modules)
RGSS Library (RPG)
RGSS Library (Classes)
RGSS Library (Modules)
RGSS Library (Editor)
RGSS2 Library (RPG)
RGSS2 Library (Classes)
RGSS2 Library (Modules)
RGSS2 Library (Editor)

All up for a new project name, or any suggestions for the direction this is going. Main goal is to make this more open than just a RMXP project, and making updates happen at anytime. I don't want to overcomplicate things, but I am always up for change and evolution.
 
I don't want my name in it, as it is a community project, and with what I have planned, any co-admin will be able to update it without me (and you better believe I am electing you for one of those positions). I only want to get it going and after that, will be here for maintenance purposes.

And besides, just like Trickster you forgot Module lol
 
Yeah, I'll host it there (will get a .tk domain once we get a name), but will perform regular backups and give all admins access to download SQL tables so if my hosting ever goes down and someone else wants to host it, I can walk someone threw it.

SRL (Scripter's Ruby Library)

or we can step away from acroynms altogether. Whatever we decide, you'll be able to find it at:

www.name.tk

Already begun working on index page, GUI, pages and and SQL table layout. Depending on how long it takes me to help a friend move on my days off, I could have this up and running as soon as friday night. :biggrin:
 
problem with underline and spiketrough

im calling this:
self.bitmap.font.underline = true
self.bitmap.draw_text(0, 0, needed_rect.width, needed_rect.height, "text")

Give me a error:
5575
cant covert finxium into string
 

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