Introduction
This patch enables game designers to use an 'altered' version of MGC's Mode7 system in tandem with DerVVulfman's Lycan ABS. Its effect would allow games to be played, and allow combat to occur, on Mode7 horizon perspective maps and make use of the more recent transparent wall/tileset effect added into the Mode7 Edit script.
Script
Patch
Code:
#==============================================================================
# ** Lycan ABS / MGC Mode7 Edit Patch
#------------------------------------------------------------------------------
# by DerVVulfman
# version 1.2
# 10-18-2015
# RGSS / RPGMaker XP (The Lycan ABS V 9.9+ & MGC Mode7 Edit)
#==============================================================================
#
# INTRODUCTION:
#
# This patch enables game designers to use an 'altered' version of MGC's Mode7
# system in tandem with DerVVulfman's Lycan ABS. Its effect would allow games
# to be played, and allow combat to occur, on Mode7 horizon perspective maps
# and make use of the more recent transparent wall/tileset effect added into
# the Mode7 Edit script.
#
#
#------------------------------------------------------------------------------
#
# INSTALLATION:
#
# Place the MGC Mode7 Edit script above the Lycan ABS Engine system, prefer-
# ably among the optional scripts such as View Range, the Enemy Bars, and the
# like.
#
# Then place this patch below the Lycan ABS system itself.
#
# Note: It need not be below the Frank's Multipose add-ons as this patch does
# not affect the way individual frames are exrracted and rendered from
# custom characterset graphics,
#
#
#------------------------------------------------------------------------------
#
# MAP LOOPING / MAP WRAPPING:
#
# Both the Lycan ABS and the Mode7 systems include the ability to have looped
# maps. This feature allows one to make a large map that the player can walk
# where the map edges will join together and give an 'infinite' sized map ex-
# perience. It is a very popular feature for those making a large world map.
# However, there are some things to cover.
#
# The Lycan ABS method of looped/wrapped maps merely requires the game devel-
# oper to add the phrase '_wrap' to the end of a map's name to activate the
# feature. As it was designed for a combat system, the enemy's detection sys-
# tem will recognize maps so designed and the combatants will look across map
# borders and cross them to perform attacks.
#
# However, the Lycan ABS '_wrap' system was not designed to handle or render
# maps drawn with an angled perspective as Mode7 maps tend to appear. So when
# the Mode7 system is in use, the maps rendered will be drawn by the Mode7
# system itself. If Mode7 is used on a map with the Lycan ABS's wrap system,
# it is extremely advised to include the Mode7 Full Looping function as well.
#
# The Mode7 method of looped maps normally allows for individual vertical and
# and horizontal map looping, as well as full four-directional looping. How-
# ever, only full four-directional looping is permitted with the Lycan ABS and
# this patch. Activating this feature within a Mode7 map is performed in much
# the same manner as the Lycan ABS's built-in wrapping feature, by including
# the function code into the map's name. And you may also create a collection
# of presets within Mode7 to handle multiple Mode7 commands with less code.
#
# However, the Mode7 looping system was not designed for a map-based battle
# system, so it will not properly handle enemies that are on opposite sides of
# an invisible map border. It would be a simple thing to avoid an enemy with-
# in a Mode7 looping map to merely cross the border. At that point, the enemy
# would cease to follow. To prevent this, it is extremely advised to include
# the Lycan ABS's wrap system suffix to any looping maps.
#
# Thus, proper map looping with the Lycan ABS and Mode7 systems require the
# use of codes from both systems as thus: MAPNAME[M7][L]_wrap
#
# Even if one to wish the use of Mode7's Transparent Walls in a looped map,
# you would need to use both Mode7's Looping function and the Lycan ABS's
# '_wrap' suffix.
#
#
# The commands of [X] and [Y] within Mode7, even used in tandem ( [X][Y] )
# will not function. Only [L] for full looping will function.
#
#------------------------------------------------------------------------------
#
# REQUIRES:
#
# The Lycan ABS version 9.9 or higher.
# MGC Mode7 Edit, a reworked version of MGCaladtogel's original system which
# was edited by DerVVulfman on June 10, 2014.
#
#
#==============================================================================
#
# CREDITS AND THANKS:
#
# Thanks to GI_Toez who asked me to look into making a simplified patch to
# get Mode7 to work with the ABS. And to DrHouse93 for noticing that the
# Companion Commands/Dialog window did not properly function within Mode7.
#
#
#==============================================================================
#
# TERMS AND CONDITIONS:
#
# Free for use, even in commercial games.
#
#==============================================================================
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles the map. It includes scrolling and passable determining
# functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Determine Valid of X Coordinates
# x : x-coordinate
#--------------------------------------------------------------------------
def validity_x(x)
return true if $game_system.loop_x
return true if $game_temp.map_wrap_array[$game_map.map_id] == true
return (x >= 0 and x < width)
end
#--------------------------------------------------------------------------
# * Determine Valid of Y Coordinates
# y : y-coordinate
#--------------------------------------------------------------------------
def validity_y(y)
return true if $game_system.loop_y
return true if $game_temp.map_wrap_array[$game_map.map_id] == true
return (y >= 0 and y < height)
end
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias remode7_game_character_update update
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# If x-coordinate is out of the map
update_mode7_x_coord
# If y-coordinate is out of the map
update_mode7_y_coord
# The Original Call
remode7_game_character_update
end
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
unless @anti_modestack2 == true
alias remode7_game_player_initialize initialize
@anti_modestack2 = true
end
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Original call
remode7_game_player_initialize
# Additional Values
self.map_number_x = 0
self.map_number_y = 0
end
end
#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
# This sprite is used to display the character.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# * Frame Update (when placing a graphic into position)
#--------------------------------------------------------------------------
def update_character_coordinates
x_intermediate = @character.screen_x
y_intermediate = @character.screen_y
y_intermediate -= $game_temp.pivot + 4 if $game_system.mode7
# if vertical looping
if $game_system.loop_y
h = 32 * $game_map.height
y_intermediate = (y_intermediate + h / 2) % h - h / 2
end
# if it is a Mode7 map
if $game_system.mode7
# Acquire Mode7 Altered Y Position
mode_y = mode7_y($game_temp.distance_h, y_intermediate,
$game_temp.sin_angle, $game_temp.cos_angle,
$game_temp.pivot)
# Exit method ineffective and hide if coordinate failed
if mode_y[1] == false
self.opacity = 0
return false
end
# Set Y coordinate
self.y = mode_y[0]
self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value
self.zoom_y = zoom_x
self.x = 320 + zoom_x * (x_intermediate - 320)
if $game_system.loop_x
offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)
l = 32 * $game_map.width * zoom_x
self.x = (x + offset) % l - offset
end
# normal map
else
self.zoom_x = 1.0
self.zoom_y = 1.0
self.x = x_intermediate
self.y = y_intermediate
end
if @character.is_a?(Game_Player)
# Overworld Sprite Resize
if $game_system.ov
self.zoom_x *= $game_system.ov_zoom
self.zoom_y *= $game_system.ov_zoom
end
end
self.z = @character.screen_z(@ch)
self.y -= 32 * @character.height * zoom_y
return true
end
end
#==============================================================================
# ** Sprite_Duplicate
#------------------------------------------------------------------------------
# This sprite is a duplicate of the original character used for wrapped
# (or continuously looping) maps with some adjustments made for positioning.
# It observes the Game_Character class and is created by the Sprite_Character
# class when looped map cinditions are met.
#==============================================================================
class Sprite_Duplicate < RPG::Sprite
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :character # The original character duplicated
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
else
self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue)
# Check for special Lycan Center Character in filename
chkname = @character.character_name.dup
lastval = chkname[chkname.size-1,1]
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = (lastval == Lycan::SUFFIX_CENTER) ? (@ch/1.5) : @ch
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# Set sprite coordinates for dupliate sprites, relateive to the originals.
update_character_coordinates
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
#--------------------------------------------------------------------------
# * Frame Update (when placing a graphic into position)
#--------------------------------------------------------------------------
def update_character_coordinates
x_intermediate = @character.screen_x + @x
y_intermediate = @character.screen_y + @y
y_intermediate -= $game_temp.pivot + 4 if $game_system.mode7
# if vertical looping
if $game_system.loop_y
h = 32 * $game_map.height
y_intermediate = (y_intermediate + h / 2) % h - h / 2
end
# if it is a Mode7 map
if $game_system.mode7
# Acquire Mode7 Altered Y Position
mode_y = mode7_y($game_temp.distance_h, y_intermediate,
$game_temp.sin_angle, $game_temp.cos_angle,
$game_temp.pivot)
# Exit method ineffective and hide if coordinate failed
if mode_y[1] == false
self.opacity = 0
return false
end
# Set Y coordinate
self.y = mode_y[0]
self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value
self.zoom_y = zoom_x
self.x = 320 + zoom_x * (x_intermediate - 320)
if $game_system.loop_x
offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)
l = 32 * $game_map.width * zoom_x
self.x = (x + offset) % l - offset
end
# normal map
else
self.zoom_x = 1.0
self.zoom_y = 1.0
self.x = x_intermediate
self.y = y_intermediate
end
if @character.is_a?(Game_Player)
# Overworld Sprite Resize
if $game_system.ov
self.zoom_x *= $game_system.ov_zoom
self.zoom_y *= $game_system.ov_zoom
end
end
self.z = @character.screen_z(@ch)
self.y -= 32 * @character.height * zoom_y
return true
end
end
#==============================================================================
# ** Scene_Cmd_Dialog
#------------------------------------------------------------------------------
# This class performs command screen processing.
#==============================================================================
class Scene_Cmd_Dialog
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :spriteset # Spriteset
end
Instructions
Instructions on its use, and script placement are within the patch itself.
FAQ
I spent more time writing the instructions than the actual code.
Compatibility
Designed solely for the Lycan ABS and solely for the MGC Mode7 Edit, a re-worked version of MGCaladtogel's original Mode7 script. The Mode7 Edit is available in Save-Point.
Credits and Thanks
Thanks to GI_Toez who asked me to look into making a simplified patch to get Mode7 to work with the ABS. And to DrHouse93 for noticing that the Companion Commands/Dialog window did not properly function within Mode7.
Terms and Conditions
Free for use, even in commercial games.
This is a complete rewrite of my Lycan / Mode7 patch, with a lot more instructions and assistance. Unlike the previous version, this one does not require any alteration of the scripts themselves, and does not hamper or alter the method that generates the actual sprite graphics. Only placement of sprites is touched upon, both for the actual map sprites and duplicate sprites on connecting wrapped maps.
Okay, seriously? One small little addition to the END OF THE PATCH WAS NEEDED??? Yep, the very last part of the patch, the Scene_Cmd_Dialog section was all that was needed to allow the player to talk to companions while on a Mode7 map.
Thanks to DrHouse93 for finding the problem and reporting it.