Draw a line from x to y in visual effects
#1
Posté 27 mai 2012 - 11:27
They have a function that looks promissing
DrawLineFromCenter
or
DrawLineToCenter
but I cant get the visuals to travel from my characters location to the destination.
The angle is always off - eg - the shockwave comes from to the right of my origin, or at a 180 degree opositve on the otherside of the destination.
Im trying to make a cinematic effect where explosive shockwaves shoot out from an npc towards someone or something.
Kinda like Alice does in Resident Evil Extinction
Can someone give me a hand?
#2
Posté 28 mai 2012 - 01:00
vector pTargetPos = GetPosition( oTarget);
vector pSourcePos = GetPosition( oSource);
vector vVectorFromTargetToSource = pTargetPos - pSourcePos;
At this point the vector vVectorFromTargetToSource represents both the distance and direction that oTarget is from oSource. If you want to know the distance for use in your calculations you can get it simply by getting the magnitude from the vector like this.
float fDistanceToTarget = VectorMagnitude(vVectorFromTargetToSource);
If you Normalize the vector you it will change the vector to where it still have the same direction but its magnitude is only i meter in length. you can also do that witht he built in function:
vector vNormalizedVectorToTarget = VectorNormalize(vVectorFromTargetToSource);
if you wanted the cords lets say every 10m along the line from oSource you will need to increase your mormilized vector to a magnitude of 10. You can di this by simply multipling all of the cords in the vector by 10.
vector v10MTowardsTarget = VectorNormalize(vVectorFromTargetToSource);
v10MTowardsTarget.x *=10;
v10MTowardsTarget.y *=10;
// Just in case we are not level
v10MTowardsTarget.z *=10;
Now to get your point 10 meters away from oSource towards oTarget, all you have to do is add your 10m vector to osource.
vector vPointAlongLine = pSourcePos + v10MTowardsTarget;
To get the next point 10m down the line just add the 10m vector to your las point.
vPointAlongLine += v10MTowardsTarget;
I hope that helps.
L8
#3
Posté 28 mai 2012 - 01:32
I think it might be to do with an internal limit of how many vfx the server will display acknowledge at a time, or else just the priority of them when it comes to sending client info is lower so some get dropped.
Granted, if you're making this for SP that won't be an issue for you.
#4
Posté 28 mai 2012 - 01:39
I basically want to fire a series of vfx off in rapid succession along a straight line from a to b, at certain intervals.
The vector normalize looks to be the way to do it, No doubt I will need to wrap it all up into a for loop, to get it going from 1m to Distance to Target etc
Im sure you can imagine the effect im going for
Sort of thing where a mage shoots energy at an enemy, and it rips the ground up as it surges towards the target etc.
Im thinking of using the fireball explosion effect, so it looks like the ground is errupting on its way to the target.
I will be wrapping this into a playertool power - - so players will have the illusion of being epically powerful, by being able to launch these attacks.
#5
Posté 28 mai 2012 - 01:52
I went ahead a scripted a Getfirst/next location. Untested at this point. I hope they work for you.
//Note: The Location and vector are defined in the global namespace
// So that they can be used in both functions of the itterator.
location lCurrentIncLoc;
vector vVectorInc;
location GetNextIncLocation()
{
lCurrentIncLoc = Location
(
GetAreaFromLocation(lCurrentIncLoc),
GetPositionFromLocation(lCurrentIncLoc)+ vVectorInc,
GetFacingFromLocation( lCurrentIncLoc)
);
return lCurrentIncLoc;
}
location GetFirstIncLocation(object oSource, object oTarget, float fIncrement)
{
vVectorInc = VectorNormalize( GetPosition( oTarget) - GetPosition( oSource)) * fIncrement;
lCurrentIncLoc = GetLocation(oSource);
return GetNextIncLocation();
}
EDIT: updated per Whiz's information.
Modifié par Lightfoot8, 28 mai 2012 - 03:40 .
#6
Posté 28 mai 2012 - 03:28
#7
Posté 28 mai 2012 - 03:38
EDIT: Just figured out my typo. I was tring to multiply by an int instead of a float.
Modifié par Lightfoot8, 28 mai 2012 - 03:51 .
#8
Posté 28 mai 2012 - 08:01
// SHOCKWAVE FEAT SCRIPT// Version 0.5: 2011/05/08
#include "spell_geninc"
void shockwave(float fAngle, int nWaves, int nWaveNum, int nNumDie){
// Calculate position of this 'step' of the wave
vector vPos = GetPosition(OBJECT_SELF);
vPos.x += cos(fAngle) * nWaveNum; vPos.y += sin(fAngle) * nWaveNum;
location lLoc = Location(GetArea(OBJECT_SELF), vPos, fAngle);
ApplyEffectAtLocation(0, EffectVisualEffect(VFX_FNF_PWSTUN), lLoc);
// Damage (and knockback?) all enemies around current 'step' of the wave
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 0.95, lLoc, FALSE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{ ApplyEffectToObject(0, EffectDamage(d6(nNumDie), DAMAGE_TYPE_SONIC, DAMAGE_POWER_NORMAL), oTarget);
ApplyEffectToObject(0, EffectVisualEffect(VFX_IMP_SONIC), oTarget);
if(GetHasFeat(UPGRADE_SW_TREMOR, OBJECT_SELF))
{ ApplyEffectToObject(1, EffectKnockdown(), oTarget, 6.0f); }
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 0.5f, lLoc, FALSE, OBJECT_TYPE_CREATURE);
}
nWaves--;
nWaveNum++;
if(nWaves > 0) DelayCommand(0.1f, shockwave(fAngle, nWaves, nWaveNum, nNumDie));
}
void main()
{ location lTarg = GetSpellTargetLocation(); object oCaster = OBJECT_SELF;
int nNumDie = 2;
float fCooldown = 5.0f;
int nWaveLen = 6;
if(GetHasFeat(UPGRADE_SW_LONGWAVE, oCaster)) { nWaveLen = 10; fCooldown += 2.0f; }
if(GetHasFeat(UPGRADE_SW_TREMOR, OBJECT_SELF)) { fCooldown += 2.0f; }
shockwave(GetFacing(oCaster), nWaveLen, 1, nNumDie);
SendMessageToPC(OBJECT_SELF, "<cÌwþ>Shockwave cooling down</c>");
DelayCommand(fCooldown, IncrementRemainingFeatUses(OBJECT_SELF, 52));
DelayCommand(fCooldown, SendMessageToPC(OBJECT_SELF, "<cÌwþ>Shockwave cooldown complete</c>"));
}
In retrospect, I did a pretty inefficient variant, calculating the direction vector from the caster's facing angle every time the function recurs when I could've just passed it in as a vector (plus a few Gets inside the loop that would return the same value every time). Ah well, lessons learned and all that.
Modifié par _six, 28 mai 2012 - 08:09 .
#9
Posté 28 mai 2012 - 09:07
Would the calling convention for this function work like this?
location GetNextIncLocation()
{
lCurrentIncLoc = Location
(
GetAreaFromLocation(lCurrentIncLoc),
GetPositionFromLocation(lCurrentIncLoc)+ vVectorInc,
GetFacingFromLocation( lCurrentIncLoc)
);
return lCurrentIncLoc;
}
location GetFirstIncLocation(object oSource, object oTarget, float fIncrement)
{
vVectorInc = VectorNormalize( GetPosition( oTarget) - GetPosition( oSource)) * fIncrement;
lCurrentIncLoc = GetLocation(oSource);
return GetNextIncLocation();
}
void MySpell()
{
//Do a vfx every 1 m in a straight line from oPC to oTarget
float fDist = GetDistanceBetweenLocations(GetLocation(oPC),GetLocation(oTarget));
int i = 0;
for(i = 1; i <= FloatToInt(fDist); i++)
{
location lTarg = GetFirstIncLocation(oPC, oTarget, IntToFloat(i) );
// Apply VFX At location?
}
Note -
I just found out that CEP2.3 has lots of lovely vfx treats I never knew about.
Red Lightning, Implosion effects with colors, that stand up on their side and act as wormholes,
storm of vengeance with clouds, lightning shields, halos, spirits effects, and more....
OMG - I only found them over the weekend.
The things I could have used them for.....
To find them - just extract the visualeffect.2da from the cep top hak.
Alot of higher ground visuals in there I believe - they seem to be prefixed with hg etc
#10
Posté 28 mai 2012 - 03:07
{
//Do a vfx every 1 m in a straight line from oPC to oTarget
float fDist = GetDistanceBetweenLocations(GetLocation(oPC),GetLocation(oTarget));
location lTarg = GetFirstIncLocation(oPC, oTarget, 1 );
int i = 0;
for(i = 1; i <= FloatToInt(fDist); i++)
{
// Apply VFX At location?
lTarg = GetNextIncLocation();
}
#11
Posté 18 juin 2012 - 09:33
They were just declared as Privates instead of publics - which is why I never noticed them.
void DrawLineFromVectorToVector(int nDurationType, int nVFX, object oArea, vector vOne, vector vTwo, float fDuration, int nFrequency, float fTime);
void DrawLineFromVectorToVector(int nDurationType, int nVFX, object oArea, vector vOne, vector vTwo, float fDuration, int nFrequency, float fTime)
{
int i;
if (nFrequency < 1) nFrequency = 1;
vector vResultant = vTwo - vOne;
vector vUnit = VectorNormalize(vResultant);
float fDelay = fTime/IntToFloat(nFrequency);
float fLength = VectorMagnitude(vResultant);
float fDelta = fLength/IntToFloat(nFrequency); // distance between each node
float fAngle = VectorToAngle(vUnit);
location lPos;
float f;
for (i=0; i<nFrequency; i++)
{
f = IntToFloat(i);
lPos = Location(oArea, vOne + fDelta*f*vUnit, fAngle);
DelayCommand(f*fDelay, ApplyEffectAtLocation(nDurationType, EffectVisualEffect(nVFX), lPos, fDuration));
}
}
I experimented with it, it does work, although, the frequencey parameter needs to be set very low, otherwise you end up with fireball effects going off like a machine gun. Better to use a value in the low 10's, opposed to default of 90.





Retour en haut







