Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Reply to this topicStart new topic
> Zeriab's Anti Event Lag System, Version 1.2
Zeriab
post Sep 4 2007, 10:47 AM
Post #1


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




Zeriab's Anti Event Lag System
Version: 1.2


Introduction

This system changes the design used for controlling the events on the game map as well as reducing the number of character sprites outside of the visible area.
The new design for the events should in most cases give faster collision detection
In certain situations this system should be slightly slower though I doubt it can make any noticeable difference.
This script only makes event collision detection faster in the case where all the events are visible.
The greatest benefit from this script comes from large maps with sparse population of events. Basically, events do no come together loads at a time.

Version history
[Show/Hide] For anyone interested

Version 0.8 -------------------------------------------------- (2007-09-03)
- First release

Version 0.81 ------------------------------------------------- (2007-09-05)
- Overwrote Game_Map's passable? method for faster collision detection

Version 0.9 -------------------------------------------------- (2007-09-12)
- Support for the Non-SDK patch
- Support for defining whether and event will always be updated or never be updated by defining name patterns.

Version 1.0 -------------------------------------------------- (2007-09-24)
- Fixed compatibility issue with Blizzard's Caterpillar script
- Overwrote more methods scanning for events on a specific tile
- Support for defining whether an event will always be updated or never be updated by specifying the event's id and map_id
- Some structural changes.
- Integrated the Non-SDK patch into the main script

Version 1.05 ------------------------------------------------- (2007-11-18)
- Fixed bug where sprites might not be disposed when changing scene.

Version 1.1 -------------------------------------------------- (2008-04-10)
- Added declaration to which common events to update

Version 1.15 ------------------------------------------------- (2008-06-19)
- Added automatic detection of which common events to update (optional)

Version 1.2 -------------------------------------------------- (2008-07-04)
- Fixed a case where an event could be registered twice causing transparent
events to look less transparent.


Features

Easy to alter the size of the visible area. (In combination with resolution scripts for example)
Pattern matching on event names to ease determination of events needing special treatment. (Never update and always update)
Specify special update schemes for events by their id and the map they are on.

Screenshots

The screenshot was taking from my test map included as an attachment. There are 662 events on that 500x500 map.



Demo

http://www.sendspace.com/file/0up9up (zip version)

Script

Zeriab's Anti Event Lag System version 1.2
Note: The comments in the script are aimed at other scripters. Don't be scared by it.

Installation

You don't have to do more than copy and paste the script into the script editor BUT where you paste it matters.
If you are using the SDK 2.0+ paste the script just below the SDK.
If you are are not using the SDK then paste the script just below the default scripts

The structure in the script editor should be like this:
default scripts
(SDK)
Zeriab's Anti Event Lag System
(custom scripts)
main


Pasting the script just above main has caused errors!

You can add [A] to the name of an event if you want it always updated. A typical example is that you want an event outside of the screen to move around properly.
You can add [N] to the name of an event and it will never be updated. Great for non-animated decoration events.
Note that if you have both [A] and [N] in the name of the event the event will never be updated.

If you are not satisfied with the default settings or are curious you can look into the customization possibilities
[Show/Hide] Customization

A little below the big header there is a customization area (line 265-284) which contains:
CODE
class Game_Map
  ALWAYS_UPDATE = false
  BUFFER_SIZE = 1
  TILES_VERTICAL = 15
  TILES_HORIZONTAL = 20
  LIMIT_COMMON_EVENTS = true
  SPECIFY_COMMON_EVENTS_MANUALLY = false
  # If you want to specify which common events to update
  COMMON_EVENTS_TO_UPDATE = []
  # If you want the script to automatically read the common events and find
  # out which to update. Must be the path to the CommonEvents.rxdata
  COMMON_EVENT_FILEPATH = 'Data/CommonEvents.rxdata'
end

class Game_Event
  SPECIAL_UPDATE_IDS = {}
  NEVER_UPDATE_NAME_PATTERNS = ['[N]'] # [N] in the event name => not updated
  ALWAYS_UPDATE_NAME_PATTERNS = ['[A]'] # [A] in the event name => always updated
end


There are comments on how to use each constant in the script header. Those comments are aimed at other scripters and can therefore be fairly difficult to understand for non-scripters. The examples in the header can useful even if you are not a scripter.
I will explain each constant in a more humane way. (Using this in unison with the instructions in the header might yield the best result)

I'll start by going through class Game_Map.
ALWAYS_UPDATE
Set this to true if you want all events updated. All events will on the map will be updated just like with the default scripts. This is slow, but you will still get the effects of the changed collision detection and sprite management.
I included this option for compatibility reasons more than anything else. Don't use this if you want a few events outside of the screen to be constantly updated. In that case refer to the stuff in Game_Event

BUFFER_SIZE
The buffer size tells how many tiles outside of the visible area should be updated.
If you have many big sprites (for the events) and get the sprites just disappearing or 'freezing' for a moment near the edge of the screen the solution can be to increase the buffer size.
Be aware that increasing the buffer size makes the game slower.

TILES_VERTICAL
Use this to tell how many tiles there on a vertical line across the game screen.
Only change this value if you change the resolution.

TILES_HORIZONTAL
Use this to tell how many tiles there on a horizontal line across the game screen.
Only change this value if you change the resolution.

LIMIT_COMMON_EVENTS
Set this to false if you do not wish to limit which common events are updated.
If you do not limit the common events the next three constants have no effect. (SPECIFY_COMMON_EVENTS_MANUALLY, COMMON_EVENTS_TO_UPDATE, COMMON_EVENT_FILEPATH)

SPECIFY_COMMON_EVENTS_MANUALLY
Set this to true if you want to specify the common events manually. This is not recommended for beginners.
You will have to fill out COMMON_EVENTS_TO_UPDATE if you set this to true. COMMON_EVENT_FILEPATH will have no effect if this is true.
If this is set to false then COMMON_EVENTS_TO_UPDATE will have no use. The script will automatically detect which common events to update if this is set to false.

COMMON_EVENTS_TO_UPDATE
Fill in the array with the common event ids you want updated. (Look in the database for the numbers)
All other common events will not be updated. They can still be called using the call common event command, but they will not be started if they have the autorun or parallel process triggers.

COMMON_EVENT_FILEPATH
The path to where the common events are stored.
Only touch this if you have changed the filename where the common events are stored. If you don't know what this means then chances are that you should not change what is given.


Next we come to class Game_Event which is a bit more complicated to customize.
Typically you can be fine without modifying the following constants. Id y
SPECIAL_UPDATE_IDS
You can use this to say that specific in specific maps must always be updated or never updated.
If an event is always updated it acts just as it does with the default scripts.
If an event is never updated it not move. Neither with Autonomous Movement nor the event command 'Set Move Route...'. You can still to some degree interact with it but in general use the never update feature for decoration events.

NEVER_UPDATE_NAME_PATTERNS
You can use this to specify new patterns to look for in the names of the events.
If the name of an event matches at least one of the patterns it will never be updated.
A pattern can both be what is called a regular expression and a string. If you don't know what a regular expression is or don't understand them then don't try to use regular expressions.
The string is a piece of text and the name of the event will be checked if that piece of text is anywhere in the name. The text have to be surrounded by either 'text' or "text". There is no practical difference in case of this script.
If an event is never updated it not move. Neither with Autonomous Movement nor the event command 'Set Move Route...'. You can still to some degree interact with it but in general use the never update feature for decoration events.

ALWAYS_UPDATE_NAME_PATTERNS
You can use this to specify new patterns to look for in the names of the events.
If the name of an event matches at least one of the patterns it will always be updated.
A pattern can both be what is called a regular expression and a string. If you don't know what a regular expression is or don't understand them then don't try to use regular expressions.
The string is a piece of text and the name of the event will be checked if that piece of text is anywhere in the name. The text have to be surrounded by either 'text' or "text". There is no practical difference in case of this script.
If an event is always updated it acts just as it does with the default scripts.


Q&A's

How can I make sure that an event outside of the screen moves like I told it to?
Change the name of the event so it always updates.
With the default configurations you can do this by adding [A] anywhere in the name.

Compatibility
[Show/Hide] Technical Details

This is SDK compliant. It is written for SDK version 2.3.
It has not been tested with older versions.
Requires SDK Part 2 or the Non-SDK patch version 1.1

The following methods has been overwritten:
  • Game_Character.passable?
  • Game_Map.passable?
  • Game_Map.update_events
  • Game_Player.check_event_trigger_here
  • Game_Player.check_event_trigger_there
  • Game_Player.check_event_trigger_touch
  • Spriteset_Map.init_characters
  • Spriteset_Map.update_character_sprites


The following methods have been aliased:
  • Game_Event.jump
  • Game_Event.moveto
  • Game_Event.move_down
  • Game_Event.move_left
  • Game_Event.move_right
  • Game_Event.move_up
  • Game_Event.move_lower_left
  • Game_Event.move_lower_right
  • Game_Event.move_upper_left
  • Game_Event.move_upper_right
  • Game_Map.setup



[Show/Hide] Rataime's Sun Effect

