Aller au contenu

Photo

Creating Dynamic Daily effects.


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

#1
Xeneize

Xeneize
  • Members
  • 133 messages

Hello. I am looking to create dynamic effects that happen in an area depending on what time it is. For example, looking to make it add butterflies during daytime to a certain place and then replace them with fireflies at nightfall.

 

Now I seem to have achieved this pretty well however I am faced with the problem of how to go about the area checking for the time it is. I was considering using the OnHeartBeat of the Area so it checks what time is it every six seconds and then does stuff if the time of the day is right however...

 

The problem I have is that I only want to do the things ONCE every day, as in, the lights should be going up at nightfall, and only check again next time it's nightfall.

 

I know that I plan to have it first remove all night effects at dawn, and then place the dawn effects, same goes with nightfall, removing the dawn effects then adding the nightfall effects.

 

How would I go about making each event happen only once when the time of the day is right, and... is the area onheartbeat script the best way to go about it?

 

Thanks in advance for sharing!



#2
Tchos

Tchos
  • Members
  • 5 054 messages

This may help:

http://nwn2.wikia.co...eartbeat_events



#3
Loki_999

Loki_999
  • Members
  • 430 messages

Can't remember where i saw it, but i thought i saw a function that allows you to set an object's heartbeat rate. Not sure if it only works for creatures, maybe you can stick on areas or placeables. So when module loads, set its HB to work once per whatever.

 

I could have been imagining things... i mean, sometimes i even dream in NWScript.... :-|



#4
Psionic-Entity

Psionic-Entity
  • Members
  • 195 messages

Not sure about heartbeat rate, but the way I set up something similar is to tie it on the module heartbeat. I run the built in functions to get the module minute and second, then run a script if minute is 1 and second is less than 7. The script checks the hour and makes any necessary changes (turning on and off lights, creating or destroying VFX, etc.) I haven't tested other systems but in my opinion this is an effective low-impact solution, particularly if you use ExecuteScript to call your functions after you checked the hour.



#5
Tchos

Tchos
  • Members
  • 5 054 messages

SetCustomHeartbeat works on placeables as well as creatures.  I tested it some time ago.  I don't recall if it works on areas or the module, but I doubt it.



#6
Dann-J

Dann-J
  • Members
  • 3 161 messages

I have lights, fires and torch effects that come on at night and disappear during the day. I use an ipoint with a standard heartbeat rate, with a couple of checks at the very beginning that abort the script if it's not necessary:

 

object oArea = GetArea(OBJECT_SELF);
if (oArea != GetArea(GetFirstPC())) return;

int iDay = GetLocalInt(OBJECT_SELF, "Day");

if (iDay == GetIsDay()) return;

 

If both of those two checks are false, that means something needs to be done (turn night lights off during the day, or turn them on during the night). The local integer is set to match GetIsDay() once the script has done its thing.



#7
Loki_999

Loki_999
  • Members
  • 430 messages

SetCustomHeartbeat works on placeables as well as creatures.  I tested it some time ago.  I don't recall if it works on areas or the module, but I doubt it.

 

Ah, there we go. So, you can set a custom hearbeat on a placeable, and use that the control the area/module.  Although... single player i'm not sure. I know if running as a server, a heartbeat tied to a creature/placeable can happily run even if nobody is in that area (although creatures should go into LOW AI mode.. technically speaking.. we have never been 100% convinced this is true).



#8
Dann-J

Dann-J
  • Members
  • 3 161 messages

Ah, there we go. So, you can set a custom hearbeat on a placeable, and use that the control the area/module.  Although... single player i'm not sure. I know if running as a server, a heartbeat tied to a creature/placeable can happily run even if nobody is in that area (although creatures should go into LOW AI mode.. technically speaking.. we have never been 100% convinced this is true).

 

In single player, creature heartbeats are reduced to once per 60 seconds (ten times slower than usual) if there's no player in the area. I don't know whether that's true of non-creature heartbeats (placeables, areas, triggers, etc).



#9
Xeneize

Xeneize
  • Members
  • 133 messages

Is there a way to tell a script to spawn something identical in every waypoint with a certain tag? So far it appears that what I have will spawn something only in one random waypoint and I actually want it to spawn that something in every waypoint in the area with the assigned tag.

 

