Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ § Climate (1.0) by Solistra [License: CC BY-SA 3.0]
- # ║ <RMVX Ace>
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Change Log
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ v1.0 (January 4th, 2013) - Initial release
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Summary
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ This script allows you to make use of weather effects by defining specific
- # ║ climates, each of which containing its own set of possible weather effects
- # ║ and the percentage chance for each effect to occur. You may define climate
- # ║ types for individual maps, or you can use regions to change the climate of
- # ║ a single map (a field map, for example). You may also define maps that have
- # ║ no climate, and maps which only play a muted BGS instead of the full effect
- # ║ (useful for interior maps).
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Required Scripts
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ None.
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Known Incompatibilities
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ None.
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Installation
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ Place this script below Materials, but above Main.
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Configuration
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ Before anything else, you'll want to configure whether or not the climate
- # ║ manager is active when a new game is started. If you set ENABLED to "false",
- # ║ note that you will have to manually start the manager (check the section on
- # ║ Script Calls below).
- # ║
- # ║ Once you have that, the real work begins: defining climate types. In this
- # ║ script, climates each have their own set of possible weather effects and
- # ║ a percentage value for each weather effect to occur (below this, you can
- # ║ also define your own weather effects, as well). The available climate types
- # ║ are written as a hash like so:
- # ║ TYPES = { arid: {none: 100}, temperate: {none: 60, rain: 20, storm: 10} }
- # ║
- # ║ This would define two climate types: arid and temperate. The arid climate
- # ║ type would always have no weather effect, while the temperate climate has
- # ║ a 60% of clear weather, a 20% chance of rain, and 10% chance of a storm.
- # ║ Note that you should make these percentage values add up to 100 for this
- # ║ script to function properly!
- # ║
- # ║ Below this, you can set up your own weather effects. This is a relatively
- # ║ advanced topic, and is unlikely to be useful unless you are using a script
- # ║ that provides new weather effects. If you are, however, you can define a
- # ║ new weather effect relatively easily:
- # ║ CALLS = { example: Proc.new{puts "Your Ruby code here."} }
- # ║
- # ║ Now you can define any background sounds that you want to play with your
- # ║ weather effects. This is a relatively simple hash which can be configured
- # ║ like so:
- # ║ BGS = { weather: ["Sound file", volume, pitch] }
- # ║ BGS = { rain: ["Rain", 80, 100] }
- # ║
- # ║ Any weather effect that does not have an associated BGS in this hash will
- # ║ have no BGS by default. Below this, you may define the default climate type
- # ║ that the climate manager will start with by setting DEFAULT_TYPE to a symbol
- # ║ corresponding to the name of a climate type (note that this is only used
- # ║ when a new game is started).
- # ║
- # ║ Lastly, you can configure the base length of each weather effect and the
- # ║ amount of time that this can vary with the WEATHER_LENGTH and WEATHER_VARY
- # ║ options. These are measured in frames (60 frames ~= 1 second), and a random
- # ║ amount from 0 to WEATHER_VARY is subtracted from WEATHER_LENGTH to get the
- # ║ amount of time for a weather effect to display. If you want weather effects
- # ║ to always take the same amount of time, you may set WEATHER_VARY to 1.
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Tags
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ ● Map Note
- # ║ <climate type !name!>
- # ║ ► Replacements:
- # ║ !name! with the name of a defined climate type.
- # ║ <climate region !id! !name!>
- # ║ ► Replacements:
- # ║ !id! with a valid region ID, and !name! with the name of a defined
- # ║ climate type.
- # ║ <weather none>
- # ║ Disables the climate manager and its weather effects on this map.
- # ║ <weather sound_only>
- # ║ Plays a muted BGS with no weather effect for the current climate.
- # ║ Useful for interiors, for example.
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Script Calls
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ There are a handful of script calls that you will most likely want to use,
- # ║ but for the most part, the climate manager does not make much use of them.
- # ║ In any case, you can enable and disable the climate manager with these
- # ║ script calls:
- # ║ $game_system.climate.enable OR start OR run
- # ║ $game_system.climate.disable OR stop OR pause
- # ║
- # ║ You may also force a particular weather effect to be shown and define how
- # ║ long it should be active with this script call:
- # ║ $game_system.climate.force_weather(:effect, frames)
- # ║
- # ║ Note that this is NOT a permanent change -- if the climate type changes in
- # ║ any way while your forced weather is active, it will deactivate and the
- # ║ manager will take over instead. You may also omit the number of frames for
- # ║ this weather effect to remain active if you want it to be active for the
- # ║ remainder of the time of the effect that it replaces.
- # ║
- # ║ Also, if you do not want to have this effect stop after any amount of time,
- # ║ you may use 1.0 / 0.0 as the frames (which is infinity), and if you want to
- # ║ immediately force a weather change, you can use 0. Examples:
- # ║ $game_system.climate.force_weather(:rain, 1.0/0.0)
- # ║ $game_system.climate.force_weather(:none, 0)
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § Aliased Methods
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ ● Game_System
- # ║ initialize
- # ║ ● Game_Map
- # ║ setup
- # ║ update
- # ║ ● Scene_Map
- # ║ update
- # ║ post_transfer
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ § New Methods
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ ● Game_Map
- # ║ update_climate_regions
- # ║ no_weather?
- # ║ weather_sound_only?
- # ║ climate_type
- # ║ determine_climate_regions
- # ║
- #═╬═════════════════════════════════════════════════════════════════════════════
- # ║ ▼ module SES::Climate
- #═╩═════════════════════════════════════════════════════════════════════════════
- module SES module Climate
- #═╦═══════════════════════════════════════════════════════════════════════════
- # ║ α BEGIN CONFIGURATION
- #═╩═══════════════════════════════════════════════════════════════════════════
- # Whether or not the climate system should be enabled by default when a new
- # game is started. If this is set to false, you will have to manually enable
- # the climate system with the script call "$game_system.climate.enable".
- ENABLED = true
- # These are the climate types that you can use. Here you will define the name
- # for each climate type and the chance for each weather effect to take place.
- # Note that the chances are percentages, so if you want them to be accurate,
- # you should make the sum of all of the weather chances equal 100.
- # climate_name: {weather_type: chance, weather_type: chance}
- TYPES = { arid: {none: 100},
- temperate: {none: 65, rain: 25, storm: 10},
- tropical: {none: 40, rain: 40, storm: 20},
- polar: {snow: 60, blizzard: 25, none: 15},
- }
- # The script calls used for weather effects. This is an advanced option --
- # the defaults should suffice unless you are using an extended weather system
- # or want to use your own script calls instead of the defaults. Ruby knowledge
- # is required. Note: do not remove the none effect, this script depends on it!
- # weather_type_name: Proc.new{puts "Your Ruby code here."}
- CALLS = { none: Proc.new{$game_map.screen.change_weather(:none, 0, 120)},
- rain: Proc.new{$game_map.screen.change_weather(:rain, 3, 120)},
- storm: Proc.new{$game_map.screen.change_weather(:storm, 6, 120)},
- snow: Proc.new{$game_map.screen.change_weather(:snow, 2, 120)},
- blizzard: Proc.new{$game_map.screen.change_weather(:snow, 9, 120)},
- }
- # Determine whether or not you want the climate manager to also play sounds
- # for weather types here (if it does, you won't want to use a BGS on your
- # maps; this script more or less monopolizes them).
- USE_BGS = true
- # Background sounds for individual weather effects. Any effects not present
- # in this hash will have no associated background sound.
- # effect_name: ["Sound file", volume, pitch]
- BGS = { rain: ["Rain", 80, 100],
- storm: ["Storm", 60, 100],
- blizzard: ["Wind", 40, 100]
- }
- # The default climate type (only used when a new game is started). Note that
- # this must be in the form of a symbol (so type becomes :type).
- DEFAULT_TYPE = :temperate
- # Length, in frames, of weather effects. This is the base length.
- WEATHER_LENGTH = 7200
- # Amount of variance, in frames, to apply to the base weather length. A random
- # number from 1 up to the value of this constant is subtracted from the base
- # weather length to determine the overall length of each weather effect. Note:
- # this option can be set to 1 to have no variance applied.
- WEATHER_VARY = 1800
- #═╦═══════════════════════════════════════════════════════════════════════════
- # ║ Ω END CONFIGURATION
- #─╫───────────────────────────────────────────────────────────────────────────
- # ║ ▼ class Manager
- #═╩═══════════════════════════════════════════════════════════════════════════
- class Manager
- attr_reader :type
- def initialize() @enabled, @type, @delay = ENABLED, DEFAULT_TYPE, 1 end
- # Selects a new weather effect from the list of effects available for the
- # current map's climate type.
- def update
- @delay = @delay <= 0 ? WEATHER_LENGTH - rand(WEATHER_VARY) : @delay - 1
- return unless update_conditions_met?
- set_climate_type if type_conditions_met?
- roll_weather_chance
- set_weather_effect
- update_weather_effect
- end
- # Performs a basic update -- sets the climate type and weather effect, but
- # does not re-roll the weather chance.
- def update_basic
- return unless @enabled
- set_climate_type if type_conditions_met?
- set_weather_effect
- update_weather_effect
- end
- # This method determines if the manager is allowed to update or not.
- def update_conditions_met?
- return false unless @enabled && @delay <= 0
- return false if $game_map.no_weather?
- return true
- end
- # Updates the effect for the currently selected weather type. Note that this
- # method does not change the weather type -- that is done in the method
- # set_weather_effect.
- def update_weather_effect
- return unless @enabled && @weather
- if $game_map.no_weather? || $game_map.weather_sound_only?
- CALLS[:none].call
- return unless $game_map.weather_sound_only?
- else CALLS[@weather].call end
- if USE_BGS
- sound = BGS[@weather]
- if sound
- volume = $game_map.weather_sound_only? ? sound[1] / 2 : sound[1]
- RPG::BGS.new("#{sound[0]}", volume, sound[2]).play
- else RPG::BGS.fade(2000) end
- end
- end
- # Sets the active climate type.
- def set_climate_type
- return unless @enabled
- @type = player_region > 0 && $game_map.climate_regions[player_region] ?
- $game_map.climate_regions[player_region] : $game_map.climate_type
- end
- # Determines whether or not the climate type should be set.
- def type_conditions_met?
- return false unless @enabled
- return true if region_conditions_met?
- return true if @type != $game_map.climate_type
- return false
- end
- # Determines if the player is in a region with an assigned climate type
- # that is not the same as the currently active climate type.
- def region_conditions_met?
- return false unless @enabled
- if player_region > 0 && $game_map.climate_regions[player_region]
- return true if @type != $game_map.climate_regions[player_region]
- end
- return false
- end
- # Sets the current weather effect based on the rolled weather chance, then
- # updates the effect so that it is displayed.
- def set_weather_effect
- return unless @enabled && @type && @chance
- sum = 0; TYPES[@type].each do |weather, value|
- last_sum, sum = sum, sum + value
- next unless @chance >= last_sum && @chance < sum
- @weather = weather; break
- end
- update_weather_effect
- end
- # Forces the weather to a specific weather effect for an optional amount of
- # time (written in number of frames).
- def force_weather(effect, time = @delay)
- @weather, @delay = effect.to_sym, time
- update_weather_effect
- end
- # Convenience methods to roll the weather chance and get the region ID that
- # the player is in respectively.
- def roll_weather_chance() @chance = rand(100) end
- def player_region() $game_map.region_id($game_player.x, $game_player.y) end
- # Convenience methods to enable or disable the climate manager.
- def enable() @enabled = true; force_weather(:none, 1) end
- alias :start :enable; alias :run :start
- def disable() @enabled = false end
- alias :pause :disable; alias :stop :pause
- def enabled?() @enabled end
- end
- #═╦═══════════════════════════════════════════════════════════════════════════
- # ║ ▲ class Manager
- #═╩═══════════════════════════════════════════════════════════════════════════
- end end
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ ▲ module SES::Climate
- #═╩═════════════════════════════════════════════════════════════════════════════
- ($imported ||= {})["SES - Climate"] = 1.0
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ ▼ class Game_System
- #═╩═════════════════════════════════════════════════════════════════════════════
- class Game_System
- attr_reader :climate
- # Aliased to initialize the new instance variable @climate, which holds an
- # instance of the climate manager.
- alias :ses_climate_gs_init :initialize
- def initialize(*args, &block)
- ses_climate_gs_init(*args, &block)
- @climate = SES::Climate::Manager.new
- end
- end
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ ▲ class Game_System
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ ▼ class Game_Map
- #═╩═════════════════════════════════════════════════════════════════════════════
- class Game_Map
- attr_reader :last_map, :climate_regions
- # Aliased to provide information about the previous map and collect climate
- # regions defined in the map's note box.
- alias :ses_climate_gm_setup :setup
- def setup(*args, &block)
- @last_map = @map unless @map.nil?
- ses_climate_gm_setup(*args, &block)
- @climate_regions = determine_climate_regions
- end
- # Aliased to make use of the new method update_climate_regions.
- alias :ses_climate_gm_upd :update
- def update(*args, &block)
- ses_climate_gm_upd(*args, &block)
- update_climate_regions
- end
- # New method that will cause the climate type and weather effect to be changed
- # accordingly if the player enters a climate region.
- def update_climate_regions
- if $game_system.climate.region_conditions_met?
- $game_system.climate.update_basic
- end
- end
- # Methods for accessing information relevant to the climate manager that is
- # stored in a map's note box.
- def no_weather?(map = @map) map.note =~ /\<weather none\>/ ? true : false end
- def weather_sound_only?(map = @map)
- map.note =~ /\<weather sound\_only\>/ ? true : false
- end
- def climate_type(map = @map)
- map.note =~ /\<climate type (\S+)\>/ ? $1.to_sym : $game_system.climate.type
- end
- def determine_climate_regions()
- hash = {}; @map.note.split(/[\r\n]/).each do |note|
- hash[$1.to_i] = $2.to_sym if note =~ /\<climate region (\d{1,2}) (\S+)>/
- end; return hash
- end
- end
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ ▲ class Game_Map
- #─╫─────────────────────────────────────────────────────────────────────────────
- # ║ ▼ class Scene_Map
- #═╩═════════════════════════════════════════════════════════════════════════════
- class Scene_Map < Scene_Base
- # Aliased to update the climate manager when Scene_Map is the active scene.
- alias :ses_climate_sm_upd :update
- def update(*args, &block)
- ses_climate_sm_upd(*args, &block)
- $game_system.climate.update
- end
- # Aliased to update the climate manager accordingly based on information
- # provided both by the current map and the previous one.
- alias :ses_climate_sm_post :post_transfer
- def post_transfer(*args, &block)
- if $game_system.climate.enabled?
- if $game_map.no_weather? || $game_map.weather_sound_only?
- $game_map.screen.change_weather(:none, 0, 0)
- RPG::BGS.stop if $game_map.no_weather?
- else
- if $game_map.climate_type($game_map.last_map) != $game_map.climate_type
- $game_system.climate.update_basic
- else $game_system.climate.update_weather_effect end
- end
- end
- ses_climate_sm_post(*args, &block)
- end
- end
- #═╦═════════════════════════════════════════════════════════════════════════════
- # ║ ▲ class Scene_Map
- #═╩═════════════════════════════════════════════════════════════════════════════
Advertisement
Add Comment
Please, Sign In to add comment