Paste this code in a new section anywhere below Rataime's Sun Effect and above main. (use can press Insert to create a new section)
CODE
alias Zantilag_XPML_read XPML_read
def XPML_read(markup,event_id,max_param_number=0)
  return if $game_map.events[event_id].nil?
  Zantilag_XPML_read(markup,event_id,max_param_number=0)
end



[Show/Hide] Near Fantastica's Particle Engine v2

Paste this code in a new section anywhere below Near Fantastica's Particle Engine v2 and above main. (use can press Insert to create a new section)
CODE
class Spriteset_Map
  def update_character_sprites
    nf_particles_spriteset_map_update_character_sprites
    for sprite in @character_event_sprites
      next unless sprite.character.is_a?(Game_Event)
      if sprite.character.pe_refresh == true
        sprite.character.pe_refresh = false
        @particle_engine.remove_effect(sprite.character)
        @particle_engine.add_effect(sprite.character)
      end
    end
  end
end




Credits and Thanks

Thanks goes to Enterbrain for making this possible.
Special thanks to Blizzard for many suggestions, help and support :3
Special thanks to:
Eilei
Shadow Wolf
Untravaersil
darksora

I would like to thank everyone using their time to try and use my system.
I would like to thank everyone reading this topic.
Thanks.

Terms and Conditions
[Show/Hide] License
Copyright © 2007 Zeriab

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser Public License for more details.

For the full license see <http://www.gnu.org/licenses/>
The GNU General Public License: http://www.gnu.org/licenses/gpl.txt
The GNU Lesser General Public License: http://www.gnu.org/licenses/lgpl.txt


Author's Notes

I would be delighted if you report any bug, errors or issues you find.
In fact I would be delighted if you took the time and replied even if you have nothing to report.
Suggestions are more than welcome

And finally: ENJOY!

- Zeriab

This post has been edited by Zeriab: Jul 5 2008, 04:14 AM


__________________________
Go to the top of the page
 
+Quote Post
   
Guest_RPG Wizard_*
post Sep 5 2007, 08:10 AM
Post #2





Guests





May I ask what a SDK is? I am kinda noob at RMXP >_<

Looks really useful, may I add this to the site once the script section is done? He he. Maybe you can make some exclusive scripts to us, and I'll kiss you!
Go to the top of the page
 
+Quote Post
   
Zeriab
post Sep 6 2007, 01:10 AM
Post #3


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




The SDK stands for 'Software Development Kit'. It can be found at rmxp.org.
Anyway I have included a non-SDK script of version 0.81 so you don't need to search for the SDK.

You can add the script to the site if you want happy.gif
I'm not really sure whether I want to make exclusive scripts or not. It is something I need to think about.

Thanks for the comments
~ Zeriab

CODE

#==============================================================================
# ** Anti Event Lag System ~ non-SDK version
#------------------------------------------------------------------------------
# Zeriab
# Version 0.81
# 2007-09-05 (Year-Month-Day)
#------------------------------------------------------------------------------
# * Version History :
#
# Version 0.8 -------------------------------------------------- (2007-09-03)
# - First release
#
# Version 0.81 ------------------------------------------------- (2007-09-05)
# - Overwrote Game_Map's passable? method for faster collision detection
#------------------------------------------------------------------------------
# * Description :
#
# This script was designed to reduce lag by changing the data structure of
# the events in the Game_Map class and update the functionality accordingly
# A goal of this script is not to change the normal event behavior, so
# implementing it into a project should not effect previous events. It might
# effect custom scripts.
#
# Note : It is advised to place this below all other scripts, if you have
# a script that aliases or modifies the Game_Event, Game_Map or Spriteset_Map
# update methods.
#------------------------------------------------------------------------------
# * License :
#
# Copyright © 2007 Zeriab
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# For the full license see <http://www.gnu.org/licenses/>
# The GNU General Public License: http://www.gnu.org/licenses/gpl.txt
# The GNU Lesser General Public License: http://www.gnu.org/licenses/lgpl.txt
#------------------------------------------------------------------------------
# * Compatibility :
#
# The following methods has been overwritten:
# * Game_Event.passable?
# * Game_Map.passable?
# * Game_Map.update
# * Spriteset_Map.initialize
# * Spriteset_Map.update
#------------------------------------------------------------------------------
# * Instructions :
#
# Place this script just above main.
# There are 3 constants you can change at will in the top of the
# Game_Map class: (You don't have to wink.gif)
#
# BUFFER_SIZE ~ Default = 2
# -------------------------
# You can increase or decrease the buffer size by altering this value.
# The greater this value the greater area around the visible area is updated
# at the price of potential more lag.
# The lower this value the smaller area around the visible area is update
# with the potential of less lag.
# Too low a value may get the sprites to sort of 'freeze' in the outskirts
# of the screen.
# Bigger sprites requires bigger buffer to prevent this.
#
# TILES_HORIZONTAL ~ Default = 20
# -------------------------------
# Specifies how many tiles there are horizontal
# I included the option to change this value if you want to alter
# the size of the game window.
# If you for example want 800x600 I suggest changing this value to 27
#
# TILES_VERTICAL ~ Default = 15
# -----------------------------
# Specifies how many tiles there are vertical
# Specifies how many tiles there are horizontal
# I included the option to change this value if you want to alter
# the size of the game window.
# If you for example want 800x600 I suggest changing this value to 20
#==============================================================================

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

