Glitchfinder
Staff
By: Glitchfinder
Introduction
Glitchfinder's Quicksand script implements a feature most people have wanted, but few have managed: quicksand in RMXP. The quicksand has adjustable sinking speeds, and you die if you stay completely submerged for too long. To top it all off, the deeper you are, the slower you move. Excellent for use in deathtrap puzzles and the like.
Features
- Adds quicksand!
- The player actually sinks into the ground!
- The player dies if they can't get out!
- The deeper the player is, the slower they move!
- The player pops out of the ground if they manage to escape the quicksand!
- Easy debugging!
Screenshots
I have a screenshot, and I might actually make a video if I can be bothered to reinstall my screen capture software and configure it again.

Script
Here's the script, but I recommend you try to demo to get an idea of how it works.
Code:
#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
# ** Team Scriptastic's Quicksand [RPG Maker XP]
# Version 1.20
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# This script adds quicksand that a player can sink into and die.
#==============================================================================
# * Version History
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Version 1.00 ------------------------------------------------- (2009-08-08)
# - Initial Version
# - Author: Glitchfinder
# Version 1.10 ------------------------------------------------ (2009-08-15)
# - Added maximum depth
# - Modified player speed to slow character when sinking.
# - Author: Glitchfinder
# Version 1.20 ------------------------------------------------ (2009-08-16)
# - Added debug code to print tile ID that the player is standing on.
# - Author: theory
#==============================================================================
# * Instructions
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Place this script above Main, and below the default scripts. (I realize this
# is obvious to most, but some people don't get it.)
#
# This script requires an intermediate level of scripting experience to use.
# Setup takes place inside the Scriptastic class located immediately following
# this header.
# Quicksand.default - Don't touch this one.
#
# Quicksand[(tileset filename)] = {
# 'tile_ids' => [##],
# 'speed' => [##],
# 'autotiles' => [##],
# 'autotile_speeds' => [##],
# 'game_over' => [(true or false)]
# }
#
# 'tile_ids'
# Replace tile_ids ## with the tile ID of the tiles you would like to have a
# quicksand effect. While not a simple task, we have attempted to make it as
# easy as possible by including a simple utility method for you.
# You can "Call Script..." on any event, and enter "print_tile_ids".
# This will display a window with the tile IDs for the tile on each of the
# three layers.
# To make matters easier, I added a button for this. Press F5 while in debug
# mode to display the tile IDs where the player stands for all three layers.
# If this button collides with another script configuration, simply
# change the Input.trigger?(keycode) command in Scriptastic.quicksand_debug .
# Enter the tile ID of the desired tile(s) in the tile_ids array, seperated by
# commas if using more than one tile.
#
# 'speed'
# Replace the ## in speed with the number of frames it takes to reach the
# fully buried (game_over, if applicable) state. Number of frames implies
# that lower numbers will be faster, while higher numbers will be slower. The
# actual sinking speed is a percentage of the bitmap height of the character,
# so larger events will sink faster than lower events, though it will bear the
# same time limit (same number of frames) they have to make it across (out)
# before becoming completely buried.
# Note that if you used more than one tile, these speeds will have to be
# entered in the same manner, comma seperated, and in THE EXACT SAME ORDER,
# even if they are all the same speed.
#
# 'autotiles'
# Similar to tile_ids, this is used to assign a quicksand effect to autotiles.
# The autotile id is much simpler, however, as its defined by the order they
# appear in the top row of the tileset in the editor. Note that the blank
# tile at the left counts as '0', and cannot be assigned a quicksand effect.
# The top row of tiles (eight across) would look like this: 0,1,2,3,4,5,6,7 .
# Enter them in the same manner as tile_ids, comma seperated if assigning a
# quicksand effect to more than one autotile.
#
# 'autotile_speeds'
# This is the same as 'speed', only the order applies to (and must reflect)
# the 'autotiles' array rather than the 'tile_ids' array. Again, make sure
# your entries are in the same order as the autotiles for proper operation.
#
# 'game_over'
# For each tileset, this is either true or false. If it's true, the player
# will reach a game_over screen a few seconds after becoming completely buried.
# If set to false, the player will simply be inhibited, and not killed as a
# result of being buried.
#
#
# If you are having trouble with this script, double check your tile ids, and
# make sure you have the same number of tile_id's (or 'autotiles') as you do
# entries for 'speed' and 'autotile_speeds'.
#==============================================================================
# * Method List
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Game_Character
#
# print_tile_ids
# Prints the tile ids of the tiles under the character, in order from the
# first layer to the third. Called by the Interpreter's print_tile_ids()
# method.
#
# Interpreter
#
# print_tile_ids(character)
# prints the id of all tiles under the specified character. The character
# variable can be -1 for the player, 0 for the current event, or a higher
# number for the event whose ID it matches.
#==============================================================================
# * Usage
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# This script may be used with the following terms and conditions:
#
# 1. This script is free to use in any noncommercial project. If you wish to
# use this script in a commercial (paid) project, please contact
# Glitchfinder at his website.
# 2. This script may only be hosted at the following domains:
# [url=http://www.glitchkey.com]http://www.glitchkey.com[/url]
# [url=http://www.hbgames.org]http://www.hbgames.org[/url]
# 3. If you wish to host this script elsewhere, please contact Glitchfinder.
# 4. If you wish to translate this script, please contact Glitchfinder. He
# will need the web address that you plan to host the script at, as well
# as the language this script is being translated to.
# 5. This header must remain intact at all times.
# 6. Glitchfinder remains the sole owner of this code. He may modify or
# revoke this license at any time, for any reason.
# 7. Any code derived from code within this script is owned by Glitchfinder,
# and you must have his permission to publish, host, or distribute his
# code.
# 8. This license applies to all code derived from the code within this
# script.
# 9. If you use this script within your project, you must include visible
# credit to Glitchfinder, within reason.
#≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
module Scriptastic
def self.quicksand_debug
return Input.trigger?(Input::F5)
end
Quicksand = {}
Quicksand.default = {
'tile_ids' => [],
'speed' => [],
'autotiles' => [],
'autotile_speeds' => [],
'gameover' => false
}
Quicksand['007-Swamp01'] = {
'tile_ids' => [],
'speed' => [],
'autotiles' => [5, 6, 7],
'autotile_speeds' => [240, 160, 120],
'gameover' => true
}
end
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
if $DEBUG # Only load this ID check hack if in $DEBUG mode.
class Scene_Map
alias scriptastic_quicksand_scene_map_update update
def update
if Scriptastic.quicksand_debug
$game_system.map_interpreter.print_tile_ids(-1)
end
scriptastic_quicksand_scene_map_update
end
end
end
#==============================================================================
# ** Game_Character (part 1)
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :quicksand_height # ID
#--------------------------------------------------------------------------
# * Alias Methods
#--------------------------------------------------------------------------
alias scriptastic_quicksand_game_character_initialize initialize
alias scriptastic_quicksand_game_character_update update
alias scriptastic_quicksand_game_character_move_type_custom move_type_custom
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
scriptastic_quicksand_game_character_initialize
@quicksand_height = 0.00
@old_name_quicksand = ''
@original_move_speed = @move_speed
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
scriptastic_quicksand_game_character_update
if @old_name_quicksand != @character_name
bitmap = RPG::Cache.character(@character_name, @character_hue)
@quicksand_height = bitmap.height / 4
@old_name_quicksand = @character_name
end
end
#--------------------------------------------------------------------------
# * Move Type : Custom
#--------------------------------------------------------------------------
def move_type_custom
# Interrupt if not stopping
if jumping? or moving?
return
end
# Loop until finally arriving at move command list
if @move_route_index < @move_route.list.size
command = @move_route.list[@move_route_index]
if command.code == 29
@original_move_speed = command.parameters[0]
end
end
scriptastic_quicksand_game_character_move_type_custom
end
#--------------------------------------------------------------------------
# * Print Tile IDs
#--------------------------------------------------------------------------
def print_tile_ids
tile_ids = []
for i in 0..2
tile_ids.push($game_map.data[@x, @y, i])
end
x = @x.to_s
y = @y.to_s
s = "The currently specified coordinates are (" + x + ", " + y + ").\n\n"
s += "The tile ID of layer one is " + tile_ids[0].to_s + ".\n"
s += "The tile ID of layer two is " + tile_ids[1].to_s + ".\n"
s += "The tile ID of layer three is " + tile_ids[2].to_s + ".\n"
print s
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 Methods
#--------------------------------------------------------------------------
alias scriptastic_quicksand_game_player_update update
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
scriptastic_quicksand_game_player_update
quicksand_data = Scriptastic::Quicksand[$game_map.tileset_name]
quicksand = false
for i in [2, 1, 0]
tile_id = $game_map.data[@x, @y, i]
autotile_id = 0
if tile_id >= 48 && tile_id <= 383
if tile_id >= 48 && tile_id < 96
autotile_id = 1
elsif tile_id >= 96 && tile_id < 144
autotile_id = 2
elsif tile_id >= 144 && tile_id < 192
autotile_id = 3
elsif tile_id >= 192 && tile_id < 240
autotile_id = 4
elsif tile_id >= 240 && tile_id < 288
autotile_id = 5
elsif tile_id >= 288 && tile_id < 336
autotile_id = 6
else
autotile_id = 7
end
end
if (quicksand_data['tile_ids'].include?(tile_id) ||
quicksand_data['autotiles'].include?(autotile_id)) &&
@quicksand_height >= 1
index = quicksand_data['tile_ids'].index(tile_id)
if index == nil
index = quicksand_data['autotiles'].index(autotile_id)
speed = quicksand_data['autotile_speeds'][index].to_f
else
speed = quicksand_data['speed'][index].to_f
end
@quicksand_height = (@quicksand_height * (speed - 1.00)) / speed
if @quicksand_height.truncate == 0 && quicksand_data['gameover'] == true
$scene = Scene_Gameover.new
end
quicksand = true
break
end
end
bitmap = RPG::Cache.character(@character_name, @character_hue)
percent = @quicksand_height / (bitmap.height / 4)
@move_speed = (@original_move_speed * percent).to_i
@move_speed = 1 if @move_speed <= 0
@move_speed
unless quicksand == true
if @quicksand_height > bitmap.height / 4
@quicksand_height = bitmap.height / 4
elsif @quicksand_height < bitmap.height / 4
@quicksand_height = (@quicksand_height * (11.00)) / 10.00
end
end
end
end
#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
# This sprite is used to display characters. It observes a instance of the
# Game_Character class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# * Alias Methods
#--------------------------------------------------------------------------
alias scriptastic_sprite_popup_sprite_character_initialize initialize
alias scriptastic_sprite_popup_sprite_character_update update
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : viewport
# character : character (Game_Character)
#--------------------------------------------------------------------------
def initialize(viewport, character = nil)
@height = nil
scriptastic_sprite_popup_sprite_character_initialize(viewport, character)
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
scriptastic_sprite_popup_sprite_character_update
if @quicksand_height != @character.quicksand_height
rect = self.src_rect
y_offset = rect.height - @character.quicksand_height.truncate
self.y += y_offset
self.src_rect.height = @character.quicksand_height.truncate
@quicksand_height = @character.quicksand_height
end
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
def print_tile_ids(character)
chara = get_character(character)
chara.print_tile_ids if chara != nil
end
end
Demo
You can download the demo here
Instructions
Place this script above Main, and below the default scripts. (I realize this is obvious to most, but some people don't get it.)
This script requires an intermediate level of scripting experience to use. Setup takes place inside the Scriptastic class located immediately following this header.
Code:
Quicksand.default # Don't touch this one.
Quicksand[(tileset filename)] = {
'tile_ids' => [##],
'speed' => [##],
'autotiles' => [##],
'autotile_speeds' => [##],
'game_over' => [(true or false)]
}
'tile_ids'
Replace tile_ids ## with the tile ID of the tiles you would like to have a quicksand effect. While not a simple task, we have attempted to make it as easy as possible by including a simple utility method for you. You can "Call Script..." on any event, and enter "print_tile_ids". This will display a window with the tile IDs for the tile on each of the three layers.
To make matters easier, I added a button for this. Press F5 while in debug mode to display the tile IDs where the player stands for all three layers. If this button collides with another script configuration, simply change the Input.trigger?(keycode) command in Scriptastic.quicksand_debug. Enter the tile ID of the desired tile(s) in the tile_ids array, separated by commas if using more than one tile.
'speed'
Replace the ## in speed with the number of frames it takes to reach the fully buried (game_over, if applicable) state. Number of frames implies that lower numbers will be faster, while higher numbers will be slower. The actual sinking speed is a percentage of the bitmap height of the character, so larger events will sink faster than lower events, though it will bear the same time limit (same number of frames) they have to make it across (out) before becoming completely buried.
Note that if you used more than one tile, these speeds will have to be entered in the same manner, comma separated, and in THE EXACT SAME ORDER, even if they are all the same speed.
'autotiles'
Similar to tile_ids, this is used to assign a quicksand effect to autotiles. The autotile id is much simpler, however, as it's defined by the order they appear in the top row of the tileset in the editor. Note that the blank tile at the left counts as '0', and cannot be assigned a quicksand effect. The top row of tiles (eight across) would look like this: [0,1,2,3,4,5,6,7] . Enter them in the same manner as tile_ids, comma separated if assigning a quicksand effect to more than one autotile.
'autotile_speeds'
This is the same as 'speed', only the order applies to (and must reflect)
the 'autotiles' array rather than the 'tile_ids' array. Again, make sure your entries are in the same order as the autotiles for proper operation.
'game_over'
For each tileset, this is either true or false. If it's true, the player will reach a game_over screen a few seconds after becoming completely buried. If set to false, the player will simply be inhibited, and not killed as a result of being buried.
If you are having trouble with this script, double check your tile ids, and make sure you have the same number of 'tile_ids' (or 'autotiles') as you do entries for 'speed' and 'autotile_speeds'.
Method List
Mouse.update
Updates mouse input. Calls to this method are not necessary unless the default Input module is not being updated.
Game_Character
print_tile_ids
Prints the tile ids of the tiles under the character, in order from the first layer to the third. Called by the Interpreter's print_tile_ids() method.
Interpreter
print_tile_ids(character)
Prints the id of all tiles under the specified character. The character variable can be -1 for the player, 0 for the current event, or a higher number for the event whose ID it matches.
Terms and Conditions
- This script is free to use in any noncommercial project. If you wish to use this script in a commercial (paid) project, please contact Glitchfinder at his website.
- This script may only be hosted at the following domains:
http://www.glitchkey.com
http://www.hbgames.org - If you wish to host this script elsewhere, please contact Glitchfinder.
- If you wish to translate this script, please contact Glitchfinder. He will need the web address that you plan to host the script at, as well as the language this script is being translated to.
- The script header must remain intact at all times.
- Glitchfinder remains the sole owner of this code. He may modify or revoke this license at any time, for any reason.
- Any code derived from code within this script is owned by Glitchfinder, and you must have his permission to publish, host, or distribute his code.
- This license applies to all code derived from the code within this script.
- If you use this script within your project, you must include visible credit to Glitchfinder, within reason.