My goal is to give my city a magical look, so there will be pillars all around, that at nightfall, orbs of light along with light effects will appear(and disappear at dawn).



#10
kevL

kevL
  • Members
  • 4 061 messages
string sLight = "ResRef_of_Light";

object oPoint = GetFirstObjectInArea();
while (GetIsObjectValid(oPoint))
{
    if (GetTag(oPoint) == "light_This")
    {
        location lLoc = GetLocation(oPoint);
        CreateObject(OBJECT_TYPE_LIGHT, sLight, lLoc);
    }

    oPoint = GetNextObjectInArea();
}
EDIT: more-or-less real code

#11
Tchos

Tchos
  • Members
  • 5 054 messages

Is there a way to tell a script to spawn something identical in every waypoint with a certain tag? So far it appears that what I have will spawn something only in one random waypoint and I actually want it to spawn that something in every waypoint in the area with the assigned tag.

 

My goal is to give my city a magical look, so there will be pillars all around, that at nightfall, orbs of light along with light effects will appear(and disappear at dawn).

 

There's code in the SoZ On Client Enter scripts (such as for the taverns) that does this.  It checks every waypoint in the area for a tag prefix of "sp_" and then spawns a creature with whatever resref appears after the "sp_" in the tag.  Then it marks the waypoint with a local integer to prevent it from doing it more than once.  It could be changed to spawn a placeable or effect instead of a creature, etc.



#12
Dann-J

Dann-J
  • Members
  • 3 161 messages

Is there a way to tell a script to spawn something identical in every waypoint with a certain tag? So far it appears that what I have will spawn something only in one random waypoint and I actually want it to spawn that something in every waypoint in the area with the assigned tag.

 

My goal is to give my city a magical look, so there will be pillars all around, that at nightfall, orbs of light along with light effects will appear(and disappear at dawn).

 

That's exactly what my own 'nightlight' script does. It cycles through the area looking for ipoints with specific tags, then reads local variables off them to determine what special effect to spawn at the spot. It also looks for the nearest light object to the ipoint and turns it on or off (to avoid the bug that causes lights to lose their tags when a saved game is loaded).

void main()
{
object oArea = GetArea(OBJECT_SELF);
if (oArea != GetArea(GetFirstPC()))
return;

int iDay = GetLocalInt(OBJECT_SELF, "Day");

if (iDay == GetIsDay())
	return;

object oLight;
object oEffect;
int i = 1;
string sEffect;

if (iDay == 1 && !GetIsDay())
	{
	oLight = GetNearestObject(OBJECT_TYPE_PLACEABLE, OBJECT_SELF);
	while(GetIsObjectValid(oLight))
		{
		i++;
		if (GetTag(oLight) == "nightlight")
			{
			sEffect = GetLocalString(oLight, "Effect");
			oEffect = CreateObject(OBJECT_TYPE_PLACED_EFFECT, sEffect, GetLocation(oLight), 0, "LightEffect");
			SetLocalObject(oLight, "EffectObject", oEffect);
			SetLightActive(GetNearestObject(OBJECT_TYPE_LIGHT, oLight),1);
			}//end if nightlight		
		oLight = GetNearestObject(OBJECT_TYPE_PLACEABLE, OBJECT_SELF, i);		
		}//end while	
	SetLocalInt(OBJECT_SELF, "Day", 0);		
	}//end if night
else
	{
	oLight = GetNearestObject(OBJECT_TYPE_PLACEABLE, OBJECT_SELF);
	while(GetIsObjectValid(oLight))
		{
		i++;
		if (GetTag(oLight) == "nightlight")	
			{
			oEffect = GetLocalObject(oLight, "EffectObject");
			SetLightActive(GetNearestObject(OBJECT_TYPE_LIGHT, oLight),0);
			DestroyObject(oEffect);
			DeleteLocalObject(oLight, "EffectObject");
			}//end if nightlight
		oLight = GetNearestObject(OBJECT_TYPE_PLACEABLE, OBJECT_SELF, i);		
		}//end while	
	SetLocalInt(OBJECT_SELF, "Day", 1);
	//Rooster crows
	if (GetTimeHour() < 8)
	AssignCommand(GetFirstPC(), PlaySound("al_an_rooster1", TRUE));		
	}//end if day	
		
}