class Game_Map
#--------------------------------------------------------------------------
# * Constants
#--------------------------------------------------------------------------
BUFFER_SIZE = 2
TILES_VERTICAL = 15
TILES_HORIZONTAL = 20
ALWAYS_UPDATE = false
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :event_map
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias_method :zeriab_antilag_gmmap_setup, :setup
#--------------------------------------------------------------------------
# * Setup
#--------------------------------------------------------------------------
def setup(*args)
# Makes an event map as a hash
@event_map = {}
# Original Setup
zeriab_antilag_gmmap_setup(*args)
# Adds all the events on the map to the event map
for event in @events.values
add_event(event.x, event.y, event)
end
end

#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Refresh map if necessary
if $game_map.need_refresh
refresh
end
# If scrolling
if @scroll_rest > 0
# Change from scroll speed to distance in map coordinates
distance = 2 ** @scroll_speed
# Execute scrolling
case @scroll_direction
when 2 # Down
scroll_down(distance)
when 4 # Left
scroll_left(distance)
when 6 # Right
scroll_right(distance)
when 8 # Up
scroll_up(distance)
end
# Subtract distance scrolled
@scroll_rest -= distance
end
# Update map event
for event in @events.values
# checks if the event is visible or needs to be updated
if ALWAYS_UPDATE || visible?(event.x, event.y) || event.need_update?
event.update
end
end
# Update common event
for common_event in @common_events.values
common_event.update
end
# Manage fog scrolling
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
# Manage change in fog color tone
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
# Manage change in fog opacity level
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end
end

#--------------------------------------------------------------------------
# * Called when an event has been moved with it's old x and y coordinate
# Used to update its position in the event_map
#--------------------------------------------------------------------------
def move_event(old_x,old_y,event)
# Checks if the event has moved to a new position.
return if old_x == event.x && old_y == event.y
# Removes the event from its old position
remove_event(old_x, old_y, event)
# Adds the event to its new position
add_event(event.x,event.y,event)
# Gets the spriteset from Scene_Map
spriteset = $scene.instance_eval('@spriteset')
# Checks that it actually is a Spriteset_Map.
if spriteset.is_a?(Spriteset_Map)
# Tells the spriteset to update the event to its new position
spriteset.update_event(old_x,old_y,event)
end
end

#--------------------------------------------------------------------------
# * Adds an event to the event_map at the given x and y coordinate
#--------------------------------------------------------------------------
def add_event(x,y,event)
# Checks if there are not any events on the specific tile
if @event_map[[x,y]].nil?
# Sets the position on the map to be an array containing the given
# event. (In case there are placed additional events on this tile)
@event_map[[x,y]] = [event]
else
# Adds the event to the array of events on the specific tile
@event_map[[x,y]] << event
end
end

#--------------------------------------------------------------------------
# * Removes an event from the event_map with the given x and y coordinate
#--------------------------------------------------------------------------
def remove_event(x,y,event)
# Checks if there actually are an event on the given coordinates
return if @event_map[[x,y]].nil?
# Checks whether or not there are more events than the given event on
# with the given coordinates
if @event_map[[x,y]].size > 1
# Deletes the events from the array of events
@event_map[[x,y]].delete(event)
else
# Deletes the key along with the corresponding value from the hashmap
# since there are no other events on the tile.
@event_map.delete([x,y])
end
end

#--------------------------------------------------------------------------
# * Gets min_x, max_x, min_y and max_y including the buffer-size
# Returns min_x, max_x, min_y, max_y (tile-coordinates)
# Returns a Rect if 'true' is given as the argument
#--------------------------------------------------------------------------
def get_tile_area(rect = false)
# Gets the upper left x and y tile-coordinate
x = $game_map.display_x / 128
y = $game_map.display_y / 128
# Computes the min and max coordinates when considering the buffer-size
min_x = x - BUFFER_SIZE
min_y = y - BUFFER_SIZE
max_x = x + TILES_HORIZONTAL + BUFFER_SIZE
max_y = y + TILES_VERTICAL + BUFFER_SIZE
# Makes sure the min and max coordinates are within the map
if min_x < 0
min_x = 0
end
if max_x >= $game_map.width
max_x = $game_map.width - 1
end
if min_y < 0
min_y = 0
end
if max_y >= $game_map.height
max_y = $game_map.height - 1
end
# Checks if the return should be a Rect
if rect
# Returns the result as a Rect
return Rect.new(min_x, min_y, max_x - min_x, max_y - min_y)
else
# Returns the result as the min and max coordinates
return min_x, max_x, min_y, max_y
end
end

