Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- # Give NPCs Random Positions When Entering a Map
- # Author: DiamondandPlatinum3
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # Description:
- #
- # This script allows you to set certain NPCs to have random positions
- # when the game is setting up a map, this allows your NPCs to look somewhat
- # less robot like. Whilst this can be done via events, this script also
- # checks tile passability, so your NPCs won't end up on a roof if they're
- # not supposed to.
- #
- # Included is an event switch that turns off this feature, the purpose of
- # turning off this feature is for cutscenes, wouldn't want a random NPC to
- # be in your way now would we?
- #
- # You may also use Regions to give your NPCs specific tiles they can
- # randomise to.
- #
- #------------------------------------------------------------------------------
- # Instructions:
- #
- # ~ To give an NPC the ability to appear in random locations on the map, all
- # you have to do is edit their event name to include either:
- # <Random>, <RANDOM>, <random>, <RaNdOm>
- #
- #
- # ~ If you wish to give the NPC a specific Region ID it can only randomise to
- # you must add another tag just after the above with:
- # <Region: ?> <= For Singular Regions
- # <Region: [?, ?, ?, etc]> <= For Multiple Regions
- # Replacing the Question Mark(s) with a Valid Region ID(s).
- #
- #
- # ~ Similarly you can also use the value of a variable to determine the
- # RegionID if you'd prefer. To do so you must enter:
- # <Region: \v[?]> <= For Singular Variables Containing a Region ID
- # <Region: \v[?, ?, ?, etc]> <= For Multiple Variables Containing a Region ID
- # Replacing the Question Mark(s) with a Variable ID(s).
- #
- #
- # ~ You can also a Tag to block any region(s).
- # This will alow the event to randomise to any tile that does NOT
- # contain this Region ID. To do so you must enter:
- # <RegionBlock: ?> <= For Singular Regions to Block
- # <RegionBlock: [?, ?, ?, etc]> <= For Multiple Regions to Block
- #
- # You can also use variables with the RegionBlock the same as above:
- # <RegionBlock: \v[?]> <= For Singular Variables Containing a Region ID
- # <RegionBlock: \v[?, ?, ?, etc]> <= For Multiple Variables Containing a Region ID
- #
- #
- # ~ You may also use the first comment in their event list to do the same
- # as above if you do not wish to edit the name.
- #
- #
- #
- # ~ Example ScreenShots:
- # NameTag: http://i.imgur.com/gIGpPaz.png
- # CommentTag: http://i.imgur.com/GIxiT08.png
- #
- # NameTag with Region: http://i.imgur.com/HRMpiNx.png
- # CommentTag with Region: http://i.imgur.com/D2bz6Ed.png
- #
- # NameTag with Region Variable: http://i.imgur.com/3Y4JKT0.png
- # CommentTag with Region Variable: http://i.imgur.com/kIjN9qb.png
- #
- # Multiple Regions: http://i.imgur.com/mvBykmp.png
- # Multiple Region Variables: http://i.imgur.com/5yru4Xc.png
- #
- # Block Regions: http://i.imgur.com/bN2zVY3.png
- #
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- #==============================================================================
- # ** Game_Map
- #------------------------------------------------------------------------------
- # This class handles maps. It includes scrolling and passage determination
- # functions. The instance of this class is referenced by $game_map.
- #==============================================================================
- class Game_Map
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * Editable Region
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # Turn This Event Switch On To Stop Random Positioning, use for cutscenes
- TURN_OFF_RANDOM_POSITIONING_EVENT_SWITCH_ID = 10
- # The problem with Randomising is that it will not always get you a good
- # position every single time, or possibly the next few times. This can cause
- # lag if the randomiser keeps picking awkward positions, so here you can set
- # the maximum allowable rejections per NPC. Should the Randomiser exceed this
- # limit, your NPC will stay in its original position
- MAXIMUM_POSITION_REJECTIONS = 50
- #--------------------------------------------------------------------------
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * Struct Setup
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- DP3MapRegionStruct = Struct.new(:region_id, :x, :y)
- DP3RandomRegionRegex = /<Region:\s?(\[?(?:\d+,?\s?)+\]?)>/im
- DP3RandomRegionBlockRegex = /<RegionBlock:\s?(\[?(?:\d+,?\s?)+\]?)>/im
- DP3RandomRegionVariableRegex = /<Region:\s?\\v(\[(?:\s?\d+,?\s?)+\])>/im
- DP3RandomRegionBlockVariableRegex = /<RegionBlock:\s?\\v(\[(?:\s?\d+,?\s?)+\])>/im
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # *= Alias Listings
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- alias_method(:dp3_gamemap_setup_f98ha, :setup )
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * Aliased Method: Setup
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def setup( *args )
- # Call Original Method
- dp3_gamemap_setup_f98ha( *args )
- # Call New Method
- dp3_randomise_event_positions() if !$game_switches[TURN_OFF_RANDOM_POSITIONING_EVENT_SWITCH_ID]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Randomise Event Positions
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_randomise_event_positions()
- tag = /<RANDOM>/im
- @events.each_key do |key|
- event = @events[key]
- if dp3_get_event_first_comment(event) =~ tag || event.dp3_get_event_name() =~ tag
- dp3_setupregionshash()
- reg_id = dp3_check_event_for_region_tag(event)
- if reg_id[0]
- dp3_randomise_event_position_based_on_blocked_regions( event, reg_id[1] )
- elsif reg_id[1] > 0
- dp3_randomise_event_position_based_on_region( event, reg_id[1] )
- else
- dp3_randomise_event_position_based_on_passability( event )
- end
- end
- end
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Setup Regions Hash
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_setupregionshash()
- return if !@dp3_regions_hash.nil? && @dp3_regions_hash[:map_id] == @map_id # No need to do it again if we've already got it
- dp3_create_regions_hash()
- dp3_populate_regions_hash()
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Create Regions Hash
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_create_regions_hash()
- @dp3_regions_hash.clear if @dp3_regions_hash
- @dp3_regions_hash = {}
- @dp3_regions_hash[:map_id] = @map_id
- for i in 1..63
- @dp3_regions_hash[i] = []
- end
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Populate Regions Hash
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_populate_regions_hash()
- for x in 0..(self.width)
- for y in 0..(self.height)
- reg_id = region_id( x, y )
- next if reg_id == 0
- @dp3_regions_hash[reg_id].push(DP3MapRegionStruct.new( reg_id, x, y ))
- end
- end
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Get Active Regions
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_get_active_regions()
- active_regions = Array.new()
- @dp3_regions_hash.each_key do |reg_id|
- if @dp3_regions_hash[reg_id].is_a?(Array)
- active_regions.push(reg_id) unless @dp3_regions_hash[reg_id].empty?
- end
- end
- return active_regions
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Get Event All Comments
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_get_event_first_comment( event )
- comment = ""
- unless event.list.nil?
- if event.list[0].code == 108
- event.list.each do |command|
- break if command.code != 108 && command.code != 408
- comment += command.parameters[0]
- end
- end
- end
- return comment
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Check Event For "Region Tag
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_check_event_for_region_tag( event )
- tag = /<Region/im
- comment_tag = dp3_get_event_first_comment(event)
- match_tag = ""
- match_tag = comment_tag if comment_tag =~ tag
- match_tag = event.dp3_get_event_name() if match_tag == "" && event.dp3_get_event_name() =~ tag
- if match_tag != ""
- methods = dp3_get_region_regex_checking_methods()
- methods.each do |method|
- result = method.call(match_tag)
- return result if result[1].is_a?(Array) || result[1] != 0
- end
- end
- return [false, 0]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Get Region Regex Checking Methods
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_get_region_regex_checking_methods()
- return [ method(:dp3_check_region_regex),
- method(:dp3_check_regionvariable_regex),
- method(:dp3_check_regionblock_regex),
- method(:dp3_check_regionblockvariable_regex), ]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Check Region Regex
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_check_region_regex(tag)
- if tag =~ DP3RandomRegionRegex
- region_ids = $1.scan(/\d+/).collect{ |i| i.to_i }
- return [false, region_ids[rand(region_ids.size)]]
- end
- return [false, 0]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Check Region Variable Regex
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_check_regionvariable_regex(tag)
- if tag =~ DP3RandomRegionVariableRegex
- region_ids = $1.scan(/\d+/).collect{ |i| i.to_i }
- return [false, $game_variables[region_ids[rand(region_ids.size)]]]
- end
- return [false, 0]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Check Region Block Regex
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_check_regionblock_regex(tag)
- if tag =~ DP3RandomRegionBlockRegex
- block_region_ids = $1.scan(/\d+/).collect{ |i| i.to_i }
- return [true, block_region_ids]
- end
- return [false, 0]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Check Region Block Variable Regex
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_check_regionblockvariable_regex(tag)
- if tag =~ DP3RandomRegionBlockVariableRegex
- block_region_ids = $1.scan(/\d+/).collect{ |i| $game_variables[i.to_i] }
- return [true, block_region_ids]
- end
- return [false, 0]
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Standable Position?
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_standableposition?( event, x, y )
- return false unless self.valid?(x, y)
- return true if event.through
- return self.airship_land_ok?( x, y ) && !event.collide_with_characters?(x, y)
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Randomise Event Position Based on Passability
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_randomise_event_position_based_on_passability( event )
- x = y = -1;
- rejection_count = 0
- while (!dp3_standableposition?( event, x, y )) do
- return if rejection_count == MAXIMUM_POSITION_REJECTIONS
- rejection_count += 1
- x = rand(self.width)
- y = rand(self.height)
- end
- event.moveto( x, y )
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Randomise Event Position Based on Region
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_randomise_event_position_based_on_region( event, reg_id )
- return if @dp3_regions_hash[reg_id].empty?
- x = y = -1;
- rejection_count = 0
- while (!dp3_standableposition?( event, x, y )) do
- return if rejection_count == MAXIMUM_POSITION_REJECTIONS
- rejection_count += 1
- map_pos = @dp3_regions_hash[reg_id][rand(@dp3_regions_hash[reg_id].size)]
- x = map_pos.x
- y = map_pos.y
- end
- event.moveto( x, y )
- end
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Randomise Event Position Based on Blocked Regions
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_randomise_event_position_based_on_blocked_regions( event, blocked_regions )
- x = y = -1;
- current_region_id = 0
- rejection_count = 0
- while (!dp3_standableposition?( event, x, y ) || blocked_regions.include?(current_region_id)) do
- return if rejection_count == MAXIMUM_POSITION_REJECTIONS
- rejection_count += 1
- x = rand(self.width)
- y = rand(self.height)
- current_region_id = region_id(x, y)
- end
- event.moveto( x, y )
- end
- end
- #==============================================================================
- # ** Game_Event
- #------------------------------------------------------------------------------
- # This class handles events. Functions include event page switching via
- # condition determinants and running parallel process events. Used within the
- # Game_Map class.
- #==============================================================================
- class Game_Event < Game_Character
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # * New Method: Get Original Event Name
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- def dp3_get_event_name()
- return @event.name
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement