#==============================================================================
# ** Encounter Control
#------------------------------------------------------------------------------
# SephirothSpawn
# Version 2.1
# 2007-07-30
# SDK : Version 2.0+, Part I
#------------------------------------------------------------------------------
# * Version History :
#
# Version 1 ---------------------------------------------------- (2006-08-12)
# Version 1.01 ------------------------------------------------ (2006-10-23)
# - Bug Fix : Fixed Erase Event
# Version 2 ---------------------------------------------------- (2007-03-16)
# - Update : Updated Entire Code
# Version 2.1 ------------------------------------------------- (2007-07-30)
# - Update : Added Conditionals for battle to begin.
# Added Weather Encounters.
#------------------------------------------------------------------------------
# * Requirements :
#
# Method & Class Library (2.1+)
#------------------------------------------------------------------------------
# * Description :
#
# This script was designed to give you more control of random encounters.
# Encounter Control allows you give terrain tags, circular regions and
# rectangular regions groups of enemies, instead of just map encounters.
# Additionally, it allows you to view in the debugger the regions on the map.
# You may now also let weather patterns effect encounters as well.
#
# As a bonus, you can make it so certain conditions have to true before
# encounters can happen.
#------------------------------------------------------------------------------
# * Instructions :
#
# Place The Script Below the SDK and Above Main.
#
# Creating Encounter Regions with Events
# - Comment : Enc Ctrl <type>(<params>) [<troops>]
#
# <type> : CIRC or RECT
# <params> : When CIRC : X, Y, Radius
# When Rect : X, Y, Width, Height
# <troops> : troop_id, ...
#------------------------------------------------------------------------------
# * Customization :
#
# Direct Encounter Regions
#
# Direct_Regions = {
# map_id => { [x, y] => [troop_id, ...], ... },
# ...
# }
# Rectangle Encounter Regions
#
# Rect_Regions = {
# map_id => { [x, y, width, height] => [troop_id, ...], ... },
# ...
# }
# Circle Encounter Regions
#
# Circ_Regions = {
# map_id => { [x, y, radius] => [troop_id, ...], ... },
# ...
# }
# Terrain Encounter Regions
#
# Tern_Regions = {
# map_id => { terrain_tag => [troop_id, ...], ... },
# ...
# }
# Weather Encounter
#
# Weather_Encs = {
# map_id => { weather_id => [troop_id, ...], ... },
# ...
# }
#------------------------------------------------------------------------------
# * Syntax :
#
# * Changing Encounter Conditions (Must be met to encounter)
#
# Changing Terraisn you must be on
# - $game_system.enc_conditions.terrains = [terrain_id, ...]
#
# Changing Required Weathers
# - $game_system.enc_conditions.weathers = [weather_type, ...]
#
# Variable Conditions where 1 must be met
# - $game_system.enc_conditions.variables_one = { variable_id => [x], ...}
#
# [x] = [<operator>, n]
#
# <operator> : 0 - <, 1 - <=, 2 - ==, 3 - >=, 4 - >
#
# Variable Conditions where all must be met
# - $game_system.enc_conditions.variables_all = { variable_id => [x], ...}
#
# [x] = [<operator>, n]
#
# <operator> : 0 - <, 1 - <=, 2 - ==, 3 - >=, 4 - >
#
# Switch Conditions where 1 must be met
# - $game_system.enc_conditions.switches_one = { switch_id => <bool>, ...}
#
# <bool> : true or false
#
# Switch Conditions where all must be met
# - $game_system.enc_conditions.switches_all = { switch_id => <bool>, ...}
#
# <bool> : true or false
#
# Switch Condition where script must be evaluated as true
# - $game_system.enc_conditions.call_script = 'code' or nil
#==============================================================================
#------------------------------------------------------------------------------
# * SDK Log Script
#------------------------------------------------------------------------------
SDK.log('Encounter Control', 'SephirothSpawn', 2.1, '2007-07-30')
SDK.check_requirements(2, [], {'Method & Class Library' => 2.1})
#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if SDK.enabled?('Encounter Control')
#==============================================================================
# ** Ecounter Control
#==============================================================================
module Encounter_Control
#--------------------------------------------------------------------------
# * Drct Encounter Regions
#
# Direct_Regions = {
# map_id => { [x, y] => [troop_id, ...], ... },
# ...
# }
#--------------------------------------------------------------------------
# * Rect Encounter Regions
#
# Rect_Regions = {
# map_id => { [x, y, width, height] => [troop_id, ...], ... },
# ...
# }
#--------------------------------------------------------------------------
# * Circle Encounter Regions
#
# Circ_Regions = {
# map_id => { [x, y, radius] => [troop_id, ...], ... },
# ...
# }
#--------------------------------------------------------------------------
# * Terrain Encounter Regions
#
# Tern_Regions = {
# map_id => { terrain_tag => [troop_id, ...], ... },
# ...
# }
#--------------------------------------------------------------------------
# * Weather Encounter
#
# Weather_Encs = {
# map_id => { weather_id => [troop_id, ...], ... },
# ...
# }
#--------------------------------------------------------------------------
Drct_Regions = {}
Rect_Regions = {}
Circ_Regions = {}
Tern_Regions = {}
Weather_Encs = {}
# Defaults For All Non-Defined Maps
Drct_Regions.default = {}
Rect_Regions.default = {}
Circ_Regions.default = {}
Tern_Regions.default = {}
Weather_Encs.default = {}
#==========================================================================
# ** Encounter Conditionals
#==========================================================================
class Encounter_Conditionals
#------------------------------------------------------------------------
# * Public Instance Variables
#------------------------------------------------------------------------
attr_accessor :terrains
attr_accessor :weathers
attr_accessor :variables_one
attr_accessor :variables_all
attr_accessor :switches_one
attr_accessor :switches_all
attr_accessor :call_script
#------------------------------------------------------------------------
# * Object Initialization
#------------------------------------------------------------------------
def initialize
@terrains = []
@weathers = []
@variables_one = {}
@variables_all = {}
@switches_one = {}
@switches_all = {}
@call_script = nil
end
#------------------------------------------------------------------------
# * Can Encounter? Test
#------------------------------------------------------------------------
def can_encounter?
# Return False Unless Terrains Include Current Player Terrain
return false unless @terrains.include?($game_player.terrain_tag)
# Return False Unless Weathers Include Current Weather Type
return false unless @weathers.include?($game_screen.weather_type)
# Return False Unless Variables One Set
return false unless v1?
# Return False Unless Variables All Set
return false unless va?
# Return False Unless Switches One set
return false unless s1?
# Return False Unless Switches All Set
return false unless sa?
# If Nil Call Script
if @call_script.nil?
# Return True
return true
end
# Return Inverse Of Call Script Result
return !(eval @call_script)
end
#------------------------------------------------------------------------
# * Variables One? Test
#------------------------------------------------------------------------
def v1?
@variables_one.each do |variable_id, parameters|
case parameters[0]
when 0
return true if $game_variables[variable_id] < parameters[1]
when 1
return true if $game_variables[variable_id] <= parameters[1]
when 2
return true if $game_variables[variable_id] == parameters[1]
when 3
return true if $game_variables[variable_id] >= parameters[1]
when 4
return true if $game_variables[variable_id] > parameters[1]
end
end
return false
end
#------------------------------------------------------------------------
# * Variables All? Test
#------------------------------------------------------------------------
def va?
@variables_one.each do |variable_id, parameters|
case parameters[0]
when 0
return false unless $game_variables[variable_id] < parameters[1]
when 1
return false unless $game_variables[variable_id] <= parameters[1]
when 2
return false unless $game_variables[variable_id] == parameters[1]
when 3
return false unless $game_variables[variable_id] >= parameters[1]
when 4
return false unless $game_variables[variable_id] > parameters[1]
end
end
return true
end
#------------------------------------------------------------------------
# * Switches One? Test
#------------------------------------------------------------------------
def so?
@switches.each do |switch_id, boolean|
return true if $game_switches[switch_id] == boolean
end
return false
end
#------------------------------------------------------------------------
# * Switches All? Test
#------------------------------------------------------------------------
def sa?
@switches.each do |switch_id, boolean|
return false unless $game_switches[switch_id] == boolean
end
return true
end
end
#--------------------------------------------------------------------------
# * Check For Encounter Regions
#--------------------------------------------------------------------------
def self.encounters(x, y, map_id = $game_map.map_id)
# Loads Search Data
searches = self.load_searches
# Key
key = [map_id, x, y]
# If Search Holds Information
if searches.has_key?(key)
# Load Search Info
encounters = searches[key]
# If No Search Info Recorded
else
# Starts Encounters
encounters = []
# Checks Direct Locations
Drct_Regions[map_id].each do |xy, troops|
encounters << troops if x == xy[0] && y == xy[0]
end
# Checks Rect Regions
Rect_Regions[map_id].each do |xywh, troops|
x1, y1 = xywh[0], xywh[1]
x2, y2 = x1 + xywh[2], y1 + xywh[3]
encounters << troops if x >= x1 && x <= x2 && y >= y1 && y <= y2
end
# Checks Circular Regions
Circ_Regions[map_id].each do |xyr, troops|
_x, _y, r = xyr[0], xyr[1], xyr[2]
x_, y_ = (_x - x) ** 2, (_y - y) ** 2
encounters << troops if (x + y) <= (r ** 2)
end
# Checks Terrain Regions
Tern_Regions[map_id].each do |terrain, troops|
encounters << troops if $game_map.terrain_tag(x, y) == terrain
end
# Save Encounters
self.save_searches(key, encounters)
end
# Check Weather Encounters
Weather_Encs[map_id].each do |weather_id, troops|
encounters << troops if $game_system.weather_type == weather_id
end
# Organize Encounter
encounters.flatten!
encounters.uniq!
encounters.sort!
# Return Encounters
return encounters
end
#--------------------------------------------------------------------------
# * Save Encounter Searches
#--------------------------------------------------------------------------
def self.save_searches(key, result)
# Collects Saved Searches
searches = self.load_searches
# Saves Search Result
searches[key] = result
# Resaves Searches to File
save_data(searches, 'Data/Encounter Region Searches.rxdata')
end
#--------------------------------------------------------------------------
# * Load Encounter Searches
#--------------------------------------------------------------------------
def self.load_searches
# Test For Saved Searches File
unless FileTest.exist?('Data/Encounter Region Searches.rxdata')
# Creates Search Rxdata File
save_data({}, 'Data/Encounter Region Searches.rxdata')
return {}
end
# Returns Searches
return load_data('Data/Encounter Region Searches.rxdata')
end
end
#==============================================================================
# ** Game_System
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :enc_conditions
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias_method :seph_enccontrol_gmsys_init, :initialize
alias_method :seph_enccontrol_gmsys_encd, :encounter_disabled
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Original Initialization
seph_enccontrol_gmsys_init
# Create Enccounter Conditions
@enc_conditions = Encounter_Control::Encounter_Conditionals.new
end
#--------------------------------------------------------------------------
# * Encounter Disabled
#--------------------------------------------------------------------------
def encounter_disabled
# Return True if Original True
return true if seph_enccontrol_gmsys_encd
# Return Can Encounter
return !@enc_conditions.can_encounter?
end
end
#==============================================================================
# ** Game_Event
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias_method :seph_enccontrol_gmevt_refresh, :refresh
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# Original Refresh
seph_enccontrol_gmevt_refresh
# Clear Encounter Areas
@circle_encounter_areas, @rect_encounter_areas = {}, {}
# Return if No List or Erased
return if @list.nil? || @erased
# Pass Through Event Commands
for ec in @list
# Skip If Not Comment Line
next unless [108, 408].include?(ec.code)
# Next If Not Comment Doesn't Include ENC CTRL
next unless ec.parameters[0].upcase.include?('ENC CTRL')
# Collect Troop List For Area
ec.parameters[0].dup.gsub(/\[(.+?)\]/, '')
troops = $1.split.collect! {|x| x.to_i}
# Test For Circular Range
if ec.parameters[0].upcase.include?('CIRC')
ec.parameters[0].dup.gsub(/\((.+?)\)/, '')
unless $1.nil?
circ = eval "[#{$1}]"
# Stores Enc List
@circle_encounter_areas[circ] = troops
end
end
# Test For Rect Boundaries
if ec.parameters[0].upcase.include?('RECT')
ec.parameters[0].dup.gsub(/\((.+?)\)/, '')
unless $1.nil?
rect = eval "[#{$1}]"
# Stores Enc List
@rect_encounter_areas[rect] = troops
end
end
end
end
#--------------------------------------------------------------------------
# * Circle Encounter Areas
#--------------------------------------------------------------------------
def seph_circle_enconter_areas
return @circle_encounter_areas
end
#--------------------------------------------------------------------------
# * Rect Encounter Areas
#--------------------------------------------------------------------------
def seph_rect_encounter_areas
return @rect_encounter_areas
end
end
#==============================================================================
# ** Game_Map
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :include_map_encounters
attr_accessor :include_ec_encoutners
attr_accessor :include_event_encounters
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias_method :seph_enccntrl_gmmap_in, :initialize
alias_method :seph_enccntrl_gmmap_el, :encounter_list
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Encounter Control Variable Initialization
@include_map_encounters = true
@include_ec_encounters = true
@include_event_encounters = true
# Original Initialization
seph_enccntrl_gmmap_in
end
#--------------------------------------------------------------------------
# * Get Encounter List
#--------------------------------------------------------------------------
def encounter_list
# Create Blank List
list = []
# Add Default Encounter List if Map Encounters on
list << seph_enccntrl_gmmap_el if @include_map_encounters
# Add Encounter Countrol List if EC on
x, y = $game_player.x, $game_player.y
list << Encounter_Control.encounters(x, y) if @include_ec_encounters
# Add Event Encounter List if Event Encounters on
list << event_encounters_list
# Return Organized List
return list.flatten.uniq.sort
end
#--------------------------------------------------------------------------
# * Get Event Encounter List
#--------------------------------------------------------------------------
def event_encounters_list
# Return Empty List if Turned Off
return [] unless @include_event_encounters
# Create List
list = []
# Gets Player X & Y
px, py = $game_player.x, $game_player.y
# Pass Through All Events
for event in @events.values
# Checks Circular Ranges Of Event
event.seph_circle_enconter_areas.each do |xyr, l|
list << l if VR.in_range?(px, py, xyr[0], xyr[1], xyr[2])
end
# Checks Rect Ranges of Event
event.seph_rect_encounter_areas.each do |r, l|
list << l if VR.in_rect_range?(px, py, r[0], r[1], r[2], r[3])
end
end
# Return Encounter List
return list
end
end
#==============================================================================
# ** Spriteset_Map
#==============================================================================
if $DEBUG
class Spriteset_Map
#--------------------------------------------------------------------------
# * Alias Listings
#--------------------------------------------------------------------------
alias seph_encctrl_gmmap_init initialize
alias seph_encctrl_gmmap_update update
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Original Initialization
seph_encctrl_gmmap_init
# Creates Flash Data Table & Flash Tile Flag
if @tilemap.flash_data.nil?
@tilemap.flash_data = Table.new($game_map.width, $game_map.height)
end
@seph_encctrl_tilesflashing = false
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Original Update
seph_encctrl_gmmap_update
# If A Button Is Pressed
if Input.trigger?(Input::A)
# If Tiles Flashing
if @seph_encctrl_tilesflashing
# Unflashes All Map Tiles
for x in 0...$game_map.width
for y in 0...$game_map.height
@tilemap.flash_data[x, y] = 0
end
end
# Turns Flashing Flag Off
@seph_encctrl_tilesflashing = false
# Clear Used Colors List
@flashtile_colors.clear
# If Tiles Not Flashing
else
# Sets Up Colors Array (To Prevent Matching Colors
@flashtile_colors = []
# Checks All Events
for event in $game_map.events.values
# Flashes All Circular Ranges
event.seph_circle_enconter_areas.keys.each do |xyr|
seph_flash_circular_range(xyr)
end
# Flashes All Rect Ranges
event.seph_rect_encounter_areas.keys.each do |rect|
seph_flash_rect_range(rect)
end
# Turns Flashing Flag On
@seph_encctrl_tilesflashing = true
end
end
end
end
#--------------------------------------------------------------------------
# * Flash Circular Range
#--------------------------------------------------------------------------
def seph_flash_circular_range(xyr)
# Gets Flash Color
c = get_random_color while c.nil? || @flashtile_colors.include?(c)
# Gets Circle Parameters
x, y, r = *xyr
# Flashes Tiles Within Range
for i in (x - r)..(x + r)
sa = (x - i).abs
x_ = i < x ? x - sa : i == x ? x : x + sa
y_ = Integer((r ** 2 - sa ** 2) ** 0.5)
for j in (y - y_)..(y + y_)
@tilemap.flash_data[i, j] = c
end
end
end
#--------------------------------------------------------------------------
# * Flash Rect Range
#--------------------------------------------------------------------------
def seph_flash_rect_range(rect)
# Gets Flash Color
c = get_random_color while c.nil? || @flashtile_colors.include?(c)
# Gets Rect Parameters
for x in 0...rect[2]
for y in 0...rect[3]
@tilemap.flash_data[rect[0] + x, rect[1] + y] = c
end
end
end
#--------------------------------------------------------------------------
# * Get Random Color
#--------------------------------------------------------------------------
def get_random_color
# Generate Random Colors
r, g, b = rand(18) * 15, rand(18) * 15, rand(18) * 15
# Return Hex Format
return eval "0x#{(r * 100 + g * 10 + b).to_s(16)}"
end
end
end
#--------------------------------------------------------------------------
# * End SDK Enable Test
#--------------------------------------------------------------------------
end