Author Topic: Area Lighting Day/Night  (Read 371 times)

Legacy_YeoldeFog

  • Sr. Member
  • ****
  • Posts: 415
  • Karma: +0/-0
Area Lighting Day/Night
« on: February 06, 2014, 03:35:05 pm »


               Hey!

I have a little problem. Is it possible to apply a different Environment Scheme in game?
Let say I use the Exterior Clear, and when the night comes, I want to change to Exterior Dark? Is this possible?

I am aware that there are individual setting for day and night under every Environment Scheme. When I apply an Environment Scheme in th toolset, then it randomly sets the colors of every tile according to environment.2da. (Mainlight 1, 2, 3, 4, secondary 1,2, 3, 4, etc).

Now, I would like to eliminate some lights I have during the day, and randomly apply new Mainlights and secondary lights during the night, also randomly across the area just like the toolset.

Is this possible? ':huh:'
               
               

               


                     Modifié par YeoldeFog, 06 février 2014 - 03:36 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #1 on: February 06, 2014, 05:14:56 pm »


               Is that how the environmental settings work? I didn't think individual tile lighting changed with those settings, but I don't know with certainty how exactly all that works.

As far as using environmental settings goes, have you considered creating new environmental settings that fit more with what you are trying to achieve?

As for dynamically changing lighting area wide by script… that sounds like something I would like as well. I haven't been able to turn tile lights on or off for example.
               
               

               
            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #2 on: February 06, 2014, 05:25:35 pm »


               You should be able to create predetermined Environment Schemes in-game via scripts, but the level of complexity is beyond me. This is a very simple script, that changes the colour of flames on tileset tables based on the day/night cycle.

By placing an invisible object with the TAG "THKLIGHT#" by a tileset table, it will change that tiles colour.

Is there a way to randomly do this, perhaps, but perhaps it's something you can work with.

void SetTileLight()
{

   // Set lighting below entrance shaft.
   object   oTile1    = GetObjectByTag("THKLIGHT1");
   object   oTile2    = GetObjectByTag("THKLIGHT2");
   object   oTile3    = GetObjectByTag("THKLIGHT3");
   object   oTile4    = GetObjectByTag("THKLIGHT4");
   object   oTile5    = GetObjectByTag("THKLIGHT5");
   object   oTile6    = GetObjectByTag("THKLIGHT6");

   object   oArea1    = GetArea(oTile1);
   object   oArea2    = GetArea(oTile2);
   object   oArea3    = GetArea(oTile3);
   object   oArea4    = GetArea(oTile4);
   object   oArea5    = GetArea(oTile5);
   object   oArea6    = GetArea(oTile6);

   location locTile1  = GetLocation(oTile1);
   location locTile2  = GetLocation(oTile2);
   location locTile3  = GetLocation(oTile3);
   location locTile4  = GetLocation(oTile4);
   location locTile5  = GetLocation(oTile5);
   location locTile6  = GetLocation(oTile6);

   vector   vecTile1  = GetPositionFromLocation(locTile1);
   vector   vecTile2  = GetPositionFromLocation(locTile2);
   vector   vecTile3  = GetPositionFromLocation(locTile3);
   vector   vecTile4  = GetPositionFromLocation(locTile4);
   vector   vecTile5  = GetPositionFromLocation(locTile5);
   vector   vecTile6  = GetPositionFromLocation(locTile6);


   float    facTile1  = GetFacingFromLocation(locTile1);
   float    facTile2  = GetFacingFromLocation(locTile2);
   float    facTile3  = GetFacingFromLocation(locTile3);
   float    facTile4  = GetFacingFromLocation(locTile4);
   float    facTile5  = GetFacingFromLocation(locTile5);
   float    facTile6  = GetFacingFromLocation(locTile6);

   vecTile1.x /= 10.0;
   vecTile1.y /= 10.0;

   vecTile2.x /= 10.0;
   vecTile2.y /= 10.0;

   vecTile3.x /= 10.0;
   vecTile3.y /= 10.0;

   vecTile4.x /= 10.0;
   vecTile4.y /= 10.0;

   vecTile5.x /= 10.0;
   vecTile5.y /= 10.0;

   vecTile6.x /= 10.0;
   vecTile6.y /= 10.0;

   locTile1 = Location(oArea1, vecTile1, facTile1);
   locTile2 = Location(oArea2, vecTile2, facTile2);
   locTile3 = Location(oArea3, vecTile3, facTile3);
   locTile4 = Location(oArea4, vecTile4, facTile4);
   locTile5 = Location(oArea5, vecTile5, facTile5);
   locTile6 = Location(oArea5, vecTile6, facTile6);

   int nColor;
   if      (GetIsDawn()) nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_ORANGE;
   else if (GetIsDay())  nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_ORANGE;
   else if (GetIsDusk()) nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_BLUE;
   else                  nColor = TILE_SOURCE_LIGHT_COLOR_PALE_DARK_BLUE;

   SetTileSourceLightColor(locTile1, nColor, nColor);
   SetTileSourceLightColor(locTile2, nColor, nColor);
   SetTileSourceLightColor(locTile3, nColor, nColor);
   SetTileSourceLightColor(locTile4, nColor, nColor);
   SetTileSourceLightColor(locTile5, nColor, nColor);
   SetTileSourceLightColor(locTile6, nColor, nColor);


   RecomputeStaticLighting(oArea1);
   RecomputeStaticLighting(oArea2);
   RecomputeStaticLighting(oArea3);
   RecomputeStaticLighting(oArea4);
   RecomputeStaticLighting(oArea5);
   RecomputeStaticLighting(oArea6);

}


