Author Topic: Weather  (Read 1916 times)

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
Weather
« on: December 15, 2015, 04:17:53 am »


               

I know you can set weather in exterior areas based on percentages, but how often does the game engine actually check and update weather on a map? Once a round? Once a turn? Once an Hour? Google seems to be failing me on this one.



               
               

               
            

Legacy_CaveGnome

  • Sr. Member
  • ****
  • Posts: 432
  • Karma: +0/-0
Weather
« Reply #1 on: December 16, 2015, 10:04:55 am »


               Curious about that topic too... At a minimum, the game engine checks weather settings every time you enter a new area (on area enter ?).
               
               

               
            

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
Weather
« Reply #2 on: December 30, 2015, 01:40:37 am »


               

I still haven't determined exactly how often weather checks are actually made, but a few brief tests seem to point at a check once per in-game hour and ... I did determine that weather changes on maps randomly whether or not a PC (or DM) has even entered the map.


 


My initial query stemmed from wanting a very simple weather system for my PW. I considered a few premade ones, but they were overly cumbersome for what I desired, no need for special gear, no harmful effects if not properly equipped, etc... as my PW uses a lot of special systems to add "realism", but is at best still HCR-Lite. I like stuff that enhances RP without enforcing it, if ya'll know what I mean. '<img'> It was just silly at times that it would rain on Map "A" of a town and maps "B" thru "D" where still sunny. '<img'>


 


So, how do I "know" that weather changes on unoccupied maps you might wonder? Well, in creating my own "regional" weather system, I made a series of dedicated "weather" maps, setting them up with the weather types/percentages I desired. Next I added a call to my exterior OnEnter event scripts to check a corresponding  "weather" map and set the weather to match it when a PC enters the regular maps. Lo and behold, it worked ... and weather patterns in fact change and do so consistently when traversing multiple maps of a given "weather region". None of the "control" maps can be accessed by players and further, no DMs had accessed them while testing. So for now, I've surmised that weather checks are occurring on all exterior maps whether or not folks enter them or not. I actually thought I'd need to manually force the weather to change on my regional control maps using some type of weather changing system for each master map. Apparently, not though.


 


Anyhooooo, just figured I'd post what I've learned so far.


               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Weather
« Reply #3 on: February 29, 2016, 05:24:22 pm »


               

Ah, Brings back memories of my climate system I fiddled about with ages ago.


I too was interested in making a weather system - but I wanted to make it browser configurable, so I basically had a DB where I stored area tags against climate identifiers.


 


Eg: 


 


If these 5 areas had the same climate identifier, then the weather would be synchronized across all 5 areas.