#--------------------------------------------------------------------------
# * Checks if the tile with the given x and y coordinate is visible.
# Takes the buffer size into account.
#--------------------------------------------------------------------------
def visible?(x,y)
min_x = $game_map.display_x / 128
min_y = $game_map.display_y / 128
if x >= min_x - BUFFER_SIZE && x <= min_x + BUFFER_SIZE + TILES_HORIZONTAL &&
y >= min_y - BUFFER_SIZE && y <= min_y + BUFFER_SIZE + TILES_VERTICAL
return true
end
return false
end

#--------------------------------------------------------------------------
# * Determine if Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Self (If event is determined passable)
#--------------------------------------------------------------------------
def passable?(x, y, d, self_event = nil)
# If coordinates given are outside of the map
unless valid?(x, y)
# impassable
return false
end
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
events = event_map[[x,y]]
unless events.nil?
# Loop through events on tile
for event in events
# If tiles other than self are consistent with coordinates
if event.tile_id >= 0 and event != self_event and not event.through
# If obstacle bit is set
if @passages[event.tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[event.tile_id] == 0
# passable
return true
end
end
end
end
# Loop searches in order from top of layer
for i in [2, 1, 0]
# Get tile ID
tile_id = data[x, y, i]
# Tile ID acquistion failure
if tile_id == nil
# impassable
return false
# If obstacle bit is set
elsif @passages[tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[tile_id] == 0
# passable
return true
end
end
# passable
return true
end
end

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

class Game_Event
# The method to alias and overwrite
AX = [:jump, :moveto, :move_down, :move_left, :move_right, :move_up,
:move_lower_left, :move_lower_right, :move_upper_left, :move_upper_right]
for method in AX
# Aliases the old method
new_method_as_string = 'zeriab_antilag_gmtev_' + method.to_s
new_method = new_method_as_string
alias_method(new_method, method)

# Overwrites the old method
PROG =<<FIN
def #{method}(*args)
old_x = @x
old_y = @y
#{new_method}(*args)
unless old_x == @x && old_y == @y
$game_map.move_event(old_x, old_y, self)
end
end
FIN
# Evaluates the method definition
eval(PROG)
end

#--------------------------------------------------------------------------
# * Always_update property (is false by default)
#--------------------------------------------------------------------------
attr_writer :always_update
def always_update
@always_update = false if @always_update.nil?
return @always_update
end

#--------------------------------------------------------------------------
# * Always_update property
#--------------------------------------------------------------------------
def need_update?
return true if move_route_forcing || @move_type == 3
return @trigger == 3 || @trigger == 4 || always_update
end

#--------------------------------------------------------------------------
# * Determine if Passable (Overwrite)
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
#--------------------------------------------------------------------------
def passable?(x, y, d)
# Get new coordinates
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
# If coordinates are outside of map
unless $game_map.valid?(new_x, new_y)
# impassable
return false
end
# If through is ON
if @through
# passable
return true
end
# If unable to leave first move tile in designated direction
unless $game_map.passable?(x, y, d, self)
# impassable
return false
end
# If unable to enter move tile in designated direction
unless $game_map.passable?(new_x, new_y, 10 - d)
# impassable
return false
end
# If player coordinates are consistent with move destination
if $game_player.x == new_x and $game_player.y == new_y
# If through is OFF
unless $game_player.through
# If your own graphic is the character
if @character_name != ""
# impassable
return false
end
end
end
# Checks for events on the new position
events = $game_map.event_map[[new_x,new_y]]
if events.nil?
# passable
return true
end
# Loop all events on the tile
for event in events
# If event coordinates are consistent with move destination
if event.x == new_x and event.y == new_y
# If through is OFF
unless event.through
# If self is event
if self != $game_player
# impassable
return false
end
# With self as the player and partner graphic as character
if event.character_name != ""
# impassable
return false
end
end
end
end
# passable
return true
end
end

#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
# Overwrites init_characters and update_character_sprites
#==============================================================================

class Spriteset_Map
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Make viewports
@viewport1 = Viewport.new(0, 0, 640, 480)
@viewport2 = Viewport.new(0, 0, 640, 480)
@viewport3 = Viewport.new(0, 0, 640, 480)
@viewport2.z = 200
@viewport3.z = 5000
# Make tilemap
@tilemap = Tilemap.new(@viewport1)
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
for i in 0..6
autotile_name = $game_map.autotile_names[i]
@tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name)
end
@tilemap.map_data = $game_map.data
@tilemap.priorities = $game_map.priorities
# Make panorama plane
@panorama = Plane.new(@viewport1)
@panorama.z = -1000
# Make fog plane
@fog = Plane.new(@viewport1)
@fog.z = 3000
# Make character sprites
refresh_characters
@hero_character = Sprite_Character.new(@viewport1, $game_player)
refresh_character_sprites
# Make weather
@weather = RPG::Weather.new(@viewport1)
# Make picture sprites
@picture_sprites = []
for i in 1..50
@picture_sprites.push(Sprite_Picture.new(@viewport2,
$game_screen.pictures[i]))
end
# Make timer sprite
@timer_sprite = Sprite_Timer.new
# Frame update
update
end

def refresh_characters
# Make character sprites
@character_sprites = []
@character_spritemap = {}
# Gets the tile area to search for events
min_x, max_x, min_y, max_y = $game_map.get_tile_area
# Goes through all the visible tiles and adds the sprites on those tiles
for x in min_x..max_x
for y in min_y..max_y
add_sprites(x,y)
end
end
end

#--------------------------------------------------------------------------
# * Refreshes the character sprites.
#--------------------------------------------------------------------------
def refresh_character_sprites
# Gets the character sprites
@character_sprites = @character_spritemap.values.flatten
#### Note: I do not think character sprites have to be sorted, but here it
#### is if you for some reason need them sorted.
#@character_sprites.sort! {|a,b| a.character.id <=> b.character.id}
# Adds the hero character sprite
@character_sprites.push(@hero_character)
# Updates the last screen x and y to the current x and y
@last_screen_x = $game_map.display_x / 128
@last_screen_y = $game_map.display_y / 128
# The sprites have just been refresh, no need to do this every frame.
@need_refresh = false
end

#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# If panorama is different from current one
if @panorama_name != $game_map.panorama_name or
@panorama_hue != $game_map.panorama_hue
@panorama_name = $game_map.panorama_name
@panorama_hue = $game_map.panorama_hue
if @panorama.bitmap != nil
@panorama.bitmap.dispose
@panorama.bitmap = nil
end
if @panorama_name != ""
@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)
end
Graphics.frame_reset
end
# If fog is different than current fog
if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue
@fog_name = $game_map.fog_name
@fog_hue = $game_map.fog_hue
if @fog.bitmap != nil
@fog.bitmap.dispose
@fog.bitmap = nil
end
if @fog_name != ""
@fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue)
end
Graphics.frame_reset
end
# Update tilemap
@tilemap.ox = $game_map.display_x / 4
@tilemap.oy = $game_map.display_y / 4
@tilemap.update
# Update panorama plane
@panorama.ox = $game_map.display_x / 8
@panorama.oy = $game_map.display_y / 8
# Update fog plane
@fog.zoom_x = $game_map.fog_zoom / 100.0
@fog.zoom_y = $game_map.fog_zoom / 100.0
@fog.opacity = $game_map.fog_opacity
@fog.blend_type = $game_map.fog_blend_type
@fog.ox = $game_map.display_x / 4 + $game_map.fog_ox
@fog.oy = $game_map.display_y / 4 + $game_map.fog_oy
@fog.tone = $game_map.fog_tone
# Update character sprites
update_character_sprites
# Update weather graphic
@weather.type = $game_screen.weather_type
@weather.max = $game_screen.weather_max
@weather.ox = $game_map.display_x / 4
@weather.oy = $game_map.display_y / 4
@weather.update
# Update picture sprites
for sprite in @picture_sprites
sprite.update
end
# Update timer sprite
@timer_sprite.update
# Set screen color tone and shake position
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
# Set screen flash color
@viewport3.color = $game_screen.flash_color
# Update viewports
@viewport1.update
@viewport3.update
end

