Aller au contenu

Photo

oddly enough, another constant query:


  • Veuillez vous connecter pour répondre
33 réponses à ce sujet

#1
Leurnid

Leurnid
  • Members
  • 271 messages
I am working to store specific VFX light effects color and size for each 'light' object as a local var*, and ran into a bit of trouble with it and ran out of time last night:
Retrieving a string from a local var, no problem
making said string be recognized as a constant for an effect... not happening.

I was thinking I could just store the int value of the constant as a local var, and plug that in, skipping the constant. That should be much simpler. I am not able to verify this until later, but before I get that far, is this a good way to go about this?


*The goal is a reusable script on a switch or trigger that can turn on as many lights as I set, all with different colors and radii to be assigned when the light objects are placed. I would rather drive complexity out of the switch script and keep the light information localized to the objects, if at all possible.

#2
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<fielding one...>

Shouldn't be a problem. By the time the script is compiled those "constants" are replaced with their integer equivalent. So a constant defined as 2 somewhere in an include is replaced with the number 2 everywhere that constant is mentioned.

So a function that asks for func(CONSTANT_NUMBER) can be passed an int variable as easily as an int constant.

Hmmm, Lightfoot or WhiZard can explain it better, but you shouldn't have a problem replacing the constant with variables, so long as the variable is the same type as the constant and has a valid value.

<...from left field>

#3
henesua

henesua
  • Members
  • 3 863 messages