SetTileLight();

FP!
               
               

               


                     Modifié par Fester Pot, 06 février 2014 - 05:31 .
                     
                  


            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #3 on: February 06, 2014, 05:30:41 pm »


               This script randomly creates flashing tile colours anywhere the placeable TAG "light" is found on a specific tileset grid. It's a lot more complex.

INCLUDE FILE (array4):

// Declarations

void SetFloatArray(object oObject, string sVarName, int nComponent, float fValue);
float GetFloatArray(object oObject, string sVarName, int nComponent);

void SetIntArray(object oObject, string sVarName, int nComponent, int nValue);
int GetIntArray(object oObject, string sVarName, int nComponent);

void SetLocationArray(object oObject, string sVarName, int nComponent, location lValue);
location GetLocationArray(object oObject, string sVarName, int nComponent);

void SetObjectArray(object oObject, string sVarName, int nComponent, object oValue);
object GetObjectArray(object oObject, string sVarName, int nComponent);

void SetStringArray(object oObject, string sVarName, int nComponent, string sValue);
string GetStringArray(object oObject, string sVarName, int nComponent);


void SetFloat2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, float fValue);
float GetFloat2DArray(object oObject, string sVarName, int nxComponent, int nyComponent);

void SetInt2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, int nValue);
int GetInt2DArray(object oObject, string sVarName, int nxComponent, int nyComponent);

void SetLocation2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, location lValue);
location GetLocation2DArray(object oObject, string sVarName, int nxComponent, int nyComponent);

void SetObject2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, object oValue);
object GetObject2DArray(object oObject, string sVarName, int nxComponent, int nyComponent);

void SetString2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, string sValue);
string GetString2DArray(object oObject, string sVarName, int nxComponent, int nyComponent);

string PadString(string sVarName, int nxComponent, int nyComponent);

// Implementations

void SetFloatArray(object oObject, string sVarName, int nComponent, float fValue)
{
   SetLocalFloat(oObject, sVarName+IntToString(nComponent), fValue);
   return;
}

float GetFloatArray(object oObject, string sVarName, int nComponent)
{
   return GetLocalFloat(oObject, sVarName+IntToString(nComponent));
}

void SetIntArray(object oObject, string sVarName, int nComponent, int nValue)
{
   SetLocalInt(oObject, sVarName+IntToString(nComponent), nValue);
   return;
}

int GetIntArray(object oObject, string sVarName, int nComponent)
{
   return GetLocalInt(oObject, sVarName+IntToString(nComponent));
}

void SetLocationArray(object oObject, string sVarName, int nComponent, location lValue)
{
   SetLocalLocation(oObject, sVarName+IntToString(nComponent), lValue);
   return;
}

location GetLocationArray(object oObject, string sVarName, int nComponent)
{
   return GetLocalLocation(oObject, sVarName+IntToString(nComponent));
}

