Aller au contenu

Photo

SLS and the light tag bug: fixed


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

#1
kamal_

kamal_
  • Members
  • 5 250 messages
Problem: The SLS lighting system relies on the tags of lights. However, saving and reloading the game causes lights to lose their tags, breaking SLS.

Solution: change of the SLS' ginc_sls2 script to reset the tag of the nearest light object when the action to handle placeable lights is called. Solution posted a few posts below.

potential issue: assumes the nearest light object is the one to be used. This is normally the case, but you may want to make a copy of the scripts and use the altered script where you know the closest light will be the right one, such as for usable placeables like torches.

Modifié par kamal_, 29 octobre 2011 - 11:32 .


#2
The Fred

The Fred
  • Members
  • 2 516 messages
I thought that being lost meant they were simply wiped, and all the tags replaced with blank strings.

Personally my inclination is to create lights via script and possibly store their object references somewhere (effectively giving them a unique tag). I haven't gotten onto any of that just yet, though.

#3
kamal_

kamal_
  • Members
  • 5 250 messages
I'm working on a fix. Strangely, in testing it doesn't actually matter what the tag is (I was surprised at that), just that the light object has one. In my test environment I can set the tag to the original tag, and to a different tag, it worked either way. Only when the tag is invalid after reload does it not work.

It should be possible to reassign the light object's tag since the tag is stored as a variable on the associated placeable.

#4
kamal_

kamal_
  • Members
  • 5 250 messages
in ginc_sls2, line 352 is:
string sLightTag = GetLocalString(oFitting,"lightTag");

comment that out and replace it with
            //work around tag bug. kamal
            object oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oFitting, 1);
            string sLightTag = GetLocalString(oFitting,"lightTag");
            SetTag(oLight, sLightTag);

This will change the script that controls turning the light on and off, so that it resets the light's tag automatically when the light is used, and then proceeds normally through the script. It does assume the light you want to turn on is the nearest light, but I believe that will be the case in almost all cases.

Edit: fixed with Lugaid's suggestion of using oFitting instead of OBJECT_SELF when getting nearest light object.

Modifié par kamal_, 30 octobre 2011 - 04:34 .


#5
Shallina

Shallina
  • Members
  • 1 011 messages
SetLocalObject(oArea,light,"lightTag");
GetLocalObject(oArea,"lightTag");

This is working and almost the same as using tag, you just need to store the light once.

#6
kamal_

kamal_
  • Members
  • 5 250 messages

Shallina wrote...

SetLocalObject(oArea,light,"lightTag");
GetLocalObject(oArea,"lightTag");

This is working and almost the same as using tag, you just need to store the light once.

I'd like to see a demo of that, I can see some problems with doing it that way, namely if you're doing it on the light action you could lose the tag before it's ever saved to the area.

#7
Shallina

Shallina
  • Members
  • 1 011 messages
haha
you don't understant

you set those value for every light of the area once on the on enter event (area or module).

I create all light once on the first on client enter area, at "wp_light" I create the light depending on the lamp post near it. And at the same time I construct an Array of local object in the AREA for lights. that's how i solved that problem.

#8
M. Rieder

M. Rieder
  • Members
  • 2 530 messages
Would it work to set a local string on each of the lights which takes the place of their tag and check that string in the script?

#9
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
Shouldn't that be
object oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oFitting, 1);
so that the script gets the nearest light to the fitting, not the caller?

I haven't looked at SLS, but I think each placeable light fitting should spawn it's own light source and save it as a local object.

#10
kamal_

kamal_
  • Members
  • 5 250 messages

Shallina wrote...

haha
you don't understant

you set those value for every light of the area once on the on enter event (area or module).

I create all light once on the first on client enter area, at "wp_light" I create the light depending on the lamp post near it. And at the same time I construct an Array of local object in the AREA for lights. that's how i solved that problem.

You're right I don't understand. It's because you've never posted your code for solving the issue. You've just said it's solved and provided incomplete bits of code. In fact this post I'm quoting is the most complete description you've ever given of your solution, and is still inadequate for the average scripter to recreate. Since you have a solution to a signficant commonly seen problem, why not just share the actual code and not force people to rewrite all that? That's what I don't understand.

