Author Topic: Draw a line from x to y in visual effects  (Read 1008 times)

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Draw a line from x to y in visual effects
« on: May 28, 2012, 12:27:14 am »


               I've tried using the summoning circles and pentagrams package to do this.
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?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #1 on: May 28, 2012, 02:00:51 am »


               Ok, I have not seen the movie or used the package that you mentioned.  I am guessing that you are tring to find points along the line from point 'x' oSource and point 'y'  oTarget.   If that is the case, Finding the vector between the two is all you really need to do.  Like so: 

  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   
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #2 on: May 28, 2012, 02:32:57 am »


               What I found in the drawing package I'd started making was similar to what FunkySwerve had said to expect, that is, drawn lines using beams apply properly in single player, but in a multi-player environment some of them just won't even if they're doubled up.

 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.
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #3 on: May 28, 2012, 02:39:30 am »


               Thx Lightfoot - I think this will be useful.
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.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #4 on: May 28, 2012, 02:52:47 am »


               Cool,  

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 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #5 on: May 28, 2012, 04:28:12 am »


               You can multiply vectors by floats in NWScript. (e.g. vVectorInc *= fIncrement; works fine).
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #6 on: May 28, 2012, 04:38:57 am »


               Thanks Wiz, For some reason I got a compiler error the first time I tried that. Must have been a typo on my part. Updating the function above

EDIT:  Just figured out my typo.  I was tring to multiply by an int instead of a float.  'Posted
               
               

               


                     Modifié par Lightfoot8, 28 mai 2012 - 03:51 .
                     
                  


            

Legacy__six

  • Hero Member
  • *****
  • Posts: 1436
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #7 on: May 28, 2012, 09:01:38 am »


                Not sure if this will help in the slightest, but a 'Shockwave' spell was one of the spells I used when trying out my custom magic system for my module (was designed around cooldowns replacing uses/day - blasphemous I know). This version fires in the players facing direction but is a targeted spell in spells.2da, which basically allows for a limited range whilst still able to use creatures as targets to assist aiming. Here's the code, for interest's sake. The include is just for my custom feat constants.

// 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 .
                     
                  


            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #8 on: May 28, 2012, 10:07:47 am »


               Excelent
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
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #9 on: May 28, 2012, 04:07:51 pm »


               void MySpell()
{
   //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();
   }
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Draw a line from x to y in visual effects
« Reply #10 on: June 18, 2012, 10:33:28 am »


               Turns out that the Pentacles and Summoning Circles package does have the functions I need.
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.