#13
rjshae

rjshae
  • Members
  • 4 491 messages

In a town I set a couple of variables on the lockable doors; one giving a time to lock, the other a time to unlock. An area heartbeat script goes through and flips the locks accordingly. (It's in my sample scripts; p. 17, vol IV. of the guide.)



#14
Dann-J

Dann-J
  • Members
  • 3 161 messages

In a town I set a couple of variables on the lockable doors; one giving a time to lock, the other a time to unlock. An area heartbeat script goes through and flips the locks accordingly. (It's in my sample scripts; p. 17, vol IV. of the guide.)

 

Another option is to have an NPC run around and lock doors one at a time. :)

 

I have a 'lamp master' in my current module, who runs around every morning turning street lamps off, then runs around turning them back on at night. Players can also interact with street lamps, turning them on and off at will. If you help the lamp master do his job at the right time then he doesn't bother to visit those lamps. If you want to annoy him, you can turn them on during the day or turn them off during the night, and he'll run to correct it.


  • rjshae aime ceci

#15
Xeneize

Xeneize
  • Members
  • 133 messages

Well after a day of trial and error, I still can't seem to get it. Apparently the code is way too advanced for my pay grade.

 

Here's what I require, if anyone would be kind enough to do it for me:

 

I currently have two waypoints.

 

spawn_blueglow

spawn_bluelight

 

The first waypoint will spawn the 'placed effect' called fx_death_god_light_blue

The second waypoint needs to spawn the actual light, which is called lt_phosphor0101

 

This has to happen at nightfall, and it has to happen to all of the area's waypoints with the aforementioned tags. At dawn, they need to be destroyed.

 

If anyone is capable of writing it up for the noob-self of me, I would be eternally grateful.

 

Thank you in advance for all the help!



#16
Dann-J

Dann-J
  • Members
  • 3 161 messages

You don't need to destroy the light objects. You can just turn them on and off as required via SetLightActive(). I tend to paint my night lights down in the area, so I can customise each one as required (different colours, ranges, brightness, etc).

 

If you were to create ipoints or waypoints with the tags 'nightlight', and gave each point a local string with the name of the SEF file placed effect blueprint tag for the required visual effect, then the script I posted above would do what you wanted. I run it as the HB of an ipoint. You might want to remove the part that causes the rooster to crow around dawn though (I was using the script it in a rural village).



#17
Tchos

Tchos
  • Members
  • 5 054 messages

Note that waypoints and ipoints are different object types, so must be selected using the appropriate constant if you're using GetNearestObject.  I tend to use waypoints unless I need the object to run a script, show a special effect, speak a string, or things of that nature, in which case I use an ipoint.  Waypoints are the least resource-intensive objects, and are well suited as markers for locations where you want something to happen.  But if you want an object that you can make things happen to, or one that can make things happen on its own (by attaching scripts to it), use an ipoint.



#18
Dann-J

Dann-J
  • Members
  • 3 161 messages

Note that waypoints and ipoints are different object types, so must be selected using the appropriate constant if you're using GetNearestObject.  I tend to use waypoints unless I need the object to run a script, show a special effect, speak a string, or things of that nature, in which case I use an ipoint.  Waypoints are the least resource-intensive objects, and are well suited as markers for locations where you want something to happen.  But if you want an object that you can make things happen to, or one that can make things happen on its own (by attaching scripts to it), use an ipoint.

 

Good point. I was using ipoints, so my script was only looking for OBJECT_TYPE_PLACEABLE. For waypoints you'd have to use OBJECT_TYPE_WAYPOINT.



#19
kevL

kevL
  • Members
  • 4 061 messages
NWN2_SS_111814_225045.png

Pastebin

that uses a Placed_Effect, rather than a naked effect. If you use it, create one in the TS and have it in the module dir, or as befits, same with the Light; then place down some Waypoints, change the tags/resrefs at the top of the script and recompile ... it's an Area heartbeat.

The height the waypoints are placed above ground-level matters,

#20
Xeneize

Xeneize
  • Members
  • 133 messages

Finally worked out. Thanks very much to all that were of assistance :)