void SetObjectArray(object oObject, string sVarName, int nComponent, object oValue)
{
   SetLocalObject(oObject, sVarName+IntToString(nComponent), oValue);
   return;
}

object GetObjectArray(object oObject, string sVarName, int nComponent)
{
   return GetLocalObject(oObject, sVarName+IntToString(nComponent));
}

void SetStringArray(object oObject, string sVarName, int nComponent, string sValue)
{
   SetLocalString(oObject, sVarName+IntToString(nComponent), sValue);
   return;
}

string GetStringArray(object oObject, string sVarName, int nComponent)
{
   return GetLocalString(oObject, sVarName+IntToString(nComponent));
}


void SetFloat2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, float fValue)
{
   SetLocalFloat(oObject, PadString(sVarName, nxComponent, nyComponent), fValue);
   return;
}

float GetFloat2DArray(object oObject, string sVarName, int nxComponent, int nyComponent)
{
   return GetLocalFloat(oObject, PadString(sVarName, nxComponent, nyComponent));
}

void SetInt2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, int nValue)
{
   SetLocalInt(oObject, PadString(sVarName, nxComponent, nyComponent), nValue);
   return;
}

int GetInt2DArray(object oObject, string sVarName, int nxComponent, int nyComponent)
{
   return GetLocalInt(oObject, PadString(sVarName, nxComponent, nyComponent));
}

void SetLocation2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, location lValue)
{
   SetLocalLocation(oObject, PadString(sVarName, nxComponent, nyComponent), lValue);
   return;
}

location GetLocation2DArray(object oObject, string sVarName, int nxComponent, int nyComponent)
{
   return GetLocalLocation(oObject, PadString(sVarName, nxComponent, nyComponent));
}

void SetObject2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, object oValue)
{
   SetLocalObject(oObject, PadString(sVarName, nxComponent, nyComponent), oValue);
   return;
}

object GetObject2DArray(object oObject, string sVarName, int nxComponent, int nyComponent)
{
   return GetLocalObject(oObject, PadString(sVarName, nxComponent, nyComponent));
}

void SetString2DArray(object oObject, string sVarName, int nxComponent, int nyComponent, string sValue)
{
   SetLocalString(oObject, PadString(sVarName, nxComponent, nyComponent), sValue);
   return;
}

string GetString2DArray(object oObject, string sVarName, int nxComponent, int nyComponent)
{
   return GetLocalString(oObject, PadString(sVarName, nxComponent, nyComponent));
}

string PadString(string sVarName, int nxComponent, int nyComponent)
{
   string sTemp;

   sTemp = IntToString(nxComponent);
   while (GetStringLength(sTemp) < 4)
   {
       sTemp = "0" + sTemp;
   }
   sVarName += sTemp;

   sTemp = IntToString(nyComponent);
   while (GetStringLength(sTemp) < 4)
   {
       sTemp = "0" + sTemp;
   }
   sVarName += sTemp;

   return sVarName;
}


SCRIPT (light_control):

This goes on a placeable in your area with the TAG light_control. The below script goes on the placeables OnUserDefined.

#include "array4"

void RemoveEffects(object oObject);
int TurnOffLights();
float LIGHT_DURATION = 1.0;
float LIGHT_INTERVAL = 0.8;

