Introduction
This script is a rudimentary flight system, allowing the player to fly with the push of a button.
Script
"script"
Code:
#==============================================================================
# ** DerVV's Flight
#------------------------------------------------------------------------------
# by DerVVulfman
# version 1.6
# 12-24-2015
# RGSS / RPGMaker XP
#
#==============================================================================
#
# This script is a rudimentary flight system, allowing the player to fly with
# the push of a button.
#
# Requested by Melana, and inspired (but not based upon) "Galv's Superman
# Ability" script, you can configure the rmxp key which permits flight, the
# in-game RMXP switch that permits its use, movement speeds and the suffix
# which identifies your flying charactersets.
#
# But there's more. You can also designate maps which do not permit flight.
#
# --- --- ---
#
# Event Triggering while in flight.
# ---------------------------------
# The player may fly over events on the map. But events that are set to
# the Player Touch or Event Touch triggers will activate once the player is
# overtop. They do not activate when the player is next to the event.
#
# As said before, the player may fly over events on the map, but there is
# an exception. If the event in question is set to 'always on top', the
# event is basically flying at the same level and can block the player, can
# be touched and triggered.
#
#
# Script Calls.
# -------------
# There are two script calls: force_takeoff and force_landing. These will
# allow the game designer to force the player to fly or land. However,
# these fall under certain criteria. The force_landing script call will not
# work if the player is not over an area which he can walk or land. And the
# force_takeoff script will not function if you are on a map that does not
# allow flight, and will not function if the RMXP Switch that activates
# is not turned on
#
#
# Requirements.
# -------------
# There are four arrays that allow you to set requrements for the player in
# order to permit flight. The HEROES array contains the IDs of heroes who
# can fly. The ARMORS array contains the IDs of armor that permits flight.
# the SKILLS array contains the IDs of skills that lets the player fly. And
# the STATUS array holds the IDs of status effects & ailments that lets the
# player fly. However, if the player unequips armor in flight, or loses the
# boon of a flying status effect,he MAY fall on an tile that may be harmful
# or hazardous.
#
#
# Danger Zones.
# -------------
# While the player cannot land on tiles that are impassable, it is possible
# for a player to 'fall' upon such a tile, or a tile deemed dangerous. Such
# would be the case if a player loses the ability to fly over water. For
# this, two values were created. The DANGER_TAG array allows you to set the
# terrain tags deemed hostile to the player when he lands upon it. And the
# DANGER_EVENT value identifies the common event that is performed in this
# instance.
#
#
#------------------------------------------------------------------------------
#
# COMPATIBILITY:
#
# Fairly compatible for RPGMaker XP systems. However, it does rewrite the
# Game_Player.passable? method.
#
#==============================================================================
#
# TERMS AND CONDITIONS:
#
# Free for use, even in commercial games. And as this script was requested
# by Melana, you have to give both of us credit for this script.
#
#==============================================================================
module DerVV_Flight
# Normal Options
# ==================================================
TRIGGER = Input::A # Set to the RMXP key (Currently Shift)
SUFFIX = "_Fly" # Suffix attached to end of flying characterset
ON_SWITCH = nil # RMXP Switch to permit flight (nil if unused)
SPD_INCREASE = 1 # Speed Increase when flying
# --------------------------------------------------------------------------
# Map Dangerous Terrain Tags
# (Array set allowing player death if falls into terrains)
# (Set of arrays: 1st value, map, 2nd,3rd,..9th are terrain tags)
# EX: TAG = [ [1,2,3], [2,2,4], [3,1] ]
# First array is map 1, terrain tags 2 and 3 being dangerous
# Second array is map 2, terrain tags 2 and 4 being dangerous
# Third array is map 3, only terrain tag 1 is dangerous
# ==================================================
DANGER_TAG = [[1,1]]
# --------------------------------------------------------------------------
# Map Dangerous Terrain Tags Common Event
# (Common event performed if player loses flight over
# specified dangerous terrain tag.)
# Ignored if set to nil and performs no action.
# ==================================================
DANGER_EVENT = 2
# --------------------------------------------------------------------------
# Flight Requirements
# (Arrays of 'things' that allow flight)
# ==================================================
HEROES = [] # Arrays of heroes that fly automatically
ARMORS = [1] # Arrays of armor by ID that permit flight
SKILLS = [] # Arrays of skills by ID that permit flight
STATUS = [3] # Arrays of status effects that permit flight
# --------------------------------------------------------------------------
end
#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias flying_initialize initialize
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :flying # flying flag
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Perform the original call
flying_initialize
# Add value
@flying = false
end
end
#==============================================================================
# ** 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
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias flying_setup setup
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :flight_disabled # If flight not allowed on map
#--------------------------------------------------------------------------
# * Setup
# map_id : map ID
#--------------------------------------------------------------------------
def setup(map_id)
# Perform the original call
flying_setup(map_id)
# Add values
@flight_disabled = false
@flight_disabled = true if DerVV_Flight::NO_FLY_MAPS.include?(map_id)
end
end
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
# This class deals with events. It handles functions including event page
# switching via condition determinants, and running parallel process events.
# It's used within the Game_Map class.
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias flying_over_trigger? over_trigger?
#--------------------------------------------------------------------------
# * Object Initialization
# map_id : map ID
# event : event (RPG::Event)
#--------------------------------------------------------------------------
def always_on_top
@always_on_top
end
#--------------------------------------------------------------------------
# * Determine if Over Trigger
# (whether or not same position is starting condition)
#--------------------------------------------------------------------------
def over_trigger?
return true if $game_system.flying && !@always_on_top
return flying_over_trigger?
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
#--------------------------------------------------------------------------
alias flying_update update
#--------------------------------------------------------------------------
# * Passable Determinants
# 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)
# Impassable if coordinates are outside of map
return false unless $game_map.valid?(new_x, new_y)
# Passable if debug mode is ON and ctrl key was pressed
return true if $DEBUG and Input.press?(Input::CTRL)
# Determine if passable or impassable when flying
return passable_flying?(new_x, new_y) if $game_system.flying == true
# Super, or 'default Game_Character' passable method
super
end
#--------------------------------------------------------------------------
# * Passable Event Determinants (Allows flying events to block)
# new_x : next x-coordinate
# new_y : next y-coordinate
#--------------------------------------------------------------------------
def passable_flying?(new_x, new_y)
# Loop all events
for event in $game_map.events.values
# Perform and return event test values
return passable_flying_event_test(new_x, new_y, event)
end
return true
end
#--------------------------------------------------------------------------
# * Passable Event Tests (performed within the loop)
# x : next x-coordinate
# y : next y-coordinate
# event : event tested
#--------------------------------------------------------------------------
def passable_flying_event_test(x,y, event)
# Passable when not colliding with tested event
return true unless event.x == x and event.y == y
# Passable when tested event is intangible
return true if event.through
# For events that have an actual characterset
if event.character_name != ""
# Impassable if always on top (at player's flight level)
return false if event.always_on_top == true
end
# Passable
return true
end
#--------------------------------------------------------------------------
# * Determine landable?
#--------------------------------------------------------------------------
def passable_landing?
return true if $game_map.passable?(@x, @y, 0)
return false
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Perform the original call
flying_update
# Perform trigger conditions
flying_trigger
end
#--------------------------------------------------------------------------
# * Frame Update (when testing flight button trigger)
#--------------------------------------------------------------------------
def flying_trigger
# Get current actor
actor = $game_party.actors[0]
# Prevent if flight not permitted by status ailment
return unless refresh_flight_required_state?(actor, true) == true
# Perform method if actively triggered
refresh_flight if Input.trigger?(DerVV_Flight::TRIGGER)
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh_flight
# Disable/prevent system if not met
return unless refresh_flight_requirement?
return unless refresh_flight_map?
return unless refresh_flight_switches?
# Ensure Flying/Landing passable
return unless passable_landing?
# Toggle flying
$game_system.flying = !$game_system.flying
# Branch on flying
($game_system.flying == true) ? refresh_flying : refresh_walking
end
#--------------------------------------------------------------------------
# * Frame Update (when testing controlled requirements)
#--------------------------------------------------------------------------
def refresh_flight_requirement?
# Disregard and return true if no requirements
return true if DerVV_Flight::SKILLS == [] && DerVV_Flight::ARMORS == [] &&
DerVV_Flight::HEROES == []
# Get current actor
actor = $game_party.actors[0]
# Test individual requirements
return false unless refresh_flight_required_actor?(actor)
return false unless refresh_flight_required_skill?(actor)
return false unless refresh_flight_required_armor?(actor)
return false unless refresh_flight_required_state?(actor)
return true
end
#--------------------------------------------------------------------------
# * Refresh (when testing actor requirements)
# actor : actor
#--------------------------------------------------------------------------
def refresh_flight_required_actor?(actor)
# Flight permitted when values not entered
return true if DerVV_Flight::HEROES == []
# Test for valid flying hero
return true if DerVV_Flight::HEROES.include?(actor.id)
# Update Danger Terrain Tags
refresh_required_danger_ttags
# Return false
return false
end
#--------------------------------------------------------------------------
# * Refresh (when testing skill requirements)
# actor : actor
#--------------------------------------------------------------------------
def refresh_flight_required_skill?(actor)
# Flight permitted when values not entered
return true if DerVV_Flight::SKILLS == []
# Cycle and test skills to determine if valid flight skill learned
for skill in actor.skills
return true if DerVV_Flight::SKILLS.include?(skill)
end
# Update Danger Terrain Tags
refresh_required_danger_ttags
# Return false
return false
end
#--------------------------------------------------------------------------
# * Refresh (when testing armor requirements)
# actor : actor
#--------------------------------------------------------------------------
def refresh_flight_required_armor?(actor)
# Flight permitted when values not entered
return true if DerVV_Flight::ARMORS == []
# Gather Armor (Default armor values)
actor_armor = [ actor.armor1_id, actor.armor2_id,
actor.armor3_id, actor.armor4_id ]
# Cycle and test armors to determine if valid flight armor worn
for armor in actor_armor
return true if DerVV_Flight::ARMORS.include?(armor)
end
# Update Danger Terrain Tags
refresh_required_danger_ttags
# Return false
return false
end
#--------------------------------------------------------------------------
# * Refresh (when testing status effect requirements)
# actor : actor
# test_type : testing if used before triggering flight
#--------------------------------------------------------------------------
def refresh_flight_required_state?(actor, test_type=false)
# Only perform if flying and on flight trigger test
if test_type == true
return true unless $game_system.flying == true
end
# Flight permitted when values not entered
return true if DerVV_Flight::STATUS == []
# Cycle and test states to determine if valid flight state in effect
for state in actor.states
return true if DerVV_Flight::STATUS.include?(state)
end
# Toggle flying
$game_system.flying = false
# Update Danger Terrain Tags
refresh_required_danger_ttags
# Branch on flying if testing before flight trigger
refresh_walking if test_type == true
return false
end
#--------------------------------------------------------------------------
# * Refresh (forcing determination of terrain tag danger effect)
#--------------------------------------------------------------------------
def refresh_required_danger_ttags
# Exit if danger tags set to nil
return if DerVV_Flight::DANGER_TAG.nil?
# Exit if danger tags empty
return if DerVV_Flight::DANGER_TAG == []
tag = []
# Cycle through terrain tag array
for ttags in DerVV_Flight::DANGER_TAG
# Grab terrain tag set for current map
tag = ttags.dup if ttags[0] == $game_map.map_id
end
# Delete map ID value from supplied set
tag.delete_at(0)
# Return if empty set
return if tag == []
# Get player's current terrain tag
ter_tag = $game_map.terrain_tag(@x, @y)
# If player's terrain tag is a danger tag
if tag.include?(ter_tag)
# Unless there is no danger common event to play
unless DerVV_Flight::DANGER_EVENT.nil?
# Unless the danger common event is set to 0
unless DerVV_Flight::DANGER_EVENT == 0
# Perform the common event
$game_temp.common_event_id = DerVV_Flight::DANGER_EVENT
end
end
end
end
#--------------------------------------------------------------------------
# * Refresh (when testing map condition)
#--------------------------------------------------------------------------
def refresh_flight_map?
# Flight not permitted on map, force ensure no flight
if $game_map.flight_disabled == true
refresh_flying_disable
return false
end
return true
end
#--------------------------------------------------------------------------
# * Refresh (when testing switch condition)
#--------------------------------------------------------------------------
def refresh_flight_switches?
# Nil value assumes always active
return true if DerVV_Flight::ON_SWITCH.nil?
# Flight not permitted while Switch turned off
unless $game_switches[DerVV_Flight::ON_SWITCH] == true
refresh_flying_disable
return false
end
return true
end
#--------------------------------------------------------------------------
# * Refresh (when deactivating flight)
#--------------------------------------------------------------------------
def refresh_flying_disable
return unless $game_system.flying
$game_system.flying = false
refresh_walking
end
#--------------------------------------------------------------------------
# * Refresh Flying State
#--------------------------------------------------------------------------
def refresh_flying
t_charset = $game_party.actors[0].character_name
@character_name = t_charset + DerVV_Flight::SUFFIX
@always_on_top = true
@move_speed += DerVV_Flight::SPD_INCREASE
end
#--------------------------------------------------------------------------
# * Refresh Walking State
#--------------------------------------------------------------------------
def refresh_walking
t_charset = $game_party.actors[0].character_name
@character_name = t_charset
@always_on_top = false
@move_speed -= DerVV_Flight::SPD_INCREASE
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Script Call to take off
#--------------------------------------------------------------------------
def force_takeoff
# Not permitted unless flying is turned off or wrong map
if DerVV_Flight::ON_SWITCH != nil
return unless $game_switches[DerVV_Flight::ON_SWITCH] == true
end
return if $game_map.flight_disabled == true
# Landing values
$game_system.flying = true
$game_player.refresh_flying
end
#--------------------------------------------------------------------------
# * Script Call to force landing
#--------------------------------------------------------------------------
def force_landing
# Not permitted if flying over impassable terrain
return unless $game_player.passable_landing?
# Landing values
$game_system.flying = false
$game_player.refresh_walking
end
end
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias flying_update update
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
flying_update
update_no_fly if $game_map.flight_disabled == true
end
#--------------------------------------------------------------------------
# * Frame Update (Prevent flight, or forced landing if entering no-fly map)
#--------------------------------------------------------------------------
def update_no_fly
return if $game_system.flying == false
$game_system.flying = false
$game_player.refresh_walking
end
end
Instructions
In the script as always.
Compatibility
Fairly compatible for RPGMaker XP systems. However, it does rewrite the Game_Player.passable? method.
Terms and Conditions
Free for use, even in commercial games. And as this script was requested by Melana, you have to give both of us credit for this script.
My bad. Two lines (237 and 330) had flaws, so an upgrade became due.
Line 237 should be:
Code:
if $game_map.flight_disabled == true
Line 330 should be:
Code:
update_no_fly if $game_map.flight_disabled == true
It's ALWAYS the stupid double equals... (==)
HOWEVER.....
This isn't a mere bump, but a bump to
version 1.2.
More work was done, ensuring that you cannot turn flying off (keyboard toggle or script call) while over an impassable tile. And you cannot use a script call to fly if either on a no-fly map or the RMXP switch that allows flight is off. And there was a little more work done so flying events can be activated by the player when flying.
Oh, and yeah.... I forgot to put in that there are two script calls... one that forces flight and one that turns it off.
Thanks, but I'm not done as I just decided to bump this to
version 1.4.
Probably the last (expected) version. You can now specify armor that allows flight, flying heroes, flight skills, and status effects that permit flight. You'd have to work out how status effect are removed when on the map though.
Also, if you DO have a condition like a status effect that allows flight, and suddenly wears off.... There's a new feature called DANGER_TAGs where you can set up different terrain tags that can trigger a common event if you land on one. It is recommended that this common event be used to determine how one 'splashes' down. That's what I did...
I think I will find some cool ways to use all of them in my game. :)
I just noticed that the script overwrites some changes on the actor like the oppacity, movement speed and graphic.
These commands doesn't seem to work anymore. (graphic only when I'm trying it with the one from "Set Move Route". The "Change Actor Graphic" command works)
The movement speed is either going to be the speed of the character walking or flying. You would want a different speed in this case, correct? This is a caveat as increase/decrease by a single value did not work (or haven't attained as yet).
The graphic is what the player looks like when he's flying (including any Superman cape) or not flying (cue the Clark Kent glasses). Fortunately, you DID say you could change it with the 'change actor graphic' command. Why the Set Move Route didn't work... I'll look into.
Insofar as Opacity, that's what the new BUMP TO VERSION 1.5 is for.
Minor change added to the refresh method to store and re-use the player opacity.
It doesn't bother me at all with the movement speed. I just noticed it while testing around with your script.
The oppacity works fine now. :)
I just added 2 lines to let my character have a stop animation while flying to show the wing beats.
The script also works quite well with my caterpillar script. I only had to change a few lines to activate the stop animation also for the caterpillar while flying.
Okay... this one is BOUND to be the last (expected) one.
Improvements made...
I rewrote the main segments within the Game_Player class so it didn't actually touch the Game_Player's refresh method, and handled graphic updates when needed. In the way it is handled, the methods in the 'Set Move Route' commands should now work without issues. But to make a character STICK to a new characterset, the use of the 'Change Actor Graphics' command is still preferred (the replacement graphic in the Move Route method doesn't remain put).
There IS a change to the config system as the character speed isn't going to be fixed anymore. Separate values for normal move speed and flight speed are no longer used. Instead, there is a Speed Increase value so you can set a speed value of 1, and the player moves 1 rank faster than normal.
At the same time, The code was made more modular, broken into smaller and more manageable segments, and its rewrite runs through less commands, and thus should cause less slow-down (if any frame rate slowdown was encountered while used with other scripts).