Modifié par kamal_, 30 octobre 2011 - 04:42 .


#11
kamal_

kamal_
  • Members
  • 5 250 messages

Lugaid of the Red Stripes wrote...

Shouldn't that be
object oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oFitting, 1);
so that the script gets the nearest light to the fitting, not the caller?

I haven't looked at SLS, but I think each placeable light fitting should spawn it's own light source and save it as a local object.

Good point, I will correct that. Object self should be oFitting, and was when I tested, but doesn't have to be.

#12
kamal_

kamal_
  • Members
  • 5 250 messages
Incidentally, if you make this change to ginc_sls2, and save ginc_sls2 to your override folder, it should fix the problem in every single player module that uses the SLS, thanks to the priority of the override (PWs can ignore the override folder).

#13
kamal_

kamal_
  • Members
  • 5 250 messages

M. Rieder wrote...

Would it work to set a local string on each of the lights which takes the place of their tag and check that string in the script?

Sounds like it would work. I'm not sure if lights lose variables as well as their tags. It would be more work for the builder (more clicks involved in setting a variable on an object versus a tag for new lights, or going and setting the variable to match the tag of all existing lights) but it would get those cases where the nearest light wasn't the correct one.

Line 352 is where you need to change the code if you want to do it that way. It should be straightforward and short, but it's 1:30am here right now and time for sleep.

#14
rjshae

rjshae
  • Members
  • 4 491 messages

kamal_ wrote...

Shallina wrote...

haha
you don't understant

you set those value for every light of the area once on the on enter event (area or module).

I create all light once on the first on client enter area, at "wp_light" I create the light depending on the lamp post near it. And at the same time I construct an Array of local object in the AREA for lights. that's how i solved that problem.

You're right I don't understand. It's because you've never posted your code for solving the issue. You've just said it's solved and provided incomplete bits of code. In fact this post I'm quoting is the most complete description you've ever given of your solution, and is still inadequate for the average scripter to recreate. Since you have a solution to a signficant commonly seen problem, why not just share the actual code and not force people to rewrite all that? That's what I don't understand.


For what it's worth, I'm using an interpretation of Shallina's light management technique for my own module. There's a writeup in volume 4 of my toolset notes (linked below), under the heading "Toggle Streetlights". I call the InitStreetLights routine in the area's on client enter script, then the UpdateLights call from the area heartbeat. I'd be curious to know if that code works for others. Thanks.

Modifié par rjshae, 30 octobre 2011 - 07:39 .


#15
Friar

Friar
  • Members
  • 293 messages
It doesn't appear that "Slayster" is active the vault so I thought I'd run some things by you guys here on the forums.

On an exterior area I want to have a light that operates kind of like the torches in the SLS. The difference is that I wanted the light to turn on during the day because the regular daylight properties are not giving me the effect that I am looking for. It's a deep dark hole outside.

I added sls2_onenter to the On Client Enter Script

I added sls2_heartbeat to the On Heartbeat Script

I took the prefab ghost light and placed it high in the air, shrunk it to .1, .1, .1 size, and I anchored it with lock position.

I set the variables onHours = 7, offHours = 17.

This was my attempt to make a simple switch-a-roo, but the light is just staying on at night.

I double checked to see if I had the tags correct. I found a capitalization issue, I fixed it. However, it still wont' turn off.

Then I thought I might have accidentally put the onEnter Script in the wrong slot. Nope it was right. It's supposed to be in the on client enter script slot per the instructions.

I checked to see if the problem had something to do with day and night cycles vs. default cycle. No such luck.

Now I'm hoping maybe someone here might have some ideas.

#16
kamal_

kamal_
  • Members
  • 5 250 messages
No, slayster is no longer active, I have email from him to that effect.

Does the light stay on 24/7, or is it off during the day and on at night?

#17
Friar

Friar
  • Members
  • 293 messages
I will check if it stays on 24/7.
When I tested it, it was sunrise 7ish. Also I fast forwarded 4-6 hours. So it was good during the day. I want it on during the day.
However, sunset to midnight it never turned off.