void main()
{
   int nEvent = GetUserDefinedEventNumber();
   object oLight;
   int i,j,nRandom,x,nNumLights;
   effect e;

   //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: FIRED!"));

   // Continue light flashing
   if(nEvent==1)
   {
           //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: EVENT == 1"));

       if(GetLocalInt(OBJECT_SELF, "STOP")) SetLocalInt(OBJECT_SELF, "STOP", 0);
       else
       {
          //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: LOOP!"));

           nNumLights = GetLocalInt(OBJECT_SELF, "nNumLights");
           for(i=4;i<7;i++)
           {
               nRandom=Random(nNumLights);
               //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: LOOP: RANDOM!"));

               do
               {
                 //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: LOOP: DO!"));

                   x=0;
                   for(j=1;j<i;j++)
                   {
                       if(nRandom==GetIntArray(OBJECT_SELF, "lights", j))
                       {
                           nRandom++;
                           if(nRandom==nNumLights) nRandom=0;
                           x=1;
                       }
                   }
               } while (x==1);
               SetIntArray(OBJECT_SELF, "lights", i, nRandom);
           }

           for(i=1;i<4;i++)
           {
           //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: FOR SWITCH RANDOM"));
               x=GetIntArray(OBJECT_SELF, "lights", i+3);
               SetIntArray(OBJECT_SELF, "lights", i, x);
               oLight=GetObjectByTag("light", x);
               nRandom = Random(7);
               switch(nRandom)
               {
                   case 0: e=EffectVisualEffect(VFX_DUR_LIGHT_BLUE_5); break;
                   case 1: e=EffectVisualEffect(VFX_DUR_LIGHT_GREY_5); break;
                   case 2: e=EffectVisualEffect(VFX_DUR_LIGHT_ORANGE_5); break;
                   case 3: e=EffectVisualEffect(VFX_DUR_LIGHT_PURPLE_5); break;
                   case 4: e=EffectVisualEffect(VFX_DUR_LIGHT_RED_5); break;
                   case 5: e=EffectVisualEffect(VFX_DUR_LIGHT_WHITE_5); break;
                   case 6: e=EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_5); break;
               }
               ApplyEffectToObject(DURATION_TYPE_TEMPORARY, e, oLight, LIGHT_DURATION);
           }
           DelayCommand(LIGHT_INTERVAL, SignalEvent(OBJECT_SELF, EventUserDefined(1)));
       }
   }

   // Turn off light flashing
   if(nEvent==2)
   {
   //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: EVT#2 TURN OFF LIGHT!"));
       SetLocalInt(OBJECT_SELF, "STOP", 1);
       TurnOffLights();
       SetLocalInt(OBJECT_SELF, "lights_on", FALSE);
   }

   // Start light flashing
   if(nEvent==3)
   {
       //AssignCommand(GetObjectByTag("light_control"), SendMessageToPC(GetFirstPC(), "DEBUG: EVT#3 TURN ON LIGHT!"));
       if(!GetLocalInt(OBJECT_SELF, "lights_on"))
       {
           nNumLights=TurnOffLights();
           SetLocalInt(OBJECT_SELF, "nNumLights", nNumLights);
           for(i=1;i<4;i++) SetIntArray(OBJECT_SELF, "lights", i, i);
           SetLocalInt(OBJECT_SELF, "lights_on", TRUE);
           SignalEvent(OBJECT_SELF, EventUserDefined(1));
       }
   }
}

void RemoveEffects(object oObject)
{
   effect e = GetFirstEffect(oObject);
   while(GetIsEffectValid(e))
   {
       RemoveEffect(oObject, e);
       e = GetNextEffect(oObject);
   }
   return;
}

int TurnOffLights()
{
   int i=0;
   object oLight = GetObjectByTag("light", i);
   while(GetIsObjectValid(oLight))
   {
       RemoveEffects(oLight);
       i++;
       oLight = GetObjectByTag("light", i);
   }
   return i;
}


Event to fire when entering the area in question.

 object oLightControl=GetObjectByTag("light_control");
 if (!GetLocalInt(oLightControl, "lights_on")) SignalEvent(oLightControl, EventUserDefined(3));


FP!
               
               

               
            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #4 on: February 06, 2014, 05:38:37 pm »


               You could also just put invisible placeables in the middle of each tile you want to change the colour.

//enter the time of dawn in Your mod
const int DAWN = 6;
//enter the time of dusk in Your mod
const int DUSK = 18;
//enter the number of mintes in one game hour (default is 2)
//seting it to 0 will cause the script to ignore minutes
//may be buggy...
const int MINUTES_PER_HOUR = 5;
//

#include "nw_i0_2q4luskan"
void main()
{

object oSelf = OBJECT_SELF;
location lSelf = GetLocation(oSelf);

object   oArea1    = GetArea(oSelf);
location locTile1  = GetLocation(oSelf);
vector   vecTile1  = GetPositionFromLocation(locTile1);
float    facTile1  = GetFacingFromLocation(locTile1);
vecTile1.x /= 10.0;
vecTile1.y /= 10.0;
locTile1 = Location(oArea1, vecTile1, facTile1);

int nCurrentTime = GetTimeHour();
//if its night, change to new ambient tile colour
if ((nCurrentTime > DUSK) || (nCurrentTime < DAWN))
   {

   //when is the next dawn?
   int nTimeHour;
   if (nCurrentTime>DAWN)
       {
       nCurrentTime=24 -nCurrentTime;
       nTimeHour =nCurrentTime + DAWN;
       }
   else nTimeHour = DAWN -nCurrentTime;
   float fTimeHour = HoursToSeconds(nTimeHour);

   float fTimeMinutes;
   if(MINUTES_PER_HOUR!=0)
       {

       if(GetTimeMinute()>0)
           {
            fTimeMinutes=IntToFloat(MINUTES_PER_HOUR-GetTimeMinute())* HoursToSeconds(1)/60.0;
           }
       }
   AssignCommand( GetModule(),
               
               SetTileMainLightColor(locTile1, TILE_MAIN_LIGHT_COLOR_DARK_BLUE, TILE_MAIN_LIGHT_COLOR_BLACK);
               RecomputeStaticLighting(oArea1);

   }
}


This would change a specific tile the placeable is within to DARK BLUE/BLACK Light1 Light2.

FP!
               
               

               
            

Legacy_Solus1290

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #5 on: February 07, 2014, 01:49:09 am »


               vecTile1.x /= 10.0;
vecTile1.y /= 10.0;

vecTile2.x /= 10.0;
vecTile2.y /= 10.0;

vecTile3.x /= 10.0;
vecTile3.y /= 10.0;

vecTile4.x /= 10.0;
vecTile4.y /= 10.0;

vecTile5.x /= 10.0;
vecTile5.y /= 10.0;

vecTile6.x /= 10.0;
vecTile6.y /= 10.0;

What is this code for? I notice when I locally test my lighting functions that I, too, need to divide my tile coordinates by 10 to make them work. But why does nwn handle it that way?
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Lighting Day/Night
« Reply #6 on: February 07, 2014, 05:11:12 am »


               There is no fuction to change the entire scheme no. At least not in vanilla NWN. What you can do is make up your own schemes that are based off of each type. You can change the tile lighting and the source lighting via scripting and you can change the fog amount and color. You can even change the skybox and weather with scripting. But not the entire scheme all at once.

The following script can change the tile "main" light 1 and 2 for every tile in the area:

void main()
{
    object oArea = GetArea(OBJECT_SELF);
    vector vTile;
    location lTile;
    float fAreaX = IntToFloat(GetAreaSize(AREA_WIDTH, oArea));
    float fAreaY = IntToFloat(GetAreaSize(AREA_HEIGHT, oArea));
    float fX = 0.0;
    float fY = 0.0;
    object oPC = GetPCSpeaker();
    while ((fX <= fAreaX) && (fY <= fAreaY))
    {
        vTile = Vector(fX, fY, 0.0);
        lTile = Location(oArea, vTile, 0.0);
        SetTileMainLightColor (lTile, TILE_MAIN_LIGHT_COLOR_WHITE, TILE_MAIN_LIGHT_COLOR_WHITE);
        //SetTileMainLightColor (lTile, Random(32), Random(32));
        //SetTileSourceLightColor (lTile, TILE_SOURCE_LIGHT_COLOR_WHITE, TILE_SOURCE_LIGHT_COLOR_WHITE);
        //SetTileSourceLightColor (lTile, Random(16), Random(16));
        fX = fX + 1.0;
        if(fX == fAreaX)
        {
            fY = fY + 1.0;
            fX = 0.0;
        }
    }
    RecomputeStaticLighting(oArea);
}


I originally used this script to turn the lights on and off in an area. Set the color to white to turn on and black to turn off. I did add lines that allow for changing to random colors (0-31 in nwscript) and added lines to mess with the source lights (wall torches, etc) as well. Just keep in mind the source lighting is bugged. Once you turn on a source light you can not turn it off (black) again. So if you don't mind the sourc lights always being on, you can still change the color.

Maybe this could be a starting point for specific schemes?
               
               

               


                     Modifié par GhostOfGod, 07 février 2014 - 05:13 .