Dynamic Area Lighting
#1
Posté 01 mai 2012 - 04:10
However... after I did all that work, I found the SetTileSourceLightColor function, and thought that perhaps it does work. Anyone have any experience with turning lights off (black) and on (any other color) with this method? The lexicon says it is problematic (which is the word I'd use when discussing lights and placeables) so I'm not eager to even try it. But if anyone else has had good results with this, I would like to know.
#2
Posté 01 mai 2012 - 04:41
I can't really help, but the script there is using some dynamic lighting, and works well enough. Maybe that could help (or not).
#3
Posté 01 mai 2012 - 04:50
I should have been clearer. I am interested in the torches etc... built into the tileset, and controllign their lighting. Those are called source lights.
#4
Posté 01 mai 2012 - 05:15
Placeable torches though... egads, my head hurts!
#5
Posté 01 mai 2012 - 05:38
Someday I'll figure out how to write a script which analyzes the situation and positions everything dynamically, but that likely won't work in NWN. I'm not aware of any script hooks into the model which allow you to position things relative to the model's bones, or nodes or whatever.
Modifié par henesua, 01 mai 2012 - 05:44 .
#6
Posté 01 mai 2012 - 05:39
Turning off the tile specific torch light in the Toolset by making those colors black, then firing them via a script to turn them on, worked great.
Once lit, attempting to turn them off via a script wouldn't happen. TILE_SOURCE_LIGHT_COLOR_BLACK did not douse the tileset specific torch flame.
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_BLACK;
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);
}
In the end, I had to go the route of placeable torches on the wall that were useable, so the player could place a torch, douse a burning torch or ignite a torch, driven through conversation options.
FP!
Modifié par Fester Pot, 01 mai 2012 - 05:43 .
#7
Posté 01 mai 2012 - 06:38
#8
Posté 01 mai 2012 - 07:33
Thats an issue with most placeable light sources. When I can I avoid using those. If you can, it is best to use the non-light emitting placeables and to apply a light vfx via script as a permanent visual effect. Unfortunately not all placeables can emit light in this way. The kind that look like VFXs - such as Project Q's flames - do not seem to take a light effect like this. Perhaps they lack the right kind of mesh. I dunno. And they make this all more complicated. Thankfully they are rare.
So anyway, my recommendation for you in most cases is to apply a light VFX via script rather than adjust tile lighting. You'll get a much better looking result. I do this with dynamically spawned campfires (which also have a dynamic looping sound effect that I am proud of
For the later it is possible to have the placeable automatically switch itself on as well rather than rely on a player. But that would require you to set up a framework that responds to placeable spawn or area enter or the like. Since placeables do not "spawn" that can be a little tricky, but there are many ways to solve it. You could also create two kinds of placeable prefabs - one that is placed on, the other that is placed off.
FP,
Thanks for that! It looks like we came up with different methods to solve the same thing. it would be useful to compare notes I think.
I am using the placeable's OnUse event of a torch/lantern placeable to turn it on or off. For other options rather than using a conversation, I've hooked into the AID framework and can add commands to each object: examine (provides more info and a list of other commands), light/extinguish, take, push/pull (secret doors need toggles!) etc.... I haven't come up with any other yet.
So far I have two kinds of placeables that operate this way. The main kind works as above. The other kind is a player item that when dropped on the ground becomes a placeable (lanterns and candles) which emits light. These item/placeables are taken when "used" just as a typical item would be. And they are consumable just as their item equivalents are. I have not yet them the ability to turn on or off, because the candle placeable that I am using doesn't have an off state. Until I have a candle placeable with two states and also has an identical holdable model, I think I'm just gonna stick with what I have. This means that gusts of wind simply destroy placed candles rather than blowing them out.
Disclosure: yes, I became obsessed with lighting, and light emitting items, and perception of light by creatures last year and so hopefully this is the last "light" feature that I will roll into Arnheim.
#9
Posté 01 mai 2012 - 07:59
//::///////////////////////////////////////////////
//:: Name n_am_ou_lswitch
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Turns all lights (tag "am_light") in area on/off. If
these are light objects (like a chandelier); set this int
Properties/Advanced/Variables of the light object:
IS_STANDARD_LIGHT int 1
*/
//:://////////////////////////////////////////////
//:: Created By: nereng
//:: Created On: 14/11/2004
//:://////////////////////////////////////////////
void main()
{
object oArea = GetArea(OBJECT_SELF);
object oObject = GetFirstObjectInArea(oArea);
effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);
if (GetLocalInt(OBJECT_SELF,"NW_L_AMION") == 0) //It's off; lights on!
{
ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
SetLocalInt(OBJECT_SELF,"NW_L_AMION",1);
// Loop all objects in the area
while(GetIsObjectValid(oObject))
{
if (GetTag(oObject) == "am_light")
{
if (GetLocalInt(oObject, "IS_STANDARD_LIGHT") == 1)
{
//* If this is a standard lightsource, like a chandelier
AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
SetPlaceableIllumination(oObject, TRUE);
}
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oObject);
}
oObject = GetNextObjectInArea(oArea);
}
DelayCommand(0.6,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
}
else //It's on; lights off!
{
ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
SetLocalInt(OBJECT_SELF,"NW_L_AMION",0);
while(GetIsObjectValid(oObject)) //check all objects
{
if (GetTag(oObject) == "am_light")
{
if (GetLocalInt(oObject, "IS_STANDARD_LIGHT") == 1)
{
//* If this is a standard lightsource, like a candelabra
AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
SetPlaceableIllumination(oObject, FALSE);
}
effect eEffect = GetFirstEffect(oObject);
while (GetIsEffectValid(eEffect) == TRUE)
{
if (GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT)
RemoveEffect(oObject, eEffect);
eEffect = GetNextEffect(oObject);
}
}
oObject = GetNextObjectInArea(oArea);
}
DelayCommand(0.6,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
}
}





Retour en haut







