Rune_PRC8/_module/nss/orw_area_weather.nss
Jaysyn904 d1c309ae63 Initial commit
Initial commit
2024-09-13 09:10:39 -04:00

625 lines
19 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// Olander's Realistic Weather System
// opw_area_weather
// By Don Anderson
// dandersonru@msn.com
//
// Makes Weather Function in a Module (This is called from the Module Heartbeat
// Event so this does not need to be placed anywhere)
//
////////////////////////////////////////////////////////////////////////////////
#include "orw_inc_weather"
void main()
{
object oTVar = OBJECT_SELF;
string sTVar = GetName(oTVar);
object oMod = GetModule();
object oArea = GetArea(oTVar);
string sATag = GetTag(oArea);//Each Area Tag Must be Unique!!
//Dynamic Skyboxes Enabled
int nSkybox = GetLocalInt(oMod,"WEATHERSKYBOX");
//Only Natural Areas
int nNat = GetIsAreaNatural(oArea);
if(nNat != 1) return;
//Fog color needs a kick in the rear =D
int nFSet = GetLocalInt(oArea,"FOGSET");
if(nFSet == 0)
{
SetFogColor(FOG_TYPE_ALL,FOG_MORNING,oArea);
SetLocalInt(oArea,"FOGSET",1);
}
//An Area must be Initialized First
int nAI = GetLocalInt(oArea,WEATHERINIAREA);
if(nAI == 0)
{
InializeArea(oArea,sTVar);
//Set Up Matching Areas if Source Waypoint Exists
string sSource = "SOURCE_" +sATag;
object oSource = GetNearestObjectByTag(sSource,oTVar,1);
if(GetIsObjectValid(oSource) == TRUE)
{
string sMatch = "MATCH_" +sATag;//Waypoint Must Match the Source Area Tag!!
//Now we get the areas that have the Matching Weather Waypoint
int nMth = 0;
object oMArea;
object oMatch = GetObjectByTag(sMatch,nMth);
while(GetIsObjectValid(oMatch))
{
oMArea = GetArea(oMatch);
SetLocalString(oMatch,"WEATHERSOURCE",sATag);
SetLocalString(oMArea,"WEATHERMATCH",sMatch);
if(nMth > 50) break;
nMth++;
oMatch = GetObjectByTag(sMatch,nMth);
}
}
}
//Check for Season Change and Intialize Area
int nIniSeason = GetLocalInt(oArea,WEATHERINISEASON);
int nCurSeason = GetLocalInt(oArea,WEATHERCURSEASON);
if(nCurSeason != nIniSeason)
{
SetInitializedSeason(oArea);
InializeArea(oArea,sTVar);
}
int nTZ = GetLocalInt(oArea,WEATHERTZONE);
int nPZ = GetLocalInt(oArea,WEATHERPZONE);
int nMT = GetLocalInt(oArea,WEATHERMAXTEMP);
int nWC = GetLocalInt(oArea,WEATHERWATER);
int nIT = GetLocalInt(oArea,WEATHERINITEMP);
int nIH = GetLocalInt(oArea,WEATHERINIHUMID);
int nCW = GetCurrentWeather(oArea);
int nHour = GetTimeHour();
int nSeason = GetLocalInt(oArea,WEATHERCURSEASON);
int nWarm = GetLocalInt(oArea,WEATHERWFRONT);
int nCold = GetLocalInt(oArea,WEATHERCFRONT);
int nCT = GetLocalInt(oArea,WEATHERCURTEMP);//Current Temp
int nHM = GetLocalInt(oArea,WEATHERCURHUMID);//Current Humidity
int nWet = GetCurrentWeather(oArea);
//:****************************************************************************/
//: WARM AND COLD FRONTS
int D100 = d100(1);
int nCF = CheckFront(oArea);
if(D100 >= 60)
{
if(nCF == FALSE) InitializeWarmFront(oArea);
}
if(D100 <= 59)
{
if(nCF == FALSE) InitializeColdFront(oArea);
}
//: WARM AND COLD FRONTS
//:****************************************************************************/
//:****************************************************************************/
//: NATURAL HEATING/COOLING CYCLE OF EACH DAY
//Calc the Heating and Cooling part of the day
int nHeat = 0;
if(nHour >= 0 && nHour <= 7) nHeat = 0;
if(nHour > 7 && nHour <= 16) nHeat = 1;
if(nHour > 16 && nHour <= 23) nHeat = 0;
//Warm the Air
if(nHeat == 1)
{
int nMaxR = d3(1) + nMT;
if(nCT > nMaxR) CoolAirTemp(oArea,nCW,nHeat,nCT);
else WarmAirTemp(oArea,nCW,nHeat,nCT);
}
//Cool the Air
if(nHeat == 0)
{
int nMaxR = nMT - 30;
if(nCT < nMaxR) WarmAirTemp(oArea,nCW,nHeat,nCT);
else CoolAirTemp(oArea,nCW,nHeat,nCT);
}
//Refresh Current Temp
nCT = GetLocalInt(oArea,WEATHERCURTEMP);
//: NATURAL HEATING/COOLING CYCLE OF EACH DAY
//:****************************************************************************/
//:****************************************************************************/
//: NATURAL HUMIDITY ACCUMULATION
//Humidity is Accumulated During the Heating Day and by Area Water Content
int nIWF = GetLocalInt(oArea,WEATHERWFRONT);
int nICF = GetLocalInt(oArea,WEATHERCFRONT);
if(nCF == TRUE && nIWF == 1) nWC = nWC + 5;
if(nCF == TRUE && nICF == 1) nWC = nWC - 5;
//Day Humidity During Warm Front
if(nHeat == 1 && nIWF == 1 && nPZ > 0)
{
//The chance to Raise Humidity
int nHMAdd = d100(1) + nWC;
if(nHMAdd >= 70) nHM = nHM + 1;
}
//Night Humidity During Warm Front
if(nHeat == 0 && nIWF == 1 && nPZ > 0)
{
//The chance to Raise Humidity
int nHMAdd = d100(1) + nWC;
if(nHMAdd >= 70) nHM = nHM + 1;
}
//Day Humidity During Cold Front (When Not Raining)
if(nHeat == 1 && nICF == 1 && nPZ > 0 && nWet != WEATHER_RAIN && nWet != WEATHER_SNOW)
{
//The chance to Lower Humidity
int nHMAdd = d100(1) + nWC;
if(nHMAdd <= 30) nHM = nHM - 1;
}
//Night Humidity During Cold Front (When Not Raining)
if(nHeat == 0 && nICF == 1 && nPZ > 0 && nWet != WEATHER_RAIN && nWet != WEATHER_SNOW)
{
//The chance to Lower Humidity
int nHMAdd = d100(1) + nWC;
if(nHMAdd <= 30) nHM = nHM - 1;
}
//Now Set Our New Humidity
if(nHM >= 100) nHM = 100;
if(nHM < 0) nHM = 0;
if(nPZ > 0) SetLocalInt(oArea,WEATHERCURHUMID,nHM);
else
{
nHM = 0;
SetLocalInt(oArea,WEATHERCURHUMID,nHM);
}
//: NATURAL HUMIDITY ACCUMULATION
//:****************************************************************************/
//:****************************************************************************/
//: RAIN AND SETTING WEATHER LEVEL
//Now Set Up the Weather Level Potential
//Cold Fronts Will Initiate the Rain
int nLevel = 0;//Really Clear Sky
if(nHM >= 20) nLevel = 1;//Normal
if(nHM >= 30) nLevel = 2;//Cloudy
//Cold Front
if(IsInColdFront(oArea) == TRUE && nPZ > 0)
{
//Now Set Up the Weather Level Potential
if(nHM >= 40) nLevel = 3;//Raining/Snowing
if(nHM >= 60) nLevel = 4;//Thunderstorm No Lightning
if(nHM >= 80) nLevel = 5;//Thunderstorm With Lightning
}
//Spark a Rainstorm
if(IsInWarmFront(oArea) == TRUE && nPZ > 0 && nHM >= 80)
{
nLevel = 3;//Raining/Snowing
InitializeColdFront(oArea);
}
SetLocalInt(oArea,WEATHERLEVEL,nLevel);
//Only if Dynamic Skyboxes are On
if(nSkybox == 1)
{
//Very Clear Skies
if(nLevel == 0 && GetSkyBox(oArea) != SKYBOX_DESERT_CLEAR)
{
//This Eliminates Skybox Flip Flops
if(nHM < 15) SetSkyBox(SKYBOX_DESERT_CLEAR,oArea);
}
//Party Cloudy Warm Weather Skies
if(nLevel == 1 && nCT >= 0 && GetSkyBox(oArea) != SKYBOX_GRASS_CLEAR)
{
if(GetSkyBox(oArea) == SKYBOX_WINTER_CLEAR || GetSkyBox(oArea) == SKYBOX_ICY)
{
if(nHM >= 20 && nHM < 30 && nCT >=5) SetSkyBox(SKYBOX_GRASS_CLEAR,oArea);
}
else
{
if(nHM >= 20 && nHM < 30) SetSkyBox(SKYBOX_GRASS_CLEAR,oArea);
}
}
//Party Cloudy Cold Weather Skies
if(nLevel == 1 && nCT < 0 && GetSkyBox(oArea) != SKYBOX_WINTER_CLEAR)
{
if(nHM >= 20 && nHM < 30) SetSkyBox(SKYBOX_WINTER_CLEAR,oArea);
}
//Stormy Warm Weather Skies
if(nLevel == 2 && nCT >= 0 && GetSkyBox(oArea) != SKYBOX_GRASS_STORM)
{
if(nHM >= 30 && nHM < 40) SetSkyBox(SKYBOX_GRASS_STORM,oArea);
if(GetSkyBox(oArea) == SKYBOX_ICY || GetSkyBox(oArea) == SKYBOX_WINTER_CLEAR)
{
if(nHM >= 30 && nHM < 40 && nCT >=5) SetSkyBox(SKYBOX_GRASS_STORM,oArea);
}
else
{
if(nHM >= 30 && nHM < 40) SetSkyBox(SKYBOX_GRASS_STORM,oArea);
}
}
//Stormy Cold Weather Skies
if(nLevel == 2 && nCT < 0 && GetSkyBox(oArea) != SKYBOX_ICY)
{
if(nHM >= 30 && nHM < 40) SetSkyBox(SKYBOX_ICY,oArea);
}
//Full Clouded
if(nLevel >= 3 && GetSkyBox(oArea) != SKYBOX_NONE)
{
SetSkyBox(SKYBOX_NONE,oArea);
}
}
//Now Check to see if it already Raining or Snowing and Reduce Humidity
if(nWet == WEATHER_RAIN || nWet == WEATHER_SNOW)
{
//We build down by Humidity
int nHMSub = nHM - 1;
SetLocalInt(oArea,WEATHERCURHUMID,nHMSub);
}
//: RAIN AND SETTING WEATHER LEVEL
//:****************************************************************************/
//:****************************************************************************/
//: WHAT TYPE OF FOG
int nFogLight = FOG_MORNING;
int nFogMed = FOG_LIGHTRAIN;
int nFogDark = FOG_STORMCLOUDS;
//Fog Dynamic Override
object oFDO = GetNearestObjectByTag("FOG_DYNAMICOVERRIDE",oTVar,1);
if(oFDO != OBJECT_INVALID)
{
string sName = GetName(oFDO);
if(sName == "Snow")
{
nFogLight = FOG_LSNOW;
nFogMed = FOG_MSNOW;
nFogDark = FOG_DSNOW;
}
if(sName == "Desert")
{
nFogLight = FOG_LDESERT;
nFogMed = FOG_MDESERT;
nFogDark = FOG_DDESERT;
}
if(sName == "Bluish")
{
nFogLight = FOG_LBLUISH;
nFogMed = FOG_MBLUISH;
nFogDark = FOG_DBLUISH;
}
}
//Is there a Fog Override?
object oFOver = GetNearestObjectByTag("FOG_OVERRIDE",oTVar,1);
int nFOver = GetLocalInt(oArea,"FOG_OVERRIDE");
if(oFOver != OBJECT_INVALID && nFOver == 0)
{
string sFOver = GetName(oFOver);
string sQty = GetStringLeft(sFOver,3);
string sColor = GetSubString(sFOver,4,3);
int nColor = FOG_MORNING;//Default
if(sColor == "Bla") nColor = FOG_COLOR_BLACK;
if(sColor == "Blu") nColor = FOG_COLOR_BLUE_DARK;
if(sColor == "Bro") nColor = FOG_COLOR_BROWN_DARK;
if(sColor == "Gre") nColor = FOG_COLOR_GREEN_DARK;
if(sColor == "Ora") nColor = FOG_COLOR_ORANGE_DARK;
if(sColor == "Red") nColor = FOG_COLOR_RED_DARK;
if(sColor == "Yel") nColor = FOG_COLOR_YELLOW_DARK;
int nQty = StringToInt(sQty);
SetLocalInt(oArea,"FOG_OVERRIDE",1);
SetFogAmount(FOG_TYPE_ALL,nQty,oArea);
SetFogColor(FOG_TYPE_ALL,nColor,oArea);
}
int nLight = GetIsLight();
int nFT = 0;
if(nLight == 0) nFT = FOG_TYPE_SUN;
if(nLight == 1) nFT = FOG_TYPE_SUN;
if(nLight == 2) nFT = FOG_TYPE_MOON;
int nFA = GetFogAmount(nFT,oArea);
//: WHAT TYPE OF FOG
//:****************************************************************************/
//:****************************************************************************/
//: MAKE FOG IN THE MORNING AND EVENING
int nSI = GetLocalInt(oArea,WEATHERLEVEL);
int nFO = GetLocalInt(oArea,"FOG_OVERRIDE");
if(nHour >= 0 && nHour <= 6 && nSI <= 1 && nHM >= 10 && nFO == 0)
{
if(nCW != WEATHER_CLEAR) SetWeather(oArea,WEATHER_CLEAR);
if(nHour >= 0 && nHour <= 6)
{
if(nFA <= 15) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
}
}
if(nHour >= 18 && nHour <= 23 && nSI <= 1 && nHM >= 10 && nFO == 0)
{
if(nCW != WEATHER_CLEAR) SetWeather(oArea,WEATHER_CLEAR);
if(nHour >= 18 && nHour <= 23)
{
if(nFA <= 15) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
}
}
//: MAKE FOG IN THE MORNING AND EVENING
//:****************************************************************************/
//:****************************************************************************/
//: MAKE CLOUDS BY WEATHER LEVEL
//Burn off Morning Fog
if(nHour >= 7 && nHour <= 17 && nSI <= 1 && nFO == 0)
{
if(nCW != WEATHER_CLEAR) SetWeather(oArea,WEATHER_CLEAR);
//Burn off Fog
if(nFA > 0) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Cloudy Sky
if(((nHour >=0 && nHour < 3) || (nHour >= 7 && nHour <= 23)) && nSI == 2 && nFO == 0)
{
if(nCW != WEATHER_CLEAR) SetWeather(oArea,WEATHER_CLEAR);
//Create Clouds
if(nFA < 5) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
//Waver the Cloud Shadow
if(nFA >= 5 && nFA <= 8)
{
int nRC = d2(1);
if(nRC == 1) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nRC == 2) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Build Clouds Back This Stage
if(nFA > 10) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Raining or Snowing
if(nHour >= 0 && nSI == 3 && nFO == 0)
{
//Create Clouds
if(nFA < 8) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
//Create Rain or Snow
if(nFA >= 8)
{
if(nCW != WEATHER_RAIN && nCT >= 0) SetWeather(oArea,WEATHER_RAIN);
if(nCW != WEATHER_SNOW && nCT < 0) SetWeather(oArea,WEATHER_SNOW);
}
//Waver the Cloud Shadow
if(nFA >= 8 && nFA <= 12)
{
int nRC = d2(1);
if(nRC == 1) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nRC == 2) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Build Clouds Back This Stage
if(nFA > 12) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Storm with No Lightning
if(nHour >= 0 && nSI == 4 && nFO == 0)
{
//Create Clouds
if(nFA < 10) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nFA >= 8)
{
if(nCW != WEATHER_RAIN && nCT >= 0) SetWeather(oArea,WEATHER_RAIN);
if(nCW != WEATHER_SNOW && nCT < 0) SetWeather(oArea,WEATHER_SNOW);
}
//Waver the Cloud Shadow
if(nFA >= 10 && nFA <= 13)
{
int nRC = d2(1);
if(nRC == 1) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nRC == 2) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Build Clouds Back This Stage
if(nFA > 13) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Storm with Lightning
if(nHour >= 0 && nSI == 5 && nFO == 0)
{
//Create Clouds
if(nFA < 12) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nFA >= 8)
{
if(nCW != WEATHER_RAIN && nCT >= 0) SetWeather(oArea,WEATHER_RAIN);
if(nCW != WEATHER_SNOW && nCT < 0) SetWeather(oArea,WEATHER_SNOW);
}
//Waver the Cloud Shadow
if(nFA >= 12 && nFA <= 15)
{
int nRC = d2(1);
if(nRC == 1) SetCloud(oArea,1,nFogLight,nFogMed,nFogDark);
if(nRC == 2) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//Build Clouds Back This Stage
if(nFA > 15) SetCloud(oArea,-1,nFogLight,nFogMed,nFogDark);
}
//: MAKE CLOUDS BY WEATHER LEVEL
//:****************************************************************************/
//:****************************************************************************/
//: MAKE WIND BY WEATHER LEVEL
object oWindSoft = GetNearestObjectByTag("SoftWind",oTVar);
object oWindStrong = GetNearestObjectByTag("StrongWind",oTVar);
int nWindSoft = GetLocalInt(oArea,"WINDSOFT");
int nWindStrong = GetLocalInt(oArea,"WINDSTRONG");
//Soft Winds
if(nSI <= 3 && nWindSoft == 0)
{
SoundObjectPlay(oWindSoft);
SoundObjectStop(oWindStrong);
SetLocalInt(oArea,"WINDSOFT",1);
SetLocalInt(oArea,"WINDSTRONG",0);
nWindSoft = 1;
nWindStrong = 0;
}
//Strong Winds
if(nSI > 3 && nWindStrong == 0)
{
SoundObjectPlay(oWindStrong);
SoundObjectStop(oWindSoft);
SetLocalInt(oArea,"WINDSOFT",0);
SetLocalInt(oArea,"WINDSTRONG",1);
nWindSoft = 0;
nWindStrong = 1;
}
//Wind Volume Control
if(nSI == 1 && nWindSoft == 1) SoundObjectSetVolume(oWindSoft, 5);
if(nSI == 2 && nWindSoft == 1) SoundObjectSetVolume(oWindSoft, 7);
if(nSI == 3 && nWindSoft == 1) SoundObjectSetVolume(oWindSoft, 10);
if(nSI == 4 && nWindStrong == 1) SoundObjectSetVolume(oWindStrong, 10);
if(nSI == 5 && nWindStrong == 1) SoundObjectSetVolume(oWindStrong, 15);
//: MAKE WIND BY WEATHER LEVEL
//:****************************************************************************/
//:****************************************************************************/
//: MAKE THUNDER BY WEATHER LEVEL
object oThunder = GetNearestObjectByTag("Thunder",oTVar);
int nThunder = GetLocalInt(oArea,"THUNDER");
//Stop Thunder
if(nCW != WEATHER_RAIN && nSI < 3 && nThunder == 1)
{
SoundObjectStop(oThunder);
SetLocalInt(oArea,"THUNDER",1);
}
//Start Thunder
if(nCW == WEATHER_RAIN && nSI >= 3 && nCT >= 0 && nThunder == 0)
{
SoundObjectPlay(oThunder);
SetLocalInt(oArea,"THUNDER",1);
}
//: MAKE THUNDER BY WEATHER LEVEL
//:****************************************************************************/
//:****************************************************************************/
//: MAKE LIGHTNING BY WEATHER LEVEL
//Start Lightning
if(nCW == WEATHER_RAIN && nSI == 5 && nCT >= 0 && nThunder == 1)
{
int nAir = d2(1);
location lStrike = RandomLocation(oArea,nAir);
LightningStrike(oArea,lStrike,nAir);
}
//: MAKE LIGHTNING BY WEATHER LEVEL
//:****************************************************************************/
//:****************************************************************************/
//: RESET WEATHER FRONTS
int nFCount = GetLocalInt(oArea,WEATHERCOUNTER);
int nSDurat = GetLocalInt(oArea,WEATHERDURATION);
//Currently in a Weather Front
if(nCF == TRUE)
{
if(nFCount == nSDurat)
{
SetLocalInt(oArea,WEATHERAFRONT,0);
SetLocalInt(oArea,WEATHERWFRONT,0);
SetLocalInt(oArea,WEATHERCFRONT,0);
SetLocalInt(oArea,WEATHERCOUNTER,0);
SetLocalInt(oArea,WEATHERDURATION,0);
}
}
//: RESET WEATHER FRONTS
//:****************************************************************************/
//:****************************************************************************/
//: MESSAGES TO PLAYERS IN THE AREA
int nNth = 1;
object oPC = GetNearestObject(OBJECT_TYPE_CREATURE,oTVar,nNth);
while (GetIsObjectValid(oPC) == TRUE)
{
if(GetIsPC(oPC) == TRUE || GetIsDM(oPC) == TRUE || GetIsDMPossessed(oPC) == TRUE)
{
ExecuteScript("orw_pc_message",oPC);
}
nNth++;
oPC = GetNearestObject(OBJECT_TYPE_CREATURE,oTVar,nNth);
}
//: MESSAGES TO PLAYERS IN THE AREA
//:****************************************************************************/
//:****************************************************************************/
//: FRONT COUNTER
//Only Count When a Front is in the Area
if(nSDurat > 0)
{
nFCount = nFCount + 1;
SetLocalInt(oArea,WEATHERCOUNTER,nFCount);
}
//: FRONT COUNTER
//:****************************************************************************/
}