Author Topic: Light switch system, what's wrong?  (Read 393 times)

Legacy_JM Scion

  • Jr. Member
  • **
  • Posts: 77
  • Karma: +0/-0
Light switch system, what's wrong?
« on: January 09, 2011, 08:48:38 am »


               For my current module I'm trying to devise a modern lighting system that behaves just like the lights in your house. If the player flicks a light switch, all the lights in that room turn on or off independently of other rooms, and if there's a power outage everything shuts off. Not very exciting, but in this module the player will be in considerable danger whenever the lights are off so it turns into a tense situation when you try to find the light switch.

I wrote a single script to be placed in the OnUsed slot of the light switch. What should happen is that the player uses the light switch placeable, and light effects are attached to the invisible light source objects, creating the illusion of lights turning on. The problem is, that isn't happening. Everything in the script looks fine, the object tags are in order, and the script compiles fine, so I can't see where the error could be.

On the other hand, this is the first time I'm working with combining tags and creating while loops from scratch, so I suppose the problem must be within either task.

[nwscript]
//::///////////////////////////////////////////////
//:: Static Lighting System Main File
//:: st_light_main
//:: Copyright © 2011 JM Scion
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Created By: JM Scion
//:: Created On: 1/8/11
//:://////////////////////////////////////////////

/*
I'm developing a universal light system for Static to allow for nearly
every light source in the game to be toggled without having to write
individual scripts for each.

This should allow for a more realistic and immersive experience, but if
I manage to crank out a system that gives the player advantages or disadvantages
in light and darkness, this could be a great tactical ability as well.

The mechanics are simple. Every light source in the game has the tag (LIGHT_)
followed by a unique area designation tag (A1). Lights in different rooms
have different designation tags, so that when the lights in room A turn on,
the lights in B stay off.

This script should be placed on the light switch object. So far, there should
be no need to write other scripts to handle lighting but I'm keeping room for
any specialized scripts should the need arise.

Note to self: Find and import a *click* noise for when switches are flicked.
*/

void main()
{
object oPC = GetFirstPC();
object oArea = GetArea(oPC);
int nPowerOut = GetLocalInt(oArea, "nPowerOut"); //Whether there is power in the building.
//Since it is more rare for the power to be unavailable, 0 means the power is ON
//while 1 means the power is OFF.

object oSwitch; //The light switch or object that toggles lights.
string sSwitch = GetTag(oSwitch); //Tag of the light switch.
object oLight; //The light source itself.
string sLight = GetTag(oLight); //Tag of the light source.
int nOn = GetLocalInt(oLight, "nOn"); //Whether the light is on or off.
//Set to 1 if the light is ON, 0 if the light is OFF.
int nNth; //Simple counting integer.

/*
The tag of the light switch should be the light's designation tag.
So if we wanted to turn off all the lights in room PS1, the switch's tag should
be just PS1.

First we need to check if there is power to the building. If there is a power
outage, the light can't turn on and the player must be informed.
*/

if (nPowerOut == 1)
    {
    SendMessageToPC(oPC, "There doesn't seem to be any power...");

    return;
    }

//For most instances, the switch should be the object being activated.
oSwitch = OBJECT_SELF;
oLight = GetObjectByTag("LIGHT_" + sSwitch);

//The lights are off. Turn all the lights on.
if (nOn == 0)
    {
    while (GetIsObjectValid(oLight))
        {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_LIGHT_GREY_10), oLight);
        SetLocalInt(oLight, "nOn", 1);
        nNth++;
        oLight = GetObjectByTag("LIGHT_" + sSwitch, nNth++);
        }
    return;
    }

//The lights are on. Turn the lights off.
if (nOn == 1)
    {
    while (GetIsObjectValid(oLight))
        {
        RemoveEffect(oLight, EffectVisualEffect(VFX_DUR_LIGHT_GREY_10));
        SetLocalInt(oLight, "nOn", 0);
        nNth++;
        oLight = GetObjectByTag("LIGHT_" + sSwitch, nNth++);
        }
    return;
    }
}
[/nwscript]
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Light switch system, what's wrong?
« Reply #1 on: January 09, 2011, 04:48:20 pm »


               First, I have not read through the entire script. 

Here is what i have seen with just a quick glance. 

object oSwitch; //The light switch or object that toggles lights.
 oSwitch has just ben declaired at this point it is an invalid object.
the next line tryes to get the tag of the invalid object  

string sSwitch = GetTag(oSwitch);//Tag of the light switch.
since oSwirtch == OBJECT_INVALID; sSwitch == "";
object oLight; //The light source itself.
Sam thing with oLight here as with oSwitdh   
string sLight = GetTag(oLight); //Tag of the light source.
again sLight here is a null string since oLight is an invalid object

nOn is always going to be equal to 0 since oLight is still an invalid object at this point in the script.
int nOn = GetLocalInt(oLight, "nOn"); //Whether the light is on or off.
               
               

               
            