#--------------------------------------------------------------------------
# * Updates Character Sprites
#--------------------------------------------------------------------------
def update_character_sprites
# Checks if the player has moved
unless @last_screen_x == $game_map.display_x / 128 &&
@last_screen_y == $game_map.display_y / 128
# Gets the difference in the x and y coordinate
diff_x = @last_screen_x - $game_map.display_x / 128
diff_y = @last_screen_y - $game_map.display_y / 128
# Checks if the player has moved more than one tile. (Supports 8-way)
if diff_x.abs > 1 || diff_y.abs > 1
# The player has moved more than one tile.
# This section could be extended if some of the previous visible area
# still is visible and only update the the the new areas as well as
# the parts of the old area that is now out of side.
# For ease and because this should be a rare situation I have decided
# to simple remove all sprites and start over for the new area.
@character_sprites.each {|sprite| sprite.dispose}
# Initialized the sprites for the new area
init_characters
else
# Updates the buffer
update_buffer(diff_x, diff_y)
end
# Refresh the character sprites. (To which should be updated)
refresh_character_sprites
else
# Refreshed the character sprites if it is needed
refresh_character_sprites if @need_refresh
end
# Updates the sprites.
@character_sprites.each {|sprite| sprite.update}
end

#--------------------------------------------------------------------------
# * Updates Character Sprites
#--------------------------------------------------------------------------
def update_buffer(diff_x, diff_y)
# Gets the tile area to search for events
min_x, max_x, min_y, max_y = $game_map.get_tile_area
# For change in x-coordinate
if diff_x > 0 # Left
# Removes any sprites outside of the buffer
unless max_x >= $game_map.width - 1
for y in min_y..max_y
dispose_sprites(max_x+1, y)
end
end
# Adds any new sprites comming into the buffer
for y in min_y..max_y
add_sprites(min_x, y) if @character_spritemap[[min_x,y]].nil?
end
elsif diff_x < 0 # Right
# Removes any sprites outside of the buffer
unless min_x <= 0
for y in min_y..max_y
dispose_sprites(min_x-1, y)
end
end
# Adds any new sprites comming into the buffer
for y in min_y..max_y
add_sprites(max_x, y) if @character_spritemap[[max_x,y]].nil?
end
end
# For change in y-coordinates
if diff_y > 0 # Up
# Removes any sprites outside of the buffer
unless max_y >= $game_map.height - 1
for x in min_x..max_x
dispose_sprites(x, max_y+1)
end
end
# Adds any new sprites comming into the buffer
for x in min_x..max_x
add_sprites(x, min_y) if @character_spritemap[[x,min_y]].nil?
end
elsif diff_y < 0 # Down
# Removes any sprites outside of the buffer
unless min_y <= 0
for x in min_x..max_x
dispose_sprites(x, min_y-1)
end
end
# Adds any new sprites comming into the buffer
for x in min_x..max_x
add_sprites(x, max_y) if @character_spritemap[[x,max_y]].nil?
end
end
end