(It doesn't really make sense that you go from one area to another, and go from snow to sunny weather instantly etc)


 


The intention was that mountains in the same ranges would all share snow, but at the same time, I would be able to program in seasons as well. So the weather can change based on more complex logic than just a % chance that nwn provides.


 


Anyway - the rant goes on.


I think I remember vaguely last time I looked in IDA that weather modifications in areas (might be) done as part of the MainLoop/Heatbeat.


 


Essentially, MainLoop always runs every frame of the servers life time.


Which then schedules the server heartbeat at regular intervals, and at a lower priority than that is the area heartbeats, and of course the areas with the most players get processed first, followed by the areas with high priority NPC AI, and then finally the low priority AI areas and then empty areas.


 


As far as the server is concerned, weather change is basically a task of changing one number to another.


However, when the server triggers that number change would most likely be dependent on priority as with anything else occurring in the area.


 


I am not necessarily saying that the engine chooses to use the heartbeat as its 'update' time for changing weather, but I would definitely say that priority of the area comes into play in some manner or other.


 


Unfortunately without looking at the symbols, finding the exact trigger is going to be difficult.


And the question becomes - is there really weather in nwn if you arent online to see it.


Its like 'If a tree falls in the woods, does it make a sound?'


 


After all, without the game client, weather only is a number in nwserver.


No snow, Lightning or rain is rendered or processed on the server, its all client side. 


               
               

               
            

Legacy_Grymlorde

  • Sr. Member
  • ****
  • Posts: 362
  • Karma: +0/-0
Weather
« Reply #4 on: March 01, 2016, 05:48:18 pm »


               


 It was just silly at times that it would rain on Map "A" of a town and maps "B" thru "D" where still sunny. '<img'>




 


FYI, from here in Sunnyvale, California up the peninsula through San Francisco, we have a multitude of micro-climates. Many times it has been raining at my house but not at my kid's school which is at best 1 mile away. I experience a similar but not-as-micro a climate when in lived in Denver, Colorado. Otherwise, I totally agree with you and need the same kind of control over weather in my modules.


               
               

               
            

Legacy_Gawain_VIII

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
Weather
« Reply #5 on: April 29, 2016, 06:15:08 am »


               

@kalbaern, I would love to see your weather system's script, if you were so inclined.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Weather
« Reply #6 on: April 29, 2016, 02:27:00 pm »


               

Here is something you can take a look at. Only creates a climate for an area. Documented within script. The system adjusts the weather based on the month, last month, next month, day of the month, hour of day, morning, day, evening, night with a mind on continuity.



/*::////////////////////////////////////////////////////////////////////////////
//:: Name: KMdS PNP Hard Core Rule Set 1.0
//:: System: KMdS Weather System
//:: FileName Area_environ_HB
//:: Copyright (c) 2008 Michael Careaga
//::////////////////////////////////////////////////////////////////////////////
 
    This sets he weather and with the include HC_Inc_HTF.nss
    will modify the hunger/thirst/fatigue rates it fitting.
 
    This weather script should be placed on an invisible placeable's
    HB event. The check for weather will be run once every hour and will check on
    the variables set on the placeable for the desired climate type for
    the area in which the placeable is located.
 
    Temperature for the area is also set. I use this in a seperate heartbeat
    script to run any climate base effects on the creatures/players in an area.
 
    Variables to be set upon the environment object located in every area...
 
        MIDMONTH_TEMPERATURE_1
        MIDMONTH_TEMPERATURE_2
        MIDMONTH_TEMPERATURE_3
        MIDMONTH_TEMPERATURE_4
        MIDMONTH_TEMPERATURE_5
        MIDMONTH_TEMPERATURE_6
        MIDMONTH_TEMPERATURE_7
        MIDMONTH_TEMPERATURE_8
        MIDMONTH_TEMPERATURE_9
        MIDMONTH_TEMPERATURE_10
        MIDMONTH_TEMPERATURE_11
        MIDMONTH_TEMPERATURE_12
 
        HOURLY_TEMPERATURE_VARIABLE_0
        HOURLY_TEMPERATURE_VARIABLE_1
        HOURLY_TEMPERATURE_VARIABLE_2
        HOURLY_TEMPERATURE_VARIABLE_3
        HOURLY_TEMPERATURE_VARIABLE_4
        HOURLY_TEMPERATURE_VARIABLE_5
        HOURLY_TEMPERATURE_VARIABLE_6
        HOURLY_TEMPERATURE_VARIABLE_7
        HOURLY_TEMPERATURE_VARIABLE_8
        HOURLY_TEMPERATURE_VARIABLE_9
        HOURLY_TEMPERATURE_VARIABLE_10
        HOURLY_TEMPERATURE_VARIABLE_11
        HOURLY_TEMPERATURE_VARIABLE_12
        HOURLY_TEMPERATURE_VARIABLE_13
        HOURLY_TEMPERATURE_VARIABLE_14
        HOURLY_TEMPERATURE_VARIABLE_15
        HOURLY_TEMPERATURE_VARIABLE_16
        HOURLY_TEMPERATURE_VARIABLE_17
        HOURLY_TEMPERATURE_VARIABLE_18
        HOURLY_TEMPERATURE_VARIABLE_19
        HOURLY_TEMPERATURE_VARIABLE_20
        HOURLY_TEMPERATURE_VARIABLE_21
        HOURLY_TEMPERATURE_VARIABLE_22
        HOURLY_TEMPERATURE_VARIABLE_23
 
        CHANCE_OF_PRECIPITATION
        CHANCE_OF_CONTINUED_PRECIPITATION
 
    Variables searched for from the defined functions.
    Set a value to these using the appropriate skyboxes defined below
        int nClear = GetLocalInt(oObject, "CLEAR");
        int nStorm = GetLocalInt(oObject, "STORM");
        int nCold  = GetLocalInt(oObject, "COLD");
        int nIcy   = GetLocalInt(oObject, "ICY");
 
        SKYBOX_NONE             = 0;
        SKYBOX_GRASS_CLEAR      = 1;
        SKYBOX_GRASS_STORM      = 2;
        SKYBOX_DESERT_CLEAR     = 3;
        SKYBOX_WINTER_CLEAR     = 4;
        SKYBOX_ICY              = 5;
 
    Notes on pertinent info for functions defined
 
        WEATHER_INVALID = -1;
        WEATHER_CLEAR = 0;
        WEATHER_RAIN  = 1;
        WEATHER_SNOW  = 2;
        WEATHER_USE_AREA_SETTINGS = -1;
 
//:://////////////////////////////////////////////
//:: Created By: KMdS
//:: Created On: 04/26/2008
//::////////////////////////////////////////////*/
 
void SetAreaEnvironmentAndTemperature(object oObject = OBJECT_SELF);
 
void main()
{
 
    object oArea = GetArea(OBJECT_SELF);
 
    // Initiate a looping count so that we process subroutines at whatever
    // count we need to.
    // Default is whatever number of rounds are in an game hour +1 for counter reset
    int nHBDelayProcessingCount = 60+1;
    int nHBDelay = GetLocalInt(OBJECT_SELF, "HBDELAY");
    if (nHBDelay < nHBDelayProcessingCount)
        SetLocalInt(OBJECT_SELF, "HBDELAY", nHBDelay+1);
    else{
        SetLocalInt(OBJECT_SELF, "HBDELAY", 1);
        nHBDelay = 1;
    }
 
    // Only process when loop counter at modulo 60 results in 0...(for
    // first iteration and every following IG hour)
    nModuloResult = nHBDelay%60;
    if (nModuloResult == 0)
        //Set the areas current temperature
        SetAreaEnvironmentAndTemperature();
}
 
#include"HC_Inc_HTF"
void SetAreaEnvironmentAndTemperature(object oObject = OBJECT_SELF)
{
 
    /****************************
         MONTHLY TEMPERATURE
    *****************************/
    int nCalendarMonth = GetCalendarMonth();
    string sMonth = IntToString(nCalendarMonth);
    int nCurrentMonthlyBaseTemp = GetLocalInt(oObject, "MIDMONTH_TEMPERATURE_"+sMonth);
 
    /****************************
    DAILY TEMPERATURE ADJUSTMENTS
    *****************************/
    // Determine which month to use for tamperature adjustment, the month before
    // or the month after the current one
    int nDateBaseTempAdjustment = 0;
    int nCurrentDay = GetCalendarDay();
    if(nCurrentDay < 15)
    {
        int nCalendarMonth = GetCalendarMonth();
        if(nCalendarMonth == 1)
            sMonth = "12";
        else
            sMonth = IntToString(nCalendarMonth-1);
 
        int nTemperatureAdjustment = GetLocalInt(oObject, "MIDMONTH_TEMPERATURE_"+sMonth);
        nTemperatureAdjustment -= nCurrentMonthlyBaseTemp;
 
        nTemperatureAdjustment /= 14;
        nTemperatureAdjustment*= (15 - nCurrentDay);
        nDateBaseTempAdjustment = nTemperatureAdjustment;
    }
 
    else
    {
        int nCalendarMonth = GetCalendarMonth();
        if(nCalendarMonth == 12)
            sMonth = "1";
        else
            sMonth = IntToString(nCalendarMonth+1);
 
        int nTemperatureAdjustment = GetLocalInt(oObject, "MIDMONTH_TEMPERATURE_"+sMonth);
        nTemperatureAdjustment -= nCurrentMonthlyBaseTemp;
 
        nTemperatureAdjustment /= 14;
        nTemperatureAdjustment *= (nCurrentDay-14);
        nDateBaseTempAdjustment = nTemperatureAdjustment;
    }
 
    int nDateBaseTemperature = nCurrentMonthlyBaseTemp + nDateBaseTempAdjustment;
 
    /*******************************
     HOURLY TEMPERATURE ADJUSTMENTS
    *******************************/
 
    int nHour = GetTimeHour();
    string sHour = IntToString(nHour);
    int nHourlyTemperatureAdjustment = GetLocalInt(oObject, "HOURLY_TEMPERATURE_VARIABLE_"+sHour);
 
    /*******************************
     RANDOM TEMPERATURE ADJUSTMENTS
    *******************************/
 
    // Introduce a +/- 12 degree variable weighted toward +/- 5 degrees
    int RandomTemperatureVariable = d4(8)- 20;
 
    /*******************************
          CURRENT TEMPERATURE
    *******************************/
 
    int nCurrentTemperature = nDateBaseTemperature + nHourlyTemperatureAdjustment + RandomTemperatureVariable;
 
    /**********************************************************
    CURRENT WEATHER AND WEATHER RELATED TEMPERATURE ADJUSTMENTS
    **********************************************************/
 
    // We can only have weather in an exterior environment
    object oArea = GetArea(oObject);
    if(!GetIsAreaInterior(oArea)){
        int nChanceOfPrecip = GetLocalInt(oObject, "CHANCE_OF_PRECIPITATION");
        int nChanceOfContinuedPrecip = GetLocalInt(oObject, "CHANCE_OF_CONTINUED_PRECIPITATION");
        //int nChanceOfLightning = GetLocalInt(oObject, "CHANCE_OF_LIGHTNING");
 
        int nClear = GetLocalInt(oObject, "CLEAR");
        int nStorm = GetLocalInt(oObject, "STORM");
        int nCold  = GetLocalInt(oObject, "COLD");
        int nIcy   = GetLocalInt(oObject, "ICY");
 
        int nWeather = GetWeather(oArea);
 
        // If precipitating
        if(nWeather > 0)
        {
            //  but should stop...
            if(d100() > nChanceOfContinuedPrecip)
            {
                SetWeather(oArea, WEATHER_CLEAR);
                nCurrentTemperature += 15;
                if(nCurrentTemperature < 0)
                    SetSkyBox(nIcy, oArea);
                else if(nCurrentTemperature < 32)
                    SetSkyBox(nCold, oArea);
                else
                    SetSkyBox(nClear, oArea);
            }
            // and should continue...
            else
            {
                // If raining but is 32 or below, change to snow
                if(nCurrentTemperature <= 32 && nWeather == WEATHER_RAIN)
                    SetWeather(oArea, WEATHER_SNOW);
                // If snowing but is 33 or above, change to rain
                else if(nCurrentTemperature > 32 && nWeather == WEATHER_SNOW)
                    SetWeather(oArea, WEATHER_RAIN);
            }
        }
        else if(!nWeather)
        {
            //  but should start...
            if(d100() < nChanceOfPrecip)
            {
                nCurrentTemperature -= 15;
                SetSkyBox(nStorm, oArea);
                // If 32 or below, snow
                if(nCurrentTemperature <= 32)
                    SetWeather(oArea, WEATHER_SNOW);
                // If 33 or above, rain
                else if(nCurrentTemperature > 32)
                    SetWeather(oArea, WEATHER_RAIN);
            }
            // should continue clear...
            else
            {
                if(nCurrentTemperature < 0)
                    SetSkyBox(nIcy, oArea);
                else if(nCurrentTemperature < 32)
                    SetSkyBox(nCold, oArea);
                else
                    SetSkyBox(nClear, oArea);
            }
 
        }
    }
 
    /***************************************
       FULLY ADJUSTED CURRENT TEMPERATURE
    ***************************************/
 
    // Store the current temperature on the Environment object
    SetLocalInt(oArea, "CURRENT_TEMPERATURE", nCurrentTemperature);
 
    /**********************************************
     HUNGER, THIRST, FATIGUE ADJUSTMENTS TO AREAS
    **********************************************/
 
    float HTFAdjustment =  1.00f + IntToFloat(abs(nCurrentTemperature - 65))/100;
 
    float HAdjustment = pow(IntToFloat(DEFHUNGERCONSUMERATE), HTFAdjustment)/DEFHUNGERCONSUMERATE;
    float TAdjustment = pow(IntToFloat(DEFTHIRSTCONSUMERATE), HTFAdjustment)/DEFTHIRSTCONSUMERATE;
    float FAdjustment = pow(IntToFloat(DEFFATIGUECONSUMERATE), HTFAdjustment)/DEFFATIGUECONSUMERATE;
 
    // Set consumtion rates for hot conditions
    if (nCurrentTemperature > 65)
    SetAllStagesAndHTFConsumeRates(oArea, HAdjustment, TAdjustment, FAdjustment,
                                          HAdjustment, TAdjustment, FAdjustment,
                                          HAdjustment, TAdjustment, FAdjustment,
                                          HAdjustment, TAdjustment, FAdjustment);
 
    // Set consumtion rates for cold conditions
    if (nCurrentTemperature < 65)
    SetAllStagesAndHTFConsumeRates(oArea, HAdjustment, 0.0, FAdjustment,
                                          HAdjustment, 0.0, FAdjustment,
                                          HAdjustment, 0.0, FAdjustment,
                                          HAdjustment, 0.0, FAdjustment);
}


               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Weather
« Reply #7 on: April 29, 2016, 04:51:55 pm »


               

Here is the object I use


 


http://pattycakes-sa..._obj_lig002.utp



               
               

               
            

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
Weather
« Reply #8 on: April 30, 2016, 07:10:18 pm »


               


@kalbaern, I would love to see your weather system's script, if you were so inclined.




I'm currently recovering from a fairly nasty motorcycle crash, but can pot my simple script when I'm back home in a week or two (been in the hospital almost 3 weeks now). '<img'>


               
               

               
            

Legacy_T0r0

  • Sr. Member
  • ****
  • Posts: 380
  • Karma: +0/-0
Weather
« Reply #9 on: April 30, 2016, 11:18:05 pm »


               

Crap !! Speedy recovery man......



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Weather
« Reply #10 on: April 30, 2016, 11:46:49 pm »


               

Ditto! Get well soon kalbaern.



               
               

               
            

Legacy_ehye_khandee

  • Hero Member
  • *****
  • Posts: 1415
  • Karma: +0/-0
Weather
« Reply #11 on: May 04, 2016, 06:38:26 pm »


               

best wishes for your speedy recovery Kalbaern



               
               

               
            

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
Weather
« Reply #12 on: May 10, 2016, 06:56:53 pm »


               

Back home finally! I need to rearrange my computer(s) and swap desks so that I can more comfortably use them. right now, my entire right leg is locked in extension and will remain that way for 5 months as bones heal and regrow. I have folks coming by in a day or two to help rearrange things. Once that's done, I'll post my own weather system up on the NWN Vault for folks. Thanks for the well wishes too. '<img'>