Are you just trying to make beam visual effects between 2 points? Does it not work the same way in NWN2 as in NWN1?
Orientation of placed effects
#26
Posté 26 janvier 2015 - 04:05
#27
Posté 26 janvier 2015 - 04:55
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
Posté 26 janvier 2015 - 09:03
Ah gotcha. I'm going to have to install it again one of these days and start poking around again.
#29
Posté 26 janvier 2015 - 09:05
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
Posté 26 janvier 2015 - 11:01
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
Posté 26 janvier 2015 - 12:29
Made it work
. 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
Posté 26 janvier 2015 - 01:56
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
Posté 26 janvier 2015 - 02:49
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
Posté 26 janvier 2015 - 05:50
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
Posté 26 janvier 2015 - 06:16
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
Posté 26 janvier 2015 - 08:17
#37
Posté 26 janvier 2015 - 08:28
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
Posté 26 janvier 2015 - 10:54
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
.
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
Posté 27 janvier 2015 - 08:56
#40
Posté 27 janvier 2015 - 07:09
looks great. I like the asymmetry.
#41
Posté 02 février 2015 - 08:08
glad i stopped by - this is cool ![]()
#42
Posté 04 février 2015 - 11:55
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
Posté 04 février 2015 - 12:01
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
Posté 02 août 2015 - 01:08
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 :-)
#45
Posté 02 août 2015 - 01:16
Very much like a cool VFX I saw in the Cry Wolf module, by Lorft, for the Grimms' Fairy Tales contest.
#46
Posté 02 août 2015 - 01:30
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
Posté 02 août 2015 - 05:31
a different code for dynamic beams, includes a permanent beam option
//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
Posté 02 août 2015 - 11:02
I was messing around with your divination ray example, and made this :-)

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





Retour en haut