#--------------------------------------------------------------------------
# * Called when an event has moved
#--------------------------------------------------------------------------
def update_event(old_x,old_y,event)
# Finds the sprites on the event's old position
sprites = @character_spritemap[[old_x,old_y]]
# Checks if there are any sprites on the event's old position
unless sprites.nil?
# Goes through the sprites to find which one is attached to the given
# event. Sprite is nil if no sprite on the event's old position is
# attached to the given event.
sprite = nil
for sprite in sprites
break if sprite.character == event
end
end
# If there is not a sprite attached to the event
if sprite.nil?
# Checks if the event has become visible
if $game_map.visible?(event.x, event.y)
# A sprite is create because the event is now visible
sprite = Sprite_Character.new(@viewport1, event)
# The sprite is added at the event's current position
add_sprite(event.x,event.y,sprite)
# We need to refresh the character sprites since we added one.
@need_refresh = true
end
else # A sprite is attached to the event
# Checks if the event is still visible
if $game_map.visible?(event.x, event.y)
# The event is still visible and moved from its old coordinate
# to its new coordinates.
move_event(old_x, old_y, sprite)
else
# The sprite is not visible anymore and thus removed
remove_sprite(old_x,old_y,sprite)
# The sprite is disposed since we don't want to wait for Ruby's
# garbage cleaner to remove the sprite from view. (For big sprites)
sprite.dispose
# We need to refresh the character sprites since we removed one.
@need_refresh = true
end
end
end

##
## Macros
##

#--------------------------------------------------------------------------
# * Creates and adds sprites for all the events with the given x and y
# coordinates to the spritemap.
#--------------------------------------------------------------------------
def add_sprites(x,y)
# Returns if there are no events with the given x and y coordinates
return if $game_map.event_map[[x,y]].nil?
for event in $game_map.event_map[[x,y]]
# Creates a sprite for the event
sprite = Sprite_Character.new(@viewport1, event)
# Adds the sprite to the spritemap
add_sprite(x,y,sprite)
end
end

#--------------------------------------------------------------------------
# * Disposes all the sprites on given x,y tile
#--------------------------------------------------------------------------
def dispose_sprites(x,y)
# Returns if there are no sprites with the given coordinates
return if @character_spritemap[[x,y]].nil?
for sprite in @character_spritemap[[x,y]]
# Removes the sprite from the datastructure
remove_sprite(x,y,sprite)
# Disposes the sprite
sprite.dispose
end
end

#--------------------------------------------------------------------------
# * Moves the sprite from its old coordinates to its new coordinates
#--------------------------------------------------------------------------
def move_event(old_x,old_y,sprite)
# Gets the event attached to the character
event = sprite.character
# Returns if the sprite have not change position
return if old_x == event.x && old_y == event.y
# Removes the sprite from its old location
remove_sprite(old_x, old_y, sprite)
# Adds the sprite to the new location
add_sprite(event.x, event.y, sprite)
end

##
## Low level methods, alters the datastructure directly
##

#--------------------------------------------------------------------------
# * Adds the given sprite to the given x and y coordinate to
# @character_spritemap.
#--------------------------------------------------------------------------
def add_sprite(x,y,sprite)
# Checks if there a not any sprite on the given tile already
if @character_spritemap[[x,y]].nil?
# Adds the sprite to the spriteset as an array containing the sprite
@character_spritemap[[x,y]] = [sprite]
else
# Adds the sprite to the array of sprites with the same x and y
# coordinates.
@character_spritemap[[x,y]] << sprite
end
end

#--------------------------------------------------------------------------
# * Removes the given sprite with the given x and y coordinate from
# @character_spritemap.
#--------------------------------------------------------------------------
def remove_sprite(x,y,sprite)
# Returns if there are no sprites with the given x and y coordinate
return unless !@character_spritemap[[x,y]].nil? &&
@character_spritemap[[x,y]].include?(sprite)
# Checks if there are more sprites with the same coordinates
if @character_spritemap[[x,y]].size > 1
# Removes the sprite from the array of sprites with the given coordinates
@character_spritemap[[x,y]].delete(sprite)
else
# Deletes the key attached to the array since there are no sprites left.
@character_spritemap.delete([x,y])
end
end
end


__________________________
Go to the top of the page
 
+Quote Post
   
Guest_RPG Wizard_*
post Sep 7 2007, 02:43 AM
Post #4





Guests





Confusing to understand with the SDK thing o_O
So there is a SDK for RMXP, and without it installed you can't use the script? (the SDK version on the top that is).

And about exclusive scripts, I won't beg you. Really. >_>
Go to the top of the page
 
+Quote Post
   
Zeriab
post Sep 12 2007, 02:03 PM
Post #5


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




*updates*

Sorry for the late reply. I have been busy.
In the new version there is a patch you can use if you don't have the SDK happy.gif
So no need to worry about the thing

QUOTE (RPG Wizard @ Sep 7 2007, 02:43 AM) *
Confusing to understand with the SDK thing o_O
So there is a SDK for RMXP, and without it installed you can't use the script? (the SDK version on the top that is).

And about exclusive scripts, I won't beg you. Really. >_>


__________________________
Go to the top of the page
 
+Quote Post
   
Zeriab
post Sep 24 2007, 07:21 AM
Post #6


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




Updated to version 1.0

Version 1.0 -------------------------------------------------- (2007-09-24)
- Fixed compatibility issue with Blizzard's Caterpillar script
- Overwrote more methods scanning for events on a specific tile
- Support for defining whether an event will always be updated or never be updated by specifying the event's id and map_id
- Some structural changes.
- Integrated the Non-SDK patch into the main script


__________________________
Go to the top of the page
 
+Quote Post
   
Guest_RPG Wizard_*
post Sep 30 2007, 07:27 AM
Post #7





Guests





http://www.rpgrevolution.com/resource/script/rgss/1

First script to be added! smile.gif Tell me what you think.
Go to the top of the page
 
+Quote Post
   
Zeriab
post Oct 1 2007, 04:06 AM
Post #8


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




That really looks nice. Great job thumbsup.gif
Thanks a lot for spending the probably great amount of energy creating such a cool section ^^


__________________________
Go to the top of the page
 
+Quote Post
   
Zeriab
post Jul 5 2008, 04:15 AM
Post #9


Level 12
Group Icon

Group: Revolutionary
Posts: 196
Type: Event Designer
RM Skill: Skilled




Updated to version 1.2. Major improvements on the topic as well

Version 1.05 ------------------------------------------------- (2007-11-18)
- Fixed bug where sprites might not be disposed when changing scene.

Version 1.1 -------------------------------------------------- (2008-04-10)
- Added declaration to which common events to update

Version 1.15 ------------------------------------------------- (2008-06-19)
- Added automatic detection of which common events to update (optional)

Version 1.2 -------------------------------------------------- (2008-07-04)
- Fixed a case where an event could be registered twice causing transparent
events to look less transparent.


__________________________
Go to the top of the page
 
+Quote Post
   

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 22nd May 2013 - 01:39 PM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker