Interactuable Objects & Proyectile Library
Version: 2.0B
By: MephistoX
Introduction
This script was created to allow the user to create his owns interactuable objects, like proyectiles, enemys, and in the full version pullable, pushable, throwable, switches, and a lot of things.
In this version, you can create proyectiles with custom targets, with predefined behavior or custom behavior.
I think that watching the demo you can see how it's works.
This is not a copy of the XAS, just a library to create objects, light and easy. fully compatible with most of system.
Features
Screenshots
Not neccesary.
Demo
http://www.4shared.com/file/IJANAB0R/In ... cts_2.html
Script
Just the base, for the required scripts, see the demo.
Instructions
Place the script below SDK and MACL and Above Main, read the script header for configuration. See the demo to see how to configure the events.
Feel free to ask how to configure things at other things.
Compatibility
This Script requires MACL 2.3 and 2.4 beta methods included in the demo.
Also requires SephirothSpawn's Event Spawner (Included in the demo)
Also Requires some of my methods (like MACL new methods, included in the demo)
Credits and Thanks
Credits to MephistoX if you use this script.
MACL & SDK team.
SephirothSpawn for EventSpawner, that is the skelleton of this system of course, and for references (bluescope :P)
Author's Notes
For now, the script is in beta, but is fully usable, there are somethings that need a bit of fix, and some new features to add. actually, it's funny because i removed the Pull and push feature, to be included in the full version.
PD: Check action function for now, is a quite messy and ugly, in the final version this will be reescripted for better use.
I'll be waiting for comments of course
Version: 2.0B
By: MephistoX
Introduction
This script was created to allow the user to create his owns interactuable objects, like proyectiles, enemys, and in the full version pullable, pushable, throwable, switches, and a lot of things.
In this version, you can create proyectiles with custom targets, with predefined behavior or custom behavior.
I think that watching the demo you can see how it's works.
This is not a copy of the XAS, just a library to create objects, light and easy. fully compatible with most of system.
Features
- Very Customizable, at the point you can create a lot of objects, even customize the behavior of each object.
- Acts also as a Proyectile Library, not just for RPGS, but for shooters or even an ABS (my plan)
- Much more, believe me.
Screenshots
Not neccesary.
Demo
http://www.4shared.com/file/IJANAB0R/In ... cts_2.html
Script
Just the base, for the required scripts, see the demo.
Code:
#==============================================================================
# ** Interactuable Objects & Object Caster System (BETA)
#------------------------------------------------------------------------------
# MephistoX
# Version 2.0b
# 08/08/2011
# SDK : I, II, III, IV
#------------------------------------------------------------------------------
# * Version History :
#
# Version 1 ---------------------------------------------------- (01/08/2011)
# - Log : First Version Released
# Version 2 ---------------------------------------------------- (08/08/2011)
# - Log : Reescripted Complete System, added new functions
#------------------------------------------------------------------------------
# * Requirements :
#
# Method & Class Library (2.3 +)
# Meph's MACL Additions
# Sephirothspawn's Event Spawner 2.2
#------------------------------------------------------------------------------
# * Description :
#
# This script was created to allow the developers to create interactuable
# map objects, like pushable, pullable, holdable, ..ables.
# Also includes a library to create proyectiles and dinamic objects,
# specially to create an ABS custom system or a shooter.
#
# The systems are very customizable, at the point you can create a lot of
# differents objects, and determine the behavior of them.
#------------------------------------------------------------------------------
# * Instructions :
#
# Place The Script Below the SDK and Above Main.
# Refer to module to configure the system
#
# To Assign an item, to it's configuration in the list of objects,
# you must add a comment command in the event with the following.
#
# Comment: INT::TYPE => object Type
# INT::OBID => object ID
# Creat your custom move route as you wish
#
#
# To create an object in the map, use:
#
# Comment: INT::TYPE => ROCK (type)
# INT::LIFE => 10
# INT::DESTROY => A, B, C D || ERASE
# INT::CUSTOM => If custom behavior allowed
#
#------------------------------------------------------------------------------
# * To do List :
#
# - Pull & Push Merge
# - Grab, put and throw events
# - Use SE, Use Requirements, new special types.
# - Reestructure destroy algorithm
#==============================================================================
#------------------------------------------------------------------------------
# * SDK Log Script
#------------------------------------------------------------------------------
SDK.log('Interactuable Objects', 'MephistoX', 2.0, '08/08/2011')
SDK.check_requirements(2.4, [], {'Method & Class Library' => 2.3})
#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if SDK.enabled?('Interactuable Objects')
#==============================================================================
# ** Interactuable Objects Module
# - The module contains all the created proyectiles and objects
# Refer to each header to check the configuration
#==============================================================================
module Interactuable_Objects
#--------------------------------------------------------------------------
# * Defined Objects Map
# - Map where the objects will copied (Objects_Map = ID)
#--------------------------------------------------------------------------
Objects_Map = 1
#--------------------------------------------------------------------------
# * Types, Objects & IDs
# This Keep the list of objects types, feel free to create your own
# type of object. The type is just a way to store the kind, and to use
# in the proyectile or behavior of the map objects.
# ** As a suggestion, use the simple way to create hashes to not mess
# your list of objects.
# Types = {}
# Types['YOURTYPE'] => {}
# Types['YOURTYPE'][ID] => {'Parameter => value}
#
# * Parameters (all capitalized)
# - TAG : Tag or name of your object
# - OBJECT : Id of the event in the objects map, to copy.
# - TARGET : Where should be the target of your object. [Type, range]
# Options => AROUND, UNDER, FRONT, BEHIND (Range for around)
# - AFFECT : List of affected objects, there is no list of objects,
# you just assign them to your events.
# - MAPS : Array of map ids in wich you can use the objects
# - LIMIT : Limit of objects that you can spawn at once, just the
# player has this limitation, other events that cast, no.
# - ANIMATION : Animation Displayed on target at the moment of hit
# - DAMAGE : Damage dealed for the target
# - COOLDOWN : Cooldown before casting the same object again (just player)
# - WAIT : seconds to wait before delete the casted object
# - NOINSTANT : The object will affect the target at the end.
# - CLOSER : Determine how many 'passable' tiles must be free to cast
# - STOP : Should the caster be stopped to cast?
# - AFCASTER : If the object affect caster or not (bombs, rays, etc)
# - MDIR : Maintain object assigned dir, or change to caster
# - SPOT : Where's the object will be casted (ON, RANGED)
# - ESPECIAL : My predefined custom special objects (THROWABLE, etc).
#
# Required parameters are TAG, TARGET and AFFECT, others are optional.
#
# * Examples of use and type of object for parameters
# Types['SKILLS'][1] => {'TAG' => 'MYTAG',
# 'OBJECT' => 11,
# 'MAPS' => [ 2, 4]
# 'TARGET' => ['FRONT', 0],
# 'AFFECT' => ['ROCK', 'ROCK1', 'ENEMY']
# 'LIMIT' => 10
# 'ANIMATION' => 5
# 'DAMAGE' => 5
# 'COOLDOWN' => 4
# 'WAIT' => 3
# 'NOINSTANT' => true (only if used)
# 'CLOSER' => 3
# 'STOP' => true
# 'AFCASTER' => true
# 'MDIR' => true
# 'SPOT' => ['ON, 0] # ON, RANGED
# 'SPECIAL' => ['THROW', 3]
#
# ** Throw should be used with spot 'ON'
#--------------------------------------------------------------------------
Types = {}
#--------------------------------------------------------------------------
# * CREATED SKILLS
#--------------------------------------------------------------------------
Types['SKILLS'] = {}
Types['SKILLS'][1] = {'TAG' => '[ARROW_1]',
'OBJECT' => 1,
'TARGET' => ['FRONT', 0],
'AFFECT' => ['ROCK', 'HOOK', 'ENEMY'],
'LIMIT' => 1,
'ANIMATION' => 11,
'DAMAGE' => 1,
'CLOSER' => 2}
Types['SKILLS'][2] = {'TAG' => '[BOMB]',
'OBJECT' => 5,
'TARGET' => ['AROUND', 5],
'AFFECT' => ['ROCK', 'ENEMY'],
'LIMIT' => 1,
'ANIMATION' => 30,
'DAMAGE' => 10,
'NOINSTANT' => true,
'WAIT' => 3,
'MDIR' => true,
'CLOSER' => 1,
'AFCASTER' => false}
Types['SKILLS'][3] = {'TAG' => '[INDIANA]',
'OBJECT' => 2,
'TARGET' => ['FRONT', 0],
'AFFECT' => ['ROCK'],
'LIMIT' => 1,
'ANIMATION' => 65,
'DAMAGE' => 1,
'CLOSER' => 3}
Types['SKILLS'][4] = {'TAG' => '[ACCORN]',
'SPECIAL' => ['THROW', 3],
'OBJECT' => 3,
'TARGET' => ['UNDER', 0],
'AFFECT' => ['ROCK'],
'LIMIT' => 2,
'ANIMATION' => 4,
'DAMAGE' => 1,
'SPOT' => ['ON', 0]}
Types['SKILLS'][5] = {'TAG' => '[THUNDER]',
'OBJECT' => 4,
'TARGET' => ['AROUND', 2],
'AFFECT' => ['ROCK'],
'LIMIT' => 10,
'ANIMATION' => 33,
'DAMAGE' => 1,
'SPOT' => ['ON',0],
'WAIT' => 2,
'AFCASTER' => false}
#--------------------------------------------------------------------------
# * Non Proyectil
# - The types that aren't proyectil.
# Remember to add your types in move here, becase if not, this will
# Cause a crash.
#--------------------------------------------------------------------------
Non_Proyectil = ['ENEMY', 'ROCK']
#--------------------------------------------------------------------------
# * Create Object : Creates an object in the map (Use EventSpawner)
# caster_id : ID of the caster (event or player)
# type : object type (See created types)
# id : ID of the object type
#--------------------------------------------------------------------------
def self.create_object(caster_id, type, id)
# Get Caster
caster = caster_id == 0 ? $game_player : $game_map.events[caster_id]
# Get Object
object = Types[type][id]
# Do noting if interpreter is running, spawner is moving or invalid sector
return if ($game_system.map_interpreter.running? ||
!$game_map.valid?(*caster.tile_front) || object.nil?)
# Check if item has stop parameter
if object.member?('STOP')
# Return if caster is moving
return if caster.moving?
end
# If Maps list is defined
if object.member?('MAPS')
# Check if current map is included and allow to spawn if true
return unless object['MAPS'].include?($game_map.map_id)
end
# If CLOSER range is defined
if object.member?('CLOSER')
# Calculate Closer for distance
closer_xy = caster.tile_front(object['CLOSER'])
# Return if map coordinate is invalid or events are in range
return if (!$game_map.valid?(*closer_xy) ||
!caster.objects_front(object['CLOSER']).empty?)
end
# Check if cooldown defined
if object.member?('COOLDOWN')
# Return if caster is game_player & cooldown is not over
return if (caster == (gp = $game_player) &&
gp.cooldowns.member?(object['TAG']) && gp.cooldowns[object['TAG']] > 0)
end
# Create subname to add to main tag
subname = caster == $game_player ? 'PX' : caster.id.to_s
# Create Name
name = object['TAG'] + subname
# Get Number of Thrown objects in the map
objects_number = $game_map.events_with_name(name)
# Get objects in map limit
objects_limit = object.member?('LIMIT') ? object['LIMIT'] : 1
# Return if Thrown object limit is greater or equal to limit
return if objects_number >= objects_limit && caster == $game_player
# Check of Spot defined
if object.member?('SPOT')
# Get Start Coordinates
case object['SPOT'][0]
# If ON
when 'ON'
# Start Coordinate is on caster
ox, oy = caster.tile_on
# When RANGED
when 'RANGED'
# Start coordinate is in a distance in front of the caster
ox, oy = caster.tile_front(object['SPOT'][1])
end
# If not spot defined
else
# Start point is in front of the caster
ox, oy = caster.tile_front
end
# Get the map ID for copying the objects
map_id = object.member?('MAPID') ? object['MAPID'] : Objects_Map
# Begin Event_Spawner algorithm
Event_Spawner.clone_event2(map_id, object['OBJECT'], ox, oy, name)
# Check if direction is mantain, if not, set caster direction
unless object.member?('MDIR')
Event_Spawner.set_page_graphic({'dir' => caster.direction})
end
# End Event Spawner algorithm
Event_Spawner.end_event
# If Cooldown is defined
if object.member?('COOLDOWN') && caster == $game_player
# Set Cooldown
$game_player.cooldowns[object['TAG']] = object['COOLDOWN']
end
# Get Self ID
seid = $game_map.event_with_name(object['TAG']).last
# Get map_object
map_object = $game_map.events[seid]
# Set caster for the object
map_object.object_attributes.caster = caster
# If Wait Defined
if object.member?('WAIT')
# Set Object Wait
map_object.object_attributes.time_counter = object['WAIT']
end
# Check if the Object is a special type
if object.member?('SPECIAL')
# Check the type of special object
case object['SPECIAL'][0]
# When Throwable
when 'THROW'
# Throw Object effect
map_object.throw_object(object['SPECIAL'][1])
# Reserved for special
when 'RESERVED'
end
end
end
#--------------------------------------------------------------------------
# * Do Action : Evaluates and process a defined action in the target
# target : target of the action
# object : object type (See created types)
#--------------------------------------------------------------------------
def self.do_action(target, object)
# Get target parameters
if target == $game_player
target.animation_id = object['ANIMATION']
$game_party.actors[0].hp -= object['DAMAGE']
else
target.animation_id = object['ANIMATION']
target.object_attributes.life -= object['DAMAGE']
end
target.damage = object['DAMAGE']
target.damage_pop = true
return if target == $game_player
if target.object_attributes.life <= 0
dk = target.object_attributes.destroy_kind
target.erase if dk == 'ERASE'
target.turn_switch(dk,true) if dk == 'A' || 'B' || 'C' || 'D'
end
end
end
#==============================================================================
# ** Game_Temp
#==============================================================================
class Game_Temp
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :interactuable_action # Assing interactuable action
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_method :meph_interobj_gtemp_init, :initialize
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Original Initialize
meph_interobj_gtemp_init
# Set interactuable Action
@interactuable_action = nil
end
end
#==============================================================================
# ** Game_Player
#==============================================================================
class Game_Player
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :cooldowns
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_method :meph_interobj_gplay_init, :initialize
alias_method :meph_interobj_gplay_update, :update
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(*args)
# Original Initialize
meph_interobj_gplay_init(*args)
# Set Cooldowns
@cooldowns = {}
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Orignial Update
meph_interobj_gplay_update
# Update Player Cooldowns
update_cooldowns
end
#--------------------------------------------------------------------------
# * Frame Update : Update Cooldowns
#--------------------------------------------------------------------------
def update_cooldowns
# Do nothing if hash is empty
return if @cooldowns.empty?
# Pass through each cooldown
@cooldowns.each_key do |object|
# Next if cooldown is 0
next if @cooldowns[object] == 0
# Discount 1 if 1 second has pased
if Graphics.frame_count % 40 == 0
@cooldowns[object] -= 1
@cooldowns.delete(object) if @cooldowns[object] == 0
end
end
end
end
#==============================================================================
# ** Interactuable_Objects::Attributes
# - This clase handles the interactuable attributes of the object
#==============================================================================
class Interactuable_Objects::Attributes
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :type
attr_accessor :object_id
attr_accessor :life
attr_accessor :destroy_kind
attr_accessor :caster
attr_accessor :time_counter
attr_accessor :finish_action
attr_accessor :custom_action
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@type = nil
@object_id = nil
@life = 0
@destroy_kind = nil
@caster = nil
@time_counter = 0
@finish_action = false
@custom_action = false
end
end
#==============================================================================
# ** Game_Event
#==============================================================================
class Game_Event
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :move_route
attr_reader :move_route_index
attr_reader :object_attributes
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_method :meph_interobj_gvent_init, :initialize
alias_method :meph_interobj_gevent_movetc, :move_type_custom
alias_method :meph_interobj_gvent_refresh, :refresh
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(*args)
meph_interobj_gvent_init(*args)
end
#--------------------------------------------------------------------------
# * Turn Switch : Turn event local switch
# - Letter = Local Switch Letter
# - state = Bolean
#--------------------------------------------------------------------------
def turn_switch(letter, state)
key = [@map_id, @id, letter]
$game_self_switches[key] = state
$game_map.need_refresh = true
end
#--------------------------------------------------------------------------
# * Show Animation : Show animation on event
#--------------------------------------------------------------------------
def show_animation(animation_id)
@animation_id = animation_id
end
#--------------------------------------------------------------------------
# * Move Type : Custom
#--------------------------------------------------------------------------
def move_type_custom
# Original Update
meph_interobj_gevent_movetc
# Check interaction
check_interaction
end
#--------------------------------------------------------------------------
# * Check Interaction
#--------------------------------------------------------------------------
def check_interaction
# Get attributes
attributes = @object_attributes
# Return if type == nil (Not interactuable object)
return if (attributes.type.nil? ||
Interactuable_Objects::Non_Proyectil.include?(attributes.type))
# Begin Counter Discount
attributes.time_counter -= 1 if (attributes.time_counter != 0 &&
Graphics.frame_count % 40 == 0)
# Get Object to Check
object = Interactuable_Objects::Types[attributes.type][attributes.object_id]
# Get calculate number of left moves (including evals, waits...etc)
left_moves = (@move_route.list.size - 1) - @move_route_index
# If no moves left
if left_moves == 0 && attributes.time_counter == 0
# Delete the object
$game_map.delete_event(@id)
end
# Return if the action is finished or object is nor-instant and there are
# left moves to be processed.
return if (attributes.finish_action ||
object.member?('NOINSTANT') && left_moves > 0)
# Create Targets array
targets = []
# Get Target or Targets
case object['TARGET'][0]
when 'UNDER' ; targets << object_on
# When Front, the target must be in front of the object
when 'FRONT' ; targets << object_front
# When Behind, the target must be in object's behind
when 'BEHIND' ; targets << object_behind
# When Around, the target must be around (range) the object
when 'AROUND' ; targets = objects_around(object['TARGET'][1])
end
# Return if no targets
return if targets.empty?
# Pass through each target in range
targets.each do |target|
# Pass if target is self
next if target == self || target.nil?
# Check if this object affects the caster, and pass if caster is target
next if (object.member?('AFCASTER') && attributes.caster == target)
# Finalize action verifitacion
attributes.finish_action = true
# If there is a target and target is interactuable or target is player
if target && (target == $game_player ||
object['AFFECT'].include?(target.object_attributes.type))
# Check if time counter is 0 (no time_counter defined)
$game_map.delete_event(@id) if attributes.time_counter == 0
Interactuable_Objects.do_action(target, object)
elsif target.object_attributes.custom_action
# Check if time counter is 0 (no time_counter defined)
$game_map.delete_event(@id) if attributes.time_counter == 0
# Set Interactuable action to object tag (to check)
$game_temp.interactuable_action = object['TAG']
# Start the event
target.start
end
# If Object Action is defined
end
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# Original Refresh
meph_interobj_gvent_refresh
# Clear Interactuable Flag
@object_attributes = Interactuable_Objects::Attributes.new
# Return if Erased
return if @erased || @list.nil?
# Pass through event commands
for ec in @list
# Skip if not comment or not comment next line
next unless [108, 408].include?(ec.code)
# Read Event Comment, turn downcase and delete blank spaces
comment = ec.parameters[0]
# If event is interactuable
if comment.include?('INT::TYPE')
# Get Type
object_attributes.type = comment.split(' => ')[1]
next
end
# If include OBID
if comment.include?('INT::OBID')
# Get Object ID
object_attributes.object_id = comment.split(' => ')[1].to_i
next
end
# If Include INT::LIFE (Life, resistance, or whatever)
if comment.include?('INT::LIFE')
# Get Resistance
object_attributes.life = comment.split(' => ')[1].to_i
next
end
# if include INT::DESTROY (Object is destroyable)
if comment.include?('INT::DESTROY')
# Set Destroyable
object_attributes.destroy_kind = comment.split(' => ')[1]
next
end
# if include INT::CUSTOM (Available for custom actions)
if comment.include?('INT::CUSTOM')
# Get erase type
object_attributes.custom_action = true
next
end
end
end
end
#==============================================================================
# ** Interpreter
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
alias_method :meph_interobj_inter_c115, :command_115
#--------------------------------------------------------------------------
# * Exit Event Processing
#--------------------------------------------------------------------------
def command_115
# Set interactuable action to nil
$game_temp.interactuable_action = nil
# Original process
meph_interobj_inter_c115
end
end
#--------------------------------------------------------------------------
# * End SDK Enable Test
#--------------------------------------------------------------------------
end
Instructions
Place the script below SDK and MACL and Above Main, read the script header for configuration. See the demo to see how to configure the events.
Feel free to ask how to configure things at other things.
Compatibility
This Script requires MACL 2.3 and 2.4 beta methods included in the demo.
Also requires SephirothSpawn's Event Spawner (Included in the demo)
Also Requires some of my methods (like MACL new methods, included in the demo)
Credits and Thanks
Credits to MephistoX if you use this script.
MACL & SDK team.
SephirothSpawn for EventSpawner, that is the skelleton of this system of course, and for references (bluescope :P)
Author's Notes
For now, the script is in beta, but is fully usable, there are somethings that need a bit of fix, and some new features to add. actually, it's funny because i removed the Pull and push feature, to be included in the full version.
PD: Check action function for now, is a quite messy and ugly, in the final version this will be reescripted for better use.
I'll be waiting for comments of course