Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - ForeverZer0

61
Sea of Code / Zlib: IronRuby VS Ruby
August 17, 2011, 11:17:30 pm
I am having a bit of a problem that I can't seem to figure out.  I am using IronRuby's Zlib Library in a .NET application through embedded to compress strings. Here's a sample of a script I am using, and calling through the application:


load_assembly 'IronRuby.Libraries', 'IronRuby.StandardLibrary.Zlib'

def load(path)
  file = File.open(path, 'rb')
  object = Marshal.load(file)
  file.close
  return object
end

def save(object, path)
  file = File.open(path, 'wb')
  Marshal.dump(object, file)
  file.close
end

def decompress(string)
  return Zlib::Inflate.inflate(string)
end

def compress(string)
  zlib = Zlib::Deflate.new(Zlib::BEST_COMPRESSION)
  compressed = zlib.deflate(string, Zlib::FINISH)
  return compressed
end


This works perfectly fine.  It also works for inflating objects that were Marshalled with Ruby 1.8.6. The problem arises when I compress and Marshal the string with IronRuby, then attempt to read the data in Ruby 1.8.6.  The compressed data is different, and I get "incorrect data check" errors.  It still loads fine in IronRuby, though, so I'm not sure if it has something to do with different versions of the Zlib library, so if is simply an incompatibility between the languages.  I have tried compressing the data in various ways as well, using a "--Zlib::MAX_WBITS", and every possible compression level, all still to no avail.  Its getting rather frustrating...  :???:

Any ideas?
62
Development Tools / [C#] GIF Ripper
August 03, 2011, 11:44:40 pm
GIF Ripper
Authors: ForeverZer0
Version: 1.0



Introduction

Have you ever wanted to extract the individual frames from a .gif file, but found it tedious to do in a normal graphics program?  Your problems are no more!  This application can batch rip all the frames from hundreds of .gif images at once, and within seconds.  It supports reading web addresses, so you don't even need to download the file to rip it.  All output files can be saved in one of six different formats, so there should be no need to convert them again afterwards.  Perfect getting them images from animations to your masterpiece spriteset.


Features


  • Lightweight, fast, and requires no installation

  • Supports outputting in six formats (.png, .jpg, .bmp, .tff, .exf, .gif)

  • Supports reading URLs

  • Simple and intuitive interface

  • Can import .gif files by simply dragging and dropping onto the window




Screenshots

Add your files...: ShowHide


Click to rip and convert: ShowHide


Input File: ShowHide

Output Files: ShowHide










Download

Requires Microsoft's .NET Framework 2.0 or higher.  Download and install if the program fails to start.

GIF Ripper.exe (181 KB)



Credits and Thanks


  • ForeverZer0




Author's Notes

This application is protected under the following license:
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

Please report any bugs/issues you have so they can be resolved.
Enjoy!
63
General Discussion / Decryption Test
July 18, 2011, 10:04:52 pm
As promised, I am uploading a sort sample of a "protection" method for RMXP games.
I am basically trying to get a feel for  how easy/hard it is for people to crack.  Some of you will know immediately how I did it, but I ask you not to go shouting it out just yet, since that is part of the protection.  Even with that knowledge, still see if you can find a way to unlock the files.

If you do manage to unlock the files, once again do not post your method at first, give others a chance to try.  Simply post the name of the method I added to Scene_Map, the name of the audio file played, and the name of the graphic file used in the demo.  That will be more than enough proof that you were successful.

Okay, without further adieu, here's the link:  DecryptMe!

If you are on a 64 bit system, you may get an error when attempting to start the game.  Just try enough times, and it WILL start.  I used the same method here as my one to make the portable versions of RMXP and RMVX, so the same problems persist.
65
General Discussion / [XP][VX] RPG Maker - Portable
June 25, 2011, 07:18:57 pm
RPG Maker - Portable
By: ForeverZer0




I created portable versions of the RMXP and RMVX editors for those who want to use it on a computer that may not have it installed.  I compiled the editors, RTPs, libraries, and all necessary registry values into single executables.  They have no need for an install, and writes no data to the registry, since everything runs its own little sandbox.

The applications are trial versions, so you will need to insert the registration key you were given when you purchased your legal copy of RMXP/RMVX. I will not be providing links to keygens in this topic, so please do not ask.

RPG Maker XP - Portable (43.8 MB)
RPG Maker VX - Portable (69.0 MB) (Extra Graphics included)



Instructions
Simply click and run. There is no install, so it can be run from a USB device, or from wherever you like. If the PC does not have a file association set to the project file, you can either run the program and open it from that, or set the association to this application.



Known Bugs
I have found that it sometimes generates an error on starting the application on 64-bit versions of Windows 7.  I haven't found a fix for this other than to continue to try and start it, which I have found after enough times, will start.  Other versions of Windows I have tested work fine.
66
Using External IDE as a Script Editor
Author: ForeverZer0




As many of you may know, the script editor is very basic and does not have a lot of rich features like other IDEs.  While it is not difficult to write a script in another program like Notepad++, Eclipse, Netbeans, Visual Studio, etc., it is a major pain to constantly copy-paste the script into the editor every time you want to playtest or debug the script.  Having to do so dramatically slows down development, and usually stops most from even bothering with it.  The point of this tutorial is to show you how you can do it and still have the best of both worlds.  The ability to use an external IDE, and still be able to simple click a button to start testing it.



Setting up Notepad++

For this tutorial, I will be using a Notepad++ as our IDE of choice, although the same concept can be applied to nearly all IDEs.  Notepad++ is probably the best overall compromise of power and overhead.  It integrates smoothly into Windows and supports syntax of nearly every language you will find yourself using.  There are a ton of features in Notepad++, but for the point of this tutorial I will be simply explaining how to set it up as a RMXP script editor.

Alright, so first thing first. You will need to install Notepad++. Once you have it installed, go ahead and open it.  There are many useful tweaks that you can make to improve and customize how you want the IDE to behave and allow you to be the most productive, and even setting themes and altering the colors used for different syntaxes.  Go ahead and play around and tweak the settings to try different things out.  Once your done, go to the menu bar and click the "Plugins" option, scroll down to "Plugin Mangager", then select "Show Plugin Manager"

Spoiler: ShowHide


From here you will be presented with a screen listing many various plugins available for download, which you can explore later, but for now we are looking for "NppExec", so scroll down a bit under the "Available" tab and find it.  Once found, check it and click the "Install" button.

Spoiler: ShowHide


Once it has installed and Notepad++ has restarted, you are very close to completion of this portion of the process. Now select the "Plugins" tab again, and you will "NppExec" listed there now, so select it.  There are some various options available, I would suggest checking the "Save all files on execute" option to make things easier on yourself.

Spoiler: ShowHide


After that, select the top option, or simply press F6 from the main screen to bring up the execution dialog.  Here we need to make a command to execute our RMXP game.  It should follow this pattern:
cmd.exe /c " <FULL PATH TO PROJECT'S GAME.EXE> "

You can label it however you want to keep track of multiple projects you may be working on.

Spoiler: ShowHide


Press "OK" to test it out and you should see your game start up.  From this point on you can simply click "Ctrl + F6" to quickly execute the last command from the editor without the need to navigate to this menu.  This is the conclusion of this part of the tutorial, now we just need to make a tweak to our RMXP project to have it read the scripts externally.  



Setting up RPG Maker

Make a new folder in the directory of your game, and name it "MyScripts" or whatever you want. In this folder, you can save all the custom scripts your project uses, just save them all with an .rb extension to denote that they are Ruby scripts.  This can be done multiple ways, just copy-paste the script into Notepad++, select "Save As..." and select "Ruby FIle", and set the directory to this folder.

Spoiler: ShowHide


Once done, we need only add a few lines of code to our project.  Either in "Main" before the "begin", or in a separate slot just above it, add these few lines of code:

DIRECTORY = ''
SCRIPTS = [  ]
SCRIPTS.each {|script| require "#{Dir.getwd}/#{DIRECTORY}/#{script}" }


Due to RMVX behaving strangely, you need to explicitly call "require" through the Kernel in it, like this:
DIRECTORY = ''
SCRIPTS = [  ]
SCRIPTS.each {|script| Kernel.require "#{Dir.getwd}/#{DIRECTORY}/#{script}" }


The DIRECTORY value should be the name of the folder you made earlier to contain your scripts, and the SCRIPTS array contains the names of all the scripts to load from that file.  Remove the scripts from the editor and place their filenames into the list in the order that they would be in the script editor.  Here's an example of one filled out for Chronicles of Sir-Lag-a-Lot:

Spoiler: ShowHide


And as you can see, we can now open all the scripts in the Notepad++ editor like this:

Spoiler: ShowHide


This is basically a little "bootstrap" script.  Alternatively you could create a separate Ruby document to this and simply "require" it.  You can now do any scripting you want to these scripts in the Notepad++.  When you press F6 to run the game, these scripts will be read and used for your game.

Summary: ShowHide

  • Install Notepad++

  • Install NppExec plugin for Notepad++

  • Set command to execute game

  • Create script folder, and export scripts to .rb documents into it

  • Add code snippet to game

  • Run from Notepad++



Also remember that the DEBUG variable will not be defined using this method.  You can fix this yourself by simply adding the line:
$DEBUG = true  # RMXP
$TEST = true  # RMVX

In a script somewhere.
I hope this tutorial was helpful. If there are any questions or you need additional help, feel free to ask.
67
Development Tools / [C#] Snipping Tool
June 17, 2011, 11:56:27 pm
Snipping Tool


This little tool us useful for taking screen captures on portions of the screen. It is a no-install, extremely lightweight application with practically no overhead, and there are a lot of neat features squeezed into the tiny program.



Screenshots

Spoiler: ShowHide

Spoiler: ShowHide

Spoiler: ShowHide




Features


  • Very versatile. Can capture any portion of the screen with a simple click and drag

  • Automatically copies captured image to the clipboard

  • Can save and/or open captured images directly from the application in 3 different formats (PNG, JPEG, Bitmap)

  • Shows in notification area, taskbar, or both. When in left-clicked from notification area, screen capture mode is automatically started for quick snips

  • User definable color and style for the selection rectangle

  • Automatically removes GUI from screen when capture mode begins so it doesn't block any portion of the screen

  • Image preview of snipped screen in GUI





Downloads

(130 KB) by ForeverZer0

Requires [url=http://www.microsoft.com/downloads/info.aspx?na=41&SrcFamilyId=0856EACB-4362-4B0D-8EDD-AAB15C5E04F5&SrcDisplayLang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f7%2f567758a3-759e-473e-bf8f-52154438565a%2fdotnetfx.exe]Microsoft's .NET Framework 2.0
or higher.
Download and install if you get a "Failed to initialize" error when attempting to execute program.
68
RMXP Script Database / [XP] Advanced Pathfinding
May 30, 2011, 04:00:31 pm
Advanced Pathfinding
Authors: ForeverZer0
Version: 1.1
Type: Autonomous Character Movement
Key Term: Custom Movement System



Introduction

This is an advanced an highly intelligent pathfinding system. It allows for the user to either through script or script call quickly and easily have events or the game player automatically walk a path to a given set of coordinates. The system is smart enough to quickly find paths through relatively complex areas, and adjust on the fly for any obstacle that moves to block its path. I used the A* algorithm, basic search algorithm used often for robotics. More on this algorithm can be read about here: A* Search Algorithm


Features


  • Fast and intelligent pathfinding

  • Easy to use script calls

  • Optional "range" parameter can have character find alternate locations if the preferred one is blocked and they are within the given range.

  • Optional callbacks can be given to have something execute if when the character reaches its goal, or when it fails to do so.




Screenshots

Can quickly and easily navigate a maps like these, lag-free:
Spoiler: ShowHide

Spoiler: ShowHide



Demo

Demo Link


Script

Here's the script.
Spoiler: ShowHide

#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Advanced Pathfinding
# Author: ForeverZer0
# Version: 1.1
# Date: 5.30.2011
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#
# Introduction:
#   This is an advanced an highly intelligent pathfinding system. It allows for
#   the user to either through script or script call quickly and easily have
#   events or the game player automatically walk a path to a given set of
#   coordinates. The system is smart enough to quickly find paths through
#   relatively complex areas, and adjust on the fly for any obstacle that moves
#   to block its path. I used the A* algorithm, basic search algorithm used
#   often for robotics. More on this algorithm can be read about here:
#
#               http://en.wikipedia.org/wiki/A*_search_algorithm
#
# Features:
#   - Fast and intelligent pathfinding
#   - Easy to use script calls
#   - Optional "range" parameter can have character find alternate locations
#     if the preferred one is blocked and they are within the given range.
#   - Optional callbacks can be given to have something execute if when the
#     character reaches its goal, or when it fails to do so.
#
# Instructions:
#   - Place script below default scripts, and above "Main".
#   - Use the following script call:
#
#     pathfind(X, Y, CHARACTER, RANGE, SUCCESS_PROC, FAIL_PROC)
#     
#     The X and Y are the only required arguments. The others can be omitted.
#     
#     X - The x-coordinate to pathfind to.
#     Y - The y-coordinate to pathfind to.
#
#     CHARACTER - Either an instance of the character ($game_player,
#                 $game_map.events[ID], etc) or the ID of a character. The ID
#                 will be the event ID. Use -1 for the game player.
#
#     SUCCESS_PROC - A Proc object that will be executed when the player
#                    reaches the defined coordinates.
#     FAILURE_PROC - A Proc object that will be executed when the player
#                    cannot reach the defined coordinates.
#
#   - As default, the pathfinder will make 35 attempts to recalculate a route
#     that gets blocked. This value can be changed in game with the script
#     call:
#           $game_map.collision_retry = NUMBER
#
#     You can change the default value if desired by looking down to the first
#     class below in the main script.
#   - For longer pathfind routes, it is sometimes necessary to reset the
#     search limiter. This may cause increased lag when an object blocks the
#     character from being able to move, but will increase the range that the
#     system can work with. Use the following script call:
#
#         $game_map.search_limiter = NUMBER  (Default 1000)
#
#   - If you are experiencing any compatibility problems, go to the Game_Map
#     class below and set @recalculate_paths to false. This will take away some
#     of the efficiency of recalculating collisions, but will improve may fix
#     your problem.
#
# Compatibility:
#   Highly compatible. May experience issues with Custom Movement scripts,
#   but even then, it is unlikely.
#
# Credits/Thanks:
#   - ForeverZer0, for the script
#   - Special thanks to Jragyn for help making the big maze for the demo and
#     help testing.
#   - Credit goes to the Peter Hart, Nils Nilsson and Bertram Raphael for the
#     original search algorithm that was implemented
#
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

#===============================================================================
# ** Game_Map
#===============================================================================

class Game_Map
 
  attr_accessor :collision_retry
  attr_accessor :recalculate_paths
  attr_accessor :search_limiter
 
  alias zer0_pathfinding_init initialize
  def initialize
    # Initialize instance variables used for pathfinding.
    @collision_retry = 35
    @recalculate_paths = true
    @search_limiter = 1000
    # Original method
    zer0_pathfinding_init
  end
end

#===============================================================================
# ** Interpreter
#===============================================================================

class Interpreter
 
  def pathfind(x, y, *args)
    args[0] = @event_id if args[0] == nil
    args[1] = 0 if args[1] == nil
    # Add a simpler call for using as a script call
    Pathfind.new(Node.new(x, y), *args)
  end
end

#==============================================================================
# ** Pathfind
#==============================================================================

class Pathfind

  attr_reader   :route                 
  attr_accessor :range   
  attr_reader   :goal
  attr_reader   :found
  attr_reader   :character                               
  attr_accessor :success_proc         
  attr_accessor :failure_proc         
  attr_accessor :target   
  attr_accessor :collisions       
 
  def initialize(node, char = -1, range = 0, *callbacks)
    # Set the character. Can either us an ID or an instance of a Game_Character.
    # A value of -1, which is default, is the Game_Player.
    if char.is_a?(Integer)
      @character = (char == -1) ? $game_player : $game_map.events[char]
    elsif char.is_a?(Game_Character)
      @character = char
    end
    # Set forcing flag. Will be disabled for recalculating on the fly.
    @forcing = true
    # Call a public method, since this method may need to be used again,
    # and "initialize" is private.
    setup(node, range, *callbacks)
  end
 
  def setup(node, range = 0, *callbacks)
    # Initialize the node we are trying to get to.
    @target = Node.new(node.x, node.y)
    @goal = @target.clone
    # Set beginning nodes and required variables.
    @start_node = Node.new(@character.x, @character.y)
    @nearest = Node.new(0, 0, 0, -1)
    @range, @found, @collisions = range, false, 0
    # Set callbacks for success and failure if included, else nil.
    @success_proc = callbacks[0]
    @failure_proc= callbacks[1]
    # Initialize sets to track open and closed nodes
    @open_set, @close_set = [@start_node], {} 
    # Find the optimal path
    calculate_path
  end

  def calculate_path
    # Only do calculation if goal is actually passable, unless we only
    # need to get close or within range
    if @character.passable?(@goal.x, @goal.y, 0) || @range > 0
      # Initialize counter
      counter, wait = 0, 0
      until @open_set.empty?

        counter += 1
        # Give up if pathfinding is taking more than 500 iterations
        if counter >= $game_map.search_limiter
          @found = false
          break
        end
        # Get the node with lowest cost and add it to the closed list
        @current_node = get_current
        @close_set[[@current_node.x, @current_node.y]] = @current_node
        if @current_node == @goal ||
           (@range > 0 && @goal.in_range?(@current_node, @range))
          # We reached goal, exit the loop!
          @target = @goal
          @goal, @found = @current_node, true
          break
        else # if not goal
          # Keep track of the node with the lowest cost so far
          if @current_node.heuristic < @nearest.heuristic ||
            @nearest.heuristic < 1
            @nearest = @current_node
          end
          # Get adjacent nodes and check if they can be added to the open list
          neighbor_nodes(@current_node).each {|neighbor|
            # Skip Node if it already exists in one of the lists.
            next if can_skip?(neighbor)
            # Add node to open list following the binary heap conventions
            @open_set.push(neighbor)
            arrange(@open_set.size - 1)
          }
        end
      end
    end
    # If no path was found, see if we can get close to goal
    unless @found
      if @range > 0 && @nearest.heuristic > 0 
        # Create an alternate path.
        setup(@nearest, @range, @success_proc, @failure_proc)
      elsif @failure_proc != nil && (($game_map.collision_retry == 0) ||
        (@collisions > $game_map.collision_retry))
        # If out of retries, call the Proc for failure if defined
        @failure_proc.call
      end
    end
    # Create the move route using the generated path
    create_move_route
  end

  def create_move_route
    # There's no path to generate if no path was found
    return if !@found
    # Create a new move route that isn't repeatable
    @route = RPG::MoveRoute.new
    @route.repeat = false
    # Generate path by starting from goal and following parents
    node = @goal
    while node.parent
      # Get direction from parent to node as RPG::MoveCommand
      code = case direction(node.parent.x, node.parent.y, node.x, node.y)
      when 2 then 4 # Up
      when 4 then 3 # Left
      when 6 then 2 # Right
      when 8 then 1 # Down
      else; 0
      end
      # Add movement code to the start of the array
      @route.list.unshift(RPG::MoveCommand.new(code)) if code != 0
      node = node.parent
    end
    # If the path should be assigned to the character
    if (@forcing && !@route.list.empty?)
      @collisions = 0
      @character.paths.push(self)
      @character.force_move_route(@route) if @character.paths.size == 1
    end
    # Reset forcing flag if needed
    @forcing = true
    # Return the constructed RPG::MoveRoute
    return @route
  end
 
  def arrange(index)
    # Rearrange nodes in the open_set
    while index > 0
      # Break loop unless current item's cost is less than parent's
      break if @open_set[index].score > @open_set[index / 2].score
      # Bring lowest value to the top.
      temp = @open_set[index / 2]
      @open_set[index / 2] = @open_set[index]
      @open_set[index] = temp
      index /= 2
    end
  end
 
  def get_current
    return if @open_set.empty?
    return @open_set[0] if @open_set.size == 1
    # Set current node to local variable and replace it with the last
    current = @open_set[0]
    @open_set[0] = @open_set.pop
    # Loop and rearrange array according to the A* algorithm until done.
    y = 0   
    loop {
      x = y
      # If two children exist
      if 2 * x + 1 < @open_set.size
        if @open_set[2 * x].score <= @open_set[x].score
          y = 2 * x
          if @open_set[2 * x + 1].score <= @open_set[y].score
            y = 2 * x + 1
          end
        end
      # If only one child exists
      elsif 2 * x < @open_set.size &&
        @open_set[2 * x].score <= @open_set[x].score
        y = 2 * x
      end
      # Swap a child if it is less than the parent.
      break if x == y
      temp = @open_set[x]
      @open_set[x] = @open_set[y]
      @open_set[y] = temp
    }
    # Return the original first node (which was removed)
    return current
  end

  def direction(x1, y1, x2, y2)
    # Return the numerical direction between coordinates.
    return 6 if x1 > x2 # Right
    return 4 if x1 < x2 # Left
    return 2 if y1 > y2 # Bottom
    return 8 if y1 < y2 # Top
    return 0           
  end
 
  def neighbor_nodes(node)
    # Create array to hold the nodes, then check each direction.
    nodes = []
    nodes.push(get_neighbor(node.x + 1, node.y, node)) # Right
    nodes.push(get_neighbor(node.x - 1, node.y, node)) # Left
    nodes.push(get_neighbor(node.x, node.y + 1, node)) # Down
    nodes.push(get_neighbor(node.x, node.y - 1, node)) # Up
    # Remove any nil elements, then return results.
    return nodes.compact
  end
 
  def get_neighbor(x, y, parent)
    # Calculate direction, return new node if passable.
    direction = direction(x, y, parent.x, parent.y)
    if @character.passable?(parent.x, parent.y, direction)
      # The heuristic is simply the distance
      heuristics = ((x - @goal.x).abs + (y - @goal.y).abs)
      return Node.new(x, y, parent, parent.cost + 1, heuristics)
    end
  end
 
  def can_skip?(node)
    # Branch by if node is in either the open or closed set.
    if @open_set.include?(node)
      index = @open_set.index(node)
      return true if @open_set[index].score <= node.score
      # Swap them and update list order
      @open_set[index] = node
      arrange(index)
      return true
    elsif @close_set[[node.x, node.y]] != nil
      # If the existing passed node has a lower score than this one.
      return true if @close_set[[node.x, node.y]].score <= node.score
      # Update the existing node
      @close_set[[node.x, node.y]] = node
    end
    # Return false if no criteria was met.
    return false
  end
end

#==============================================================================
# ** Game_Character
#==============================================================================

class Game_Character
 
  attr_accessor :paths
  attr_accessor :move_route_forcing
  attr_accessor :move_route

  alias zer0_pathfinding_init initialize
  def initialize
    # Add public instance variable for paths
    @paths = []
    # Original method
    zer0_pathfinding_init
  end
 
  def next_route
    # Stop any custom move route that may be occuring.
    if @move_route != nil
      # Set index and disable forcing of current route
      @move_route_index = @move_route.list.size
      @move_route_forcing = false
      # Reset to what it was originally
      @move_route = @original_move_route
      @move_route_index = @original_move_route_index
      @original_move_route = nil
    end
    # Remove first path from the paths array.
    @paths.shift
    # If there is another path to follow...
    if @paths[0] != nil
      # Setup path again to reflect any changes since original creation
      @forcing = false
      @paths[0].setup(@paths[0].target, @paths[0].range,
        @paths[0].success_proc, @paths[0].failure_proc)
      force_move_route(@paths[0].route) if @paths[0].found
    end
  end
 
  alias zer0_recalculate_paths_move move_type_custom
  def move_type_custom
    if $game_map.recalculate_paths
      # Interrupt if not stopping
      return if jumping? || moving?
      # Loop until finally arriving at move command list
      while @move_route_index < @move_route.list.size
        # Get the move command at index
        command = @move_route.list[@move_route_index]
        # If command code is 0 (end of list)
        if command.code == 0
          # If [repeat action] option is ON
          if @move_route.repeat
            # Reset move route index to the top of the list
            @move_route_index = 0
          end
          # If [repeat action] option is OFF
          unless @move_route.repeat
            # If move route is forced and not repeating
            if @move_route_forcing and not @move_route.repeat
              # The move route is no longer forced (moving ended)
              @move_route_forcing = false
              # Restore original move route
              @move_route = @original_move_route
              @move_route_index = @original_move_route_index
              @original_move_route = nil
              # If there was a path to follow and we reached goal
              if @paths[0] != nil
                if self.x == @paths[0].goal.x &&
                  y == @paths[0].goal.y && @paths[0].success_proc
                  # Call success Proc if goal is reached and it is defined.
                  @paths[0].success_proc.call
                end
                next_route
              end
            end
            # Clear stop count
            @stop_count = 0
          end
          return
        end # if command.code == 0
        # For move commands (from move down to jump)
        if command.code <= 14
          # Branch by command code
          case command.code
          when 1 then move_down                 # Move down
          when 2 then move_left                 # Move left
          when 3 then move_right                # Move right
          when 4 then move_up                   # Move up
          when 5 then move_lower_left           # Move lower left
          when 6 then move_lower_right          # Move lower right
          when 7 then move_upper_left           # Move upper left
          when 8 then move_upper_right          # Move upper right
          when 9 then move_random               # Move random
          when 10 then move_toward_player       # Move toward player
          when 11 then move_away_from_player    # Move away from player
          when 12 then move_forward             # Step forward
          when 13 then move_backward            # Step backward
          when 14 then jump(command.parameters[0], command.parameters[1]) # Jump
          end
          # If movement failure occurs when "Ignore If Can't Move" is unchecked.
          if !@move_route.skippable && !moving? && !jumping?
            # If path is current and collision limit is not reached
            if @paths[0] != nil &&
              @paths[0].collisions < $game_map.collision_retry
              # Setup path again to update starting location.
              # original goal node is used because pathfinding changes
              # the goal node to current node
              goal, range = @paths[0].target, @paths[0].range
              reach = @paths[0].success_proc
              fail = @paths[0].failure_proc
              counter = @paths[0].collisions + 1
              # Find another path to goal
              @paths[0] = Pathfind.new(goal, self, range, reach, fail)
              @paths[0].collisions = counter
              force_move_route(@paths[0].route) if @paths[0].found
              # Wait a bit before starting to follow the new path
              @wait_count = 6
              return
            elsif paths[0] != nil
              # Call failure Proc if defined and set move index.
              @move_route_index = @move_route.list.size
              @paths[0].failure_proc.call if @paths[0].failure_proc != nil
              next_route
            end
            # End method
            return
          end
          # Advance index
          @move_route_index += 1
          return
        end # if command.code <= 14
        # If waiting
        if command.code == 15
          # Set wait count (from provided parameter)
          @wait_count = command.parameters[0] * 2 - 1
          @move_route_index += 1
          return
        end # if command.code == 15
        # If direction change (turning) command
        if command.code >= 16 and command.code <= 26
          # Branch by command code
          case command.code
          when 16 then turn_down                      # Turn down
          when 17 then turn_left                      # Turn left
          when 18 then turn_right                     # Turn right
          when 19 then turn_up                        # Turn up
          when 20 then turn_right_90                  # Turn 90ยฐ right
          when 21 then turn_left_90                   # Turn 90ยฐ left
          when 22 then turn_180                       # Turn 180ยฐ
          when 23 then turn_right_or_left_90          # Turn 90ยฐ right or left
          when 24 then turn_random                    # Turn at Random
          when 25 then turn_toward_player             # Turn toward player
          when 26 then turn_away_from_player          # Turn away from player
          end
          @move_route_index += 1
          return
        end
        # If other command (commands that don't 'return')
        if command.code >= 27
          # Branch by command code
          case command.code
          when 27                                              # Switch ON
            $game_switches[command.parameters[0]] = true
            $game_map.need_refresh = true
          when 28                                              # Switch OFF
            $game_switches[command.parameters[0]] = false
            $game_map.need_refresh = true
          when 29 then @move_speed = command.parameters[0]     # Change speed
          when 30 then @move_frequency = command.parameters[0] # Change freq
          when 31 then @walk_anime = true                      # Move ON
          when 32 then @walk_anime = false                     # Move OFF
          when 33 then @step_anime = true                      # Stop ON
          when 34 then @step_anime = false                     # Stop OFF
          when 35 then @direction_fix = true                   # Direction ON
          when 36 then @direction_fix = false                  # Direction OFF
          when 37 then @through = true                         # Through ON
          when 38 then @through = false                        # Through OFF
          when 39 then @always_on_top = true                   # On top ON
          when 40 then @always_on_top = false                  # On top OFF
          when 41                                              # Change Graphic
            # Can't change into a tile
            @tile_id = 0
            @character_name = command.parameters[0]
            @character_hue = command.parameters[1]
            # Update direction
            if @original_direction != command.parameters[2]
              @direction = command.parameters[2]
              @original_direction = @direction
              @prelock_direction = 0
            end
            # Update frame
            if @original_pattern != command.parameters[3]
              @pattern = command.parameters[3]
              @original_pattern = @pattern
            end
          when 42 then @opacity = command.parameters[0]        # Change Opacity
          when 43 then @blend_type = command.parameters[0]     # Change Blending
          when 44 then $game_system.se_play(command.parameters[0]) # Play SE
          when 45 then result = eval(command.parameters[0])    # Script
          end
          # Increment move index.
          @move_route_index += 1
        end
      end
    else
      # Original method
      zer0_recalculate_paths_move
    end
  end
end

#==============================================================================
# ** Node
#==============================================================================

class Node

  attr_accessor :x                     
  attr_accessor :y                       
  attr_accessor :parent                 
  attr_accessor :cost                 
  attr_accessor :heuristic                 

  def initialize(x, y, parent = nil, cost = 0, heuristic = 0)
    # Set public instance variables.
    @x, @y, @parent, @cost, @heuristic = x, y, parent, cost, heuristic
  end

  def score
    # Return the current "score" of this node
    return @cost + @heuristic
  end
 
  def in_range?(node, range)
    # Return true/false if Nodes are within RANGE of each other.
    return (@x - node.x).abs + (@y - node.y).abs <= range
  end

  def ==(node)
    # Returns true/false of whether self and other are equal.
    return ((node.is_a?(Node)) && (node.x == @x) && (node.y == @y))
  end
end



Instructions

Place script below default scripts and above "Main".
Further instructions are within the script and demo.


Compatibility

Highly compatible. Only issue may be with other custom movement scripts.


Credits and Thanks


  • ForeverZer0, for the script

  • Special thanks to Jragyn for help making the big maze for the demo and help testing.

  • Credit goes to the Peter Hart, Nils Nilsson and Bertram Raphael for the original search algorithm that was implemented




Author's Notes

Please report any bugs/issues you may encounter so they can be resolved.
Enjoy!end
69
Jragyn pointed this out to me.
With RTP development a bit behind in my opinion, this may be a great resource for the RTP that we are already sitting on.
Something to look into.
70
I'm starting this thread so that Opera users can share cool extensions that they have found, little tips and tricks, or general discussion of the browser.

This is not a place to discuss which browsers are better. The browser that you use is merely a preference, and this thread is not for comparing one browser to another. Posts like "Chrome can do that better", or "Firefox doesn't need an extension for that, its built in" are NOT to be posted here.

Anyways, I would like to share a few cool things I have found regarding Opera. The first and foremost is a new build to the browser. This link will become outdated in a relatively short amount of time I'm sure, but here it is:

Opera 11.11.2109

This build has not yet (at the time of this post) been released as the newest version at the Opera site, but I will personally attest that the stability issues with previous versions have been fixed in this build. I have been using it for about a week with this build, and have not experienced a single crash, even viewing sites that used Flash, which seemed to have made it worse. Prior to this version Opera would crash on me about every 15-25 minutes, which was becoming very irritating.

Extensions

  • Pastebin: Extension to have your Pastebin account built right into your browser. You are always only one click away from being able to access your account and add new pastes.

  • DropBox: Have easy, direct access to your DrobBox account right through your browser. If you don't know what DropBox is by now, or don't have an account, you can register here.

  • Opera Configurator: Take control of every last setting with your browser. Lets you change practically every detail to suit your needs.

  • Virus Total Extension: With this extension, you can submit any link, download, or file to the website through your browser. Once submitted, it will be scanned using practically every single anti-virus program on the market, and you will be given a detailed result of what each AV found during its scan, before you click it. Great for downloads you may be worried about.

  • LightShot: This little tool allows you to take a snapshot of any webpage simply by click-dragging a selection box over any portion of the screen.

  • HotkeyBB: Allows you to use hotkeys to insert BB code into text boxes, very nifty for posting on forums.

  • Easy User CSS: Lets you quickly and easily modify the style sheet that any webpage uses. The changes can be saved, and the new styles of colors, fonts, and pictures used will be displayed for you everytime. Awesome tool for those who are not happy with the styling of their favorite sites.

  • Extend Tube: Makes youtube so much better. Have not had to deal with a single fucking advertisement in ages. Can also add buttons to youtube videos like Download button, Skip frames, rewind, enable/disable loop.

  • Google Images Direct: When browsing google images, you click an image, it'll take you directly to the image instead of dealing with the actual site first.

  • Youtube Dark Simplified: Gives youtube a dark theme. Much easier on the eyes.



Please feel free to share more!
71
RMXP Script Database / [XP] Event Proximity Icons
May 16, 2011, 02:29:57 am
Event Proximity Icons
Authors: ForeverZer0
Version: 1.4
Type: Event Add-On
Key Term: Misc Add-on



Introduction

This script will allow you to have various icons appear over events' heads when the player gets within a certain range of them, and the appropriate tag is found as a comment in their page.


Features


  • Easy to use

  • Can use any number of custom tags you want

  • Adjustable coordinates for icons

  • Adjustable cycle times for changing icons

  • Adjustable proximity before icons show

  • Icons transition in/out smoothly

  • Ability to have event simply glow when within range instead of use icons

  • Can customize the color and speed of the glow effect




Screenshots

Spoiler: ShowHide

Spoiler: ShowHide



Demo

Demo Link


Script

The Script: ShowHide
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Event Proximity Icons
# Author: ForeverZer0
# Version: 1.4
# Date: 6.4.2012
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#
# Introduction:
#   This script will allow you to have various icons appear over events' heads
#   when the player gets within a certain range of them, and the appropriate
#   tag is found asa comment in their page.
#
# Features:
#   - Easy to use
#   - Can use any number of custom tags you want
#   - Adjustable coordinates for icons
#   - Adjustable cycle times for changing icons
#   - Adjustable proximity before icons show
#   - Icons transition in/out smoothly
#   - Can use glow feature instead of icons
#   - Set custom glow color and speed
#
# Instructions:
#   - See configuration below.
#   - Make sure all icons are located in Graphics/Pictures directory
#
# Credits:
#   - ForeverZer0, for the script
#   - Zexion, for requesting it
#   - Taiine, for her constant reminders to add Blizz-ABS compatibility ;)
#
##+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#                            BEGIN CONFIGURATION
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

 TAGS = ['TALK', 'SEARCH', 'ATTACK']
 # These are th codes that will be searched for in event page comments
 ICONS = ['talk', 'search', 'attack']
 # These are the filenames of the respective codes, located in Pictures folder
 
 PROXIMITY = 3
 # The number of tiles away the player must be to event to show the icons.
 
 CYCLE_TIME = 2
 # The number of seconds before the icon cycles to the next one (if available)
 
 ICON_OFFSET = [0, -8]
 # The offset of the icon coodinates, adjust to your icon size
 # [X_OFFSET, Y_OFFSET]
 
 GLOW_ONLY = false
 # Set to true to have sprites glow when within range instead of using icons
 GLOW_COLOR = Color.new(255, 255, 200, 128)
 # The color of the glow.  (RED, GREEN, BLUE, ALPHA)
 GLOW_SPEED = 40
 # The glow speed.  40 = 1 second
 
 ALWAYS_ON_TOP = false
 # Set to true if icons always display over everything else.
 
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#                               END CONFIGURATION
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

#===============================================================================
# ** Game_Map
#===============================================================================

class Game_Map
 
 attr_accessor :proximity_data
 
 alias zer0_proximity_setup setup
 def setup(map_id)
   @proximity_data = {}
   zer0_proximity_setup(map_id)
 end
end

#===============================================================================
# ** Game_Event
#===============================================================================

class Game_Event
 
 alias zer0_proximity_init initialize
 def initialize(map_id, event)
   # Normal method
   $game_map.proximity_data[event.id] = [false, []]
   zer0_proximity_init(map_id, event)
   # A little extra work now, but it greatly reduces the number of checks later
   @event.pages.each {|page| page.list.each {|command|
     if [108, 408].include?(command.code) &&
       command.parameters.any? {|param| TAGS.include?(param) }
       $game_map.proximity_data[@id][0] = true
     end
   }}
   refresh
 end
 
 alias zer0_proximity_tag_refresh refresh
 def refresh
   # Call normal refresh method
   zer0_proximity_tag_refresh
   # Check current page
   if !GLOW_ONLY && $game_map.proximity_data[@id][0] && @page != nil
     # Set default values
     $game_map.proximity_data[@id] = [false, []]
     # Iterate commands and check if tag is present. If so, set respective flag
     @page.list.each {|command|
       if [108, 408].include?(command.code) &&
         TAGS.include?(command.parameters[0])
         $game_map.proximity_data[@id][0] = true
         $game_map.proximity_data[@id][1].push(command.parameters[0])
       end
     }
   end
 end
end

#===============================================================================
# ** Sprite_Character
#===============================================================================

class Sprite_Character
 
 alias zer0_proximity_tag_init initialize
 def initialize(viewport, character = nil)
   # Check if the sprite is that of an event, and has icons
   if character.id != 0
     flag = $game_map.proximity_data[character.id][0]
     if character.is_a?(Game_Event) && flag
       if ALWAYS_ON_TOP
         topview = Viewport.new(0, 0, 640, 480)
         topview.z = 9999
       end
       # Initialize sprite and bitmaps
       @icon_sprite = ALWAYS_ON_TOP ? Sprite.new(topview) : Sprite.new(viewport)
       @icon_sprite.opacity = @icon_index = 0
     end
   end
   # Normal initialize method
   zer0_proximity_tag_init(viewport, character)
 end
 
 alias zer0_proximity_tag_upd update
 def update
   # Normal update method
   zer0_proximity_tag_upd
   # Update the icons if needed
   if ![nil, 0].include?(@character.id)
     flag = $game_map.proximity_data[@character.id][0]
     if @character.is_a?(Game_Event) && flag
       GLOW_ONLY ? update_glow : update_icons
     end
   end
 end
 
 def update_glow
   # Check proximity, then set flash if within range.
   range_x = @character.x - $game_player.x
   range_y = @character.y - $game_player.y
   range = Math.hypot(range_x, range_y).abs
   if range <= PROXIMITY && Graphics.frame_count % GLOW_SPEED == 0
     self.flash(GLOW_COLOR, GLOW_SPEED)
   end
 end

 def update_icons
   # Return if no icons exist for page, or set icon if none is defined
   if $game_map.proximity_data[@character.id][1].empty?
     return
   elsif @icon_sprite.bitmap == nil
     icon_name = $game_map.proximity_data[@character.id][1][0]
     @icon_sprite.bitmap = RPG::Cache.picture(icon_name)
   end
   bw = bh = 0
   # Calculate width and height of icon and figure into the coordinates
   if @icon_sprite.bitmap != nil
     bw = ((self.bitmap.width / 4) - @icon_sprite.bitmap.width) / 2
     by = -@icon_sprite.bitmap.height
   end
   # Set coordinates of icon relative to sprite
   @icon_sprite.x = (self.x - self.ox) + bw + ICON_OFFSET[0]
   @icon_sprite.y = (self.y - self.oy) + bh + ICON_OFFSET[1]
   # Check range, fading in/out smoothly as needed
   if $BlizzABS
     pix = $BlizzABS.pixel
     char_x, char_y = @character.x, @character.y
     player_x, player_y = $game_player.x / pix , $game_player.y / pix
     if @character.is_a?(Map_Battler)
       char_x /= pix
       char_y /= pix
     end
   else
     char_x, char_y = @character.x, @character.y
     player_x, player_y = $game_player.x, $game_player.y
   end
   range_x = char_x - player_x
   range_y = char_y - player_y
   range = Math.hypot(range_x, range_y).abs
   @icon_sprite.opacity += (range <= PROXIMITY) ? 10 : -10
   # Cycle icon bitmap as needed
   if @icon_sprite.opacity > 0 && Graphics.frame_count % (CYCLE_TIME * 40) == 0
     size = $game_map.proximity_data[@character.id][1].size
     @icon_index = (@icon_index + 1) % size
     icon_name = $game_map.proximity_data[@character.id][1][@icon_index]
     @icon_sprite.bitmap = RPG::Cache.picture(icon_name)
   end
 end
 
 alias zer0_proximity_icon_dispose dispose
 def dispose
   # Disposed the icon sprite
   if @icon_sprite != nil && !@icon_sprite.disposed?
     @icon_sprite.dispose
   end
   zer0_proximity_icon_dispose
 end
end



Instructions

Place above "Main", and below default scripts.
Instructions are within the script.


Compatibility

Pixel movement scripts may cause issues, though I DID add compatibility for Blizz-ABS pixel-movement.

BlizzABS's ABSEAL will under certain circumstances not update events without graphics, which may include some of your proximity events, causing them not to work. To fix this issue, place the small script below anywhere below the BlizzABS scripts.
BlizzABS ABSEAL Fix: ShowHide
class Game_Character
 
  alias zer0_proximity_update? update?
  def update?
    if self.is_a?(Game_Event) && $game_map.proximity_data.include?(self.id)
      if @trigger == 3 || @trigger == 4 || self.name.clone.gsub!('\\eal') {''}
        return true
      end
      return in_abseal_range?
    end
    return zer0_proximity_update?
  end
end




Credits and Thanks


  • ForeverZer0, for the script

  • Zexion, for the idea and the request

  • Taiine, for her moral support adding Blizz-ABS compatibility ;)

  • Vexus, for helping track down the ABSEAL bug




Author's Notes

Please report any bugs/issues so that they can be resolved.
Enjoy!
72
Run Time Package / RTP Audio
May 15, 2011, 04:06:50 pm
Here is a list of audio resources that have been created for the ARC Run-Time Package so far.
Feel free to post any you might have in this topic, and a mod can move them to the main collection.
Please use this template for submissions:


[b]TYPE:[/b]  <BGS, BGM, SE, ME, ETC>
[b]FILENAME:[/b]  <NOT CRITICAL, BUT A CLUE AS TO WHAT THE AUDIO IS>
[b]AUTHOR:[/b]  <THE NAME YOU WOULD LIKE IN THE CREDITS FOR THIS RESOURCE>
[b]LINK:[/b]  [url=<THE LINK TO YOUR FILE SO IT CAN BE DOWNLOADED>]Link[/url]


Please ensure that all entries are either .FLAC or .WAV format.  This are lossless formats that will allow for conversion into whatever format we decide with, without losing any quality.



Submitted Audio Resources

Background Music
001-Field01: ShowHide
TYPE:  BGM
FILENAME:  001-Field01
AUTHOR:  Markus Hestnes
LINK:  Link




Ambient







Sound Effects




73
Enhanced Item Description
Authors: ForeverZer0
Version: 1.0
Type: Menu Add-on
Key Term: Menu Add-on



Introduction

This is a small script I wrote when I got started scripting, but never released. I found it going through some old projects, but I'm sure someone else can make use of it. What it does is allows you to use the same shortcuts commands you can in a "Show Text..." command, but within the descriptions for Items, Weapons, and Armors. For example, if you wanted the description to include the value of a variable, in the database where you right the descriptions, just use "\v[VAR_ID]", and the command will be replaced with the actual value of the variable during the game.


Features


  • Easy to use.

  • Makes descriptions a little more dynamic.

  • Commands included: Actor Names, Variables, Gold, Switches, and Steps.

  • Can easily add custom ones




Screenshots

Name character whatever you want: ShowHide

Use command in the description: ShowHide

Description remains correct: ShowHide



Demo

None.


Script

Here lies the script.
Spoiler: ShowHide

#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# Enhanced Item Description
# Author: ForeverZer0
# Version: 1.0
# Date: 5.14.2011
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#
# Introduction:
#   This is a small, very basic script I wrote a while back, but never released.
#   It allows for you to use the same type of commands you can use in event
#   "Show Message" commands, but within the descriptions of Weapons, Armors, and
#   Items. Review the commands below, they will be substituted in the actual
#   text to display the respective value.
#
# Commands:
#   \v[ID]  = Replaces with value of game variable with ID
#   \n[ID]  = Replaces with name of actor that has ID
#   \sw[ID] = Replaces with value of switch withg ID  (ON/OFF)
#   \g      = Replaces with amount of gold party has
#   \st     = Replaces with step count
#
# Author's Notes:
#   I can add more at request. Only values that are global to the RTP scripts
#   and cannot be easily accessed will be added to the script, though I can
#   still give someone a one line of code they can add themselves for custom
#   commands.
#
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

module RPG
 
  def self.substitute_text(message)
    text = message.clone
    text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
    text.gsub!(/\\[Nn]\[([0-9]+)\]/) {
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : '' }
    text.gsub!(/\\[Gg]/) { $game_party.gold }
    text.gsub!(/\\[Ss][Tt]/) { $game_party.steps }
    text.gsub!(/\\[Ss][Ww]\[([0-9]+)\]/) {
      $game_switches[$1.to_i] ? 'ON' : 'OFF' }
    return text
  end
 
  class Weapon
    def description
      return RPG.substitute_text(@description)
    end
  end
 
  class Armor
    def description
      return RPG.substitute_text(@description)
    end
  end
 
  class Item
    def description
      return RPG.substitute_text(@description)
    end
  end
end



Instructions

Place script anywhere above "Main".
Use the following commands in the database when making descriptions:

  • \v[ID] :  Replaces with value of game variable with ID

  • \n[ID] :  Replaces with name of actor that has ID

  • \sw[ID] :  Replaces with value of switch with ID  (ON/OFF)

  • \g :  Replaces with amount of gold party has

  • \st : Replaces with step count




Compatibility

Compatible with practically everything.


Credits and Thanks


  • ForeverZer0




Author's Notes

If you would like a custom command, feel free to ask. 
Please report any bugs/issues you encounter so that they may be resolved.
74
Core Development / Bug with Audio
May 12, 2011, 01:21:02 am
I know this is not fully implemented yet, but just wanted to point it out sooner than later.
If the sound is played to quickly together, all audio will fail and not return.

I was scrolling up and down quickly through the save files, and I noticed the volume decrease drastically. I did it a few more times quickly, and the sound stopped altogether. I restarted a few times, and found that it would do it every time.

The log read:
[xal] unable to allocate audio source!


I know you (Blizz) are still working on this, so this entire post may be a waste of both our times. Sorry if it is!  :P
75
I know that there are many people already using dropbox out there.

Most of you will know as well, that you can extend your free space by referring people. Usually you'll get 250 MB extra per referral. I just discovered however, that it's possible to double this extra space to 500 MB. This works for new referrals AND for already referred people!

The maximum free space thereby increases to great 16 GB!

What you have to:
1. You'll need a dropbox account. Don't have one yet? Sign up here: www.dropbox.com
(Of course you don't need to use my reflink. You can simply visit the website and sign up. But firstly I'd really be thankful for using it and secondly you'll get another 250 MB if you use a reflink.)

2. You'll need an educational e-mail adress. It doesn't need to end with .edu though. Don't have one? Search for free educational e-mail adresses. If you understand german you could e.g. sign up with www.uni.de EDIT: uni.de adresses seem not to be accepted by dropbox anymore. Try looking for alternatives if you don't have an educational adress yet.

3. Log in to your existing dropbox account. Then enter https://www.dropbox.com/edu into your browser. On the website enter your (educational) e-mail and confirm the sent e-mail.

Done. Your free space per referral should now be doubled.

76
ARC Reactor Engine / Resolution
May 09, 2011, 01:54:18 am
Have we decided on a "default" resolution. I realize it can do various sizes, but I was under the impression that we would be using 800x600 unless set to something other.

The reason I ask is for the RTP. I noticed a transition and a gameover sized at 640x480, and thought maybe we should be making graphics sized to the default screen size if that is going to be the case.
77
I happen to stumble upon this little bit of news when looking for some new themes for my Ubuntu 10.04.

Ubuntu 11.04

Although it is technically still BETA, it is stable and is now being used as the current version.
78
ARC Reactor Engine / Compression
May 06, 2011, 12:41:31 am
I had some thoughts on including a compression library in ARC.  RMXP's compression isn't very good as you know, basically the same as ZIP format. I think that people could benefit using a better one that is built in, such as 7-zip or something, which is free, though I haven't checked their license in detail concerning making profit on a program that uses it.

Thoughts?
79
Another thing that would be neat. That way people can click the player to listen to something before they download it.
Again, not necessary, but would be nice.

Sorry for the out-of-the-blue requests.  :P
80
RMXP Script Database / [XP] Ambient SFX
May 02, 2011, 12:39:09 am
Ambient SFX
Authors: ForeverZer0
Version: 1.1
Type: Environment Add-on
Key Term: Environment Add-on



Introduction

This system will play SE at intervals in addition to the BGM/BGS. You can configure each map separately with its own array of SE to play. The SE will played randomly and will be played at random intervals (configurable).


Features


  • Each map can be configured separately

  • Can use as many different SFX as you want for each map

  • Provides a more 'random' effect than a simple looping BGM/BGS

  • Temporary changes or enabling/disabling with script calls

  • Perfect for bird chirps, insect SFX, etc.




Screenshots

Kind of hard for sound effects...


Demo

Demo Link


Script

Click here for the script.
Spoiler: ShowHide

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Ambient SFX
# Author: ForeverZer0
# Date: 5.1.2011
# Version: 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Explanation:
#   This system will play SE at intervals in addition to the BGM/BGS. You can
#   configure each map separately with its own array of SE to play. The SE
#   will played randomly and will be played at random intervals (configurable).
#   
# Features:
#   - Each map can be configured separately
#   - Can use as many different SFX as you want for each map
#   - Provides a more 'random' effect than a simple looping BGM/BGS
#   - Temporary changes or enabling/disabling with script calls
#   - Perfect for bird chirps, insect SFX, etc.
#
# Instructions:
#   - Set your maps up using this syntax:
#
#   when MAP_ID then [DELAY, ['SE_NAME', VOLUME, PITCH],
#     ['ANOTHER_SE_NAME', VOLUME, PITCH], ['ANOTHER_SE_NAME', VOLUME, PITCH]]
#
# The system will choose a random number between 0 - DELAY each frame (that
# is 40 times per second for those who don't know), and if that number is equal
# to 0, a random SE in the array will be played. You don't need to set up any
# maps if you are not using this system for it. 
#
# The system can be toggled ON/OFF with the script call:
#
#            $game_system.AMBIENT_SE = true/false
#
# It can also be temporarily added or changed with the script call:
#
#   $game_map.ambient_SE = [DELAY, ['SE_NAME', VOLUME, PITCH],
#     ['ANOTHER_SE_NAME', VOLUME, PITCH], ['ANOTHER_SE_NAME', VOLUME, PITCH]]
#
# ...or turned off temporarilly on the current map with:
#
#   $game_map.ambient_SE = nil
#
# These will only work on a temporary basis for the current map, everything will
# return to normal once the player moves to a different map. Disable the add-on
# completely if you don't want it to persist.
#
# Author's Notes:
#   Try to avoid using WAV files for the SFX. I have found that this can cause
#   lag occasionally when the SE is played. Use OGG or MIDI.
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:

class Game_Map
 
  attr_accessor :ambient_SE

  alias zer0_ambient_sfx_setup setup
  def setup(map_id)
    @ambient_SE = case map_id
#-------------------------------------------------------------------------------
# BEGIN CONFIGURATION
#-------------------------------------------------------------------------------
    # You can add more than 1 map_id per case.     ex. (when 1, 8, 32)
    when 1
      [150, ['Birdsong1', 80, 100], ['Birdsong2', 80, 100],
      ['Birdsong3', 80, 100], ['Birdsong4', 80, 100]]
    when 2
      [40, ['Cricket', 80, 100], ['Frog', 80, 100]]
#-------------------------------------------------------------------------------
# END CONFIGURATION
#-------------------------------------------------------------------------------
    end
    zer0_ambient_sfx_setup(map_id)
  end
 
  alias zer0_ambient_sfx_upd update
  def update
    if $game_system.AMBIENT_SFX && @ambient_SE != nil
      if rand(@ambient_SE[0]) == 0
        r = rand(@ambient_SE.size - 1) + 1
        $game_system.se_play(RPG::AudioFile.new(*@ambient_SE[r]))
      end
    end
    zer0_ambient_sfx_upd
  end
end

#===============================================================================
# ** Game_System
#===============================================================================

class Game_System
 
  attr_accessor :AMBIENT_SFX
 
  alias zer0_ambient_sfx_init initialize
  def initialize
    zer0_ambient_sfx_init
    @AMBIENT_SFX = true
  end
end



Instructions

Place script below Game_Map and above "Main". There are instructions for configuration in the script.


Compatibility

No known compatibility issues.


Credits and Thanks


  • ForeverZer0, for the script




Author's Notes

Try to avoid using WAV files for the SFX. I have found that this can cause lag occasionally when the SE is played. Use .OGG or .MIDI. Although RMXP does not support playing them streaming, their small file size and good compression make them good for such a thing.
81
Event Range Conditions
Authors: ForeverZer0
Version: 1.1
Type: Event Add-On
Key Term: Game Utility



Introduction

Allows you to set up conditional branches in events that will be based off the event's coordinates in relation to the player's coordinates without having to create any variables for the X and Y of each.


Features


  • Conditions based on distance radius

  • Conditions based on if they are ON/OFF screen

  • Conditions based on linear distance on each axis

  • Conditions based on whether they are above, below, left, or right in relation to player or other event

  • Simple to use




Screenshots

None.


Demo

None.


Script

Click here for the script.
Spoiler: ShowHide

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Event Range Conditions
# Author: ForeverZer0
# Date: 5.1.2011
# Version: 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Explanation:
#
#   Allows you to set up conditional branches in events that will be based off
#   the event's coordinates in relation to the player's coordinates without
#   having to create any variables for the X and Y of each.
#
#   Here are the new features you can use a conditional branch. Just type these
#   into the script box for the branch.
#
#   range?(RANGE, EVENT_ID) - Will be true if player is anywhere in the radius
#                             defined by RANGE from the event with EVENT_ID
#
#   on_screen?(EVENT_ID)    - Will be true if the event with EVENT_ID is within
#                             the visible screen
#
#   x_dist?(DIST, EVENT_ID) - Returns true if the player's x/y is within DIST
#            OR               of event's x/y with EVENT_ID. These are absolute
#   y_dist?(DIST, EVENT_ID)   values, meaning it doesn't matter which direction,
#                             it just uses the total distance in tiles for that
#                             axis. Use a DIST of 0 to check if that axis is
#                             equal.
#
#   player_above?(EVENT_ID) - Returns true when player is above event.
#   player_below?(EVENT_ID) - Returns true when player is below event.
#   player_right?(EVENT_ID) - Returns true when player is right of the event.
#   player_left?(EVENT_ID)  - Returns true when player is left of the event.
#
#   For all of these, if the conditional branch that is using them is within
#   the event that it applies to, you do not have to include the EVENT_ID, it
#   is assumed to be that event's ID unless otherwise defined.
#
#   You can use these as a condition for just about anything, such as having
#   an event say something, run away, or run toward the player if it is within a
#   specific distance, and it's much easier than using multiple branches and
#   game variables to set it up.
#
#   Remember that if you use a range condition with a parallel trigger, it will
#   continue to execute as long as the condition is met and if the player cannot
#   move during the event's code, the game will effectively be stuck.
#
# Compatability:
#
#   - You may encounter issues if using a Pixel Movement script, though it
#     should still work fine with an 8-Way Movement script. (Not tested)
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:

class Interpreter
 
  def range?(range = 4, id = @event_id)
    e = $game_map.events[id]
    radius = (Math.hypot((e.x - $game_player.x), (e.y - $game_player.y))).abs
    return (radius <= range)
  end
 
  def on_screen?(id = @event_id)
    x, y = $game_map.events[id].real_x, $game_map.events[id].real_y
    return ((x - $game_map.display_x + 64) / 4).between?(0, 640) &&
      ((y - $game_map.display_y) / 4).between?(0, 480)
  end
 
  def x_dist?(distance = 0, id = @event_id)
    x_dif = ($game_map.events[id].x - $game_player.x).abs
    return (x_dif <= distance)
  end
 
  def y_dist?(distance = 0, id = @event_id)
    y_dif = ($game_map.events[id].y - $game_player.y).abs
    return (y_dif <= distance)
  end
 
  def player_above?(id = @event_id)
    return ($game_map.events[id].y > $game_player.y)
  end
 
  def player_below?(id = @event_id)
    return ($game_map.events[id].y < $game_player.y)
  end
 
  def player_right?(id = @event_id)
    return ($game_map.events[id].x < $game_player.x)
  end
 
  def player_left?(id = @event_id)
    return ($game_map.events[id].x > $game_player.x)
  end
end



Instructions

Place script anywhere below the Interpreter scripts, and above "Main"
The different script calls are listed within the script.


Compatibility

Possible compatibility issues with pixel-movement scripts.


Credits and Thanks


  • ForeverZer0, for the script




Author's Notes

Please report any bugs/issues you find.
Hope you enjoy!
82
RMXP Script Database / [XP] Pickpocket
May 02, 2011, 12:37:03 am
Pickpocket
Authors: ForeverZer0
Version: 1.5
Type: NPC Pickpocket System
Key Term: Player / Party / Troop Add-on



Introduction

Anybody who played the PSX game Star Ocean will know exactly what this is. It is basically a system that will allow you to pickpocket NPCs to receive various items, weapons, and armors if you have a certain accessory.


Features


  • Easy, quick configuration to setup each event, can be done in a single comment in an event's page

  • Variables log all successes, failures, and total attempts, which can be easily used in something else, such as a Affection System or Good/Evil System.




Screenshots

None.


Demo

Demo Link


Script

Click here for the script.
Spoiler: ShowHide

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Pickpocket Ability
# Author: ForeverZer0
# Date: 5.4.2011
# Version: 1.5
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Version History:
#   v.1.0 - Original Release
#   v.1.1 - Added configuration for Input
#   v.1.2 - More efficient and improved method of gathering pickpocket data
#         - No longer requires comment codes to be in brackets []
#           (Old configurations will still work, though)
#         - Configurable search codes
#         - No longer requires 'Pickpocket' comment for initialization
#         - Consolidated various class methods/variables
#         - Better looking pickpocket result window, and got rid of annoying bug
#           that would 'talk' to event when exiting result window
#         - Added config for font color of result item
#         - Improved coding/compatability
#   v.1.3 - Removed from Zer0 Add-On Collection
#         - Optimized code
#         - Added a TOTAL_ATTEMPTS_VARIABLE
#         - Added ability to use a single comment instead of three in a row
#   v.1.4 - Added switch to turn system ON/OFF
#         - Made the item requirement optional (Thanks, GrieverSoft)
#         - Improved the result window. Now draws icons.
#   v.1.5 - Reconfigured to allow for weapons to also add pickpocket ability
#         - Created configuration to allow for different equipment to give
#           bonuses to the odds of a successful steal
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Explanation:
#
#   - Anybody who played the PSX game Star Ocean will know exactly what this is.
#     It is basically a system that will allow you to pickpocket NPCs to recieve
#     various items, weapons, and armors if you have a certain accessory.
#
# Features:
#   
#   - Easy, quick configuration to setup each event
#   - Variables log all successes and failures for easy merging into an
#     Affection System, Good & Evil System, etc.
#
# Instructions:
#
#   - Setup the few configurations below.   
#   - This script uses comments in the event's pages. Here's how to configure:
#     
#     ** In a single comment or consecutive single line comments *
#
#       Chance = X     - where X is equal to the percentage of
#                        a successful pickpocket. (0 - 100)
#   
#       Type = Y       - where Y is the type of item that will be recieved (0-2)
#                         0 = Item
#                         1 = Weapon
#                         2 = Armor
#     
#       ItemID = Z     - where Z is equal to the database ID of the item, weapon,
#                        or armor (based off of the third comment).
#
#   That's it for setting up events. There are a few more configurations below.
#   For a player to use the ability, they have to have the "Bandit's Gloves"
#   equipped, or whatever you want to call it (see below), and press the Z button
#   (configurable) while touching an event and a pickpocket attempt will be made.
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#                           BEGIN CONFIGURATION
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:

module Pickpocket
 
  #-----------------------------------------------------------------------------
  # The following two methods define equipment that can offer the ability to
  # pickpocket (if ITEM_REQUIRE), and the bonus that different equipment can
  # give. In each respective method for armors and weapons, any ID that has
  # a return value for it will be an item that unlocks the pickpocket ability
  # if equipped. The returned value will define the bonus percentage that the
  # item gives to the overall odds of success.
  #
  # EXAMPLE:
  #
  #         when 34 then 10
  #
  #   This does two things: Lets the weapon/armor with ID:34 provide the ability
  #   to steal if equipped, and adds a 10% bonus to the success rate.
  #-----------------------------------------------------------------------------
 
  def self.armors(armor_id)
    return case armor_id
    # when ARMOR_ID then PERCENT_ADDED
    when 33 then 0  # Bandit's Glove
    when 34 then 10 # Thief's Glove
    when 35 then 25 # Magician's Hand
    end
  end
 
  def self.weapons(weapon_id)
    return case weapon_id
    # when WEAPON_ID then PERCENT_ADDED
    when 32 then 0
    end
  end
 
  # Define any bonuses that are given for having a specific actor in the party.
  def self.actor_bonus(actor_id)
    return case actor_id
    # when ACTOR_ID then PERCENT_ADDED
    when 1 then 3
    else
      0 # Default case. Do not edit.
    end
  end
 
  PICKPOCKET_SWITCH = 20
  # ID of the switch that will turn the system ON/OFF.
 
  SUCCESS_SE = ['055-Right01', 80, 100]
  # SE played when attempt is successful [FILENAME, VOLUME, PITCH]
  FAIL_SE    = ['057-Wrong01', 80, 100]
  # SE played when attempt fails [FILENAME, VOLUME, PITCH]
 
  SUCCESS_VARIABLE = 1
  # In-game variable that will be equal to total successful pickpockets
  FAILURE_VARIABLE = 2
  # In-game variable that will be equal to total unsuccessful pickpockets
  TOTAL_ATTEMPTS_VARIABLE = 3
  # Variable that will be equal to total attempts, successful or not.
 
  ITEM_REQUIRE = true
  # Set to true/false. Determines if an item is required to use the ability.
 
  STEAL_BUTTON = Input::Z
  # This will be the button that is used to pickpocket events, mind you this the
  # the game button, not just the button on your keyboard.
 
  CHANCE_STRING = 'Chance = '
  TYPE_STRING = 'Type = '
  ITEM_ID_STRING = 'ItemId = '
  # These are the strings that the system searches for in event's comments. If
  # you would like something different, change them. It will match the number
  # that immediately follows them.
 
  RESULT_FONT_COLOR = Color.new(128, 255, 128)
  # This will be the font color that the item is written in when the result
  # of a successful pickpocket is displayed on-screen. (Red, Green, Blue)
 
  USE_MODIFIER = false
  # If true, will apply a formula using the party's dexterity to get a
  # small bonus to the chance of success. (below)
 
#-------------------------------------------------------------------------------
# * Modifier Formula
#
#   (TOTAL_PARTY_DEX รท PARTY_SIZE) = X

#   (Square Root of X) * 0.66 = MODIFIER
#
#   The modifier is added to the chance. It's not much, but at higher levels,
#   it can add a different dynamic to pickpocketing. In a quick test using the
#   default curves, it's about a 5 point bonus at level 1, and with the same
#   actors all at level 99, it is about a 16 point bonus. Even with the entire
#   party all having 999 dexterity, the bonus will not exceed 21 points, which
#   I feel is an appropriate curve. Check out the method and fiddle around
#   with the '0.66' if you want to alter it. Just bust out a calculator and plug
#   the formula in real quick to see what values your getting.
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#                         END CONFIGURATION
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
end

#===============================================================================
# ** Game_Map
#===============================================================================

class Game_Map
 
  attr_reader   :steal_data   # Array of pickpocket events, remade for each map
  attr_accessor :attempted    # Logs all attempted steals for each map
 
  alias zer0_pickpocket_init initialize
  def initialize
    @steal_data, @attempted = [], {}
    zer0_pickpocket_init
  end
 
  alias zer0_pickpocket_map setup
  def setup(map_id)
   unless @attempted.has_key?(map_id)
     @attempted[map_id] = []
   end
   zer0_pickpocket_map(map_id)
   refresh_pickpocket
end
 
  def comment_code(string)
    # Returns array of event IDs with matching number after 'string'
    array = []
    @map.events.each_key {|key|
      event = @map.events[key]
        event.pages.reverse.each {|page|
          page.list.each_index {|i|
            if [108, 408].include?(page.list[i].code) &&
              page.list[i].parameters[0] =~ /#{string}([0-9]+)/
              array.push([event.id, $1.to_i])
            end
        }}}
    return array
  end
 
  def refresh_pickpocket
    @steal_data.clear
    chance = comment_code(Pickpocket::CHANCE_STRING)
    type = comment_code(Pickpocket::TYPE_STRING)
    item_id = comment_code(Pickpocket::ITEM_ID_STRING)
    chance.each_index {|i|
      id, ch, ty, it = chance[i][0], chance[i][1], type[i][1], item_id[i][1]
      @steal_data.push([id, ch, ty, it])
    }
  end
end

#===============================================================================
# ** Game_Player
#===============================================================================

class Game_Player
 
  alias zer0_pickpocket_map update
  def update
    zer0_pickpocket_map
    if Input.trigger?(Pickpocket::STEAL_BUTTON) && $game_party.can_pickpocket?
      # Get coordinates/direction in relation to event
      dir_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
      dir_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
      $game_map.steal_data.each_index {|i|
        id = $game_map.steal_data[i][0]
        if $game_map.events[id].x == dir_x && $game_map.events[id].y == dir_y
          return if $game_map.attempted[$game_map.map_id].include?(id)
          pickpocket(i)
          $game_map.attempted[$game_map.map_id].push(id)
        end
      }
    end
  end
 
  def pickpocket(index)
    # Get a random number between 0 - 100
    r = rand(101)
    # Initialize modifier (remains at 0 unless USE_MODIFIER is true)
    modifier = $game_party.equipment_mod
    if Pickpocket::USE_MODIFIER
      $game_party.actors.each_index {|i|
        modifier += $game_party.actors[i].base_dex
      }
      modifier = (modifier / $game_party.actors.size)
      modifier = (Math.sqrt(modifier)) * 0.66
    end
    # Gather the event's pickpocket data from the steal_data list
    chance = ($game_map.steal_data[index][1] + modifier.round)
    item_type = $game_map.steal_data[index][2]
    item_id = $game_map.steal_data[index][3]
    # If the random number is less than the chance, SUCCESS!
    if chance >= r
      $game_system.se_play(RPG::AudioFile.new(*Pickpocket::SUCCESS_SE))
      case item_type
      when 0
        $game_party.gain_item(item_id, 1)
        item = $data_items[item_id]
      when 1
        $game_party.gain_weapon(item_id, 1)
        item = $data_weapons[item_id]
      when 2
        $game_party.gain_armor(item_id, 1)
        item = $data_armors[item_id]
      end
      $game_variables[Pickpocket::SUCCESS_VARIABLE] += 1
      # Set the result of the pickpocket to the screen
      $scene.pickpocket_result(item) if $scene.is_a?(Scene_Map)
    else
      $game_system.se_play(RPG::AudioFile.new(*Pickpocket::FAIL_SE))
      $game_variables[Pickpocket::FAILURE_VARIABLE] += 1
    end
    $game_variables[Pickpocket::TOTAL_ATTEMPTS_VARIABLE] += 1
  end
end

#===============================================================================
# ** Game_Party
#===============================================================================

class Game_Party
 
  alias pickpocket_init initialize
  def initialize
    pickpocket_init
    # Store pickpocket weapons and armors to prevent checking later
    @pickpocket_weapons = (1..$data_weapons.size).find_all {|i|
      Pickpocket.weapons(i) != nil }
    @pickpocket_armors = (1..$data_armors.size).find_all {|i|
      Pickpocket.armors(i) != nil }
    @mods = []
  end
   
  def can_pickpocket?
    # Check switch
    return false unless $game_switches[Pickpocket::PICKPOCKET_SWITCH]
    # Return false if message window is showing
    return false if $game_temp.message_window_showing
    # Check equipment if required
    if Pickpocket::ITEM_REQUIRE
      @mods = []
      weapons = @pickpocket_weapons.find_all {|id| party_weapons.include?(id) }
      armors = @pickpocket_armors.find_all {|id| party_armors.include?(id) }
      # Add modifiers of found equipment.
      @mods += weapons.collect {|weapon_id| Pickpocket.weapons(weapon_id) }
      @mods += armors.collect {|armor_id| Pickpocket.armors(armor_id) }
      return @mods != []
    end
    return true
  end
   
  def party_weapons
    # Returns array of the party's weapon IDs
    return @actors.collect {|actor| actor.weapon_id }
  end
 
  def party_armors
    # Returns array of party's armor IDs
    armors = []
    $game_party.actors.each {|actor|
      armors.push(actor.armor1_id)
      armors.push(actor.armor2_id)
      armors.push(actor.armor3_id)
      armors.push(actor.armor4_id)
    }
    return armors
  end
 
  def equipment_mod
    actor_bonus = @actors.collect {|actor| Pickpocket.actor_bonus(actor.id) }
    bonus = 0
    actor_bonus.each {|percent| bonus += percent }
    # Returns the highest percentage-adding value of all current equipment.
    return @mods != [] ? (@mods.sort[-1] + bonus) : bonus
  end
end

#===============================================================================
# ** Window_Pickpocket
#===============================================================================

class Window_Pickpocket < Window_Base
 
  def initialize(item)
    # Initialize window through parent class.
    super(176, 192, 224, 96)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.draw_text(0, 0, self.contents.width, 32, 'Received a', 1)
    self.contents.font.color = Pickpocket::RESULT_FONT_COLOR
    # Calculate coordinates to draw name and icon.
    icon = RPG::Cache.icon(item.icon_name)
    w = 32 + self.contents.text_size(item.name + '!').width
    x = (self.contents.width - w) / 2
    self.contents.blt(x + 4, 32, icon, Rect.new(0, 0, 24, 24))
    self.contents.draw_text(x + 32, 32, w, 32, item.name + '!')
  end
end

#===============================================================================
# ** Scene_Map
#===============================================================================

class Scene_Map
 
  def pickpocket_result(item)
    # Displays the result on screen in a message.
    window = Window_Pickpocket.new(item)
    loop {
      [Graphics,Input, @spriteset].each {|obj| obj.update }
      break if Input.trigger?(Input::C) || $scene != self
    }
    window.dispose
  end
end



Instructions

Place script above "Main" and below the default scripts.
Instructions on how to set up an event are in the script.


Compatibility

No known compatibility issues.


Credits and Thanks


  • ForeverZer0, for the script




Author's Notes

Please report any bugs or issues you encounter. Enjoy!
83
Advertising / rpgmakers.net
May 01, 2011, 03:46:51 pm
I found a new RM website, created by our very own CP member Valdred. It is still in a development, but thus far the site looks fantastic. The layout is nice and user-friendly, and has some very neat features.

The site is just getting started, so be sure to lend your support by checking it out. I have also decided to host my scripts there as well to support the site. If you would like to register, you can do so by following this link:

www.rpgmakers.net
84
I was curious why we don't have this. It would make copy-pasting scripts out code boxes mush more convenient. I understand its not exactly needed, but I have always thought it would be a nice feature.
85
Sea of Code / [C#] Does anyonw know how to fix this?
April 26, 2011, 11:04:56 pm
Okay here's my problem, look at the first picture:

A normal window proportioned nicely.
Spoiler: ShowHide


Now, I form set to allow the user to resize it, but the result is not what I want. The bottom group box is the only one that appears to stretch. The others actually do, they are just cutoff. Here's what I mean:
Spoiler: ShowHide
 

My question is does anyone know a way to have it behave properly without manually having to code it by calculating height and coordinates, etc.?
Is there a setting I am missing?
86
Spritesheet Separator/Combiner
Authors: ForeverZer0
Version: 1.0
Type: Image Splitter/Combiner
Key Term: Game Utility



Introduction

This is a very basic script I wrote to help myself split up one of them big icon sheets into individual files. After admiring its niftiness for a second, I realized someone else may get some use out of it as well, so here it is. I have also included the ability to combine multiple images into a single one.


Features


  • Extremely simple to use.

  • Splits large icon/sprite sheets up into uniform images, then saves them as individual files in a matter of seconds.

  • Can seperate any image into pieces of any size.

  • Can combine separate files into a single sheet.
  • Lightweight and fast




Screenshots

None.


Demo

None.


Script

Click spoiler for the script.
Spoiler: ShowHide

#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
# Spritesheet Seperator/Combiner
# Author: ForeverZer0
# Date: 5.14.2011
# Version: 1.0
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#
# Introduction:
#   This is a very basic script I wrote to help myself split up one of them big
#   icon sheets into individual files. After admiring its niftiness for a sec, I
#   realized someone else may get some use out of it as well, so here it is.
#
# Features:
#   - Extremely simple to use.
#   - Splits large icon/sprite sheets up into uniform images, then saves them as
#     individual files in a matter of seconds.
#   - Can seperate any image into pieces of any size.
#   - Combines many images of any size into one single file
#   - Lightweight and fast
#
# Instructions:
#   - Place script in new project or temporarily in an existing game anywhere
#     before "Main"
#   - Make any needed changes to the few configurations at the top of the script
#   - Run the game
#
# Credits:
#   - ForeverZer0, for the script
#
# Author's Notes:
#   - Report bugs/issues at www.chaos-project.com
#
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#                          BEGIN CONFIGURATION
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

MODE = 1
# Select the mode to run in.
#   0 = Split Image
#   1 = Combine Images

FOLDER_NAME = 'Images'
# The folder name that the images will be placed into, or the folder where
# the images are contained that will be combined.

#---------------------------------
# Image Splitting
#---------------------------------

SOURCE_FILE = 'test.png'
# The name of the source file that will be split. Place in game directory.

SPLIT_X = 24
SPLIT_Y = 24
# The width/height in pixels to split the image file into on each axis.

BASE_NAME = 'icon'
# The base name used for the output files.

NAMING_TYPE = 1
# Define the naming convention applied to the base name.
# 0 = Numerically. (icon 1, icon 2, icon 3, etc, etc)
# 1 = Coordinates. (icon 1x2, icon 3x4, icon 3x5, etc. etc)

#---------------------------------
# Image Combining
#---------------------------------

IMAGES_WIDE = 12
# The number of images that will be placed per row

FILENAME = 'combined'
# The output filename

#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
#                           END CONFIGURATION
#=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

module Zlib
 class Png_File < GzipWriter
#-------------------------------------------------------------------------------
   def make_png(bitmap_Fx,mode)
     @mode = mode
     @bitmap_Fx = bitmap_Fx
     self.write(make_header)
     self.write(make_ihdr)
     self.write(make_idat)
     self.write(make_iend)
   end
#-------------------------------------------------------------------------------
   def make_header
     return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
   end
#-------------------------------------------------------------------------------
   def make_ihdr
     ih_size = [13].pack("N")
     ih_sign = "IHDR"
     ih_width = [@bitmap_Fx.width].pack("N")
     ih_height = [@bitmap_Fx.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
#-------------------------------------------------------------------------------
   def make_idat
     header = "\x49\x44\x41\x54"
     data = make_bitmap_data
     data = Zlib::Deflate.deflate(data, 8)
     crc = [Zlib.crc32(header + data)].pack("N")
     size = [data.length].pack("N")
     return size + header + data + crc
   end
#-------------------------------------------------------------------------------
   def make_bitmap_data1
     w = @bitmap_Fx.width
     h = @bitmap_Fx.height
     data = []
     for y in 0...h
       data.push(0)
       for x in 0...w
         color = @bitmap_Fx.get_pixel(x, y)
         red = color.red
         green = color.green
         blue = color.blue
         alpha = color.alpha
         data.push(red)
         data.push(green)
         data.push(blue)
         data.push(alpha)
       end
     end
     return data.pack("C*")
   end
#-------------------------------------------------------------------------------
   def make_bitmap_data
     gz = Zlib::GzipWriter.open('hoge.gz')
     t_Fx = 0
     w = @bitmap_Fx.width
     h = @bitmap_Fx.height
     data = []
     for y in 0...h
       data.push(0)
       for x in 0...w
         t_Fx += 1
         if t_Fx % 10000 == 0
           Graphics.update
         end
         if t_Fx % 100000 == 0
           s = data.pack("C*")
           gz.write(s)
           data.clear
         end
         color = @bitmap_Fx.get_pixel(x, y)
         red = color.red
         green = color.green
         blue = color.blue
         alpha = color.alpha
         data.push(red)
         data.push(green)
         data.push(blue)
         data.push(alpha)
       end
     end
     s = data.pack("C*")
     gz.write(s)
     gz.close    
     data.clear
     gz = Zlib::GzipReader.open('hoge.gz')
     data = gz.read
     gz.close
     File.delete('hoge.gz')
     return data
   end
#-------------------------------------------------------------------------------
   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
end

#===============================================================================
# ** Bitmap
#===============================================================================

class Bitmap

 def make_png(name="like", path="",mode=0)
   make_dir(path) if path != ""
   Zlib::Png_File.open("temp.gz") {|gz| gz.make_png(self, mode) }
   Zlib::GzipReader.open("temp.gz") {|gz| $read = gz.read }
   f = File.open(path + name + ".png","wb")
   f.write($read)
   f.close
   File.delete('temp.gz')
   end
#-------------------------------------------------------------------------------
 def make_dir(path)
   dir = path.split("/")
   dir.each_index {|i|
     unless dir == "."
       add_dir = dir[0..i].join("/")
       begin
         Dir.mkdir(add_dir)
       rescue
       end
     end
   }
 end
end

#===============================================================================
# Processing
#===============================================================================

time = Time.now

if MODE == 0
 bitmap = Bitmap.new(SOURCE_FILE)
 count = 0
 (0...(bitmap.width / SPLIT_X)).each {|x| (0...(bitmap.height / SPLIT_Y)).each {|y|
   count += 1
   icon = Bitmap.new(SPLIT_X, SPLIT_Y)
   rect = Rect.new(x * SPLIT_X, y * SPLIT_Y, SPLIT_X, SPLIT_Y)
   icon.blt(0, 0, bitmap, rect)
   name = (BASE_NAME + (NAMING_TYPE == 0 ? " #{count}" : " #{x+1}x#{y+1}"))
   icon.make_png(name, FOLDER_NAME + '/')
   if count % 80 == 0
     Graphics.update
   end
 }}

elsif MODE == 1
 
 images = Dir.entries(FOLDER_NAME) - ['.', '..']
 if images.empty?
   print("No image files found in #{FOLDERNAME} directory.")
   exit
 end
 images.collect! {|filename| Bitmap.new("#{FOLDER_NAME}/#{filename}") }
 w, h, num = images[0].width, images[0].height, images.size
 canvas = Bitmap.new(w * IMAGES_WIDE, (num.to_f / IMAGES_WIDE).ceil * h)
 images.each_with_index {|image, i|
   x, y = (i % IMAGES_WIDE) * w, (i / IMAGES_WIDE) * h
   canvas.blt(x, y, image, Rect.new(0, 0, w, h))
   if (i % 80) == 0
     Graphics.update
   end
 }
 canvas.make_png(FILENAME, '')
end

print ("Process Complete!\n" +
     "#{count} images converted in #{Time.now.to_f - time.to_f} seconds.")
exit



Instructions

Place script anywhere above main, place source file in game directory, make any needed adjustments to the configuration, then run the game.


Compatibility

None.


Credits and Thanks


  • ForeverZer0, for the script.




Author's Notes

Please report any bugs/issues, I'll be sure to help you resolve them.
87
Core Development / Advertising
April 20, 2011, 12:46:11 am
It may still be a little premature for this, but I don't specifically mean posting up actual advertisement around the internet. Would it maybe be a good idea to start spreading the word a little around the RPG Maker community?  I know I pretty much stick with CP.  I may occasionally scope out RMRK every once in a while, but I must say I don't really know what's going on in there forums.  My point is, I'm sure there are many others out there who are the same, who may not even know CP, let alone ARC, who need informed of its greatness ( 8)).

I just thought maybe we should throw together an "advertisement" post with some basic details, list some features, links, etc. and post it up on some other RM sites.

Thoughts?

88
I'd like to know what opinions others may have as to which is the best one. I use Hex Workshop v.6, and I have tried one or two others, but for some reason I always feel that it is somehow lacking. Any editors out there that someone thinks is great?
89
Electronic and Computer Section / My New Computer
March 04, 2011, 11:24:10 pm
So the other day I ordered a new PC, which I should be getting here with a few weeks. I'm pretty pumped about, it's a huge improvement over my current Inspiron. Here's the specs:

Model: Dell XPS 15
Operating System: Windows 7 Home Premium 64bit
Processor: 2nd Generation Intel Core i7-2620M  2.70 GHz with Turbo Boost 2.0, up to 3.40 GHz
Memory: 6GB RAM
Screen: 15.6" HD LCD
Video: NVIDIA GeForce GT 525M 1GB graphics with Optimus

Not the absolute best, but that is a damn fine machine in my book. I can't wait!  ;)
90
ARC Reactor Engine / Zer0 Division Engine
March 02, 2011, 10:45:31 pm
I've been tossing around the idea to built a new RMXP engine. I don't yet have the whole idea formulated as of yet, but I have been doing some brainstorming and have even began some coding.

Here's the idea:

C# application with embedded Ruby Interpreter
The loose plan is to built the editor with C# and embed an IronRuby interpreter. I have already managed to embed the interpreter and manage to execute some Ruby code using C#, so it is not nearly as difficult as I imagined. I am slightly leary of IronRuby since I have not worked with it before, but I think I will explore it some more for its compatibility with the .NET Framework and ease of use passing data back and forth between the languages.

Ruby 1.9.1
Now this may not seem like such a big deal to those who aren't scripters, but 1.9.1 is far superior to the 1.8 version of Ruby that RMXP uses by default. In addition to being faster, one addition that a 1.9.1 will add is the WINOLE library, which allows for MUCH easier ways to access and manipluate external programs through a script. One example of where this would have been handy is the screenshot.dll that many scripters use. With WINOLE, you would not need any external .dll, and it could have been easily done in maybe 25 lines of code (although that specific feature will likely be a built in feature with my engine). There are far more advantages than mentioned here, as I am sure most Ruby scripters who are familiar with 1.9.1 can attest to.

RubyGems
Gems are add-ons that can basically be added to the Ruby source code. There are thousands of them with a wide array of uses, ranging from added functionality to existing classes, to complex ones like WxRuby that allow you to make Windows forms, which Game_Guy and I were experimenting around with a an idea to re-write the database. This is one of the main reasons I was second-guessing the idea of using IronRuby. Although Gems can be used with IronRuby, not all the bugs have yet been worked smoothed out, and some Gems simply don't work. This will allow for even more ability to scripter to take advantage of Ruby's full potential, which is hampered down in the existing RMXP.

Extensibility
I plan to have the editor be fully extensible, and allow for the use of plugins for the editor. This feature has not been fully thought through yet, but will definitely be a there. What this will do is allow for you to simply copy-paste a .dll that someone created to the "Plug-Ins" folder, and when you run the editor, there will be new tab pages for editting of custom scripts you may have. For example, think of the BABS configuration or the CCTS configuration I just wrote. The plug-in feature would allow for similar things to be written as a .dll and embedded right into the main editor for a one-stop place to edit your game.

Totally Revamped Editor
I plan to re-code the editor to allow for more features. Many of the built in limits will be eliminated, such as a max level of 999, any stats, number of characters, enemies, etc., etc. It will  be easier to use, have many minor improvements, and I also plan to not make it modulas. This will allow you to have the map editor, script editor, and database all open at the same time and not having to close one to use the other. It always irritated me that you couldn't do that. All of them will be resizeable and can also be opened during playtesting. This is the part that I will be coding first, and I will likely release it before the whole engine so that people can begin to take advantage of it.

Open Source
I will leave the engine open source so that it can be editted by anyone with the ability to do so.

Compatibility
One of the greatest things about this engine is that any and all existing RMXP projects will be able to work with it.



I will continue to keep you all posted on progress, but as of the moment it is mainly a bit of a side-project that I do as a hobby to challenge myself. Needless to say, even an approximate release date is not even possible at this time, but I would love to hear anyone's thoughts and feedback.