Legacy_JM Scion

  • Jr. Member
  • **
  • Posts: 77
  • Karma: +0/-0
Light switch system, what's wrong?
« Reply #2 on: January 10, 2011, 02:44:51 am »


               Ugh, you're absolutely right. I thought I was being organized but completely overlooked that part.

So now I've properly declared the objects oSwitch and oLight. The lights turn on perfectly. The problem is now they don't turn off. I'm not sure if I'm not setting or calling the nOn integer correctly, or not removing the light effect properly.

I realize that it would be simpler to just have the Light Source invisible objects have the light effect attached to their OnSpawn scripts and then spawn them in or destroy them to simulate lights turning on and off, but I don't know if that would result in a performance hit when the light objects are spawning in.

Here's what I have for the bottom half of the script right now:

[nwscript]
//The lights are on. Turn the lights off. This is a bit complicated.
if (nOn == 1)
    {
    while (GetIsObjectValid(oLight))
        {
        //We need to loop through the effects to find the right one.
            effect eLoop=GetFirstEffect(oLight);

            while (GetIsEffectValid(eLoop))
                {
                if (GetEffectType(eLoop)==EFFECT_TYPE_VISUALEFFECT)
                DelayCommand(0.5, RemoveEffect(oPC, eLoop));

                eLoop=GetNextEffect(oLight);
                }
        SetLocalInt(oLight, "nOn", 0);
        nNth++;
        oLight = GetObjectByTag("LIGHT_" + sSwitch, nNth++);
        }
    return;
    }
else
//The lights are off. Turn all the lights on.
if (nOn == 0)
    {
    while (GetIsObjectValid(oLight))
        {
        DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_LIGHT_WHITE_10), oLight));
        SetLocalInt(oLight, "nOn", 1);
        nNth++;
        oLight = GetObjectByTag("LIGHT_" + sSwitch, nNth++);
        }
    return;
    }
[/nwscript]
               
               

               


                     Modifié par JM Scion, 10 janvier 2011 - 02:46 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Light switch system, what's wrong?
« Reply #3 on: January 10, 2011, 03:44:11 am »


               Might have something to do with this line:

DelayCommand(0.5, RemoveEffect(oPC, eLoop));

I don't think you mean to remove the effect from a player (oPC) but rather oLight?

It also seems like you are trying to advance nNth twice?:

nNth++;
oLight = GetObjectByTag("LIGHT_" + sSwitch, nNth++);

I am also a bit confused about how you are checking the "nOn" integer. Are you just checking the first light source and going off of that? Why not just set it on the switch itself to see if it is on or off? Just a thought.

Maybe structured a bit more like so?:

void main()
{
    object oSwitch = OBJECT_SELF;
    string sSwitch = GetTag(oSwitch); //Tag of the light switch.
    string sLight = "LIGHT" + sSwitch;
    int nOn = GetLocalInt(oSwitch, "nOn");
    int nNth = 1;
    object oLight = GetNearestObjectByTag(sLight, oSwitch, nNth);

    if (nOn == 0)//light is off
    {
        while (GetIsObjectValid(oLight))
        {
            effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_GREY_10);
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oLight);
            nNth++;
            oLight = GetNearestObjectByTag(sLight, oSwitch, nNth);
        }
        SetLocalInt(oSwitch, "nOn", 1);
        return;
    }

    if (nOn == 1)//light is on
    {
        while (GetIsObjectValid(oLight))
        {
            effect eLoop = GetFirstEffect(oLight);
            while (GetIsEffectValid(eLoop))
            {
                if (GetEffectType(eLoop) == EFFECT_TYPE_VISUALEFFECT)
                DelayCommand(0.5, RemoveEffect(oLight, eLoop));
                eLoop = GetNextEffect(oLight);
            }
            nNth++;
            oLight = GetNearestObjectByTag(sLight, oSwitch, nNth);
        }
        SetLocalInt(oSwitch, "nOn", 0);
        return;
    }
}

Good luck.
               
               

               


                     Modifié par GhostOfGod, 10 janvier 2011 - 04:11 .
                     
                  


            

Legacy_JM Scion

  • Jr. Member
  • **
  • Posts: 77
  • Karma: +0/-0
Light switch system, what's wrong?
« Reply #4 on: January 10, 2011, 08:43:19 am »


               I need to stop writing scripts at 3 AM. So many senseless typos. Thanks so much for your help Ghost. I just tried it and the lights turn on and off in unison and without fail. I feel like a five year old playing with the light switches now.



As for why the nOn integer is stored on an individual light source instead of the switch itself, sometimes the power in the building may go out on the player, or the player activates the lights in a building via a fuse box rather than the switches. I'm not too fond of the integer method myself, I'd rather run a command that looks for the light visual effect on the light source objects directly rather than an integer. But I'll tackle that some other time, the system works for the moment and it's time to build around it.