#================================================
#
# Script: EncounterControl
# by: whitesphere (whitesphere@comcast.net)
# September 4 2014
#================================================
=begin
================================================================================
Description: Allows turning specific encounters ON or OFF based on a switch
and allows an encounter to be Friendly (i.e. it will call a Common Event
instead of a battle)
--------------------------------------------------------------------------------
History
v1.0 (2014/09/04)
Initial release
--------------------------------------------------------------------------------
Terms of Use
- You are free to use this script for non-commercial or commercial projects.
- Reported bug will be fixed, but no guarantee on requested features.
- No guarantee either for compatibility fixes.
- Give credit to whitesphere (me), and do not delete this header.
--------------------------------------------------------------------------------
In each Map, add one or more notetags like this:
<encounter troop="35" switch="1" friendly="3">
The "troop" tag defines the Troop ID. This tag as well as at least one of the two other ones below must be present.
If the "switch" tag is present, the troop can only be selected if the specified switch is ON
If the "friendly" tag is present, instead of starting the battle, this script will call the Common Event ID listed.
The above example says "On the current map, enable Troop ID 35 only if Switch 1 is ON. And, when a Random Encounter would produce Troop ID 35, call Common Event 3 instead."
--------------------------------------------------------------------------------
=end
####################################################################
# Module which reads XML formatted note tags and returns them as
# HashMaps
module Tag_reader
###################################################################
# Represents a single XML node
class XML_node
#####################################
# Constructor
def initialize(name)
@name=name
# Set of name=value pairs
@attributes={}
end
###################################
# Adds an attribute
def add_attribute(name, value)
@attributes[name]=value
end
###################################
# Returns this as an XML string
def to_s
result="<"+@name
@attributes.each {
|key, value| result += " "+key+"=\""+value+"\""
}
result += " />\n"
return result
end
attr_reader

name)
attr_reader

attributes)
end
#######################################################
# Reads a set of XML tags
class XML_Reader
def initialize()
@nodes=[]
end
##########################################################
# Reads the XML tags in note_string. Does nothing if the
# note string is empty or nil. Returns the set of nodes read
# from the note_string. This may be empty
def read(note_string)
@nodes.clear
if (note_string == nil)
return @nodes
end
note_s=note_string.to_s.strip
# Ignore empty strings
string_len=note_s.length
if (string_len == 0)
return
end
index=0
worker=""
right_index=0
node_name=""
# Parse the XML string
while (index < string_len)
# Search for < mark
if (note_s[index] != '<')
index += 1
next
end
# Find the > mark after the < mark
right_index=note_s.index("/>",index)
if (right_index == nil)
right_index=note_s.index('>',index)
if (right_index == nil)
break
end
end
# This is a string from < to >
worker=note_s.slice(index, right_index-index+1)
worker=worker.strip
# Find name="value" pairs
# Skip the <name part of the XML
attr_index=worker.index(' ')
node_name=worker.slice(1,attr_index).strip
new_node=XML_node.new(node_name)
while (worker.length > attr_index)
if (worker[attr_index] == ' ')
attr_index += 1
next
end
value_index=worker.index("=\"", attr_index)
if (value_index == nil)
break
end
# Backspace to find the previous space or < mark - start of the
# attribute
attr_start_index=value_index-1
while (worker[attr_start_index] != '<' &&
worker[attr_start_index] != ' ')
attr_start_index -=1
end
# Get to the start of the attribute name
attr_start_index += 1
# Skip the =" marker after attribute name
second_quote=worker.index("\"", value_index+3)
if (second_quote == nil)
break
end
attr=worker.slice(attr_start_index, value_index-attr_index)
value=worker.slice(value_index+2, second_quote-value_index-2)
new_node.add_attribute(attr, value)
attr_index = second_quote+1
end
@nodes << new_node
index=right_index+1
end
return @nodes
end
end
end
#
module EncounterControl
##########################################################################
# CONSTANTS
# Extra information we require
class Extra_data
attr_reader

switch_id)
attr_reader

friendly_event_id)
attr_reader

troop_id)
# The Constructor
def initialize(troop_id, switch_id, friendly_event_id)
@troop_id=troop_id.to_i
@switch_id=nil
@friendly_event_id=nil
if (switch_id != nil)
@switch_id=switch_id.to_i
end
if (friendly_event_id != nil)
@friendly_event_id=friendly_event_id.to_i
end
end
end
# Lists the extra-data for each Troop ID
class Troop_group
def initialize(extra_data_set)
@extra_data={}
if (extra_data_set != nil)
extra_data_set.each {
|entry| @extra_data[entry.troop_id]=entry
}
end
end
def get_extra_data(troop_id)
return @extra_data[troop_id]
end
end
def self.init()
@@troop_group=nil
end
def self.load()
@@troop_group=Troop_group.new($game_map.extra_data_set)
end
def self.get_extra_data(troop_id)
if (@@troop_group == nil)
return nil
end
return @@troop_group.get_extra_data(troop_id)
end
end
# Create the static member
EncounterControl::init()
# Stores the new encounter data
class Game_Map
attr_reader

map_id)
alias EncounterControl_setup setup
def setup(map_id)
EncounterControl_setup(map_id)
# Load the new data
EncounterControl::load()
end
# We fetch these from the RPG::Map method
def extra_data_set
return @map.extra_data_set
end
end
#--------------------------------------------------------------------------
# We override these 2 methods to change the encounter logic
class Game_Player < Game_Character
alias EncounterControl_encounter encounter
alias EncounterControl_encounter_ok? encounter_ok?
#--------------------------------------------------------------------------
# * Check the switch ID if need be
#--------------------------------------------------------------------------
def encounter_ok?(encounter)
extra_data=EncounterControl::get_extra_data(encounter.troop_id)
if (extra_data != nil && extra_data.switch_id != nil &&
$game_switches[extra_data.switch_id] == false)
return false
end
return EncounterControl_encounter_ok?(encounter)
end
# Add the check for friendly events. Can't call the alias because
# the troop id is created within the method.
def encounter
return false if $game_map.interpreter.running?
return false if $game_system.encounter_disabled
return false if @encounter_count > 0
make_encounter_count
troop_id = make_encounter_troop_id
return false unless $data_troops[troop_id]
extra_data=EncounterControl::get_extra_data(troop_id)
if (extra_data != nil && extra_data.friendly_event_id != nil)
$game_temp.reserve_common_event(extra_data.friendly_event_id)
return false
else
BattleManager.setup(troop_id)
BattleManager.on_encounter
return true
end
end
end
class RPG::Map
def read_note_tag_as_nodes
if (@node_set == nil)
reader=Tag_reader::XML_Reader.new
@node_set=reader.read(@note)
end
return @node_set
end
# Returns the current set of special encounter data
def extra_data_set
if (@extra_data_set != nil)
if (@extra_data_set.empty?)
return nil
end
return @extra_data_set
end
@extra_data_set=[]
nodes=read_note_tag_as_nodes
if (nodes == nil)
return nil
end
nodes.each {
|current|
if (current.name != "encounter")
next
end
troop_id=current.attributes["troop"]
switch_id=current.attributes["switch"]
friendly_event_id=current.attributes["friendly"]
if (troop_id == nil)
next
end
if (switch_id == nil && friendly_event_id == nil)
next
end
new_mapping=EncounterControl::Extra_data.new(troop_id, switch_id, friendly_event_id)
@extra_data_set << new_mapping
}
return @extra_data_set
end
end