+- Save-Point (https://www.save-point.org)
+-- Forum: Games Development (https://www.save-point.org/forum-4.html)
+--- Forum: Code Support (https://www.save-point.org/forum-20.html)
+--- Thread: BIG MAPS and Anti-Lag (/thread-8067.html)
Okay, I tested this script in my game and tried to connect the 25 120x120 maps of my first area to one big map.
The result is kinda odd: The game begins to lag but only when I move vertically. Moving right or left doesn't create any lag.
And the lag seems to be caused by events (especially moving events) so maybe my anti lag script has issues with the Bigmap script. 25 500x500 maps without any event was no problem. x.x
Hm. I guess that depends on the Anti-Lag script.... and how many events you have running. Well, I haven't tested it with all anti-Lag, nor tested event capacity.
You went to a full 2500x2500 tile map? Schweet!
But I have to say that I've never encountered the issue you're having with vertical movement. There should be no difference with movement at all as the system literally crafts a new virtual map and doesn't actually alter the movement system other than teleporting. Character speed and movement is typically governed by the Game_Character class, and I touched neither Game_Character, Game_Player nor their related sprites and spriteset systems.
I'm using the one from Near Fantastica. I'm not sure if it works together with the new big map so maybe all events are being updated all the time.
There are around 300 events on one map so there should be ~7500 in total. Some of them are moving plus updating dynamic sound effects and light effects. But usually the anti lag script only updates the stuff in range of the player so my guess is it's not working properly. A normal 500x500 map with 999 moving events is no problem at all.
If I include only 10 or 15 of the maps it runs smooth without any lag and even 25 or even more empty maps don't cause any lag. So it's definetely an event issue.
The vertical movement thing is weird. While moving horizontal the game runs in 60 fps. When moving vertical it drops down to 19-20.^^
This is the script, if you are interested.
Content Hidden
Code:
#======================================
# Anti Event Lag Script
#======================================
# By: Near Fantastica
# Date: 12.06.05
# Version: 4
#======================================
# Heretic Revision August 21st, 2012
# ----- HERETIC NOTES -----
# THIS SCRIPT HAS BEEN MODIFIED!
# The original version of the script did increase framerates at the cost
# of flat out making some things not work at all.
# This revision of the original script should fix those issues.
# #1 Fixed an issue where Events that used Multiple Event Pages
# (which require conditions) were never refreshed, as the call to
# change those events was ommitted entirely, apparently by accident.
# #2 Fixed Events moving Off Screen to not update. Any time Set Move Route
# is called, the moved Event will now Update correctly. Useful for Cutscenes
# where an NPC walks to On Screen from Off Screen.
# #3 If you use an "Autonomous Movement", and want an Event or NPC to be
# updated regardless if they are on the screen or not, you'll need to
# add \al_update to that Event's Name. The Naming Parameter was used
# to allow functionality to be maintained across any number of Event Pages.
# #4 This script only updates Events or NPC's around that are close enough
# to the Player that they require being updated. For Large Sprites, this
# can cause some issues. I adjusted the distance so that Large Sprites
# won't cause glitches by partially staying on the screen when they aren't
# supposed to be there.
# --- Notes for Compatability ---
# This script makes changes to update in both Spriteset_Map and Game_Map classes
# There isnt a whole heck of a lot of script to run the optimizations, so if
# you have ANY other script that makes changes to update in either of those
# classes, place those scripts BELOW this one.
#
# Other Scripts that FULLY REDEFINE def update will break this script.
#
# If another script does fully redefine def update, you can probably try
# combine the two scripts. I've commented out the spots of code that need
# to be there for anti-lag to work.
# NAMING OPTIONS
# - \al_update
# For Example: "EV031\al_update" can move around anywhere on the Map and will
# be updated regardless of where it is at on the Map!
# (\al_ is just an abbreviation for "Anti Lag", which hopefully is unique!)
# Events with \al_update in their name will ALWAYS be Updated
# I also changed "Set Move Route" to automatically add a @lag_include Flag
# to the Event so that the Event will ALWAYS be able to move. This will
# most likely happen for Cutscenes where an Event needs to be able to
# move around regardless of its Range from Player on the Map. Once you
# leave a Map and return, this will reset and the Event or NPC will only
# update if it is On Screen, or at least close to the Screen
module Update_Range
# Note: Module for both the Game_Map and Spriteset_Map classes
#--------------------------------------------------------------------------
# In Range - Determines whether or not an Event should be Updated
#--------------------------------------------------------------------------
def in_range?(object)
display_x = $game_map.display_x - 1750 #750 # 256
display_y = $game_map.display_y - 1750 #750 # 256
display_width = $game_map.display_x + 4900 #2820 3000
display_height = $game_map.display_y + 4900 #2180 3000
if object.real_x <= display_x or
object.real_x >= display_width or
object.real_y <= display_y or
object.real_y >= display_height
return false
end
# Valid
return true
end
end
class Game_Map
# Makes In-Range Definiton available in the Game_Map class
include Update_Range
#--------------------------------------------------------------------------
# Update - Updates Events in a Game Map - FULL REDEFINITION
#--------------------------------------------------------------------------
def update
# Refresh map if necessary
if $game_map.need_refresh
# Refresh the Game Map - CRITICAL for changing Event Pages
refresh
end
# If scrolling
if @scroll_rest > 0
distance = 2 ** @scroll_speed
case @scroll_direction
when 2
scroll_down(distance)
when 4
scroll_left(distance)
when 6
scroll_right(distance)
when 8
scroll_up(distance)
end
@scroll_rest -= distance
end
# This is the Event Anti Lag Code
for event in @events.values
# If Event is In Range, Auto, Parallel, Set Move Route, or Cat Actor
if event.trigger == 3 or event.trigger == 4 or event.lag_include or
in_range?(event)
# Update the Event
event.update
# If you have other code to run, allow this part to run first, then
# run other parts of scripts here inside of the conditional branch.
end
end
# End Event Anti Lag Code
for common_event in @common_events.values
common_event.update
end
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
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
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
end
class Spriteset_Map
# Make Range Definiton available in the Sprite_Map class
include Update_Range
#--------------------------------------------------------------------------
# * Frame Update - Full Redefinition
#--------------------------------------------------------------------------
def update
if @panorama_name != $game_map.panorama_name or
@panorama_hue != $game_map.panorama_hue
# Set the Values
@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_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
@tilemap.ox = $game_map.display_x / 4
@tilemap.oy = $game_map.display_y / 4
@tilemap.update
@panorama.ox = $game_map.display_x / 8
@panorama.oy = $game_map.display_y / 8
@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
# This is the Sprite Anti Lag Code
for sprite in @character_sprites
if sprite.character.is_a?(Game_Event)
# If Event is Auto, Parallel, Set to Always Update (/al_update) or In Range
if sprite.character.trigger == 3 or sprite.character.trigger == 4 or
sprite.character.lag_include or
in_range?(sprite.character)
# Update the Sprite
sprite.update
# If you have other code to run, allow this part to run first, then
# run other parts of scripts here inside of the conditional branch.
end
# Not an Event, thus, Player, so always update the Players Sprite
else
# Update the Sprite
sprite.update
end
end
# End Sprite Anti Lag Code
@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
for sprite in @picture_sprites
sprite.update
end
@timer_sprite.update
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
@viewport3.color = $game_screen.flash_color
@viewport1.update
@viewport3.update
end
end
class Interpreter
#--------------------------------------------------------------------------
# * Set Move Route Alias
#--------------------------------------------------------------------------
# Check for Method Existence
unless self.method_defined?('anti_lag_command_209')
# Create an Alias
alias anti_lag_command_209 command_209
end
#--------------------------------------------------------------------------
# * Set Move Route
#--------------------------------------------------------------------------
# This forces Events that are being applied a Set Move Route to ALWAYS
# be updated. Prevents Events that are set to Move On Screen from
# being able to Move. They cant move without being updated first.
def command_209
# Run the Original
anti_lag_command_209
# Get character
character = get_character(@parameters[0])
# If no character exists
if character == nil or character.is_a?(Game_Player)
# Continue
return true
end
# Set @lag_include Flag
character.lag_include = true
end
end
class Game_Event < Game_Character
attr_accessor :lag_include # Always Updates
# Check for Method Existence
unless self.method_defined?('anti_lag_initialize')
# Create an Alias
alias anti_lag_initialize initialize
end
#----------------------------------------------------------------------------
# * Initialize the Map
#----------------------------------------------------------------------------
def initialize(map_id, event, *args)
# Run the Original
anti_lag_initialize(map_id, event, *args)
# Check for Events with \al_update
check_name_tags(event)
end
#----------------------------------------------------------------------------
# * Check Each Event for Special Name Tags: \al_update, \off_map
#----------------------------------------------------------------------------
def check_name_tags(event)
# Check each Event's Name to see if it has \al_update
event.name.gsub(/\\al_update/i) {@lag_include = true}
end
end
RE: BIG MAPS and Anti-Lag - DerVVulfman - 06-05-2020
As it is more akin to getting two scripts to work together, code support seemed more fitting.
Yeah, Jaime's work is excellent for a jumping off point. Some of it still has valid uses, and way less complicated. This being very much different to over-complicated works that do the job super well... but only a freakin' NASA Technicians can figure it out.
There are a number of anti-lag systems. And if I were to have around 1000 events, sure. Granted, you are limited to 999 events per map anyway, and they never thought anyone would go beyond. Oh, you edited it... and made it extend out to grab MORE events in a shot. It didn't restrict but went the other way.
Now I coulda brought up Amaranth's... or Lambchop's when she was at RMXP.Org (now HBGames)> Wow, I'm going back a decade there. And I still have her on facebook. But, her system does not really go beyond 1000 events either.
So enter Zeriab's. Yep, the Huggin' King's Anti-Lag system did MUCH better than the others. Compared to the others, it is massive, hitting Game_Map... Character... Player... and more. But it did much much better. Oh, and what I said about NASA Technicians????
What was my test? It was a 9x9 grid of 500x500 tile maps. Of those, five have 998 chicken events all walking around. That's a lot of chickens. Well, they all had 998 events, but lag hit. Each re-test, I deleted a map and recreated one without events. First all 9 with 998.... on down.
With Zeriab's Anti-Lag, I suffer no lag with 5 maps of 998. And with 6 maps of 998, I suffer only 20% lag. So I think 5000 events is the magic number. And 6000 is pushing it. Just remember that Big Maps is making one array of ALL of the events of all your maps. It's not sorting through one batch of 999 and another of 999. It is sorting through them ALL in one shot every so often.
And here's Zeriab's script. Definitely have it before Big Maps:
Are you a NASA Technician?
Code:
#==============================================================================
# ** Anti Event Lag System
#------------------------------------------------------------------------------
# Zeriab
# Version 1.2b
# 2008-09-12 (Year-Month-Day)
#------------------------------------------------------------------------------
# * Requirements :
#
# If you have the SDK : Version 2.0+, Part I, II
# Does not require the SDK
#------------------------------------------------------------------------------
# * 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
#
# Version 0.9 -------------------------------------------------- (2007-09-12)
# - Support for the Non-SDK patch
# - Support for defining whether an 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.
#
# Version 1.2b ------------------------------------------------- (2008-09-12)
# - Fixed a stack error problem caused when pressing F12.
#------------------------------------------------------------------------------
# * 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.
#------------------------------------------------------------------------------
# * License :
#
# Copyright (C) 2007, 2008 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 :
#
# This is SDK compliant. It is written for SDK version 2.3.
# It requires SDK 2.0+ if you are using the SDK
# The Non-SDK patch is integrated so you can run it without the SDK
#
# 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
#------------------------------------------------------------------------------
# * Instructions :
#
# Place this script just below the SDK if you are using the SDK.
# Place this script just below the default if using the Non-SDK Patch
#
# default scripts
# (SDK)
# Zeriab's Anti Event Lag System
# (custom scripts)
# main
#
# ~ Game_Map ~
# There are 4 constants you can change at will in the top of the
# Game_Map class: (You don't have to ;))
#
# ALWAYS_UPDATE ~ The default is false
# -------------------------------
# You can set this to true if you want all events to be update always
# This a slower option, but events behave like they do without the script.
# You will still benifit from the faster collision detection and fewer sprites
# This has higher priority than the event specific features. I.e never_update
#
# BUFFER_SIZE ~ The default is 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_VERTICAL ~ The default is 15
# -----------------------------
# Specifies how many tiles there are vertical
# 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
#
# TILES_HORIZONTAL ~ The default is 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
#
# LIMIT_COMMON_EVENTS - The default is true
# -----------------------------
# You can see this to false if you want all common events updated.
# This constant only has an effect during the upstart of the program. Changing
# it during the game will have no effect.
# If it is set to false you can safely ignore the following three constants
#
# SPECIFY_COMMON_EVENTS_MANUALLY - The default is false
# -----------------------------
# Specifies whether you want to enter which common events should be updated
# manually. If this is set to false you can safely ignore
# COMMON_EVENTS_TO_UPDATE while COMMON_EVENT_FILEPATH is of importance.
# Vice-versa is COMMON_EVENTS_TO_UPDATE important and COMMON_EVENT_FILEPATH
# safe to ignore if SPECIFY_COMMON_EVENTS_MANUALLY is set to true.
# If this is set to false which common events to update will be atomatically
# detected.
# As a general rule of thumb: Only change this to true if you have problems
# with the automatic detection or you want to prevent certain common events
# with autorun or parallel process as trigger.
#
# COMMON_EVENTS_TO_UPDATE
# -----------------------------
# This constant is an array of common event ids. Only the common events with
# the ids specified in the array will be updated. The ids are the numbers
# shown in the database with any leading 0s removed. In general only common
# events which have autorun or parallel process needs to be updated.
# It will have no effect if SPECIFY_COMMON_EVENTS_MANUALLY is false
# Let's say we want the common events 005, 009 and 020 to be updated. First we
# will remove the leading 0s and get 5, 9 and 20. Next we will put them in the
# array and get as end result:
#
# COMMON_EVENTS_TO_UPDATE = [5, 9, 20]
#
# If we had put [005, 009, 020] as the array we would have gotten an error
# when starting the game.
# If we now want to update common event 045 we would add 45 to the array:
#
# COMMON_EVENTS_TO_UPDATE = [5, 9, 20, 45]
#
#
# COMMON_EVENT_FILEPATH - The default is 'Data/CommonEvents.rxdata'
# -----------------------------
# Specifies the relative file path (To the directory of where the Game.exe is)
# to where the common events are stored.
# Only change this if you have changed the name or place of the
# CommonEvents.rxdata file.
# It will have no effect if SPECIFY_COMMON_EVENTS_MANUALLY is true
#
#
# ~ Game_Event ~
# Next we come to the Constants in Game_Event. They are given above the
# Game_Map code. They have been split from the other Game_Event code for
# Easier access:
#
# SPECIAL_UPDATE_IDS
# ------------------
# This constant contains a hash where you can specify how specific events
# should be updated. Special update ids has priority over name patterns.
# The keys are all a 2-elements array. [Map_ID, Event_ID]
# The value is either an 'A' for always update or 'N' for never update.
# Here is an example:
#
# SPECIAL_UPDATE_IDS = {[1,1]=>'A',
# [1,2]=>'N'}
#
# Notice the first line [1,1]=>'A'
# It means that the event with id 1 on map 1 will always be updated.
#
# Notice the first line [1,2]=>'N'
# It means that the event with id 2 on map 1 will never be updated.
# Let's say we wanted the event with id 5 on map 3 to always be updated.
# This can be achieved by adding [5,3]=>'A' to the hash:
#
# SPECIAL_UPDATE_IDS = {[1,1]=>'A',
# [1,2]=>'N',
# [5,3]=>'A'}
#
#
# NEVER_UPDATE_NAME_PATTERNS
# --------------------------
# Here you can specify any number of patterns which will be checked when a
# new map is loaded. Any events which matches at least one of the patterns
# given here will never be updated.
# A pattern is assumed to be either a String or a RegExp. In the case of a
# String name.include?(string) is used. Otherwise the =~ operator is used
# Note: The never_update feature has higher priority than the always_update.
# If an event's name matches both a always update pattern and a never_update
# pattern it will never update.
#
# ALWAYS_UPDATE_NAME_PATTERNS
# ---------------------------
# Here you can specify any number of patterns which will be checked when a
# new map is loaded. Any events which matches at least one of the patterns
# given here will always be updated.
# Note: The always_update feature has lower priority than the never_update.
# If an event's name matches both a always update pattern and a never_update
# pattern it will never update.
#==============================================================================
if Module.constants.include?('SDK')
#----------------------------------------------------------------------------
# * SDK Log Script
#----------------------------------------------------------------------------
SDK.log('Anti Event Lag System', 'Zeriab', 1.2, '2008-06-25')
SDK.check_requirements(2.0)
end
#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if !Module.constants.include?('SDK') || SDK.enabled?('Anti Event Lag System')
#==============================================================================
# ** Constants for the anti lag script
#==============================================================================
class Game_Map
ALWAYS_UPDATE = false
BUFFER_SIZE = 2
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
#==============================================================================
# ** Automatic configuration generation
#==============================================================================
class Game_Map
if LIMIT_COMMON_EVENTS && !SPECIFY_COMMON_EVENTS_MANUALLY
# Find the common events which needs to be updated
COMMON_EVENTS_TO_UPDATE = []
# Load the common events
common_events = load_data(COMMON_EVENT_FILEPATH)
# Go through the common events
for common_event in common_events.compact
# Check if there is a need for the common event to update
if common_event.trigger > 0
# C
COMMON_EVENTS_TO_UPDATE << common_event.id
end
end
end
end
class Game_Map
#--------------------------------------------------------------------------
# * 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)
# Go through each event
for event in @events.values
# Check how the event should be updated
event.check_update
end
end
#--------------------------------------------------------------------------
# * Update Events ~ Overwritten to only updating visible and special events
#--------------------------------------------------------------------------
def update_events
# Runs through the events
for event in @events.values
# checks if the event is visible or needs to be updated
if ALWAYS_UPDATE || event.need_update?
event.update
end
end
end
# Only overwrite this method if common events should be limited
if LIMIT_COMMON_EVENTS
#--------------------------------------------------------------------------
# * Update Common Events ~ Updates only the necessary common events
#--------------------------------------------------------------------------
def update_common_events
for i in COMMON_EVENTS_TO_UPDATE
@common_events[i].update
end
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) && spriteset.respond_to?(:update_event)
# 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
#--------------------------------------------------------------------------
# * Get Designated Position Event ID
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def check_event(x, y)
# Retrives the events on the specified tile
events = event_map[[x,y]]
unless events.nil?
# Loop through events on tile
for event in events
if event.x == x and event.y == y
return event.id
end
end
end
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
# Retrives the events on the specified tile
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
class Game_Character
#--------------------------------------------------------------------------
# * 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
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.to_sym
next if self.method_defined?(new_method)
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) priority under never_update
#--------------------------------------------------------------------------
attr_writer :always_update
def always_update
@always_update = false if @always_update.nil?
return @always_update
end
#--------------------------------------------------------------------------
# * Never_update property (is false by default) priority over always_update
#--------------------------------------------------------------------------
attr_writer :never_update
def never_update
@never_update = false if @never_update.nil?
return @never_update
end
#--------------------------------------------------------------------------
# * Need Update method. Fast checks here.
#--------------------------------------------------------------------------
def need_update?
return false if never_update
return true if always_update
return true if $game_map.visible?(x, y)
return true if @move_type == 3
return @trigger == 3 || @trigger == 4
end
#--------------------------------------------------------------------------
# * Checks how the event should be updated.
#--------------------------------------------------------------------------
def check_update
name = @event.name
# Checks if the event is never to be updated. (For decoration)
for pattern in NEVER_UPDATE_NAME_PATTERNS
if (pattern.is_a?(String) && name.include?(pattern)) ||
!(pattern =~ name).nil?
self.never_update = true
end
end
# Checks if the event is to be always updated.
for pattern in ALWAYS_UPDATE_NAME_PATTERNS
if (pattern.is_a?(String) && name.include?(pattern)) ||
!(pattern =~ name).nil?
self.always_update = true
end
end
# Checks for special update for the particular id (overrules the patterns)
special_update = SPECIAL_UPDATE_IDS[[@map_id,@id]]
unless special_update.nil?
# Checks if it never should be updated
if special_update.downcase == 'n'
self.never_update = true
self.always_update = false
# Checks if it always should be updated
elsif special_update.downcase == 'a'
self.always_update = true
self.never_update = false
end
end
end
end
class Game_Player
#--------------------------------------------------------------------------
# * Same Position Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_here(triggers)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# Retrives the events on the specified tile
events = $game_map.event_map[[@x,@y]]
unless events.nil?
# Loop through events on tile
for event in events
# If event triggers are consistent
if triggers.include?(event.trigger)
# If starting determinant is same position event (other than jumping)
if not event.jumping? and event.over_trigger?
event.start
result = true
end
end
end
end
return result
end
#--------------------------------------------------------------------------
# * Front Event Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_there(triggers)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# Calculate front event coordinates
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# Retrives the events on the specified tile
events = $game_map.event_map[[new_x,new_y]]
unless events.nil?
# Loop through events on tile
for event in events
# If event triggers are consistent
if triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
end
# If fitting event is not found
if result == false
# If front tile is a counter
if $game_map.counter?(new_x, new_y)
# Calculate 1 tile inside coordinates
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
# Retrives the events on the specified tile
events = $game_map.event_map[[new_x,new_y]]
unless events.nil?
# Loop through events on tile
for event in events
# If event triggers are consistent
if triggers.include?(event.trigger)
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
end
end
end
return result
end
#--------------------------------------------------------------------------
# * Touch Event Starting Determinant
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# Retrives the events on the specified tile
events = $game_map.event_map[[x,y]]
unless events.nil?
# Loop through events on tile
for event in events
# If event coordinates and triggers are consistent
if [1,2].include?(event.trigger)
# If starting determinant is front event (other than jumping)
if not event.jumping? and not event.over_trigger?
event.start
result = true
end
end
end
end
return result
end
end
class Spriteset_Map
#--------------------------------------------------------------------------
# * Initializes Character Sprites (Overwrite)
#--------------------------------------------------------------------------
def init_characters
# Creates the array used for holding the hero sprite.
# Is here for compatibility reasons.
@character_sprites = []
# Refreshes the characters in the spritemap
refresh_characters
# Refreshes the character sprites
refresh_character_sprites
end
#--------------------------------------------------------------------------
# * Refreshes the characters.
#--------------------------------------------------------------------------
def refresh_characters
# Make character sprites
@character_event_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_event_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_event_sprites.sort! {|a,b| a.character.id <=> b.character.id}
# 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
#--------------------------------------------------------------------------
# * 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_event_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_event_sprites.each {|sprite| sprite.update}
# Updates the hero sprite. Is here to increase compatibility with other
# scripts using this array. Most caterpillar scripts for example
@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 unless 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
#------------------------------------------------------------------------------
# * End SDK Enable Test
#------------------------------------------------------------------------------
end
unless Module.constants.include?('SDK')
#============================================================================
# * Compatibility :
#
# This will probably not be compatible with scripts extending or modifying
# the overwritten methods.
#
# The following methods has been overwritten:
# * Game_Map.update
# * Spriteset_Map.initialize
# * Spriteset_Map.update
#============================================================================
#============================================================================
# ** Game_Map
#============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Update Common Events
#--------------------------------------------------------------------------
def update_common_events
for common_event in @common_events.values
common_event.update
end
end
#------------------------------------------------------------------------
# * Frame Update Overwrite
#------------------------------------------------------------------------
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
update_events
# Update common event
update_common_events
# 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
end
#============================================================================
# ** Spriteset_Map
#============================================================================
class Spriteset_Map
#------------------------------------------------------------------------
# * Object Initialization Overwrite
#------------------------------------------------------------------------
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
init_characters
# Make hero sprite
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
# 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
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
# Dispose of tilemap
@tilemap.tileset.dispose
for i in 0..6
@tilemap.autotiles[i].dispose
end
@tilemap.dispose
# Dispose of panorama plane
@panorama.dispose
# Dispose of fog plane
@fog.dispose
# Dispose of weather
@weather.dispose
# Dispose of picture sprites
for sprite in @picture_sprites
sprite.dispose
end
# Dispose of character sprites
for sprite in @character_event_sprites
sprite.dispose unless sprite.disposed?
end
# Dispose of timer sprite
@timer_sprite.dispose
# Dispose of viewports
@viewport1.dispose
@viewport2.dispose
@viewport3.dispose
end
#------------------------------------------------------------------------
# * Frame Update Overwrite
#------------------------------------------------------------------------
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
end
end
Okay I did some testing and it's insane. Together with the HiddenChest Engine I can run 37000 events with Zeriabs anti lag system. So I had 7x5 maps with 999 events plus 2 more full and 3 empty maps in the bigmap.
And even beyond 37000 the lag isn't that much but makes playing too annoying for my taste. And it can crash if too many stuff is on the screen so I think keeping it below 35000~37000 might be a good idea.
With the Near Fantastica script it ended at around 5000 events.
I had to comment out the following lines because they throw this error in HiddenChest
(693-705)
Code:
# Checks if the event is never to be updated. (For decoration)
for pattern in NEVER_UPDATE_NAME_PATTERNS
if (pattern.is_a?(String) && name.include?(pattern)) ||
!(pattern =~ name).nil?
self.never_update = true
end
end
# Checks if the event is to be always updated.
for pattern in ALWAYS_UPDATE_NAME_PATTERNS
if (pattern.is_a?(String) && name.include?(pattern)) ||
!(pattern =~ name).nil?
self.always_update = true
end
end
Now I only need to make Zeriabs script compatible with my game. There are some nasty errors so far but I will try to fix them now.
Something people usually forget is that operators in Ruby are a bit weird.
and follows the logical order, i.e. if check1 and check2
&& does it in the reverse order, e.g. if check2 && check1
There operator precedence DOES matter! && has a higher precedence than and.
So print name and pattern to verify which one isn't a string and when one of them is a regular expression or Regexp instead. Why? That's because the scripter forgot that passing a single string, whether it's the first or second parameter, to a match operator will always throw a TypeError in Ruby. That should NOT happen at all. This happens when you include strings and regular expressions. In my humble opinion he should have picked just one of them to reduce the number of tests needed to run the method.
Solution? I guess it could be something like...
Code:
if (pattern.is_a?(String) and name.include?(pattern)) ||
(pattern.is_a?(Regexp) and !(pattern =~ name).nil?)
I don't think name should ever be a Regexp. Not even a mad scientist like would ever dare to make it a regular expression.
RE: BIG MAPS and Anti-Lag - DerVVulfman - 06-07-2020
That block of code is what allows you to add the codes [N] and [A] which lets you make events 'Never' update and 'Always' update. That should be quite simple. Odd.
Thank you for that fix. Now it also works with HiddenChest. The newer ruby version seems to be more sensitive. It worked with the normal RMXP exe before.
I was also able to fix most of the incompatibilities. Now I only need to figure out how to make it work with the higher resolution fix.
Edit: Fixed ^^
Now my first area is one big map and it's fantastic. It feels so much better to fly around when everything is seamless. Thank you very for your help :)
RE: BIG MAPS and Anti-Lag - DerVVulfman - 06-09-2020
Just a little heads up. The "SPECIAL_UPDATE_IDS" feature that Zeriab added seems a bit... iffy to me. Doesn't really work so well. BUT hey, tell me I'm wrong here. But make an event and erase its name. It acts as if it is a 'Never Update' event too, right?