Aller au contenu

Photo

Orientation of placed effects


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

#26
GhostOfGod

GhostOfGod
  • Members
  • 863 messages

Are you just trying to make beam visual effects between 2 points? Does it not work the same way in NWN2 as in NWN1?



#27
kevL

kevL
  • Members
  • 4 052 messages

hey GoG,
visual effects became their own creature in NwN2 ( special effect files )
another way of looking at it: NwN effects don't even work in 2; all references in spellscripts etc. were replaced by Obsidian ...

which is too bad because i'd use some of the NwN1 effects in a heartbeat (thinking, buffs).



#28
GhostOfGod

GhostOfGod
  • Members
  • 863 messages

Ah gotcha. I'm going to have to install it again one of these days and start poking around again.



#29
andysks

andysks
  • Members
  • 1 645 messages
It is true that some functions in there are distractions. Quest specific and motb specific like getting the PC as spirit eater. They do get the vfx from the 2da, I noticed that.
The whole system they use is quite simple actually. Once the beam starts, the variables on the placeable tell it to which placeable to go next. Now, if someone like me, doesn't want to rotate and reflect, that's all. If the last placeable in line has no variables, the beam will just stop there.

A step further, if one wants to rotate and reflect, needs to specify if the placeable is one sided, and where the beam will go if it faces north, east etc. All with tags of the next placeable specified in variables.

It can be an ipoint as well, since the last one they use in motb is actually the point where a companion copy spawns.

#30
andysks

andysks
  • Members
  • 1 645 messages

I think it is all clear for people who can read these scripts. Once I test my own I will post the results and more thorough way of how I did it. But there is only one question still. There is a variable on the placeable which starts it all. In MotB an obelisk, in my case it will be a book.

 

On the script it looks like that:

const string VAR_fFACING_OFFSET 			= "FACING_OFFSET"; 	// offset from defined front to desired front

On the MotB example, this number is set to 90.

The obelisk needs to send the beam west. But the question is, what does defined front mean? Is it north by default? Does everything placed on the toolset looks north by default? And therefore if I place an ipoint showing north, wanting to send the beam south I just set this variable to 180? What if I turn the starting point to look south on the toolset? Does front change or not?



#31
andysks

andysks
  • Members
  • 1 645 messages

Made it work B) . Thanks KevL for pointing me to the MotB thing. I had completely forgotten about that.

Note that I only wanted direction and end, and not reflection. If one wants to reflect beams he has to dig a bit further but the principle is the same.

 

What I needed, in case someone wants to do the same:

 

This goes on conversation. The string tag is the object which will start the beam. Commented out the MotB specific parts. One can even remove them if he wants. The beam they use is 545, I don't know which 2da holds this though to be honest, in case we want a different type.

// e_p_beamactivator_us
/*
   	Activate Beam Starter from dialogue
*/
// EPF 5/11/07

//Remove e_inc functions ie: spirit eater

#include "ginc_reflection"
//#include "kinc_spirit_eater"
//#include "e_inc_reflection"



void main()
{

	string sBeamStarterTag = "BeamStarter1";   //GetLocalString(OBJECT_SELF, VAR_BEAM_START);
	object oBeamStarter = GetObjectByTag(sBeamStarterTag);
		
	//object oSE = GetSpiritEater();
	//AddJournalQuestEntry("q53_uncanny_reflections",100,oSE,TRUE);
	
	/*object oMod = GetModule();
	if(!GetLocalInt(oMod, VAR_SET_USEABLE))
	{
		SetMirrorsUseable(TRUE);
		SetLocalInt(oMod,VAR_SET_USEABLE,TRUE);
	}*/
	
	//PlaySound(SFX_REMOTE);
	//BeamStarterInitialization(oBeamStarter, fBeamDuration, fBeamPropagationDelay, iBeamType); 
	StartBeam(oBeamStarter);
		
}

Then we need this on the OnUserDefined of the Beam Starter.

ToNorth = string with the tag of the destination.

ToSouth = string with the tag of the destination.

ToEast = string with the tag of the destination.

ToWest = string with the tag of the destination.

(In my case they were all equal since beams lead to the same spot).

BEAM_DURATION = floating point with duration. I set it to 5 for testing. It stayed 5 seconds. I will search a permanent way.

BEAM_PROPAGATION_DELAY = floating point. No idea what it does, I kept it a 0,2 and saw no difference.

BEAM_TYPE = intergrer with the beam type. 2da entry I guess.

FACING_OFFSET = floating point with degree angle towards where the starting beam will go. By default everything we place down faces north. My placeable was facing SouthEast. but that didn't matter. It turned out that North is default no matter how you turn your Beam Starter. Therefore, 90 will turn the beam east, 180 south and so on.

 

This script went on the UserDefined slot on the Beam starter. I don't know why it is important, but it made it work. Especially the part with the case EVENT_BEAM_STRIKE:. I searched in all the scripts and couldn't find where this is mentioned.

// kp_beam_starter_ud
/*
	Description:
	Handles user defined events for the Beam Starter.
	see "kp_beam_reflector_ud" for additional details
	
// These 4 variables apply to the facing of the beam starter object
// (Useful if the object rotates and needs to hit different objects).
//These are tags of the object the beam goes to. If all beams go to the same object, all have same tag.
const string VAR_NORTH 		= "ToNorth";
const string VAR_SOUTH 		= "ToSouth";
const string VAR_EAST 		= "ToEast";
const string VAR_WEST 		= "ToWest";

// Variables on the Beam Starter 
const string VAR_fBEAM_DURATION 			= "BEAM_DURATION"; 				// float 
const string VAR_fBEAM_PROPAGATION_DELAY 	= "BEAM_PROPAGATION_DELAY";		// float 
const string VAR_fBEAM_TYPE					= "BEAM_TYPE";					// int 	
const string VAR_fFACING_OFFSET 			= "FACING_OFFSET"; 	// offset from defined front to desired front
	
*/
// ChazM 4/19/07

#include "ginc_reflection"
#include "ginc_event_handlers"

void main()
{	
	object oSelf = OBJECT_SELF;
	
	switch (GetUserDefinedEventNumber())
    {
	
    	case EVENT_BEAM_STRIKE: // hit by an uncanny reflection.
		{	
		    effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
   			ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oSelf);
			break;
		}	
		
 				
	}
}

Finally, I needed to put this on the hb slot of the Beam Starter. They did it like that, so I thought it was important. No idea what it does.

// gp_pseudo_spawn_hb
/*
	Description:
	Signal UserDefinedEvent on the first hearbeat - simulating an onspawn.
	Useful for keeping everything together in the UD script.
*/
// ChazM 4/19/07

#include "ginc_vars"
#include "ginc_event_handlers" 

// Fire the EVENT_PLACEABLE_SPAWN event just once.
void main()
{
	// use event number as done flag number since this is unlikely to be an already used "done" flag.
	if (IsMarkedAsDone(OBJECT_SELF, EVENT_PLACEABLE_SPAWN))
		return;
	
	SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_PLACEABLE_SPAWN));
	MarkAsDone(OBJECT_SELF, EVENT_PLACEABLE_SPAWN);
}

There can be an easier way of doing such things, but I couldn't find it. Also, even if at the moment I only needed a single beam, reflecting beams is something that I can think numerous places where I can use it. So even if this way is a bit complicated, it looks stable and it was worth looking at the scripts in order to know what to do if I want to reflect the beams as well.


  • rjshae aime ceci

#32
4760

4760
  • Members
  • 1 204 messages

Thanks for sharing your finding!

Regarding the continuous emission of the beam, why not set the duration to permanent instead of instant in kp_beam_starter_ud)?

           ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oSelf);


#33
andysks

andysks
  • Members
  • 1 645 messages

I don't think that's what this is. The

ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oSelf);

applies the VFX_IMP_FLAME_M

 

While the duration in the variables corresponds to the beam which is 545, coming from the visualeffects.2da as I saw now which is the prismatic ray. But I am certain that there is somewhere in the scripts where the DURATION is mentioned for this. Probably where the applying of the beam takes place.

 

Here it is: from ginc_reflection

SetLocalFloatDefualt(oBeamStarter, VAR_fBEAM_DURATION, DEF_BEAM_DURATION);

which is that:

// defaults
const float DEF_BEAM_DURATION 			= 1.7f;

so low...

 

I think if one doesn't want to change the whole ginc_duration for own purposes, then something like a line on the initialization script could work on overriding the default setting of the include.

Something to make the DEF_BEAM_DURATION   =  DURATION_TYPE_PERMANENT



#34
andysks

andysks
  • Members
  • 1 645 messages

There is only one thing left to do, which came out from the tests. In MotB there is only one beam starter. In my case 4 in the same area. No matter what I try, the first one to get the beam started works, but the rest don't. Any one of them can get its beam started, so the problem lies elsewhere. Perhaps there is a function there in ginc_reflection which marks the event as done and never to happen again? What would I be looking for?



#35
4760

4760
  • Members
  • 1 204 messages

I noticed that the hb of the beam starter has 

MarkAsDone(OBJECT_SELF, EVENT_PLACEABLE_SPAWN);

to prevent it from restarting. Maybe OBJECT_SELF is not referring to the beam starter but to the module, as the script is run from an OnHeartBeat slot?



#36
andysks

andysks
  • Members
  • 1 645 messages
I actually removed this hb from all beam starters because 1: I can set it to unuseable instead, and 2: it was not a necessity for the system to work. The problem stayed though. One beam starts, the rest won't.

#37
kevL

kevL
  • Members
  • 4 052 messages

sorta sounds like a tag conflict. Perhaps multiple objects with the same tag (either in dialog or scripted string defn's), such that once one is marked done they're all considered done

( alternate theory, typo )



#38
andysks

andysks
  • Members
  • 1 645 messages

Recap:

 

A Beam Starter cannot have the same first target as the next one. Don't ask why, but that's what fixed it. Placing 4 ipoints with unique tags, and not just one where all beams would go to, and each of the 4 Beam Starter leading to each own target caused all 4 to fire :wizard: .

 

Something else: the pseudo hb is not needed. As 4760 pointed, it probably only causes stuff to happen only once. Setting the placeable not useable once the beam starts does the same and I prefer it.

 

Also, the UserDefined causes only a small fire effect and nothing more. In truth, the whole beam thing starts from conversation and variables on the Starter take care of the rest. No other scripts needed for this to work, except if you want to reflect it.

 

Picture with the success would come but photobucket is down :).



#39
andysks

andysks
  • Members
  • 1 645 messages

NWN2_SS_012615_234334_zps6ershbup.jpg

 

Preliminary version of how this should look. Energy beams lead to a single target. I got the grip of this system, so if someone wants to do something like that... feel free to ask specifics by sending me a message if not everything's clear from what's written in this thread.


  • rjshae aime ceci

#40
kevL

kevL
  • Members
  • 4 052 messages

looks great. I like the asymmetry.



#41
Morbane

Morbane
  • Members
  • 1 883 messages

glad i stopped by - this is cool :D



#42
Darin

Darin
  • Members
  • 282 messages

I tend to avoid VFX for the function: EffectNWN2SpecialEffectFile(string sFileName, object oTarget).  Only issue is you need to know the filename of the beam you want to us...

 

Good news is, if you want a beam to start at object oStart and end at object oEnd, two lines of code (or one if you combine) does this:

effect eVis = EffectNWN2SpecialEffectFile("insert_sef_vilename_here",oEnd);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oStart,6.0)

The NWN2 Sef function allows you to specify the destination of the effect file (which seems to be the issue you're having).  Again, bad news is you need to know the filename....I use the module Sunjammer Visual Effects whatever to look through the various effects to find the one I want.



#43
andysks

andysks
  • Members
  • 1 645 messages

You can use the power bar browse vfx plugin. Bad thing is it doesn't have a search option so that we use keywords, but it's useful nonetheless. Thanks for the info but I got it working. Quite easy actually once I found out about the ginc_reflection. One can do cool stuff with vfx.



#44
kamal_

kamal_
  • Members
  • 5 238 messages

Alright. In game it looks freaky. Either my vfx is wrong, or one can't spawn horizontal beams if they are not part of a spell(?).

Seeing in the VFX browser of the power bar all spell beams to be modeled as going upwards, even thought in game they are horizontal or bent, from caster to target supports this idea. I don't know.

I think thought that it's an interesting topic. It does add a lot in some highly magic areas. but for now I think next step is to go for a spell, meaning for a non permanent effect. Because they way I see it, a beam/ray cannot even be turned in the editor like the godrays which exist in all axises.

 

I would like though for this topic to go on, in case we are able to create a method for future use :).

 

Edit: Kevl, I missed your reply. The academy ray might be the last hope. Forgot about it. I'll get back with the news.

A bit more experimenting with this because I'd like the ability to direct beams. If you apply a sp_ray such as the divination ray example as a Appearance (visual effect) to a creature,what happens is the origin and target are both the creature. For the divination ray, which originates at the head and goes to the target's body, it does this with the creature itself as the origin and target.

 

I was messing around with your divination ray example, and made this :-)

https://youtu.be/X4QIXiv7I8M



#45
Tchos

Tchos
  • Members
  • 5 030 messages

Very much like a cool VFX I saw in the Cry Wolf module, by Lorft, for the Grimms' Fairy Tales contest.



#46
kamal_

kamal_
  • Members
  • 5 238 messages

Very much like a cool VFX I saw in the Cry Wolf module, by Lorft, for the Grimms' Fairy Tales contest.

Turns out beams have an amplitude property, you can adjust that to get the wave motion.



#47
kamal_

kamal_
  • Members
  • 5 238 messages

a different code for dynamic beams, includes a permanent beam option

 

https://youtu.be/fqhEBzMFwv0

//modified lightning bolt spell to make a generic ray

#include "X0_I0_SPELLS"
#include "x2_inc_spellhook" 
#include "ginc_debug"
#include "nw_I0_SPELLS"

void main()
{
//or however you want to trigger your beam, in this case by object OnUsed
object oPC = GetLastUsedBy();
if (!GetIsPC(oPC)) return;

//relevant variables, you could also pass these in via the main (object oOrigin, object oTarget, int nDuration, float  fMaxDistance) etc to make a generalized function
float fMaxDistance = 3000.0; //I suppose we want the beam to be able to cross the map if needed, at least for example purposes
object oOrigin = GetObjectByTag("test_origin");
object oTarget = GetObjectByTag("test_target");
int nBeamType= VFX_BEAM_LIGHTNING;
int nHitVFX= VFX_HIT_SPELL_DIVINATION;
int nDuration =  2; // 0 for instance, 1 for temporary beam, 2 for permanent beam

if (GetIsObjectValid(oOrigin)) //sanity check
	{
	if (GetIsObjectValid(oTarget))
		{
		// SendMessageToPC(GetFirstPC(), "valid origin and target");
		}
	}

// since this is just a vfx beam and does no damage, these are technically not needed,, theoretically we could change as appropriate as it's used for damage calculations
/*
int  nCasterLevel = 10; 
int nDamage;
int nMetaMagic = GetMetaMagicFeat();
*/

//Set the lightning stream to start at the caster's hands
 
	effect eBeam = EffectBeam(nBeamType, oOrigin, BODY_NODE_CHEST);
    effect eVis  = EffectVisualEffect(nHitVFX);
    effect eDamage;
	
	location lOrigin = GetLocation(oOrigin);	 
    location lTarget = GetLocation(oTarget);
    float fDelay;
    int nCnt = 1;

    if (GetIsObjectValid(oTarget) && GetDistanceToObject(oTarget) <= fMaxDistance)
    {
           if (oTarget != OBJECT_SELF && oOrigin != oTarget)
           {
		   SendMessageToPC(GetFirstPC(), "target!=SELF");
                if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
            		{	
               		//we would normally signal this depending on the beam type, but no need for a pure vfx beam. kamal	
					//SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_LIGHTNING_BOLT));
                   	
					/*
				  	//Make an SR check
                   	if (!MyResistSpell(OBJECT_SELF, oTarget))
        	       	{
				   
				   	//if our beam should do damage, do it here
				   
                        //Roll damage
                        nDamage =  d6(nCasterLevel);
        		        //Enter Metamagic conditions
        		        if (nMetaMagic == METAMAGIC_MAXIMIZE)
        		        {
        			         nDamage = 6 * nCasterLevel;//Damage is at max
                        }
        		        if (nMetaMagic == METAMAGIC_EMPOWER)
        		        {
        			         nDamage = nDamage + (nDamage/2); //Damage/Healing is +50%
                        }
                        //Adjust damage based on Reflex Save, Evasion and Improved Evasion
                        nDamage = GetReflexAdjustedDamage(nDamage, oTarget, GetSpellSaveDC(),SAVING_THROW_TYPE_ELECTRICITY);
                        //Set damage effect
                        eDamage = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);
                        if(nDamage > 0)
                        {
                            fDelay = GetSpellEffectDelay(GetLocation(oTarget), oTarget);
                            //Apply VFX impcat, damage effect and lightning effect
                            DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oTarget));
                            DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget));
                        }
						
						
                    } //end of hostile and resist spell
					*/
					
                }
			//	SendMessageToPC(GetFirstPC(), "applying beam");
				ApplyEffectToObject(nDuration, eBeam,oTarget,1.0);
        }

}
}


#48
Dann-J

Dann-J
  • Members
  • 3 161 messages

 

 

I was messing around with your divination ray example, and made this :-)

https://youtu.be/X4QIXiv7I8M

 

hqdefault.jpg

 

"I'm giving you cancer with my mind..."