Juan J. Sánchez
Sponsor
Medina Stories Custom Movement System Version: 1.1.0
By: Juan J. Sánchez
Introduction
This script combines MGCaladtogel's New Mode 07 script and Fukuyama's Caterpillar Walking script, along with my custom movement system, allowing more frames, eight directions, sneaking, dashing, idle animation, custom stances, and much more. It works with both custom and standard character sets. It now features Kristovski's Add-on, which adjusts the game controls in accordance with the rotation of the camera, allowing for a pseudo-3D experience.
Features
Video
http://www.youtube.com/watch?v=7DJzZRpyV-A
Screenshots
Demo
Medina Stories Custom Movement System v1.1.0 Demo
Medina Stories Custom Movement System v1.0.0 Demo
Script
MGCaladtogel's New Mode 07 script
MGCmode7.dll file
Fukuyama's Caterpillar Walking script
Instructions
Copy the scripts in the same order they were posted. The script, Medina Stories Custom Movement System, works as a stand-alone script. If you add MGCaladtogel's New Mode 07 script, you must add the MGCaladtogel's New Mode 07 / MS Custom Movement Patch. Remember to add the MGCmode7.dll file in your game folder if using MGCaladtogel's New Mode 07 script. If you add Fukuyama's Caterpillar Walking script, you must add the Fukuyama's Caterpillar Walking / MS Custom Movement Patch. Kristovski's Add-on allows you to change game controls in accordance to the rotation of the camera. The Draw Actor Graphic / MS Custom Movement Patch is necessary to fix an error in standard menus. If you are using custom menus, you might not need this patch.
The script works with almost any character set. You can configure the character set in the MOVEMENT module at the beginning of the Medina Stories Custom Movement System script. Every custom character set must have a suffix which can be defined in the MOVEMENT module. The standard suffix is "_custom". You can use the following character set from the MMORPG Ragnarok Online to test the script.
Configuring and activating custom stances
Configuring and activating custom animations
Compatibility
Not SDK compatible.
The script rewrites the following classes: Game_Character, Game_Player and Sprite_Character. MGCaladtogel's New Mode 07 script and Fukuyama's Caterpillar Walking script rewrite classes of their own.
The script assumes all characters, both events and players, have the same amount of directions. When using characters with different amount of directions, movement might become funny.
There seems to be an error with MGCaladtogel's New Mode 07 script. When looping a map, vertical sprites become unstable. You might want to avoid vertical sprites in looped maps, such as world maps.
Please inform me of any other compatibility issues.
Credits and Thanks
All credits for the Medina Stories Custom Movement System go to Juan J. Sánchez. Do not credit me as medinastories, Medina, Medina Stories, or any other variation of these names.
The New Mode 07 script and Kristovski's Add-on were written by MGCaladtogel. The Caterpillar Walking script was written by Fukuyama. I do not count with permissions to distribute the aforementioned scripts.
The character set provided, obtained from the MMORPG Ragnarok Online, is property of Gravity Co., LTD.
Special thanks go to DerVVulfman, whose scripts I edited to write my own. For a similar insight into custom movement, I suggest searching for DerVVulfman's Eight Directions & More Frames script.
Author's Notes
This script was designed for my RPG Maker XP project, Medina Stories. I first had the idea to make this script a couple of years ago upon encountering MGCaladtogel's New Mode 07 script. When I further analyzed DerVVulfman's Eight Directions & More Frames script, I decided to write my own script, specially designed for MMORPG Ragnarok Online character sets. After writing the Medina Stories Custom Movement System script, I then wrote the Fukuyama's Caterpillar Walking / MS Custom Movement Patch. Then I wrote the MGCaladtogel's New Mode 07 / MS Custom Movement Patch. Finally, I wrote the Draw Actor Graphic / MS Custom Movement Patch.
Terms and Conditions
Free for Commercial Use. Must include the scripter's name.
By: Juan J. Sánchez
Introduction
This script combines MGCaladtogel's New Mode 07 script and Fukuyama's Caterpillar Walking script, along with my custom movement system, allowing more frames, eight directions, sneaking, dashing, idle animation, custom stances, and much more. It works with both custom and standard character sets. It now features Kristovski's Add-on, which adjusts the game controls in accordance with the rotation of the camera, allowing for a pseudo-3D experience.
Features
- Movement in four and eight directions
Any standard amount of frames
MGCaladtogel's New Mode 07 script compatibility
Fukuyama's Caterpillar Walking script compatibility
Kristovski's Add-on for MGCaladtogel's New Mode 07 (adjustment of game controls in accordance to the rotation of the camera)
Simultaneous compatibility with both custom and standard character sets
Standing frame
Idle animation
Custom stances for every direction (i.e., looking clockwise, looking counter clockwise, sitting, sitting looking clockwise, sitting looking counter clockwise, etc.)
Dashing
Sneaking
Custom animations for every direction (frames, looping and speed can be customized)
Video
http://www.youtube.com/watch?v=7DJzZRpyV-A
Screenshots