Leurnid,
I did the same thing. I used a local string for color, and a local int for radius. Then created a function that took those two pieces of data and returned the integer value representing the light vfx. The function nests the data, first checking for color then embedding a switch for radius (each unit is equal to 5' radius) to return the actual value of the light vfx.

I used a string for color, because it is easier for a builder to write "green" than it is to guess at a random integer representing green. The only problem with this approach is that you need to pre-process the string to be all lowercase so you eliminate the issues with humans and their inconsistent use of capitalization.

[edit]
And I wanted to add... you could also contnue with your first method AND have a local string which  "looks" like the constant string. However, when you do this, you need to create a function that converts this string into the VFX value. You'd have a longer sequence of if/then statements to pass thorugh before arriving at the VFX value, but it works. I've done this for my "disease trigger" which takes a string and converts it to a disease to give the person who enters.

Either way you need a function which converts the local variable into the integer value represented by the constant.

The third way of course is to have the 2da next to you (the builder), as TAD mentioned alsewhere, and simply enter that into the local integer on the object. I'm too lazy as a builder for that however. I prefer to be able to look at local vars on an object and understand what is happening.

Modifié par henesua, 08 mai 2012 - 09:25 .


#4
Leurnid

Leurnid
  • Members
  • 271 messages
Well, I used the lexicon to look up the value for VFX_DUR_LIGHT_YELLOW_5, which it says is 157... plugged that into the previously working script to replace the constant, ran a test of the module, and bang! All my light sources made some electrical sounds and started pulsing blue.

Me thinks my copy of the lexicon is wrong.

Nope, I am an idiot, forgot to include my 'n' prefix when I set the local variable, lol.

Modifié par Leurnid, 08 mai 2012 - 09:32 .


#5
henesua

henesua
  • Members
  • 3 863 messages
Check the 2da.

#6
Leurnid

Leurnid
  • Members
  • 271 messages

henesua wrote...

Leurnid,
I did the same thing. I used a local string for color, and a local int for radius. Then created a function that took those two pieces of data and returned the integer value representing the light vfx. The function nests the data, first checking for color then embedding a switch for radius (each unit is equal to 5' radius) to return the actual value of the light vfx.

I used a string for color, because it is easier for a builder to write "green" than it is to guess at a random integer representing green. The only problem with this approach is that you need to pre-process the string to be all lowercase so you eliminate the issues with humans and their inconsistent use of capitalization.

[edit]
And I wanted to add... you could also contnue with your first method AND have a local string which  "looks" like the constant string. However, when you do this, you need to create a function that converts this string into the VFX value. You'd have a longer sequence of if/then statements to pass thorugh before arriving at the VFX value, but it works. I've done this for my "disease trigger" which takes a string and converts it to a disease to give the person who enters.

Either way you need a function which converts the local variable into the integer value represented by the constant.

The third way of course is to have the 2da next to you (the builder), as TAD mentioned alsewhere, and simply enter that into the local integer on the object. I'm too lazy as a builder for that however. I prefer to be able to look at local vars on an object and understand what is happening.


That is mind-bogglingly impressive, but way more complicated than my addled brain and I want to get.

I dabated going the way you did when I was setting up my conceal and cover trigger script. Using the descriptive column values versus the hard effect values. I opted to use the hard effect values to a: avoid confusion (the conceal hard effect is a percent, but so is the description, so 25% concealment is a 10% concealment bonus... wtg wotc) and b: avoid work converting values around, and c:  give greater capability to a builder, who maybe wants an intermediate value not on the standard table (20% concealment, for a 8% bonus).

When I was thinking I could use a string as the constant, I was thinking that stringing together strings to build the name of the VFX effect would let me do what you describe, but when I realized that it wasn't going to, I knew that even if I figured out a way to convert a string to a constant, it was going to be way more work than I wanted.  I would rather just include a commented list of the VFX_DUR_LIGHT values in the switch script.

My preceeding mistake taught me another fun lesson too though... if I just use locally stored numbers, I can have one of my light objects do something like emit darkness or flicker blue and make an electric buzz :lol:

#7
Leurnid

Leurnid
  • Members
  • 271 messages

henesua wrote...

...

And I wanted to add... you could also contnue with your first method AND have a local string which  "looks" like the constant string. However, when you do this, you need to create a function that converts this string into the VFX value. You'd have a longer sequence of if/then statements to pass thorugh before arriving at the VFX value, but it works. I've done this for my "disease trigger" which takes a string and converts it to a disease to give the person who enters.


I forgot to mention... I would love to see how you did that!

I was all over the lexicon and google trying to get a clue about how to pull something like that off... it was the end of the day, but even with a fresh start, I don't think I was going to get anywhere close to that solution.

#8
Leurnid

Leurnid
  • Members
  • 271 messages
OK, grrr..

I have non emitter candles that just have the flame animation... they will pulse blue and flicker, but won't produce the VFX area light effect?

#9
Failed.Bard

Failed.Bard
  • Members
  • 774 messages

Leurnid wrote...

OK, grrr..

I have non emitter candles that just have the flame animation... they will pulse blue and flicker, but won't produce the VFX area light effect?

  Some placeables can't emit light.


  As for how you'd do colour/size, that'd be easy.

153 VFX_DUR_LIGHT_BLUE_5
154 VFX_DUR_LIGHT_BLUE_10
155 VFX_DUR_LIGHT_BLUE_15
156 VFX_DUR_LIGHT_BLUE_20
157 VFX_DUR_LIGHT_YELLOW_5
158 VFX_DUR_LIGHT_YELLOW_10
159 VFX_DUR_LIGHT_YELLOW_15
160 VFX_DUR_LIGHT_YELLOW_20
161 VFX_DUR_LIGHT_PURPLE_5
162 VFX_DUR_LIGHT_PURPLE_10
163 VFX_DUR_LIGHT_PURPLE_15
164 VFX_DUR_LIGHT_PURPLE_20
165 VFX_DUR_LIGHT_RED_5
166 VFX_DUR_LIGHT_RED_10
167 VFX_DUR_LIGHT_RED_15
168 VFX_DUR_LIGHT_RED_20
169 VFX_DUR_LIGHT_ORANGE_5
170 VFX_DUR_LIGHT_ORANGE_10
171 VFX_DUR_LIGHT_ORANGE_15
172 VFX_DUR_LIGHT_ORANGE_20
173 VFX_DUR_LIGHT_WHITE_5
174 VFX_DUR_LIGHT_WHITE_10
175 VFX_DUR_LIGHT_WHITE_15
176 VFX_DUR_LIGHT_WHITE_20
177 VFX_DUR_LIGHT_GREEN_5
178 VFX_DUR_LIGHT_GREEN_10
179 VFX_DUR_LIGHT_GREEN_15
180 VFX_DUR_LIGHT_GREEN_20

Sizes for the colours in that range are done nicely by grouping, so when you store a variable for light radius, you'd make 5' radius equal 0, 10' = 1, 15' = 2, 20' = 3, and add that to your base colour stored int (153, 157, 161, 165, 169, 173, or 177) to get your vfx number.

#10
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Leurnid wrote...
...Retrieving a string from a local var, no problem
making said string be recognized as a constant for an effect... not happening.


Ok, Rolo has already said all of this, I am just going to say it a little different.

To explain why it does not work, lets look at the declaration of a Constant with an explaination of each part.


const int VFX_DUR_LIGHT_BLUE_5 = 153;
const DataType Lable = ImmediateConstant;



DataType: The data type of the ImmediateConstant
Lable: The Lable that we want the compiler to recognize in place of the ImmediateConstant
ImmediateConstant: Yep the NWN compiler will only take Immediate Constants as the value for the lable. This simply means that you can not use an expression to set the value. Even if the expression evalulates to a constant, it is still not allowed within NWN script.

The main problem you are running into is that the Lable for the constant is an instruction to the compiler. All Lables are replaced with there values within the compiled code( unless they are external, something we just can not do within nwscript). So once the script is compiled there is simply no way to know that 153 was once know as the Lable VFX_DUR_LIGHT_BLUE_5.


...I was thinking I could just store the int value of the constant as a local var, and plug that in, skipping the constant. That should be much simpler. I am not able to verify this until later, but before I get that far, is this a good way to go about this?


Yes, you can do that. You are however not skipping the constant, 153 is the constant its value never changes.
VFX_DUR_LIGHT_BLUE_5 is just a compile time Lable that someone gave to the constant 153.

henesua wrote...
Either way you need a function which converts the local variable into the integer value represented by the constant.(Constant's Lable)

Leurnid wrote....
I forgot to mention... I would love to see how you did that!


int ConvertLableToConstant( string sContLable)
{
if ( sContLable == "VFX_DUR_LIGHT_BLUE_5") return VFX_DUR_LIGHT_BLUE_5;
if ( sContLable == "VFX_DUR_LIGHT_BLUE_10") return VFX_DUR_LIGHT_BLUE_10;
if ( sContLable == "VFX_DUR_LIGHT_BLUE_15") return VFX_DUR_LIGHT_BLUE_15;
if ( sContLable == "VFX_DUR_LIGHT_BLUE_20") return VFX_DUR_LIGHT_BLUE_20;
if ( sContLable == "VFX_DUR_LIGHT_YELLOW_5") return VFX_DUR_LIGHT_YELLOW_5;
if ( sContLable == "VFX_DUR_LIGHT_YELLOW_10") return VFX_DUR_LIGHT_YELLOW_10;
if ( sContLable == "VFX_DUR_LIGHT_YELLOW_15") return VFX_DUR_LIGHT_YELLOW_15;
if ( sContLable == "VFX_DUR_LIGHT_YELLOW_20") return VFX_DUR_LIGHT_YELLOW_20;
if ( sContLable == "VFX_DUR_LIGHT_PURPLE_5") return VFX_DUR_LIGHT_PURPLE_5;
if ( sContLable == "VFX_DUR_LIGHT_PURPLE_10") return VFX_DUR_LIGHT_PURPLE_10;
if ( sContLable == "VFX_DUR_LIGHT_PURPLE_15") return VFX_DUR_LIGHT_PURPLE_15;
if ( sContLable == "VFX_DUR_LIGHT_PURPLE_20") return VFX_DUR_LIGHT_PURPLE_20;
// ect
return -1;
}

Modifié par Lightfoot8, 09 mai 2012 - 04:24 .


#11
Leurnid

Leurnid
  • Members
  • 271 messages
Figures, I just got done banging it out the hard way based on my interpretation of Henesua and Failed.Bard's comments, and you come in with a  much cleaner solution.

Just so, here is what I have right now, and it works, but LF's solution would tighten it up a bit:

void main()
{
    object oArea = GetArea(OBJECT_SELF);
    string sLights = (GetTag(OBJECT_SELF)+"_light");
    object oObject = GetFirstObjectInArea(oArea);
    effect eLight;
    int nVFXType = VFX_DUR_LIGHT_PURPLE_5; //defaults VFX setting if no override later

    if (GetLocalInt(OBJECT_SELF,"iAmOn") == 0)  //is it off?
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);  //animates switch click
        SetLocalInt(OBJECT_SELF,"iAmOn",1); //sets local var to 'on'

        while(GetIsObjectValid(oObject))    // Loop all objects in the area
        {
            if (GetTag(oObject) == sLights )    // is it a light object?
            {
                if (GetLocalInt(oObject, "iStandardLight") == 1)    // is it a std light?
                {
                    AssignCommand(oObject, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
                    SetPlaceableIllumination(oObject, TRUE);    //turns on std light
                }
                else  //then it must be a light object for VFX
                {
                    if (GetLocalInt(oObject,"iHaveVFX"))  //is light object is flagged for color?
                    {
                        string sCol = GetStringLeft(GetStringLowerCase(GetLocalString(oObject,"sColor")),1); //get the lowercase first letter of the sColor stringon the light object
                        int nSize = GetLocalInt(oObject,"nSizer");  //get the size modifier off the light object: 0=5', 1=10', 2=15', 3 =20'

                        if (sCol == "b")
                        {
                            nVFXType = (153 + nSize);
                        }
                        else if (sCol == "y")
                        {
                            nVFXType = (157 + nSize);
                        }
                        else if (sCol == "p")
                        {
                            nVFXType = (161 + nSize);
                        }
                        else if (sCol == "r")
                        {
                            nVFXType = (165 + nSize);
                        }
                        else if (sCol == "o")
                        {
                            nVFXType = (169 + nSize);
                        }
                        else if (sCol == "g")
                        {
                            nVFXType = (177 + nSize);
                        }
                        else //sCol == "w" or any other value defaults to white
                        {
                            nVFXType = (173 + nSize);
                        }
                    }
                    else //if no local variables are on the light object
                    {
                        if (GetLocalInt(OBJECT_SELF, "nVFXdefault"))  //get default on switch (uses raw VFX int)
                        {
                            nVFXType = (GetLocalInt(OBJECT_SELF, "nVFXdefault"));
                        }
                    }
                    effect eLight = EffectVisualEffect(nVFXType);
                    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oObject);
                    //applies applicable VFX to current light object
                }
            }

        oObject = GetNextObjectInArea(oArea);
        }
    }
    else //It's on; lights off!
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
        SetLocalInt(OBJECT_SELF,"iAmOn",0);

        while(GetIsObjectValid(oObject)) //check all objects
        {
            if (GetTag(oObject) == sLights )
            {
                if (GetLocalInt(oObject, "iStandardLight") == 1)
                {
                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(1.2,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
}


The foundation of this was a script by Nereng, I cleaned it up some, then got it all messy with my chaos.

While I don't mind the 'smart' color and size routine, my first thought is to just pull it back out and use the constant's int values and save myself some fuss all around.

Modifié par Leurnid, 09 mai 2012 - 06:10 .


#12
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
I wrote up a little example script, playing around with FindSubString now that I know what a useful function it is.

 For this script, you use a single string variable with the color at the start, and the radius at the end.  As an example, Green 05, or red 15.  Case doesn't matter, but with the 5' version it's best to put it as 05, and not just 5.

// (5/9/2012) Failed Bard
// Alternate placeable light system
// Playing around with FindSubString.

void main()
{
string sColors = "blu yel pur red ora whi gre";

string sColor = GetLocalString (OBJECT_SELF, "LIGHT");
int nColor = FindSubString (sColors, GetStringLowerCase( GetStringLeft (sColor, 3)));

int nBrightness = (StringToInt (GetStringRight (sColor, 2)) / 5) - 1;
if (nBrightness < 0) nBrightness = 0;
else if (nBrightness > 3) nBrightness = 3;

int nLight = 153 + nColor + nBrightness;

effect eLight = EffectVisualEffect (nLight);
ApplyEffectToObject (DURATION_TYPE_TEMPORARY, eLight, OBJECT_SELF, 10.0);
}

#13
Leurnid

Leurnid
  • Members
  • 271 messages
Ah, you went with the 3 letter designation so that with the space for padding, each one past the first would add 4 to the primary value. To slick for me, I am still brute-forcing these things.

For the lighting effects, you don't seem to need the float for duration... for whatever reason. I can't find a detailed reason why, but it works without.

*edit*
What I am finding is that if the objects being lit up are byond about 4 tiles from the player(s), the lighting update doesn't effect them, and while the animation may toggle on or off, the cast light is unpredictable.  I had one standard light in a long hall that seemed to be casting off darkness, when I was under it while testing, the hall was pitch black!

Modifié par Leurnid, 09 mai 2012 - 04:23 .


#14
Leurnid

Leurnid
  • Members
  • 271 messages
Incorporating F.B's routine and removing some more of my stupid, I get:

void main()
{
    object oArea = GetArea(OBJECT_SELF);
    string sLights = (GetTag(OBJECT_SELF)+"_light");
    object oLight = GetFirstObjectInArea(oArea);
    effect eLight;

    if (GetLocalInt(OBJECT_SELF,"iAmOn") == 0)  //is it off?
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);  //animates switch click
        SetLocalInt(OBJECT_SELF,"iAmOn",1); //sets local var to 'on'

        while(GetIsObjectValid(oLight))    // Loop all objects in the area
        {
            if (GetTag(oLight) == sLights )    // is it a light object?
            {
                if (GetLocalInt(oLight, "iStandardLight"))    // is it a std light?
                {
                    AssignCommand(oLight, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
                    SetPlaceableIllumination(oLight, TRUE);    //turns on std light
                }
                else  //then it must be a light object for VFX
                {
                    string sColor = "Blue 10"; //default light color
                    if (GetLocalInt(oLight,"iHaveVFX"))
                    {
                        sColor = (GetLocalString (oLight, "sColor"));
                    }
                    else if (GetLocalInt(OBJECT_SELF,"iHaveVFX"))
                    {
                        sColor = (GetLocalString (OBJECT_SELF, "sColor"));
                    }

                    //F.B's simplified check routine:
                    string sColors = "blu yel pur red ora whi gre";
                    int nColor = FindSubString (sColors, GetStringLowerCase( GetStringLeft (sColor, 3)));
                    int nSize = (StringToInt (GetStringRight (sColor, 2)) / 5) - 1;
                    if (nSize < 0) nSize = 0;
                    else if (nSize > 3) nSize = 3;
                    int nVFXType = 153 + nColor + nSize;

                    effect eLight = EffectVisualEffect(nVFXType);
                    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oLight);
                }
            }

        oLight = GetNextObjectInArea(oArea);
        }
    }
    else //It's on; lights off!
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
        SetLocalInt(OBJECT_SELF,"iAmOn",0);

        while(GetIsObjectValid(oLight)) //check all objects
        {
            if (GetTag(oLight) == sLights )
            {
                if (GetLocalInt(oLight, "iStandardLight") == 1)
                {
                AssignCommand(oLight, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
                SetPlaceableIllumination(oLight, FALSE);
                }
                effect eEffect = GetFirstEffect(oLight);
                while (GetIsEffectValid(eEffect) == TRUE)
                    {
                    if (GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT)
                        RemoveEffect(oLight, eEffect);
                    eEffect = GetNextEffect(oLight);
                    }
            }
            oLight = GetNextObjectInArea(oArea);
        }
    }
    DelayCommand(1.2,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
}


Instead of putting an int on the switch for a switch default, and a constant in the script for a script default color, I smoothed out my garbled logic so F.B's color checking routine could also handle the switch and script defaults, allowing for consistent definition without extra routines, in fact, this trimmed some fat out of the script.

Modifié par Leurnid, 09 mai 2012 - 06:09 .


#15
Leurnid

Leurnid
  • Members
  • 271 messages
This script, and several like it that I already use, check to see if there are local variables to use looking for a local int value; ( iHaveVFX ) in this case.
It would be just as easy to check to see of the string value I am really there looking for has a value stored ( sColor != "" )..
The advantage of using the int-flag, is I can keep the effect's value on the object, and toggle it on or off via the integer. whereas checking for the string value is lean and clean...

I figure this comes down to personal preference, but if anybody has opinions about this, I would love to here em.

#16
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
It's generally not a good practice to define a variable within a while or for loop, it can cause oddities in behaviour. The variables at the start should likely look something like:

object oArea = GetArea(OBJECT_SELF);
string sLights = (GetTag(OBJECT_SELF)+"_light");
object oLight;
effect eLight, eEffect;

string sColors = "blu yel pur red ora whi gre";
string sColor;
int nColor, nSize, nVFXType;

Modifié par Failed.Bard, 09 mai 2012 - 08:39 .


#17
Leurnid

Leurnid
  • Members
  • 271 messages
Yeah, after I posted, I moved a few things around and removed a couple of vars entirely:

void main()
{
    object oArea = GetArea(OBJECT_SELF);
    string sLights = (GetTag(OBJECT_SELF)+"_light");
    object oLight = GetFirstObjectInArea(oArea);
    effect eLight;
    string sColor;
    string sColors = "blu yel pur red ora whi gre";

    if (GetLocalInt(OBJECT_SELF,"iAmOn") == 0)  //is it off?
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);  //animates switch click
        SetLocalInt(OBJECT_SELF,"iAmOn",1); //sets local var to 'on'

        while(GetIsObjectValid(oLight))    // Loop all objects in the area
        {
            if (GetTag(oLight) == sLights )    // is it a light object?
            {
                if (GetLocalInt(oLight, "iStandardLight"))    // is it a std light?
                {
                    AssignCommand(oLight, ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
                    SetPlaceableIllumination(oLight, TRUE);    //turns on std light
                }
                else  //then it must be a light object for VFX
                {
                    sColor = "White 5"; //set default then check for prefered light color
                    if (GetLocalInt(oLight,"iHaveVFX")) sColor = (GetLocalString (oLight, "sColor"));
                    else if (GetLocalInt(OBJECT_SELF,"iHaveVFX")) sColor = (GetLocalString (OBJECT_SELF, "sColor"));

                    //F.B's simplified vfx color converter:
                    int nColor = FindSubString (sColors, GetStringLowerCase( GetStringLeft (sColor, 3)));
                    int nSize = (StringToInt (GetStringRight (sColor, 2)) / 5) - 1;
                    if (nSize < 0) nSize = 0;
                    else if (nSize > 3) nSize = 3;
                    eLight = EffectVisualEffect(153 + nColor + nSize);
                    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oLight);
                }
            }

        oLight = GetNextObjectInArea(oArea);
        }
    }
    else //It's on; lights off!
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);
        SetLocalInt(OBJECT_SELF,"iAmOn",0);

        while(GetIsObjectValid(oLight)) //check all objects
        {
            if (GetTag(oLight) == sLights )
            {
                if (GetLocalInt(oLight, "iStandardLight") == 1)
                {
                    AssignCommand(oLight, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
                    SetPlaceableIllumination(oLight, FALSE);
                }
                else
                {
                    effect eEffect = GetFirstEffect(oLight);
                    while (GetIsEffectValid(eEffect) == TRUE)
                    {
                        if (GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT) RemoveEffect(oLight, eEffect);
                        eEffect = GetNextEffect(oLight);
                    }
                }
            }
            oLight = GetNextObjectInArea(oArea);
        }
    }
    DelayCommand(1.2,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
}



#18
Leurnid

Leurnid
  • Members
  • 271 messages
my test mod isn't the ideal stripped down environment to fully test something, I have a lot of other script experiments floating around (and I am usually too lazy to export them into a fresh module), but as far as I can tell, the VFX_DUR_LIGHTs when toggled on, and wandered away from (past about 4 tiles) by the Player(s), and then turned off, for some reason do not turn off properly, leaving an illuminated area... this is probably well known with some clever work around, and I would like to hear it.

#19
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
From the Lexicon on RecomputeStandardLighting:

Known Bugs

The game engine is bugged when it comes to lighting. Even if you turn off a light and call RecomputeStaticLighting, there'll still be a glow around the spot. BioWare has known about this bug for quite some time now, and the fact that it hasn't been fixed yet probably suggests that it can't or won't be.

 

Likely it's at least partly that, a hardcoded graphic engine bug.

#20
Leurnid

Leurnid
  • Members
  • 271 messages
well poo on them

#21
henesua

henesua
  • Members
  • 3 863 messages
Delay the call to recompute static lighting. You'll need to fine to how long the delay is. You will never need to exceed 6.0 seconds as far as i know.

The problem is that the light is still in play when the script runs the recompute lighting function. If you are recomputing from a "death" script for a placeable, then you should assign the recompute to the light source's area. AssignCommand(oArea, DelayCommand(3.0, RecomputeStaticLighting()));

something like that.

#22
Leurnid

Leurnid
  • Members
  • 271 messages
Delaying that more (was already 1.2 seconds) didn't help.

Edit: thought I had something, didn't, deleted it.

Modifié par Leurnid, 10 mai 2012 - 04:39 .


#23
henesua

henesua
  • Members
  • 3 863 messages
 Works fine for me.

//::///////////////////////////////////////////////
//:: aa_light_death
//:://////////////////////////////////////////////
/*
    Death Event for a light placeable

*/
//:://////////////////////////////////////////////
//:: Created: The Magus (2012 may 7)
//:://////////////////////////////////////////////

void main()
{
    object oArea    = GetArea(OBJECT_SELF);
    AssignCommand(oArea, DelayCommand(2.4, RecomputeStaticLighting(oArea)) );
    object oPair    = GetLocalObject(OBJECT_SELF, "PAIRED");
    object oSource  = GetLocalObject(OBJECT_SELF, "LIGHT_OBJECT");
    SetLocalInt(oSource, "NW_L_AMION", 0);
    if(GetIsObjectValid(oPair))
        DestroyObject(oPair);
    DestroyObject(OBJECT_SELF);
}





the following is a snippet in an onUsed event for turning a placeable off:

        SetLocalInt(OBJECT_SELF,"NW_L_AMION",0); // state tracking
        PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE);

        // handle lights
        if(GetLocalInt(OBJECT_SELF, "LIGHTABLE"))
        {
            DeleteLocalInt(OBJECT_SELF, "iLight"); // light tracking
            // remove effects
            effect eEffect = GetFirstEffect(OBJECT_SELF);
            while (GetIsEffectValid(eEffect) == TRUE)
            {
                if(     GetEffectType(eEffect)==EFFECT_TYPE_VISUALEFFECT
                    &&  GetEffectCreator(eEffect)==OBJECT_SELF
                  )
                    DelayCommand(0.3, RemoveEffect(OBJECT_SELF, eEffect));
                eEffect = GetNextEffect(OBJECT_SELF);
            }

            DelayCommand(0.4,SetPlaceableIllumination(OBJECT_SELF, FALSE));
            DelayCommand(0.9,RecomputeStaticLighting(GetArea(OBJECT_SELF)));
        }

Modifié par henesua, 10 mai 2012 - 01:11 .


#24
Leurnid

Leurnid
  • Members
  • 271 messages
*does a double take*

GetLocalObject is freaking me out... the beginning and the end of that I get, but the GetLocalObject... can you store an object in an object!?!?


*EDIT* 
And why do so many people use 'NW_L_AMION' for state tracking? I haven't seen anything official regarding it, but it is a fairly common thing.

Modifié par Leurnid, 10 mai 2012 - 05:48 .


#25
AndarianTD

AndarianTD
  • Members
  • 701 messages

Leurnid wrote...

*does a double take*

GetLocalObject is freaking me out... the beginning and the end of that I get, but the GetLocalObject... can you store an object in an object!?!?


Sure you can -- except that strictly speaking, you're not storing "an object in an object" with this. You're storing and getting a handle to an object, which is what all the "Get Object" functions give you. Objects exist globally in the game's object data structures, which is why you have to search for them with GetObjectByTag, etc. But object handles are relatively stable, so you can store one on another object for easy retrieval later from that object. I say "relatively" because you have to be careful; object handles can change or go away, say, if a creature is destroyed (which includes what happens to a horse when you mount it).

Leurnid wrote...

Retrieving a string from a local var, no problem
making said string be recognized as a constant for an effect... not happening.


That'll never work, because the constant name is just a label to refer the compiler to it's associated constant int value. It's not saved in the .ncs file and not available at runtime.

I was thinking I could just store the int value of the constant as a local var, and plug that in, skipping the constant. That should be much simpler. I am not able to verify this until later, but before I get that far, is this a good way to go about this?

*The goal is a reusable script on a switch or trigger that can turn on as many lights as I set, all with different colors and radii to be assigned when the light objects are placed. I would rather drive complexity out of the switch script and keep the light information localized to the objects, if at all possible.


That's how I've done it when I've scripted similar things. You should be able to look up the int values for the constants in the Lexicon for easy reference.

Modifié par AndarianTD, 10 mai 2012 - 11:33 .