. What my version does is you can create "weather patterns" on specific maps and every 45 minutes the system does a heartbeat and applies the effect based off parameters in MYSQL.
I call it "Dynamic Weather System" because the weather can adjust to different condition. (i.e. it can go from thunderstorm to light storm or fog to rain, etc.) Also, I added lightning ground-strikes. You will need to add adiditional placeables to the maps to get it to work. If you want them let me know.
Code: Select all
-- ----------------------------
-- Table structure for cmnsee_weather
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather`;
CREATE TABLE `cmnsee_weather` (
`weather_pattern` varchar(64) DEFAULT NULL,
`fogchance` varchar(64) DEFAULT NULL,
`rainchance` varchar(64) DEFAULT NULL,
`timewindow_start` time DEFAULT NULL,
`timewindow_end` time DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of cmnsee_weather
-- ----------------------------
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'aboveaverage', 'aboveaverage', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'high', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'veryhigh', 'occasional', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'occasional', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'aboveaverage', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'aboveaverage', 'aboveaverage', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'occasional', 'moderate', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'high', 'high', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'veryhigh', 'aboveaverage', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'occasional', 'aboveaverage', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'aboveaverage', 'aboveaverage', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'moderate', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'moderate', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'aboveaverage', 'high', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'aboveaverage', 'aboveaverage', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'aboveaverage', 'rare', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'occasional', 'rare', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'moderate', 'rare', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'moderate', '18:00:00', '04:59:00');
-- ----------------------------
-- Table structure for cmnsee_weather_current
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather_current`;
CREATE TABLE `cmnsee_weather_current` (
`weather_pattern` varchar(64) NOT NULL,
`fog` int(1) DEFAULT NULL,
`rain` int(1) DEFAULT NULL,
`sunnyandclear` int(1) DEFAULT NULL,
PRIMARY KEY (`weather_pattern`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of cmnsee_weather_current
-- ----------------------------
INSERT INTO `cmnsee_weather_current` VALUES ('goblin', '0', '0', '2');
INSERT INTO `cmnsee_weather_current` VALUES ('harts', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('kortuga', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('sharessia', '0', '0', '1');
INSERT INTO `cmnsee_weather_current` VALUES ('sunbright', '1', '0', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('sylsrefuge', '0', '0', '2');
INSERT INTO `cmnsee_weather_current` VALUES ('valley', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('volcanoisland', '0', '0', '1');
-- ----------------------------
-- Table structure for cmnsee_weather_maps
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather_maps`;
CREATE TABLE `cmnsee_weather_maps` (
`areatag` varchar(64) DEFAULT NULL,
`interior` int(11) DEFAULT NULL,
`weather_pattern` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of cmnsee_weather_maps
-- ----------------------------
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaCove', '0', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('SunbrightIsland', '0', 'sunbright');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugaclub', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('PurpleCrowBazaar', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugastylistshop', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaMercantile', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaBathHouse', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugatemple', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('haven_volcanoisland', '0', 'volcanoisland');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugasewer', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('GoblinIsland', '0', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('goblincaves1', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('goblincaves2', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('vermincaves', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('Connisle', '0', 'harts');
INSERT INTO `cmnsee_weather_maps` VALUES ('ValleyofDeath', '0', 'valley');
INSERT INTO `cmnsee_weather_maps` VALUES ('Haven', '0', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('myrin', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenMercantile', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('SensualServices', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('inn', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('MagesGuild', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenTemple', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('FestHall', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenKeep', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('EnchantedDragonFoundry', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('syls_refuge', '0', 'sylsrefuge');
Code: Select all
cmnsee_weather_includes
#include "nwnx_sql"
float weatherdelay = 300.0;
void SendMessageToAllPlayers(string area, string message)
{
object oTarget = GetFirstPC();
while (GetIsObjectValid(oTarget))
{
if (GetTag(GetArea(oTarget)) == area)
{
SendMessageToPC(oTarget,message);
}
oTarget = GetNextPC();
}
}
void PlayThunder(object oArea)
{
// WE HAVE STOPPED
if(GetLocalInt(oArea, "LIGHTNINGON") == 0){return;}
location lChecker = GetLocation(GetFirstObjectInArea(oArea));
object oTarget = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,lChecker);
if (oTarget == OBJECT_INVALID) return;
string sThunder = "as_na_thunder_" + IntToString(Random(7) + 1);
object oTemp = CreateObject(OBJECT_TYPE_PLACEABLE, "alb_temp_weather", GetLocation(oTarget));
DelayCommand(IntToFloat(d2()), AssignCommand(oTemp, PlaySound(sThunder, TRUE)));
DestroyObject(oTemp, 10.0, FALSE);
}
void LightningDamage(object LightningStrike)
{
int nCount = 1;
object oPlayer = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,GetLocation(LightningStrike), nCount);
while (GetIsObjectValid(oPlayer))
{
if (GetDistanceBetween(oPlayer, LightningStrike) < 4.0 && GetDistanceBetween(oPlayer, LightningStrike) > 0.00)
{
effect eVis = EffectVisualEffect(VFX_COM_HIT_ELECTRICAL);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPlayer, 1.0);
effect eHurt = EffectDamage( FloatToInt((GetCurrentHitPoints(oPlayer) * 0.15)), DAMAGE_TYPE_ELECTRICAL, DAMAGE_POWER_NORMAL, TRUE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHurt, oPlayer);
SendMessageToPC(oPlayer,"<i>*You were just struck by lightning!*</i>");
}
nCount++;
oPlayer = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,GetLocation(LightningStrike), nCount);
}
}
void LightningStrike (object oArea)
{
object LightningStrike = GetNearestObjectByTag("alb_lightning_spot", GetFirstObjectInArea(oArea), Random(20));
effect eVFX = EffectNWN2SpecialEffectFile("sp_lightning_superray");
effect eVFX2 = EffectNWN2SpecialEffectFile("sp_storm_veng_light");
effect eVFX3 = EffectNWN2SpecialEffectFile("fx_light_white_20");
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, LightningStrike);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX2, LightningStrike);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX3, LightningStrike);
DelayCommand(0.5,RemoveSEFFromObject(LightningStrike, "fx_light_white_20"));
DelayCommand(5.0,RemoveSEFFromObject(LightningStrike, "sp_lightning_superray"));
DelayCommand(5.0,RemoveSEFFromObject(LightningStrike, "sp_storm_veng_light"));
LightningDamage(LightningStrike);
}
void MakeLightning(object oArea)
{
// LIGHTNING
object oLight = GetNearestObjectByTag("alb_lightning", GetFirstObjectInArea(oArea));
SetLightActive(oLight, TRUE); int iCounter;
if (d4() == 1) LightningStrike(oArea);
DelayCommand(IntToFloat(d2()+ 1),SetLightActive(oLight, FALSE));
DelayCommand(IntToFloat(d2()), PlayThunder(oArea));
}
void RandomLightning(object oArea)
{
if(GetLocalInt(oArea, "LIGHTNINGON") == 0) return;
MakeLightning(oArea);
if (d4() == 1) DelayCommand(3.0, MakeLightning(oArea));
// KEEP GOING IF REQUIRED
DelayCommand(IntToFloat(Random(30)+5), RandomLightning(oArea));
}
void CancelSounds(object oTarget, string tag)
{
int nSound = 0;
object oSound = GetNearestObjectByTag(tag,oTarget,nSound);
while (GetIsObjectValid(oSound))
{
SoundObjectStop(oSound);
nSound++;
oSound = GetNearestObjectByTag(tag,oTarget,nSound);
}
}
void StopSounds(object oTarget)
{
object oSound = GetFirstObjectInArea(oTarget);
CancelSounds(oSound, "alb_rain_light");
CancelSounds(oSound, "alb_rain_stormheavy");
CancelSounds(oSound, "alb_rain_heavy");
CancelSounds(oSound, "alb_thunder_ambient");
CancelSounds(oSound, "alb_rain_light_interior");
CancelSounds(oSound, "alb_rain_stormheavy_interior");
CancelSounds(oSound, "alb_rain_heavy_interior");
CancelSounds(oSound, "alb_thunder_ambient_interior");
}
void ResetAllNWN2Fog(object oTarget)
{
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNRISE);
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_DAYTIME);
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNSET);
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONRISE);
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_NIGHTTIME);
ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONSET);
}
void SetAllNWN2Fog(object oTarget, int nColor, float fFogStart, float fFogEnd)
{
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNRISE, nColor, fFogStart, fFogEnd );
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_DAYTIME, nColor, fFogStart, fFogEnd );
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNSET, nColor, fFogStart, fFogEnd );
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONRISE, nColor, fFogStart, fFogEnd );
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_NIGHTTIME, nColor, fFogStart, fFogEnd );
SetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONSET, nColor, fFogStart, fFogEnd );
}
void SetFogColours(object oArea, int iCurrentPower)
{
if(iCurrentPower == 1){SetAllNWN2Fog(oArea, FOG_COLOR_WHITE, 45.0, 65.0);} //Fog
if(iCurrentPower == 2){SetAllNWN2Fog(oArea, FOG_COLOR_GREY, 45.0, 70.0);} //Light rain
if(iCurrentPower == 3){SetAllNWN2Fog(oArea, FOG_COLOR_BLACK, 45.0, 65.0);} //Heavy rain
if(iCurrentPower == 4){SetAllNWN2Fog(oArea, FOG_COLOR_BLACK, 45.0, 50.0);} //Thunderstorm
}
void RemoveWeatherEffect(object oTarget, string effectname)
{
if (GetIsAreaInterior(oTarget) == TRUE) return;
int iCounter = 1;
object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oTarget), iCounter);
while(oWeatherUnit != OBJECT_INVALID)
{
RemoveSEFFromObject(oWeatherUnit, effectname);
iCounter = iCounter + 1;
oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oTarget), iCounter);
}
}
void RemoveAllEffects(object oArea)
{
if (GetIsAreaInterior(oArea) == TRUE) return;
// USE A STATIC OBJECT TO LOOP FROM (PC MAY MOVE AND CHANGE TARGET)
int iCounter = 1;
object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
while(oWeatherUnit != OBJECT_INVALID)
{
// REMOVE ALL POSSIBLE WEATHER EFFECTS
RemoveSEFFromObject(oWeatherUnit, "fx_area_fog_white"); // AREA FOG
RemoveSEFFromObject(oWeatherUnit, "fx_rain_splash"); // HEAVY RAIN
RemoveSEFFromObject(oWeatherUnit, "fx_rain_nosplash"); // HEAVY RAIN
RemoveSEFFromObject(oWeatherUnit, "fx_rain_light"); // LIGHT RAIN
iCounter = iCounter + 1;
oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
}
}
void UpdateSkyEffect(object oArea, string SEFEffectFile)
{
if (GetIsAreaInterior(oArea) == TRUE) return;
effect eVFX = EffectNWN2SpecialEffectFile(SEFEffectFile);
int iCounter = 1;
object oWeatherUnit = GetNearestObjectByTag("alb_skybox_unit", GetFirstObjectInArea(oArea), iCounter);
while(oWeatherUnit != OBJECT_INVALID)
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, oWeatherUnit);
iCounter = iCounter + 1;
oWeatherUnit = GetNearestObjectByTag("alb_skybox_unit", GetFirstObjectInArea(oArea), iCounter);
}
}
void UpdateUnitEffect(object oArea, string SEFEffectFile)
{
if (GetIsAreaInterior(oArea) == TRUE) return;
effect eVFX = EffectNWN2SpecialEffectFile(SEFEffectFile);
int iCounter = 1;
object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
while(oWeatherUnit != OBJECT_INVALID)
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, oWeatherUnit);
iCounter = iCounter + 1;
oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
}
}
void StopWeather(object oArea)
{
RemoveAllEffects(oArea);
StopSounds(oArea);
ResetAllNWN2Fog(oArea);
DeleteLocalInt(oArea,"LIGHTNINGON");
DeleteLocalInt(oArea,"WEATHERON");
DeleteLocalInt(oArea,"FOGCOLOR");
DeleteLocalInt(oArea,"FOGENABLED");
SetWeather(oArea, 0, 0);
}
void StopAllWeather(string area)
{
SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
string sArea;
while (SQLFetch() == SQL_SUCCESS)
{
sArea = SQLGetData(1);
StopWeather(GetObjectByTag(sArea));
}
}
void PlaySounds(object oTarget, int choice)
{
string soundtag; string tag; string tag2; int iCounter = 1;
if (choice == 1)
{
tag = "alb_rain_light";
tag2 = "alb_rain_light_interior";
}
if (choice == 2)
{
tag = "alb_rain_heavy";
tag2 = "alb_rain_heavy_interior";
}
if (choice == 3)
{
tag = "alb_rain_stormheavy";
tag2 = "alb_rain_stormheavy_interior";
}
if (choice == 4)
{
tag = "alb_thunder_ambient";
tag2 = "alb_thunder_ambient_interior";
}
SoundObjectPlay(GetNearestObjectByTag(tag, GetFirstObjectInArea(oTarget)));
object oSound = GetNearestObjectByTag(tag2, GetFirstObjectInArea(oTarget), iCounter);
while(oSound != OBJECT_INVALID)
{
SoundObjectPlay(oSound);
iCounter = iCounter + 1;
oSound = GetNearestObjectByTag(tag2, GetFirstObjectInArea(oTarget), iCounter);
}
}
void FogOn(object oArea, int rain)
{
if (GetLocalInt(oArea,"FOGENABLED") == 1 || GetIsAreaInterior(oArea)) return;
if (GetIsAreaInterior(oArea) == TRUE) return;
RemoveWeatherEffect(oArea, "fx_area_fog_white");
UpdateUnitEffect(oArea, "fx_area_fog_white");
SetLocalInt(oArea,"FOGENABLED",1);
if (rain == 1) return;
SetFogColours(oArea, 1);
SetLocalInt(oArea,"FOGCOLOR",1);
SendMessageToAllPlayers(GetTag(oArea),"<i>*A heavy fog descends over the area*</I>");
}
void FogOff(object oArea, int rain)
{
if (GetIsAreaInterior(oArea) == TRUE) return;
float delay = weatherdelay; //5 minutes
SendMessageToAllPlayers(GetTag(oArea), "<i>*The heavy fog begins to fade away*</I>");
DelayCommand(delay, StopWeather(oArea));
}
void AreaFogOnOff(string area, int fogswitch)
{
SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"' AND interior=0;");
string sArea;
while (SQLFetch() == SQL_SUCCESS)
{
sArea = SQLGetData(1);
if (fogswitch == 1) FogOn(GetObjectByTag(sArea), 0);
if (fogswitch == 0) FogOff(GetObjectByTag(sArea), 0);
}
}
void Drizzle(object oArea)
{
// START THIS SOUND
if (GetIsAreaInterior(oArea) == TRUE) return;
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
// REDUCE LIGHTING
SetFogColours(oArea, 1);
SetWeather(oArea, 0, 2);
// SETTINGS
SetLocalInt(oArea,"LIGHTNINGON",0);
SetLocalInt(oArea,"WEATHERON",1);
SetLocalInt(oArea,"FOGCOLOR",1);
DeleteLocalInt(oArea,"FOGENABLED");
}
void LightRainStorm(object oArea)
{
// START THIS SOUND
DelayCommand(0.5, StopSounds(oArea));
DelayCommand(1.0, PlaySounds(oArea, 1)); //Light rainstorm
if (GetIsAreaInterior(oArea) == TRUE) return;
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
DelayCommand(0.5, UpdateUnitEffect(oArea,"fx_rain_light"));
// REDUCE LIGHTING
ResetAllNWN2Fog(oArea);
SetFogColours(oArea, 2);
SetWeather(oArea, 0, 2);
// ADD DOWNPOUR RAIN & SPLASH
FogOn(oArea, 1);
// SETTINGS
SetLocalInt(oArea,"LIGHTNINGON",0);
SetLocalInt(oArea,"WEATHERON",2);
SetLocalInt(oArea,"FOGCOLOR",2);
}
void HeavyRainStorm(object oArea)
{
// START THIS SOUND
DelayCommand(0.5, StopSounds(oArea));
DelayCommand(1.0, PlaySounds(oArea, 2)); //Heavy Rainstorm
if (GetIsAreaInterior(oArea) == TRUE) return;
// REDUCE LIGHTING
ResetAllNWN2Fog(oArea);
SetFogColours(oArea, 3);
SetWeather(oArea, 0, 4);
// ADD DOWNPOUR RAIN & SPLASH
FogOn(oArea, 1);
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
DelayCommand(1.0, UpdateUnitEffect(oArea,"fx_rain_splash"));
// SETTINGS
SetLocalInt(oArea,"LIGHTNINGON",0);
SetLocalInt(oArea,"WEATHERON",3);
SetLocalInt(oArea,"FOGCOLOR",3);
}
void ThunderStorm(object oArea)
{
// START THIS SOUND
DelayCommand(0.5, StopSounds(oArea));
DelayCommand(1.0, PlaySounds(oArea, 3)); //Heavy rainstorm
DelayCommand(1.0, PlaySounds(oArea, 4)); //Thunder, ambient
if (GetIsAreaInterior(oArea) == TRUE) return;
// REDUCE LIGHTING
ResetAllNWN2Fog(oArea);
SetFogColours(oArea, 4);
SetWeather(oArea, 0, 5);
// ADD DOWNPOUR RAIN & SPLASH
FogOn(oArea, 1);
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
DelayCommand(1.0, UpdateUnitEffect(oArea,"fx_rain_splash"));
// START LIGHTNING
DelayCommand(IntToFloat(Random(10) + 5), RandomLightning(oArea));
// SETTINGS
SetLocalInt(oArea,"LIGHTNINGON",1);
SetLocalInt(oArea,"WEATHERON",4);
SetLocalInt(oArea,"FOGCOLOR",4);
}
void DynamicRainStorm(string area, int stormtype, string weatherpattern, int onoff)
{
int weatheron = GetLocalInt(GetObjectByTag(area),"WEATHERON");
if (weatheron == stormtype) return;
string sMessage; int interior;
if (GetIsAreaInterior(GetObjectByTag(area)) == TRUE) interior = 1;
float delay = weatherdelay; //5 minutes
//OFF SWITCHES
if (weatheron == 1 && onoff == 0) //Drizzle stops
{
sMessage = "<i>*The rain storm passes by*</I>";
if (interior == 1) sMessage = "<i>*The sound of light rain outside stops.*</I>";
DelayCommand(delay / 2,StopAllWeather(weatherpattern));
}
//OFF SWITCHES
if (weatheron == 2 && onoff == 0) //Light rain stops.
{
sMessage = "<i>*The rain storm passes by*</I>";
if (interior == 1) sMessage = "<i>*The sound of light rain outside stops.*</I>";
DelayCommand(delay / 2, Drizzle(GetObjectByTag(area)));
DelayCommand(delay * 1.5,StopAllWeather(weatherpattern));
}
if (weatheron == 3 && onoff == 0) //Heavy rain stops.
{
sMessage = "<i>*The heavy rain begins to let up.*</I>";
if (interior == 1) sMessage = "<i>*The sound of heavy rain outside begins to let up. Perhaps the storm is passing by.*</I>";
DelayCommand(delay, LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 2, Drizzle(GetObjectByTag(area)));
DelayCommand(delay * 3, StopAllWeather(weatherpattern));
}
if (weatheron == 4 && onoff == 0)
{
sMessage = "<i>*The thunder storm begins to pass through the area.*</I>";
if (interior == 1) sMessage = "<i>*The thundering outside begins to let up.*</I>";
DelayCommand(delay * 0.75,HeavyRainStorm(GetObjectByTag(area))); //Thunderstorm stops.
DelayCommand(delay * 2,LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 3,Drizzle(GetObjectByTag(area)));
DelayCommand(delay * 4,StopAllWeather(weatherpattern));
}
//ON SWITCHES (NO WEATHER ON)
if (weatheron == 0 && stormtype == 1 && onoff == 1)
{
DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
sMessage = "<i>*A light drizzle begins to fall on the area.*</I>";
if (interior == 1) sMessage = "<i>*A light drizzle can be heard outside.*</I>";
}
if (weatheron == 0 && stormtype == 2 && onoff == 1)
{
DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
sMessage = "<i>*A light rain begins to fall on the area.*</I>";
if (interior == 1) sMessage = "<i>*A light rain can be heard outside.*</I>";
}
if (weatheron == 0 && stormtype == 3 && onoff == 1)
{
DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
sMessage = "<i>*A light rain begins to fall on the area with dark clouds in the distance.*</I>";
if (interior == 1) sMessage = "<i>*A light rain can be heard outside and over-time seems to be picking up.*</I>";
DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
}
if (weatheron == 0 && stormtype == 4 && onoff == 1)
{
DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
sMessage = "<i>*A light rain begins to fall on the area with dark clouds spotted in the distance. The sound of distant thunder can be heard.*</I>";
if (interior == 1) sMessage = "<i>*A light rain can be heard outside and the sound of distant thunder can be heard.*</I>";
DelayCommand(delay * 1.5,HeavyRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 3.0,ThunderStorm(GetObjectByTag(area)));
}
//ON SWITCHES (WEATHER ALREADY ON)
//DRIZZLE
if (weatheron == 1 && stormtype == 2 && onoff == 1) //Drizzle becomes light rain.
{
sMessage = "<i>*The rain storm suddenly begins to pick up.*</I>";
if (interior == 1) sMessage = "<i>*The rain outside begins to pick up.*</I>";
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
}
if (weatheron == 1 && stormtype == 3 && onoff == 1) //Drizzle becomes
{
sMessage = "<i>*The rain storm suddenly begins to pick up heavily.*</I>";
if (interior == 1) sMessage = "<i>*The rain outside begins to pick up heavily.*</I>";
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
}
if (weatheron == 1 && stormtype == 4 && onoff == 1) //Light rain becomes thunderstorm.
{
sMessage = "<i>*The rain storm begins to pick up heavily. The sound of thunder can be heard in the distance.*</I>";
if (interior == 1) sMessage = "<i>*The rainstorm outside suddenly picks up heavily and the sound of thunder can be heard in the distance.*</I>";
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 2.75, ThunderStorm(GetObjectByTag(area)));
}
//LIGHT RAIN
if (weatheron == 2 && stormtype == 3 && onoff == 1) //Light rain becomes heavy storm.
{
sMessage = "<i>*The rain storm suddenly begins to pick up.*</I>";
if (interior == 1) sMessage = "<i>*The rain outside begins to pick up.*</I>";
DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
}
if (weatheron == 2 && stormtype == 4 && onoff == 1) //Light rain becomes thunderstorm.
{
sMessage = "<i>*The rain storm begins to pick up heavily. The sound of thunder can be heard in the distance.*</I>";
if (interior == 1) sMessage = "<i>*The rainstorm outside suddenly picks up heavily and the sound of thunder can be heard in the distance.*</I>";
HeavyRainStorm(GetObjectByTag(area));
DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 3.0, ThunderStorm(GetObjectByTag(area)));
}
//HEAVY RAIN
if (weatheron == 3 && stormtype == 4 && onoff == 1)
{
if (interior == 1) sMessage = "<i>*The heavy rain picks up with the sound of thunder in the area.*</I>";
if (interior == 1) sMessage = "<i>*The rain suddenly picks up heavily with loud rumbles of thunder making the ground shake. You can see frequent lightning strikes outside if you look.*</I>";
DelayCommand(delay, ThunderStorm(GetObjectByTag(area)));
}
//ON SWITCHES (DOWNGRADES)
//LIGHT RAIN BECOMES DRIZZLE
if (weatheron == 2 && stormtype == 1 && onoff == 1)
{
sMessage = "<i>*The rain begins to let up into a drizzle.*</I>";
if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
DelayCommand(delay, Drizzle(GetObjectByTag(area)));
}
//HEAVY RAIN BECOMES DRIZZLE
if (weatheron == 3 && stormtype == 1 && onoff == 1)
{
sMessage = "<i>*The heavy rain begins to let up into a drizzle.*</I>";
if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
DelayCommand(delay * 1.5, LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 2.0, Drizzle(GetObjectByTag(area)));
}
//HEAVY STORM BECOMES LIGHT RAIN
if (weatheron == 3 && stormtype == 2 && onoff == 1)
{
sMessage = "<i>*The heavy rain begins to let up into a gentle shower.*</I>";
if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
DelayCommand(delay * 1.5, LightRainStorm(GetObjectByTag(area)));
}
//THUNDER STORM BECOMES DRIZZLE
if (weatheron == 4 && stormtype == 1 && onoff == 1)
{
sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues and slowly lets up into a drizzle.*</I>";
if (interior == 1) sMessage = "<i>*The thundering outside begins to let up, but the heavy rain continues and slowly lets up into a drizzle.*</I>";
DelayCommand(delay, HeavyRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 2.0, LightRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 3.0, Drizzle(GetObjectByTag(area)));
}
//THUNDER STORM BECOMES LIGHT RAIN
if (weatheron == 4 && stormtype == 2 && onoff == 1)
{
sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues and slowly lets up.*</I>";
if (interior == 1) sMessage = "<i>*The thundering outside begins to let out, but the heavy rain continues and slowly lets up.*</I>";
DelayCommand(delay, HeavyRainStorm(GetObjectByTag(area)));
DelayCommand(delay * 2.0, LightRainStorm(GetObjectByTag(area)));
}
//THUNDER STORM BECOMES HEAVY
if (weatheron == 4 && stormtype == 3 && onoff == 1)
{
sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues.*</I>";
if (interior == 1) sMessage = "<i>*The thundering outside begins to let out, but the heavy rain continues.*</I>";
DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
}
SendMessageToAllPlayers(area,sMessage);
}
void RainAreaOff(string area)
{
SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
string sArea;
while (SQLFetch() == SQL_SUCCESS)
{
sArea = SQLGetData(1);
DynamicRainStorm(sArea, 0, area, 0);
}
}
void RainAreaOn(string area)
{
int iRoll = d100(); int stormtype;
if (iRoll > 0) stormtype = 1;
if (iRoll >= 45) stormtype = 2;
if (iRoll >= 75) stormtype = 3;
if (iRoll >= 90) stormtype = 4;
int weatheron = GetLocalInt(GetObjectByTag(area),"WEATHERON");
if (weatheron == stormtype) return;
SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
string sArea;
while (SQLFetch() == SQL_SUCCESS)
{
sArea = SQLGetData(1);
DynamicRainStorm(sArea, stormtype, area, 1);
}
}
void ChangeWeather(object oPC)
{
object oArea = GetArea(oPC);
int weather = GetLocalInt(oArea,"WEATHERON"); SetLocalInt(oArea,"NOHEARTBEAT",1);
//0 - light rain, 1 - medium rain, 2 - heavy rain, 3 - thunderstorm
if (weather == 0)
{
SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to drizzle!");
Drizzle(oArea);
return;
}
if (weather == 1)
{
SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to light-rain!");
LightRainStorm(oArea);
return;
}
if (weather == 2)
{
StopWeather(oArea);
SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to heavy-rain!");
HeavyRainStorm(oArea);
return;
}
if (weather == 3)
{
StopWeather(oArea);
SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to thunderstorm!");
ThunderStorm(oArea);
return;
}
if (weather == 4)
{
StopWeather(oArea);
SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather reset!");
StopWeather(oArea);
DeleteLocalInt(oArea,"NOHEARTBEAT");
}
}
int WeatherChance(string name)
{
if (name == "alwayson") return 100;
if (name == "veryhigh") return 60;
if (name == "high") return 50;
if (name == "aboveaverage") return 45;
if (name == "moderate") return 35;
if (name == "occasional") return 25;
if (name == "uncommon") return 16;
if (name == "low") return 8;
if (name == "rare") return 4;
if (name == "veryrare") return 1;
return 0;
}
void WeatherUpdate(string weatherpattern, int category, int status)
{
string sQuery;
weatherpattern = SQLEncodeSpecialChars(weatherpattern);
//1 - fog
if (category == 1) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"',"+IntToString(status)+",'0',0)"+
" ON DUPLICATE KEY UPDATE fog='"+IntToString(status)+"', rain='0', sunnyandclear='0';";
//2 - rain
if (category == 2) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"','0',"+IntToString(status)+",'0')"+
" ON DUPLICATE KEY UPDATE fog='0', rain='"+IntToString(status)+"', sunnyandclear='0';";
//3 - clear
if (category == 3) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"','0','0',"+IntToString(status)+")"+
" ON DUPLICATE KEY UPDATE fog='0', rain='0', sunnyandclear='"+IntToString(status)+"';";
SQLExecDirect(sQuery);
}
void HeartbeatWeather()
{
if (GetLocalInt(OBJECT_SELF,"NOHEARTBEAT") == 1) return;
SetLocalInt(OBJECT_SELF,"NOHEARTBEAT",1);
DelayCommand(2700.0,DeleteLocalInt(OBJECT_SELF,"NOHEARTBEAT"));
string sQuery; string areatag = SQLEncodeSpecialChars(GetTag(OBJECT_SELF));
SQLExecDirect("SELECT weather_pattern from cmnsee_weather_maps WHERE areatag='"+areatag+"' AND interior=0;");
SQLFetch();
string weatherpattern = SQLGetData(1);
if (weatherpattern == "") return;
string sWeatherpattern = SQLEncodeSpecialChars(weatherpattern);
sQuery = "SELECT fogchance, rainchance FROM cmnsee_weather WHERE (timewindow_start <= timewindow_end and NOW() >= timewindow_start and NOW() <= timewindow_end AND weather_pattern='"+sWeatherpattern+"') or (timewindow_end < timewindow_start and (NOW() <= timewindow_end or NOW() >= timewindow_start) AND weather_pattern='"+sWeatherpattern+"') LIMIT 1;";
SQLExecDirect(sQuery); SQLFetch();
int fogchance = WeatherChance(SQLGetData(1));
int rainchance = WeatherChance(SQLGetData(2));
int weatheron = GetLocalInt(OBJECT_SELF,"WEATHERON");
int fogon = GetLocalInt(OBJECT_SELF,"FOGENABLED");
int iRollFog = d100(); int iRollRain = d100();
//Rain turning on.
if (iRollRain <= rainchance)
{
RainAreaOn(weatherpattern);
WeatherUpdate(weatherpattern, 2, 1);
return;
}
//Rain turning off. No fog.
if (iRollRain > rainchance && weatheron >= 1 && iRollFog > fogchance)
{
RainAreaOff(weatherpattern);
WeatherUpdate(weatherpattern, 3, 2);
return;
}
//Fog turning on.
if (iRollFog <= fogchance)
{
if (weatheron == 1)
{
RainAreaOff(weatherpattern);
DelayCommand((weatherdelay / 2) + 25.0, AreaFogOnOff(weatherpattern, 1));
}
if (weatheron == 2)
{
RainAreaOff(weatherpattern);
DelayCommand((weatherdelay * 1.5) + 25.0, AreaFogOnOff(weatherpattern, 1));
}
if (weatheron == 3)
{
RainAreaOff(weatherpattern);
DelayCommand((weatherdelay * 3) + 25.0, AreaFogOnOff(weatherpattern, 1));
}
if (weatheron == 4)
{
RainAreaOff(weatherpattern);
DelayCommand((weatherdelay * 4) + 25.0, AreaFogOnOff(weatherpattern, 1));
}
if (weatheron > 0)
{
WeatherUpdate(weatherpattern, 1, 2);
return;
}
WeatherUpdate(weatherpattern, 1, 1);
AreaFogOnOff(weatherpattern, 1);
return;
}
//It's sunny!
if (iRollRain > rainchance && iRollFog > fogchance || iRollFog > fogchance)
{
if (weatheron >= 1) RainAreaOff(weatherpattern);
if (weatheron == 0 && fogon == 1) AreaFogOnOff(weatherpattern, 0);
if (weatheron == 0 && fogon != 0) StopAllWeather(weatherpattern);
WeatherUpdate(weatherpattern, 3, 1);
}
}