Demo
Medina Stories Custom Movement System v1.1.0 Demo
Medina Stories Custom Movement System v1.0.0 Demo
Script
MGCaladtogel's New Mode 07 script
MGCmode7.dll file
Fukuyama's Caterpillar Walking script
Medina Stories Custom Movement System
MGCaladtogel's New Mode 07 / MS Custom Movement Patch
Fukuyama's Caterpillar Walking / MS Custom Movement Patch
Kristovski's Add-on
Drawing Actor Graphic / MS Custom Movement Patch
Ruby:
#==============================================================================
# ** Movement
#------------------------------------------------------------------------------
# This module contains global variables and classes.
#==============================================================================
module MOVEMENT
#--------------------------------------------------------------------------
# * General Configuration
# DIR8_ENABLED : 8 directions input enabled
# SUFFIX : suffix for custom character sets
# DIRECTIONS : standard number of directions
#--------------------------------------------------------------------------
DIR8_ENABLED = true
SUFFIX = '_custom'
DIRECTIONS = 8
#----------------------------------------------------------------------
# ** Stances
# STANCE_IDLE : idle
# STANCE_LOOKING_CW : looking clockwise
# STANCE_LOOKING_CCW : looking counter clockwise
# STANCE_SITTING : sitting
# STANCE_SITTING_CW : sitting looking clockwise
# STANCE_SITTING_CCW : sitting looking counter clockwise
#----------------------------------------------------------------------
STANCE_IDLE = 1
STANCE_LOOKING_CW = 9
STANCE_LOOKING_CCW = 10
STANCE_SITTING = 12
STANCE_SITTING_CW = 11
STANCE_SITTING_CCW = 13
#----------------------------------------------------------------------
# ** Frames
# TOTAL_FRAMES : total number of frames
# FRAMES : standard number of frames
# STAND_FRAME_ENABLED : standing frame enabled
#----------------------------------------------------------------------
TOTAL_FRAMES = 13
FRAMES = 8
STAND_FRAME_ENABLED = true
#----------------------------------------------------------------------
# ** Idle Animation
# IDLE_ENABLED : idle stance enabled
# IDLE_TIME : idle stance time delay
# IDLE_FRAMES : idle stance standard number of frames
# IDLE_LOOP_ENABLED : idle stance loop enabled
# IDLE_SPEED : idle stance speed
#----------------------------------------------------------------------
IDLE_ENABLED = true
IDLE_TIME = 200
IDLE_FRAMES = 8
IDLE_LOOP_ENABLED = true
IDLE_SPEED = 2
#--------------------------------------------------------------------------
# * Action Configuration
# SPEED_NORMAL : normal speed
# SPEED_DASH : dash speed
# SPEED_SNEAK : sneak speed
#--------------------------------------------------------------------------
SPEED_NORMAL = 3
SPEED_DASH = 4
SPEED_SNEAK = 1
#----------------------------------------------------------------------
# ** Buttons
# DASH_BUTTON : key for dashing
# SNEAK_BUTTON : key for sneaking
#----------------------------------------------------------------------
DASH_BUTTON = Input::Z
SNEAK_BUTTON = Input::Y
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
#--------------------------------------------------------------------------
# * Modules
#--------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :step_anime # character step flag
attr_reader :walk_anime # character movement flag
attr_reader :stop_count # number of steps left
attr_accessor :dashing # dashing flag
attr_accessor :sneaking # sneaking flag
attr_accessor :waiting # waiting flag
attr_accessor :looking_cw # looking clockwise flag
attr_accessor :looking_ccw # looking counter clockwise flag
attr_accessor :sitting # sitting flag
attr_accessor :sitting_cw # sitting clockwise flag
attr_accessor :sitting_ccw # sitting counter clockwise flag
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
return update_custom_anim if @animating
if jumping?
update_jump
elsif moving?
update_move
else
update_stop
end
if @anime_count > 18 - @move_speed * 2
if not @step_anime and @stop_count > 0
@pattern = @original_pattern
else
if @character_name.include?(SUFFIX)
@pattern = ((@pattern + 1 ) % FRAMES)
else
@pattern = ((@pattern + 1 ) % 4)
end
end
@anime_count = 0
end
if @wait_count > 0
@wait_count -= 1
return
end
if @move_route_forcing
move_type_custom
return
end
return if @starting or lock?
if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
case @move_type
when 1 # Random
move_type_random
when 2 # Approach
move_type_toward_player
when 3 # Custom
move_type_custom
end
end
end
#--------------------------------------------------------------------------
# * Move Lower Left
#--------------------------------------------------------------------------
def move_lower_left(turn_enabled = true)
if turn_enabled
turn_downleft
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
@x -= 1
@y += 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Lower Right
#--------------------------------------------------------------------------
def move_lower_right(turn_enabled = true)
if turn_enabled
turn_downright
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
@x += 1
@y += 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Left
#--------------------------------------------------------------------------
def move_upper_left(turn_enabled = true)
if turn_enabled
turn_upleft
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
@x -= 1
@y -= 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Left
#--------------------------------------------------------------------------
def move_upper_right(turn_enabled = true)
if turn_enabled
turn_upright
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
@x += 1
@y -= 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Random
#--------------------------------------------------------------------------
def move_random
case rand(8)
when 0 # Move down
move_down(false)
when 1 # Move left
move_left(false)
when 2 # Move right
move_right(false)
when 3 # Move up
move_up(false)
when 4 # Move lower left
move_lower_left
when 5 # Move lower right
move_lower_right
when 6 # Move upper left
move_upper_left
when 7 # Move upper right
move_upper_right
end
end
#--------------------------------------------------------------------------
# * Move Toward Player
#--------------------------------------------------------------------------
def move_toward_player
sx = @x - $game_player.x
sy = @y - $game_player.y
return if sx == 0 and sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
end
move_down if sy < 0
move_left if sx > 0
move_right if sx < 0
move_up if sy > 0
move_lower_left if sx > 0 and sy < 0
move_lower_right if sx < 0 and sy < 0
move_upper_left if sx > 0 and sy > 0
move_upper_right if sx < 0 and sy > 0
end
#--------------------------------------------------------------------------
# * Move Away From Player
#--------------------------------------------------------------------------
def move_away_from_player
sx = @x - $game_player.x
sy = @y - $game_player.y
return if sx == 0 and sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
end
move_down if sy > 0
move_left if sx < 0
move_right if sx > 0
move_up if sy < 0
move_lower_left if sx < 0 and sy > 0
move_lower_right if sx > 0 and sy > 0
move_upper_left if sx < 0 and sy < 0
move_upper_right if sx > 0 and sy < 0
end
#--------------------------------------------------------------------------
# * Turn Upper Left
#--------------------------------------------------------------------------
def turn_upleft
unless @direction_fix
if DIRECTIONS == 8
@direction = 7
else
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
end
@stop_count = 0
end
#--------------------------------------------------------------------------
# * Turn Uppper Right
#--------------------------------------------------------------------------
def turn_upright
unless @direction_fix
if DIRECTIONS == 8
@direction = 9
else
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
end
@stop_count = 0
end
#--------------------------------------------------------------------------
# * Turn Lower Left
#--------------------------------------------------------------------------
def turn_downleft
unless @direction_fix
if DIRECTIONS == 8
@direction = 1
else
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
end
@stop_count = 0
end
#--------------------------------------------------------------------------
# * Turn Lower Right
#--------------------------------------------------------------------------
def turn_downright
unless @direction_fix
if DIRECTIONS == 8
@direction = 3
else
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
end
end
#--------------------------------------------------------------------------
# * Set Custom Animation
#--------------------------------------------------------------------------
def set_custom_anim
return if @animating
@total_frames = FRAMES
@total_frames = IDLE_FRAMES if @waiting
@loop_enabled = false
@loop_enabled = IDLE_LOOP_ENABLED if @waiting
@anim_speed = 1
@anim_speed = IDLE_SPEED if @waiting
@frame_count = @total_frames
@anim_wait = 0
@pattern = 0
@animating = true
end
#--------------------------------------------------------------------------
# * Frame Update (custom animation)
#--------------------------------------------------------------------------
def update_custom_anim
update_jump if jumping?
if @anim_wait >= 8
@pattern = ((@pattern + 1 ) % @total_frames)
@frame_count -= 1
@anim_wait = 0
end
@anim_wait += @anim_speed if @anim_wait < 18 - @move_speed * 2
if @frame_count == 0
if @loop_enabled == true
@frame_count = @total_frames
else
end_custom_anim
end
return
end
end
#--------------------------------------------------------------------------
# * End Custom Animation
#--------------------------------------------------------------------------
def end_custom_anim
@animating = false
@waiting = false if @waiting
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
#--------------------------------------------------------------------------
# * Modules
#--------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#--------------------------------------------------------------------------
# * Invariables
#--------------------------------------------------------------------------
@@idle_time = 0
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :idle_time # idle time
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
@idle_time = @@idle_time
unless $game_system.map_interpreter.running? or $game_temp.message_window_showing
@dashing = false
@sneaking = false
trigger_d unless DASH_BUTTON == nil
trigger_s unless SNEAK_BUTTON == nil
unless @dashing or @sneaking
@move_speed = SPEED_NORMAL
end
end
last_moving = moving?
unless moving? or $game_system.map_interpreter.running? or
@move_route_forcing or $game_temp.message_window_showing
if DIR8_ENABLED == true
case Input.dir8
when 2 # Move down
move_down
when 4 # Move left
move_left
when 6 # Move right
move_right
when 8 # Move up
move_up
when 1 # Move lower left
move_lower_left
when 3 # Move lower right
move_lower_right
when 7 # Move upper left
move_upper_left
when 9 # Move upper right
move_upper_right
end
if IDLE_ENABLED
if Input.dir8 == 0
@@idle_time += 1 unless @waiting
trigger_w if @@idle_time == IDLE_TIME
else
@@idle_time = 0
@waiting = false
end_custom_anim
end
end
else
case Input.dir4
when 2 # Move down
move_down
when 4 # Move left
move_left
when 6 # Move right
move_right
when 8 # Move up
move_up
end
if IDLE_ENABLED
if Input.dir4 == 0
@@idle_time += 1 unless @waiting
trigger_w if @@idle_time == IDLE_TIME
else
@@idle_time = 0
@waiting = false
end_custom_anim
end
end
end
end
last_real_x = @real_x
last_real_y = @real_y
super
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
$game_map.scroll_down(@real_y - last_real_y)
end
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
$game_map.scroll_left(last_real_x - @real_x)
end
if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
$game_map.scroll_right(@real_x - last_real_x)
end
if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
$game_map.scroll_up(last_real_y - @real_y)
end
unless moving?
if last_moving
result = check_event_trigger_here([1,2])
if result == false
unless $DEBUG and Input.press?(Input::CTRL)
if @encounter_count > 0
@encounter_count -= 1
end
end
end
end
if Input.trigger?(Input::C)
check_event_trigger_here([0])
check_event_trigger_there([0,1,2])
end
end
end
#----------------------------------------------------------------------
# * Trigger Processing: Dash
#----------------------------------------------------------------------
def trigger_d
return if (DIR8_ENABLED ? Input.dir8 == 0 : Input.dir4 == 0)
return if Input.press?(SNEAK_BUTTON)
if Input.press?(DASH_BUTTON)
@dashing = true
@move_speed = SPEED_DASH
end
end
#----------------------------------------------------------------------
# * Trigger Processing: Sneak
#----------------------------------------------------------------------
def trigger_s
return if (DIR8_ENABLED ? Input.dir8 == 0 : Input.dir4 == 0)
return if Input.press?(DASH_BUTTON)
if Input.press?(SNEAK_BUTTON)
@sneaking = true
@move_speed = SPEED_SNEAK
end
end
#----------------------------------------------------------------------
# * Trigger Processing: Idle
#----------------------------------------------------------------------
def trigger_w
@@idle_time = 0
@waiting = true
self.set_custom_anim
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
#--------------------------------------------------------------------------
# * Modules
#--------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#--------------------------------------------------------------------------
# * 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)
if @character.character_name.include?(SUFFIX)
if STAND_FRAME_ENABLED
@cw = bitmap.width / (TOTAL_FRAMES + 1)
else
@cw = bitmap.width / TOTAL_FRAMES
end
@ch = bitmap.height / DIRECTIONS
else
@cw = bitmap.width / 4
@ch = bitmap.height / 4
end
self.ox = @cw / 2
self.oy = @ch
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
if @character.character_name.include?(SUFFIX)
if not @character.step_anime and @character.stop_count > 0
if @character.waiting
sx = (@character.pattern + STANCE_IDLE) * @cw
else
sx = @character.pattern * @cw
end
else
if STAND_FRAME_ENABLED
sx = (@character.pattern + 1) * @cw
else
sx = @character.pattern * @cw
end
end
else
sx = @character.pattern * @cw
end
sx = STANCE_LOOKING_CW * @cw if @character.looking_cw
sx = STANCE_LOOKING_CCW * @cw if @character.looking_ccw
sx = STANCE_SITTING * @cw if @character.sitting
sx = STANCE_SITTING_CW * @cw if @character.sitting_cw
sx = STANCE_SITTING_CCW * @cw if @character.sitting_ccw
if @character.character_name.include?(SUFFIX)
if DIRECTIONS == 8
value = (@character.direction == 7 or @character.direction == 9) ? 3 : 1
sy = (@character.direction - value) * @ch
else
sy = (@character.direction - 2) / 2 * @ch
end
else
sy = (@character.direction - 2) / 2 * @ch
end
self.src_rect.set(sx, sy, @cw, @ch)
end
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
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
end
MGCaladtogel's New Mode 07 / MS Custom Movement Patch
Ruby:
#==============================================================================
# ** 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
#--------------------------------------------------------------------------
# * Modules
#--------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#--------------------------------------------------------------------------
# * Aliased methods (F12 compatibility)
#--------------------------------------------------------------------------
if !@already_aliased
alias update_neoM7_sprite_character update
@already_aliased = true
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
if !$game_system.neoM7
update_neoM7_sprite_character
return
end
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)
if @character.character_name.include?(SUFFIX)
if STAND_FRAME_ENABLED
@cw = bitmap.width / (TOTAL_FRAMES + 1)
else
@cw = bitmap.width / TOTAL_FRAMES
end
@ch = bitmap.height / DIRECTIONS
else
@cw = bitmap.width / 4
@ch = bitmap.height / 4
end
self.ox = @cw / 2
self.oy = @ch
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
if @character.character_name.include?(SUFFIX)
if not @character.step_anime and @character.stop_count > 0
if @character.waiting
sx = (@character.pattern + STANCE_IDLE) * @cw
else
sx = @character.pattern * @cw
end
else
if STAND_FRAME_ENABLED
sx = (@character.pattern + 1) * @cw
else
sx = @character.pattern * @cw
end
end
else
sx = @character.pattern * @cw
end
sx = STANCE_LOOKING_CW * @cw if @character.looking_cw
sx = STANCE_LOOKING_CCW * @cw if @character.looking_ccw
sx = STANCE_SITTING * @cw if @character.sitting
sx = STANCE_SITTING_CW * @cw if @character.sitting_cw
sx = STANCE_SITTING_CCW * @cw if @character.sitting_ccw
if @character.character_name.include?(SUFFIX)
if DIRECTIONS == 8
dir = (@character.direction == 7 or @character.direction == 9) ? 3 : 1
current_dir = (@character.direction - dir)
theta = $scene.spriteset.tilemap.theta rescue 0
if $scene.spriteset != nil and $scene.spriteset.tilemap.is_a?(Tilemap_neoM7)
dir_list = [0, 1, 2, 5, 6, 7, 4, 3]
current_dir = dir_list[(dir_list.index(current_dir % 8) + ((theta + 22.5) % 360) / 45) % 8]
end
sy = current_dir * @ch
else
current_dir = (@character.direction - 2) / 2
theta = $scene.spriteset.tilemap.theta rescue 0
if $scene.spriteset != nil and $scene.spriteset.tilemap.is_a?(Tilemap_neoM7)
dir_list = [0, 2, 3, 1]
current_dir = dir_list[(dir_list.index(current_dir % 4) + ((theta + 45) % 360) / 90) % 4]
end
sy = current_dir * @ch
end
else
current_dir = (@character.direction - 2) / 2
theta = $scene.spriteset.tilemap.theta rescue 0
if $scene.spriteset != nil and $scene.spriteset.tilemap.is_a?(Tilemap_neoM7)
dir_list = [0, 2, 3, 1]
current_dir = dir_list[(dir_list.index(current_dir % 4) + ((theta + 45) % 360) / 90) % 4]
end
sy = current_dir * @ch
end
self.src_rect.set(sx, sy, @cw, @ch)
self.length = @cw
self.height = @ch
end
x_intermediate = @character.screen_x
y_intermediate = @character.screen_y - 4
if $game_system.neoM7_loop
diff_y = ($game_player.y - @character.y).to_i
offset_y = ($game_map.height << 5) * (diff_y >= 0 ?
(diff_y / ($game_map.height >> 1)) :
(diff_y / ($game_map.height >> 1)) + 1)
diff_x = ($game_player.x - @character.x).to_i
offset_x = ($game_map.width << 5) * (diff_x >= 0 ?
(diff_x / ($game_map.width >> 1)) :
(diff_x / ($game_map.width >> 1)) + 1)
neoM7_character(x_intermediate + offset_x, y_intermediate + offset_y)
else
neoM7_character(x_intermediate, y_intermediate)
end
if !on_screen_x(x) or !on_screen_y(y)
self.opacity = 0
return
end
neoM7_zoom(x, y)
self.opacity = 255
self.z = 4 * y
self.y -= 32 * @character.height * zoom_y
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
end
Fukuyama's Caterpillar Walking / MS Custom Movement Patch
Ruby:
#==============================================================================
# ** Movement
#------------------------------------------------------------------------------
# Caterpillar movement of actor is carried out on map.
#==============================================================================
module Train_Actor
#============================================================================
# ** Game_Party_Actor
#----------------------------------------------------------------------------
# This class handles the party train actors. Its functions include event
# starting determinants and map scrolling.
#============================================================================
class Game_Party_Actor < Game_Character
#------------------------------------------------------------------------
# * Modules
#------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#------------------------------------------------------------------------
# * Move Lower Left
#------------------------------------------------------------------------
def move_lower_left(turn_enabled = true)
if turn_enabled
turn_downleft
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
@x -= 1
@y += 1
increase_steps
end
end
#------------------------------------------------------------------------
# * Move Lower Right
#------------------------------------------------------------------------
def move_lower_right(turn_enabled = true)
if turn_enabled
turn_downright
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
@x += 1
@y += 1
increase_steps
end
end
#------------------------------------------------------------------------
# * Move Upper Left
#------------------------------------------------------------------------
def move_upper_left(turn_enabled = true)
if turn_enabled
turn_upleft
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
@x -= 1
@y -= 1
increase_steps
end
end
#------------------------------------------------------------------------
# * Move Upper Right
#------------------------------------------------------------------------
def move_upper_right(turn_enabled = true)
if turn_enabled
turn_upright
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
@x += 1
@y -= 1
increase_steps
end
end
#------------------------------------------------------------------------
# * Frame Update
#------------------------------------------------------------------------
if @train_patch_stack.nil?
@train_patch_stack = true
alias train_patch_update update
def update
train_patch_update
@dashing = $game_player.dashing
@sneaking = $game_player.sneaking
@waiting = $game_player.waiting
@idle_time = nil if !@waiting
if @waiting && @character_name.include?(SUFFIX)
@idle_time = $game_player.idle_time if @idle_time == nil
@idle_time += 1
if @idle_time == IDLE_TIME
@idle_time = 0
@waiting = true
self.set_custom_anim
end
end
self.end_custom_anim if !@waiting
end
end
end
end
Kristovski's Add-on
Ruby:
#============================================================================
# Add-on for H-Mode7 Engine
# V.1.1 - 10/01/2011
# Author : MGC
#
# This add-on reorients the direction controls when the map is rotated.
# This is a request from Kristovki.
#============================================================================
module Input
#--------------------------------------------------------------------------
# * Aliased methods (F12 compatibility)
#--------------------------------------------------------------------------
class << self
if !@already_aliased
alias dir4_neoM7_input dir4
alias dir8_neoM7_input dir8
@already_aliased = true
end
end
#--------------------------------------------------------------------------
# * Dir4
#--------------------------------------------------------------------------
Left = [6, 2, 8, 4]
def self.dir4
unless $game_system.neoM7
return dir4_neoM7_input
end
input_value = dir4_neoM7_input
unless input_value == 0
case $game_system.neoM7_theta
when 45...135
camera_direction = 4
when 135...225
camera_direction = 2
when 225...315
camera_direction = 6
else
camera_direction = 8
end
case camera_direction
when 2
input_value = 10 - input_value
when 4
input_value = 10 - Left[(input_value >> 1) - 1]
when 6
input_value = Left[(input_value >> 1) - 1]
when 8
input_value = input_value
end
end
return input_value
end
#--------------------------------------------------------------------------
# * Dir8 - V.1.1
#--------------------------------------------------------------------------
Dir8_Index = [0, 5, 4, 3, 6, 0, 2, 7, 0, 1]
Dir8_Left = [8, 9, 6, 3, 2, 1, 4, 7]
def self.dir8
unless $game_system.neoM7
return dir8_neoM7_input
end
input_value = dir8_neoM7_input
unless input_value == 0
offset = (($game_system.neoM7_theta + 23) / 45) % 8
input_value = Dir8_Left[(Dir8_Index[input_value] + offset) % 8]
end
return input_value
end
end
Drawing Actor Graphic / MS Custom Movement Patch
Ruby:
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
# This class is for all in-game windows.
#==============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
# * Modules
#--------------------------------------------------------------------------
include MOVEMENT # MOVEMENT module
#--------------------------------------------------------------------------
# * Draw Actor Graphic
# actor : actor
# x : draw spot x-coordinate
# y : draw spot y-coordinate
#--------------------------------------------------------------------------
def draw_actor_graphic(actor, x, y)
bitmap = RPG::Cache.character(actor.character_name, actor.character_hue)
if actor.character_name.include?(SUFFIX)
if STAND_FRAME_ENABLED
cw = bitmap.width / (TOTAL_FRAMES + 1)
else
cw = bitmap.width / TOTAL_FRAMES
end
ch = bitmap.height / DIRECTIONS
else
cw = bitmap.width / 4
ch = bitmap.height / 4
end
src_rect = Rect.new(0, 0, cw, ch)
self.contents.blt(x - cw / 2, y - ch / 2, bitmap, src_rect)
end
end
Instructions
Copy the scripts in the same order they were posted. The script, Medina Stories Custom Movement System, works as a stand-alone script. If you add MGCaladtogel's New Mode 07 script, you must add the MGCaladtogel's New Mode 07 / MS Custom Movement Patch. Remember to add the MGCmode7.dll file in your game folder if using MGCaladtogel's New Mode 07 script. If you add Fukuyama's Caterpillar Walking script, you must add the Fukuyama's Caterpillar Walking / MS Custom Movement Patch. Kristovski's Add-on allows you to change game controls in accordance to the rotation of the camera. The Draw Actor Graphic / MS Custom Movement Patch is necessary to fix an error in standard menus. If you are using custom menus, you might not need this patch.
The script works with almost any character set. You can configure the character set in the MOVEMENT module at the beginning of the Medina Stories Custom Movement System script. Every custom character set must have a suffix which can be defined in the MOVEMENT module. The standard suffix is "_custom". You can use the following character set from the MMORPG Ragnarok Online to test the script.

