Author Topic: oddly enough, another constant query:  (Read 803 times)

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #15 on: May 09, 2012, 09:38:21 pm »


               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 .
                     
                  


            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #16 on: May 09, 2012, 10:35:16 pm »


               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)));
}


               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #17 on: May 09, 2012, 10:53:13 pm »


               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.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #18 on: May 09, 2012, 11:30:23 pm »


               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.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #19 on: May 09, 2012, 11:42:47 pm »


               well poo on them
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #20 on: May 10, 2012, 12:44:28 am »


               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.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #21 on: May 10, 2012, 05:30:26 am »


               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 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #22 on: May 10, 2012, 06:31:45 am »


                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 .
                     
                  


            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #23 on: May 10, 2012, 06:42:29 am »


               *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 .
                     
                  


            

Legacy_AndarianTD

  • Hero Member
  • *****
  • Posts: 725
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #24 on: May 10, 2012, 12:05:08 pm »


               

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 .
                     
                  


            

Legacy_AndarianTD

  • Hero Member
  • *****
  • Posts: 725
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #25 on: May 10, 2012, 12:13:53 pm »


               

Failed.Bard wrote...

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...:


There's no problem with defining variables within a while or for loop. I do it in NWSCRIPT all the time. All you have to do is make sure that a variable declared within the scope of the loop (the curly braces) is initialized properly and used exclusively within that scope -- especially if it's hiding a variable with the same name at a higher scope.
               
               

               


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


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #26 on: May 10, 2012, 02:26:33 pm »


                

Leurnid wrote...

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!?!?


as Andarian said, its a pointer to an object. With lighting I often have more than one object to get the effect. In order to keep track of them, I reference them on each other. Thats what "PAIRED" is all about. This enables me to destroy both objects in a pair. One of those objects was a flame placeable (which could not receive the light visualeffect), the other was a placeable light. The "LIGHT_OBJECT" is the object which players interact with to produce the light. Since it is not destroyed, I track state (On versus Off) on that object.


 

Leurnid wrote... 
*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.


The reason why I am using it: I started with the standard On/Off script that bioware provides for placeables, and never changed the label they used for this state tracking variable. It probably doesn't matter, but I chose to keep it because I didn't know if any other scripts used the same label. And once I started using it, I included it in my own scripts which do look at placeable state. And so... now I am locked into using it, unless I find/replace all these references throughout my scripts. It doesn't seem worth it to me to do so.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #27 on: May 10, 2012, 05:43:07 pm »


               

henesua wrote...

 

Leurnid wrote...

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!?!?


as Andarian said, its a pointer to an object. With lighting I often have more than one object to get the effect. In order to keep track of them, I reference them on each other. Thats what "PAIRED" is all about. This enables me to destroy both objects in a pair. One of those objects was a flame placeable (which could not receive the light visualeffect), the other was a placeable light. The "LIGHT_OBJECT" is the object which players interact with to produce the light. Since it is not destroyed, I track state (On versus Off) on that object.


So do you store that locally on an object as a string var then, but pull it up as an object (by tag I assume)... I have been attempting to do the same thing using locally stored strings, getting those, and getting the objects by tag using those strings... it sounds like GetLocalObject could save me some lines of potential error and waste.

Leurnid wrote... 
*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.


The reason why I am using it: I started with the standard On/Off script that bioware provides for placeables, and never changed the label they used for this state tracking variable. It probably doesn't matter, but I chose to keep it because I didn't know if any other scripts used the same label. And once I started using it, I included it in my own scripts which do look at placeable state. And so... now I am locked into using it, unless I find/replace all these references throughout my scripts. It doesn't seem worth it to me to do so.


Because it had the NW_ prefix, I had hoped it was used someplace officially at some point... I have noticed that a lot people name their local  vars with CAPS_LIKE_A_CONSTANT, for some reason, it bugs me, but I suspect now, based on that answer, the reason for that too is because of a convention started by the folks at Bioware... Is there anything to be said for or against the practice?
               
               

               


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


            

Legacy_eeriegeek

  • Jr. Member
  • **
  • Posts: 75
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #28 on: May 10, 2012, 06:17:12 pm »


               The use of ALL_CAPS for constant definition is just a convention, but it wasn't started by Bioware. It dates at least back to its use as a convention when defining constants for C preprocessor macros.
               
               

               
            

Legacy_Leurnid

  • Sr. Member
  • ****
  • Posts: 473
  • Karma: +0/-0
oddly enough, another constant query:
« Reply #29 on: May 10, 2012, 06:27:21 pm »


               

eeriegeek wrote...

The use of ALL_CAPS for constant definition is just a convention, but it wasn't started by Bioware. It dates at least back to its use as a convention when defining constants for C preprocessor macros.


I'm sorry, I must have misspoke... I meant that I see a lot people use local variables stored with an all cap string, as if they were constants.