EDIT:
Also, I am not using any other scripts in that area. I won't need to use your commoner AI on this area Kamal.

Modifié par koundog1, 25 janvier 2014 - 06:32 .


#18
Friar

Friar
  • Members
  • 293 messages

To answer your question Kamal,

 

The lighting stays on 24/7.



#19
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi,

Here is what I posted in my blog when I encountered this problem:-

"My solution was to apply a search for all light objects (that I might later need to reference) at the start of the game, and add a local variable to them which I could search for instead. Add to that a change in the way I searched for lights, using GetNearestObject for a LIGHT object rather than by its tag, and I believe I have now fixed all light references in my modules."

From this blog post:- http://worldofalthea...era-action.html

Cheers,
Lance.

And for those who like to look at code, here is an extract from my module heartbeat code that handles all module lighting. Obviously, you will have to reinterpret what you need from it:-

 // INITIALIZE AT ZERO TO FORCE STATE CHECK
	int AreaMoodSet = GetLocalInt(oAreaPC, "AreaMoodSet");
	
	// NIGHT SET
	if(!GetIsDay() && (AreaMoodSet == 2 || AreaMoodSet == 0))
	{	
	SetLocalInt(oAreaPC, "AreaMoodSet", 1);
	
	//SendMessageToAllPCs("ACTIVATE AMBIENT AT NIGHT");
	
		// NIGHT FIREFLIES SETUP
		int iCount = 1;	object FliesWP = GetNearestObjectByTag("FireFlies", oPC, iCount);
		
		while(FliesWP != OBJECT_INVALID)
		{
		CreateObject(OBJECT_TYPE_PLACED_EFFECT, "alb_fireflies_big", GetLocation(FliesWP));		
		iCount = iCount + 1; FliesWP = GetNearestObjectByTag("FireFlies", oPC, iCount);
		}
	
		// NIGHT FOG SETUP
		iCount = 1;	object FogWP = GetNearestObjectByTag("GraveyardWP", oPC, iCount);
		
		while(FogWP != OBJECT_INVALID)
		{
		CreateObject(OBJECT_TYPE_PLACED_EFFECT, "graveyardfog", GetLocation(FogWP));		
		iCount = iCount + 1; FogWP = GetNearestObjectByTag("GraveyardWP", oPC, iCount);
		}
		
		// INITIAL DESTROYME LIGHT SETUP
		iCount = 0; object oLight = GetObjectByTag("DESTROYME", iCount);
		
		if(oLight != OBJECT_INVALID)
		{
			while(oLight != OBJECT_INVALID)
			{			
			SetLocalInt(oLight, "DESTROYME", 1);
			
			iCount = iCount + 1; oLight = GetObjectByTag("DESTROYME", iCount);		
			}
		}		
		
		// INITIAL MOOD LIGHT SETUP (FIXES "EVERY" MOOD LIGHT IN MODULE)
		iCount = 0; oLight = GetObjectByTag("MoodLight", iCount);
		
		if(oLight != OBJECT_INVALID)
		{
			while(oLight != OBJECT_INVALID)
			{
			//SendMessageToAllPCs("LIGHT OFF FOUND");
			SetLocalInt(oLight, "LightTagFixMood", 1);		
			SetLightActive(oLight, TRUE);				// NEAREST LIGHT FIX APPLED	HERE
			
			iCount = iCount + 1; oLight = GetObjectByTag("MoodLight", iCount);		
			}
		}		
		
		// AREA MOOD LIGHT NOW UPDATED VIA ITS VARIABLE WHEN DAY/NIGHT CHANGES
		else
		{
			iCount = 1; oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oPC, iCount);
			
			while(oLight != OBJECT_INVALID)
			{			
			//SendMessageToAllPCs("LIGHT OFF FOUND FIXED");
			if(GetLocalInt(oLight, "LightTagFixMood") == 1){SetLightActive(oLight, TRUE);}	// NEAREST LIGHT FIX APPLED	HERE
								
			iCount = iCount + 1; oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oPC, iCount);
			}
		}		
	}
	
	// DAY SET
	if(GetIsDay() && (AreaMoodSet == 1 || AreaMoodSet == 0))
	{
	SetLocalInt(oAreaPC, "AreaMoodSet", 2);
	
	//SendMessageToAllPCs("DEACTIVATE AMBIENT AT NIGHT");
	
		// NIGHT FIREFLIES SETUP		
		int iCount = 1;	object FliesEffect = GetNearestObjectByTag("alb_fireflies_big", oPC, iCount);
		
		while(FliesEffect != OBJECT_INVALID)
		{
		DestroyObject(FliesEffect);
		iCount = iCount + 1; FliesEffect = GetNearestObjectByTag("alb_fireflies_big", oPC, iCount);
		}
	
		// NIGHT FOG SETUP
		iCount = 1;	object FogEffect = GetNearestObjectByTag("GraveyardFog", oPC, iCount);
		
		while(FogEffect != OBJECT_INVALID)
		{
		DestroyObject(FogEffect);
		iCount = iCount + 1; FogEffect = GetNearestObjectByTag("GraveyardFog", oPC, iCount);
		}
		
		// INITIAL DESTROYME LIGHT SETUP
		iCount = 0; object oLight = GetObjectByTag("DESTROYME", iCount);
		
		if(oLight != OBJECT_INVALID)
		{
			while(oLight != OBJECT_INVALID)
			{			
			SetLocalInt(oLight, "DESTROYME", 1);
			
			iCount = iCount + 1; oLight = GetObjectByTag("DESTROYME", iCount);		
			}
		}				
		
		// INITIAL MOOD LIGHT SETUP
		iCount = 0; oLight = GetObjectByTag("MoodLight", iCount);
		
		if(oLight != OBJECT_INVALID)
		{
			while(oLight != OBJECT_INVALID)
			{
			//SendMessageToAllPCs("LIGHT ON FOUND");
			SetLocalInt(oLight, "LightTagFixMood", 1); SetLightActive(oLight, FALSE); // NEAREST LIGHT FIX APPLED HERE
			
			iCount = iCount + 1; oLight = GetObjectByTag("MoodLight", iCount);		
			}
		}		
		
		// AREA MOOD LIGHT NOW UPDATED VIA ITS VARIABLE WHEN DAY/NIGHT CHANGES
		else
		{
			iCount = 1; oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oPC, iCount);
			
			while(oLight != OBJECT_INVALID)
			{			
			//SendMessageToAllPCs("LIGHT ON FOUND FIXED");
			if(GetLocalInt(oLight, "LightTagFixMood") == 1){SetLightActive(oLight, FALSE);} // NEAREST LIGHT FIX APPLED HERE
								
			iCount = iCount + 1; oLight = GetNearestObject(OBJECT_TYPE_LIGHT, oPC, iCount);
			}
		}						
	}	


#20
Friar

Friar
  • Members
  • 293 messages

That is impressive.

Especially considering that all I want to do is get a single light I placed in an exterior area to turn on during the day and turn off at night.

 

I look forward to seeing the world of Althea, though. I think the night fog and fireflies will really add a lovely ambiance.



#21
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

That is impressive.
Especially considering that all I want to do is get a single light I placed in an exterior area to turn on during the day and turn off at night.
 
I look forward to seeing the world of Althea, though. I think the night fog and fireflies will really add a lovely ambiance.


Hi Friar,

I'm pleased you noticed that. :) Believe it or not, when I first started, I had no intentions to add this level of ambiance or character to the module. I was originally just going to go bare-boned and concentrate on plots and quests, but seeing all the great work already produced made me decide to up my own design somewhat. (Edit: I was particularly pleased with the fireflies and fog effects myself. :) )

That's also why I ended up adding an active weather system and other systems, all to try to make the world feel "alive" surrounding the rest of the ideas I had in mind. I never thought I would see the day when I was asking for "portly" NPCs (ref another post I made), so it just goes to show how great this community is at inspiring one to keep level of details in mind if one wants their own module to be memorable.

I do hope you do manage to play my mod ... the more who can enjoy it the better ... and it will have made all the effort it is taking worthwhile ... and especially from other builders who have helped me to get this far with things like area designs. I hope the effort I am putting in reflects the appreciation I have for their contributions towards it.

Lance.