Configuring and activating custom stances
Step 1. In the MOVEMENT module, under General Configuration, in the subsection Stances, add a variable with the frame number of your stance. The variable name should be written in capital letters and should be easy to remember. The standard name is "STANCE_<NAME>". For the purpose of teaching, I shall be using the name "STANCE_SITTING".
Step 2. In the Game_Character class, under Public Instance Variables, add an attribute accessor with the same name as your stance. The attribute accessor name should be written in lower case letters. If your variable name is "STANCE_SITTING", your attribute accessor name should be "sitting".
Step 3. In the Sprite_Character class, under update method, add the following code in line 582. If using MGCaladtogel's New Mode 07 / MS Custom Movement Patch, do this in the patch in line 78. This concludes the configuration of custom stances.
Step 4. To activate a custom stance for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Step 5. To inactivate a custom stance for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
STANCE_SITTING = 1
Step 2. In the Game_Character class, under Public Instance Variables, add an attribute accessor with the same name as your stance. The attribute accessor name should be written in lower case letters. If your variable name is "STANCE_SITTING", your attribute accessor name should be "sitting".
Ruby:
attr_accessor :sitting
Step 3. In the Sprite_Character class, under update method, add the following code in line 582. If using MGCaladtogel's New Mode 07 / MS Custom Movement Patch, do this in the patch in line 78. This concludes the configuration of custom stances.
Ruby:
sx = STANCE_SITTING * @cw if @character.sitting
Step 4. To activate a custom stance for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
self.sitting = true
Step 5. To inactivate a custom stance for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
self.sitting = false
Configuring and activating custom animations
Step 1. In the MOVEMENT module, under General Configuration, in the subsection Stances, add a variable with the initial frame number of your animation. The variable name should be written in capital letters and should be easy to remember. The standard name is "STANCE_<NAME>". For the purpose of teaching, I shall be using the name "STANCE_ATTACKING".
Step 2. In the MOVEMENT module, under General Configuration, make a new subsection and add the following variables: <NAME>_FRAMES, <NAME>_LOOP_ENABLED and <NAME>_SPEED. The first variable determines how many frames the animation has. The second variable determines whether the animation stops or whether it plays in an infinite loop. The third variable determines the animation speed, from 1, the slowest speed, to 8, the fastest speed.
Step 3. In the Game_Character class, under Public Instance Variables, add an attribute accessor with the same name as your animation. The attribute accessor name should be written in lower case letters. If your variable name is "STANCE_ATTACKING", your attribute accessor name should be "attacking".
Step 4. In the Game_Character class, under set_custom_anim method, add the following code at the beginning of the method, after the variables have been declared.
Step 5. In the Game_Character class, under end_custom_anim method, add the following code at the end of the method.
Step 6. In the Sprite_Character class, under update method, add the following code in line 582. If using MGCaladtogel's New Mode 07 / MS Custom Movement Patch, do this in the patch in line 78. This concludes the configuration of custom animations.
Step 7. To activate a custom animation for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Step 8. To inactivate a custom animation for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
STANCE_ATTACKING = 1
Step 2. In the MOVEMENT module, under General Configuration, make a new subsection and add the following variables: <NAME>_FRAMES, <NAME>_LOOP_ENABLED and <NAME>_SPEED. The first variable determines how many frames the animation has. The second variable determines whether the animation stops or whether it plays in an infinite loop. The third variable determines the animation speed, from 1, the slowest speed, to 8, the fastest speed.
Ruby:
#----------------------------------------------------------------------
# ** Attacking Animation
# ATTACKING_FRAMES : attacking stance standard number of frames
# ATTACKING_LOOP_ENABLED : attacking stance loop enabled
# ATTACKING_SPEED : attacking stance speed
#----------------------------------------------------------------------
ATTACKING_FRAMES = 8
ATTACKING_LOOP_ENABLED = true
ATTACKING_SPEED = 2
Step 3. In the Game_Character class, under Public Instance Variables, add an attribute accessor with the same name as your animation. The attribute accessor name should be written in lower case letters. If your variable name is "STANCE_ATTACKING", your attribute accessor name should be "attacking".
Ruby:
attr_accessor :attacking
Step 4. In the Game_Character class, under set_custom_anim method, add the following code at the beginning of the method, after the variables have been declared.
Ruby:
@total_frames = FRAMES
@total_frames = ATTACKING_FRAMES if @attacking
@loop_enabled = false
@loop_enabled = ATTACKING_LOOP_ENABLED if @attacking
@anim_speed = 1
@anim_speed = ATTACKING_SPEED if @attacking
Step 5. In the Game_Character class, under end_custom_anim method, add the following code at the end of the method.
Ruby:
@attacking = false if @attacking
Step 6. In the Sprite_Character class, under update method, add the following code in line 582. If using MGCaladtogel's New Mode 07 / MS Custom Movement Patch, do this in the patch in line 78. This concludes the configuration of custom animations.
Ruby:
sx = (@character.pattern + STANCE_ATTACKING) if @character.attacking
Step 7. To activate a custom animation for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
self.attacking = true
self.set_custom_anim
Step 8. To inactivate a custom animation for a given character, event or player, in Event Commands, under Move Event..., under Script..., add the following code.
Ruby:
self.end_custom_anim
Compatibility
Not SDK compatible.
The script rewrites the following classes: Game_Character, Game_Player and Sprite_Character. MGCaladtogel's New Mode 07 script and Fukuyama's Caterpillar Walking script rewrite classes of their own.
The script assumes all characters, both events and players, have the same amount of directions. When using characters with different amount of directions, movement might become funny.
There seems to be an error with MGCaladtogel's New Mode 07 script. When looping a map, vertical sprites become unstable. You might want to avoid vertical sprites in looped maps, such as world maps.
Please inform me of any other compatibility issues.
Credits and Thanks
All credits for the Medina Stories Custom Movement System go to Juan J. Sánchez. Do not credit me as medinastories, Medina, Medina Stories, or any other variation of these names.
The New Mode 07 script and Kristovski's Add-on were written by MGCaladtogel. The Caterpillar Walking script was written by Fukuyama. I do not count with permissions to distribute the aforementioned scripts.
The character set provided, obtained from the MMORPG Ragnarok Online, is property of Gravity Co., LTD.
Special thanks go to DerVVulfman, whose scripts I edited to write my own. For a similar insight into custom movement, I suggest searching for DerVVulfman's Eight Directions & More Frames script.
Author's Notes
This script was designed for my RPG Maker XP project, Medina Stories. I first had the idea to make this script a couple of years ago upon encountering MGCaladtogel's New Mode 07 script. When I further analyzed DerVVulfman's Eight Directions & More Frames script, I decided to write my own script, specially designed for MMORPG Ragnarok Online character sets. After writing the Medina Stories Custom Movement System script, I then wrote the Fukuyama's Caterpillar Walking / MS Custom Movement Patch. Then I wrote the MGCaladtogel's New Mode 07 / MS Custom Movement Patch. Finally, I wrote the Draw Actor Graphic / MS Custom Movement Patch.
Terms and Conditions
Free for Commercial Use. Must include the scripter's name.