/*:
* @plugindesc Weather controls for your entire game world, by map. (See "Help...") Requires MOG_Weather_EX and WorldWeatherZones.
* @author Ben Hendel-Doying
*
* @param Min Steps Until Weather Change
* @desc Minimum number of steps by the player between weather changes. Set to -1 to disable changing weather by stepping.
* Default: 100
* @default 100
*
* @param Max Steps Until Weather Change
* @desc Maximum number of steps by the player between weather changes. Set to -1 to disable changing weather by stepping.
* Default: 200
* @default 200
*
* @help
* 1. Set the options for this plugin, as desired.
* 2. If you haven't done so already, download and install MOG_Weather_EX, and
* familiarize yourself with it! Try using it on its own, without this plugin.
* Once you're comfortable with how MOG_Weather_EX works, reinstall this
* plugin, and continue reading these instructions. (Go on! I'll wait!)
* 3. Using your maps' notes, tag maps indicating which "zone" of weather they
* belong to. Examples:
* <WorldWeather.Zone:Desert>
* <WorldWeather.Zone:Forest>
* You can make up any zone names you want, and those names can include
* spaces, numbers, periods, dashes, etc. Maps without such tags will not have
* any weather effects (good for "indoor" rooms).
* 2. Install the WorldWeatherZones.js plugin, and edit it! Follow the
* instructions within to define the behavior of your zones.
*
* If you want to force the weather to change, you can do so in an event. Add a
* script block, and use the following:
*
* $gameSystem.changeWeather();
*
* You can also change the minimum and maximum steps between weather changes
* (including using -1 to disable automatic weather changes).
*
* $gameSystem._minStepsUntilWeatherChange = 200;
* $gameSystem._maxStepsUntilWeatherChange = 500;
*
* Or directly set how long it should be until the next weather change:
*
* $gameSystem._stepsUntilWeatherChange = 10;
*
* Or disable weather change (until you call $gameSystem.changeWeather() again):
*
* $gameSystem._stepsUntilWeatherChange = -1;
*
* You can also script Conditional Branches based on various weather properties.
*
* Are you currently in a Desert zone?
*
* $dataMap.meta == 'Desert'
*
* Are there at least 100 steps until the weather changes?
*
* $gameSystem._stepsUntilWeatherChange >= 100
*
* Be creative! Have fun! :)
*
* Compatibility:
* * REQUIRES PLUGIN MOG_Weather_EX
* * REQUIRES PLUGIN WorldWeatherZones
* * ALIASES Game_Map..setup
* * ADDS Game_Map..setupWeather
* * ALIASES Game_Player..moveStraight
* * ALIASES Game_Player..moveDiagonally
* * ALIASES Game_System..initialize
* * ADDS Game_System..pickWeatherForZone
* * ADDS Game_System..changeWeather
* * ADDS Game_System..countStepForWeatherChange
* * ADDS Game_System.._minStepsUntilWeatherChange
* * ADDS Game_System.._maxStepsUntilWeatherChange
* * ADDS Game_System.._stepsUntilWeatherChange
* * ADDS Game_System.._weatherByZone
* * ADDS Array..pickOne
*/

var BenMakesGames = window.BenMakesGames || {};

Object.defineProperty(Array.prototype, 'pickOne', {
enumerable: false,
value: function() {
return this;
}
});

(function() {
BenMakesGames.WorldWeather = {};
BenMakesGames.WorldWeather.Parameter = PluginManager.parameters('WorldWeather');
BenMakesGames.WorldWeather.MinimumSteps = !isNaN(parseInt(BenMakesGames.WorldWeather.Parameter)) ? parseInt(BenMakesGames.WorldWeather.Parameter) : 200;
BenMakesGames.WorldWeather.MaximumSteps = !isNaN(parseInt(BenMakesGames.WorldWeather.Parameter)) ? parseInt(BenMakesGames.WorldWeather.Parameter) : 200;

var WorldWeather_Game_Map_setup = Game_Map.prototype.setup;

Game_Map.prototype.setup = function(mapId) {
WorldWeather_Game_Map_setup.call(this, mapId);

this.setupWeather();
};

Game_Map.prototype.setupWeather = function() {
if($dataMap.meta.hasOwnProperty('WorldWeather.Zone'))
{
var weatherZone = $dataMap.meta;

if(!$gameSystem._weatherByZone.hasOwnProperty(weatherZone))
$gameSystem._weatherByZone = $gameSystem.pickWeatherForZone(weatherZone);

var weather = $gameSystem._weatherByZone;

if(weather == null)
$gameSystem.clearWeatherEX();
else
{
// we don't set $gameSystem._weatherData = weather, because that has a greater potential for
// conflict with future versions of MOG_Weather_EX, or other plugins for MOG_Weather_EX. so we set
// only precisely what we need to set!
$gameSystem._weatherData.mode = weather.type;
$gameSystem._weatherData.power = weather.power;
$gameSystem._weatherData.blendMode = weather.blendType;
$gameSystem._weatherData.fileName = weather.fileName;
}
}
else
$gameSystem.clearWeatherEX();
};

var WorldWeather_Game_System_initialize = Game_System.prototype.initialize;

Game_System.prototype.initialize = function()
{
WorldWeather_Game_System_initialize.call(this);

this._minStepsUntilWeatherChange = BenMakesGames.WorldWeather.MinimumSteps;
this._maxStepsUntilWeatherChange = BenMakesGames.WorldWeather.MaximumSteps;
this._weatherByZone = {};

this.changeWeather();
};

Game_System.prototype.pickWeatherForZone = function(zone)
{
if(zone == null || zone == '' || !$worldWeatherZones.hasOwnProperty(zone))
return null;

var weatherList = $worldWeatherZones();

if(weatherList == null || weatherList.length == 0)
{
return null;
}
else
{
var weather = weatherList.pickOne();

if(weather == null)
return null;
else if (
!weather.hasOwnProperty('type')
|| !weather.hasOwnProperty('power')
|| !weather.hasOwnProperty('blendType')
|| !weather.hasOwnProperty('fileName')
)
{
throw new Error('World weather zone did not return correctly-formatted weather data.');
}
else
{
return weather;
}
}
};

Game_System.prototype.changeWeather = function()
{
if(this._minStepsUntilWeatherChange == -1 || this._maxStepsUntilWeatherChange == -1)
this._stepsUntilWeatherChange = -1;
else
this._stepsUntilWeatherChange = Math.randomInt(this._maxStepsUntilWeatherChange - this._minStepsUntilWeatherChange + 1) + this._minStepsUntilWeatherChange;

this._weatherByZone = {};

if($gameMap != null && $dataMap != null)
$gameMap.setupWeather();
};

Game_System.prototype.countStepForWeatherChange = function()
{
if(this._stepsUntilWeatherChange > 0)
{
this._stepsUntilWeatherChange--;

if(this._stepsUntilWeatherChange == 0)
this.changeWeather();
}
};

WorldWeather_Game_Player_moveStraight = Game_Player.prototype.moveStraight;
WorldWeather_Game_Player_moveDiagonally = Game_Player.prototype.moveDiagonally;

Game_Player.prototype.moveStraight = function(d) {
WorldWeather_Game_Player_moveStraight.call(this, d);
$gameSystem.countStepForWeatherChange();
};

Game_Player.prototype.moveDiagonally = function(horz, vert) {
WorldWeather_Game_Player_moveDiagonally.call(this, horz, vert);
$gameSystem.countStepForWeatherChange();
};

})();