Encounter Restrictions
Author: modern algebra
Date: August 25, 2007
Version History
- February 5, 2008: Split the two functions of the script into independent scripts. It made sense since they did not rely on one another and the separation not only allows people to use one or the other functions, but makes it easier to configure. Naturally, they are mutually compatible. For the actual scripts:
- Encounters Based on Troop Level - Version 2.1: Made setting troop levels more intuitive and less error prone. Slightly changed code. Otherwise same as 2.0
- Encounter Areas - Version 1.1: More intuitive database, as well as added the option to deactivate areas
- Version 2.5b: Minor modifications to the code. The most important thing was saving the areas in a less wasteful way with broader applications. (I.e. Initialize when necessary, rather then using a partially filled array)
- Version 2.5: Added in an option to set encounter areas, restoring some of the lost functionality of RM 2K3. As well, you can now turn on and off the level differentiating algorithm at will.
- Version 2.0: Rewrote the script for better compatibility, optimization, as well making it easier to implement
- Version 1.1: Minor bug fixes
- Version 1.0: Original Script
Description
The Encounter Level Range Script allows the game maker to give monster troops levels, and then based on those levels, it determines what enemy troops can be attacked by the player at his current level. That is kind of confusing, so I will try to explain a little better by example. The maker can set up a map with possible enemies being Angels, Cherubims, and Seraphims. You can enter this map at any time, and so you want the encounters to reflect what level the hero party is. You don't want the party attacking Seraphims when they are level 1, because they will be crushed, and you don't want them to fight Angels when they are level 99, because it's too easy. Thus, you just set up in the script what levels the enemy troops are, and with this script you will only be able to fight monster troops that are within level range of your heroes.
The Encounter Areas script allows you to set encounter areas. What this means is you can easily set it so that different areas of the map have different enemies. This is especially useful for world maps and the like.
Features
Encounter Level Range- Allows you to set the levels for each monster troop in the database
- Only allows the player to fight monster troops within his level range
- Allows you to set what the range is for every map
Encounter Areas- Allows you to set encounter areas, and only in those areas can specified monsters attack you.
- Allows you to control whether level effects encounters for each map
Instructions
See Scripts for instructions. They are located in the header and in the Editable Region (where you set up troop levels)
Scripts
Encounter Level Range[/list]
#=============================================================
# Encounter Levels Script
# Version: 1.0
# Author: Modern Algebra (rmrk.net)
# Date: February 5, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Instructions:
# Set up the regular map encounter lists (areas included) with all the monsters that
# you ever want to appear in that area or map.
#
# The system basically works by giving monster troops levels and by setting a
# level range within which all encounters must reside. By default, this level range
# is between (Actor's Average Level - 5) and (Actor's Average Level + 5). The
# range can be changed at any time to make certain maps harder or easier by
# using the following code in a call script:
#
# $game_system.min_level = x
# $game_system.max_level = x
#
# Where x is the value you are changing it to.
# Keep in mind that min level, like max level, is added to the party's average level.
# So, if you set $game_system.min_level = 5, then the minimum level of encounters
# would be party's average level + 5, not party's average level - 5.
#
# You can also turn the levelling feature on and off completely at will, using this code:
#
# $game_system.level_boolean = true (to turn it on)
# $game_system.level_boolean = false (to turn it off)
#
# For instructions on setting the troop levels, see the Editable Region at Line 58.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Compatibility:
# It ought to be compatible with any script that does not modify the
# make_encounter_troop_id method of Game_Player (and I can't think of any script
# that would want to besides one like this).
#=============================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# aliased method - initialize
# new instance variables - level_boolean, min_level, max_level
# new method - troop_levels
#=============================================================
class Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :level_boolean # Turns on and off the level range function
attr_accessor :min_level # The lower limit of the encounter range
attr_accessor :max_level # The upper limit of the encounter range
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Retrieve Troop Level
# Adds an Encounter_Area object to the areas array.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def troop_levels (id)
# By default, level = id
level = id
case id
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Editable Region
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Here is where you can set up the levels of each respective troop. As
# you can see below, all you need to do is use this code:
#
# when id; level = X
#
# where id is the ID of the troop and X is the level you want that troop to
# have. I also recommend placing the name of the troop next to them for
# easy editing, so:
#
# when id; level = X # name
#
# If you do not set a level, the troop's level will be assumed to be equal to it's ID
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
when 1; level = 2 # Slime * 2
when 2; level = 5 # Bat * 2
when 3; level = 8 # Bee * 2
when 4; level = 11 # Spider * 3
when 5; level = 13
when 6; level = 14
when 7;
when 8;
when 9;
when 10;
when 11;
when 12;
when 13;
when 14;
when 15;
when 16;
when 17;
when 18;
when 19;
when 20;
when 21;
when 22;
when 23;
when 24;
when 25;
when 26;
when 27;
when 28;
when 29;
when 30;
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * End Editable Region
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
return level
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_encounter_levels_init initialize
def initialize
ma_encounter_levels_init
@min_level = -5
@max_level = 5
@level_boolean = true
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * End Editable Region
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
end
#==============================================================
# ** Game_Player
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# overwritten methods - make_encounter_troop_id
#==============================================================
class Game_Map
#-------------------------------------------------------------------------
# * Encounter List
# returns the encounter list based on party level
#-------------------------------------------------------------------------
alias ma_encounter_level_restrictions_encounter_list encounter_list
def encounter_list
# If level feature active
if $game_system.level_boolean
encounters = []
# Calculate Party Level Average
average_level = 0
$game_party.actors.each {|i| average_level += i.level}
average_level /= $game_party.actors.size
# Set Range
min = [average_level + $game_system.min_level,1].max
max = [average_level + $game_system.max_level,99].min
unless min > max
# Test average agains all troops in the list
ma_encounter_level_restrictions_encounter_list.each {|i|
troop_level = $game_system.troop_levels (i)
# Add to the returning array If troop level within range
encounters.push (i) if troop_level.between? (min, max)
}
end
else
# Return the full encounter list
encounters = ma_encounter_level_restrictions_encounter_list
end
return encounters
end
end
Encounter Areas Script#==============================================================================
# Encounter Area Restriction
# Version: 1.1
# Author: Modern Algebra (rmrk.net)
# Date: February 5, 2008
#------------------------------------------------------------------------------
# Instructions:
# See inside the editable region at line 48 for instructions on setting up
# the database.
# You can also add a new region at any time in the game by using this code
# in a call script:
#
# $game_system.set_area(x, y, width, height, monster troop array, map_id, name)
#
# In order to make it fit, it may be easier to first assign each value to a
# variable, like so:
#
# x = starting x coordinate for area
# y = starting y coordinate for area
# w = width of area
# h = height of area
# t = [1st troop ID, 2nd Troop ID, ...] for all troops in the area
# m = map id to set the new area in
# n = 'name' of area
# $game_system.set_area (x,y,w,h,t,m,n)
#
# If you ever want to disable or enable an area (for instance, if the player
# comes back to the map after a major event and you no longer want him to
# fight the troops held in an old array), then you can use these codes:
#
# $game_system.area(name, map ID).active = true
# $game_system.area(name, map ID).active = true
#
# If you do not specify map ID, then it will be assumed to be the map you
# are currently located on.
#==============================================================================
# *** Encounter_Regions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Stores all pertinent data regarding encounters
#==============================================================================
module Encounter_Regions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Regions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def self.areas
@areas = []
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Editable Region
#----------------------------------------------------------------------
# Set initial areas here. Set them up like this:
#
# self.set_area (x, y, width, height, monster troop array, map_id, name)
#
# In the 1st example area below, we have defined an area at x = 10, y = 6,
# width = 4, height = 5, in the 1st map with monsters 2, 3, and 8 appearing
# in the area. Essentially, this means that on the first map, you can
# encounter monster troops 2, 3 and 8 if the player coordinates are within
# (10-13, 6-10). The name is 'Lies'. If you do not want to give the area
# a name, then merely type in nil.
#
# You can set as many areas as you like for as many maps as you like.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
self.set_area (7, 1, 8, 3, [1,2,3], 1, 'Fence')
self.set_area (0, 12, 11, 7, [4,5], 1, 'Forest')
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * End Editable Region
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return @areas
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Area
# Adds an Encounter_Area object to the areas array.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def self.set_area (x, y, width, height, array, map_id, name = '')
# Initialize array if this is the first map for which there is an area
@areas[map_id] = [] if @areas[map_id].nil?
id = @areas[map_id].size
area = Encounter_Area.new (x, y, width, height, array, map_id, name)
@areas[map_id].push (area)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ** Encounter Area
#--------------------------------------------------------------------------
# The object which represents an area
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Encounter_Area
#----------------------------------------------------------------------
# * Public Instance Variables
#----------------------------------------------------------------------
attr_reader :map_id
attr_reader :rect
attr_reader :monster_troops # The monsters within the troop
attr_reader :name
attr_accessor :active
#----------------------------------------------------------------------
# * Initialize
# Adds a Game_Area object to the array.
#----------------------------------------------------------------------
def initialize (x, y, width, height, array, map_id, name)
@rect = Rect.new (x, y, width, height)
@monster_troops = array
@name = name
@map_id = map_id
@active = true
end
#----------------------------------------------------------------------
# * Within?
# Checks if the position specified is within the area
#----------------------------------------------------------------------
def within? (x, y)
return x.between? (@rect.x, @rect.x + @rect.width - 1) &&
y.between? (@rect.y, @rect.y + @rect.height - 1)
end
#----------------------------------------------------------------------
# * Equals?
# Determine if two Encounter_Area objects are equal
#----------------------------------------------------------------------
def == (other)
return other.map_id == @map_id && other.rect == @rect
end
end
end
#==============================================================================
# ** Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# aliased methods - initialize
# new methods - set_area, update_regions
# new instance variables - regions
#==============================================================================
class Game_System
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_reader :regions # Contains area data
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_encounter_areas_init initialize
def initialize
ma_encounter_areas_init
@regions = []
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set Area
# Adds an Encounter_Area object to the areas array.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def set_area (x, y, width, height, array, name = '', map_id = $game_map.map_id)
area = Encounter_Regions::Encounter_Area.new (x, y, width, height, array, map_id, name)
# If first area in the map, initialize array
@regions[map_id] = [] if @regions[map_id].nil?
@regions[map_id].push (area) unless @regions[map_id].include? (area)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Areas
# Adds an Encounter_Area object to the areas array.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_regions
# For all areas in the database
Encounter_Regions.areas.each {|regions|
next if regions.nil?
regions.each {|area|
# Initialize the array if this is the first area to be set to that map
@regions[area.map_id] = [] if @regions[area.map_id].nil?
# Add the area to the regions if it does not already exist
@regions[area.map_id].push (area) unless @regions.include? (area)
}
}
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Retrieve Area by name and map_id
# map_id : the ID of the map
# name : the name of the area you want
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def area (name = '', map_id = $game_map.map_id)
@regions[map_id].each {|i| return i if i.name == name}
return false
end
end
#==============================================================================
# ** Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Summary of Changes:
# aliased methods - encounter_list
#==============================================================================
class Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Encounter List
# Returns the encounter list, with modifications based on level
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_encounter_areas_encounter_list encounter_list
def encounter_list
# Run original method
encounters = ma_encounter_areas_encounter_list
return encounters if $game_system.regions[@map_id].nil?
# Add monsters from each area the player is within
$game_system.regions[@map_id].each { |area|
next unless area.active
# Add all unique elements from the area to the encounter_list
encounters |= area.monster_troops if area.within? ($game_player.x, $game_player.y)
}
return encounters
end
end
#======================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
# Summary of Changes:
# aliased method - main
#======================================================================
class Scene_Title
alias ma_encounter_regions_main_update main
def main
# Run original method
ma_encounter_regions_main_update
# Merge new database entries with the game areas
$game_system.update_regions
end
end
Credit
Support
I will fix all bugs that arise with the script, as well as make it compatible with other scripts if any compatibility issues arise. I will provide support on RMRK, and anywhere else I post this, but I will most swiftly respond if you post your question on RMRK.
Known Compatibility Issues
N/A so far
Demo
Demo Attached
Author's Notes
This script is posted at RMRK and RMRevolution. If you see it anywhere else, please notify me. If you want to post it somewhere else, just ask