• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Missile

Level 19
Joined
Mar 18, 2012
Messages
1,716
I'm didn't read Kenny's system yet, so a link would be helpful.
Then I can tell you the differences.

You can do really a lot of things EXCEPT the things you mentioned.
Missile enumeration is not very well supported, because no-one so far requested that feature.
Instead I was asked to keep things as easy and simple as possible.

However it would be easy for me to implement what you are asking for.
The required data structure is already there, just that there is no API
for missileCollidesWithMissile, EnumMissilesOfType, EnumMissilesInRange and
GetInstanceByMissileDummy.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Thanks for the link. I'll take a look into it asap.

Edit:
So I started reading Kenny's code. It's pretty cool. It has more features. Some of them are very neat.
Personally I think the API in there is a bit more convoluted.
It's definitly worse in performance, not only due to trigger evaluations vs function calls.

Here:
http://www.hiveworkshop.com/forums/2805968-post22.html

But if you don't want Missile to have a requirement, feel free to copy the algorithm behind it.
The to do list is outdated. Rectangle collision is already in Missile.

Edit: I started making Missile v. 3.0.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
I moved Missile back to the submission section, because I literally re-wrote the entire code.

Missile 3.0 is also not backwards compatible to the previous versions.

The old version can be found here. Missile v.2.5

I still testing and optimizing the code and write the static parabola missile motion.
It will most likely be a quadratic bezier curve.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
What's so great about this version that you completely discard the already-perfect-and-awesome previous version? Did you consider to submit this one as another Missile lib, named BezierMissile or something? I don't have idea how could you throw your great work away just like that. I got a heartbreak here.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
The previous missile library had a major flaw.
It wasn't working properly in 3D space, but only in 2D.
Speed was a vector in x and y axis, but z was left out.

For example you were not able to make a jump in place missile or
a falling meteor.

Don't worry I will not delete the old missile system,
but to me it was not satisfying in the end.

I could give this library the name Projectile if people want me to.

I will write a detailed tutorial about this library soon.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Physics-based
That can be achieve by using Missile_MOTION_DRIVER_NONE.
You can set start angle, start pitch, speed, acceleration and gravity.

onPeriodic gives you loop controll if you wish to change angle, pitch, ...
in a certain phase of the missile movement.
JASS:
                static if thistype.onPeriodic.exists then
                    if this.exists then
                        static if LIBRARY_MissileCollision then
                            call this.cacheUnitPos()
                        endif
                        if thistype.onPeriodic(this) then
                            call thistype.terminateM(this)
                        endif
                    endif
                endif

onTerrain is called if the missile hits the ground.
JASS:
                static if thistype.onTerrain.exists then
                    if this.exists and this.z <= this.minFlyHeight then
                        call GetTerrainNormal(this.x, this.y, TERRAIN_TILE_RADIUS)
                        // Compute the dot product of the terrain vector and missile velocity.
                        if tempX*this.velX + tempY*this.velY + tempZ*this.velZ < 0.00 and thistype.onTerrain(this, tempX, tempY, tempZ) then
                            call thistype.terminateM(this)
                        endif
                    endif
                endif

Spline-based (or Bezier-based)
Missile_MOTION_DRIVER_BALLISTIC is the arcing movement
which is used for hardcoded warcraft projectiles.
method setArcByTime takes real tX, real tY, real tZ, real arc, real time returns nothing
and
method setArcBySpeed takes real tX, real tY, real tZ, real arcValue, real newSpeed returns nothing

Parabolic-based(simple "give start-end points and max height")
That will be Missile_MOTION_DRIVER_PARABOLA. It's not coded yet.
The parabola will be drawn via quadratic bezier equation.
 
For example you were not able to make a jump in place missile or a falling meteor.
Huh? Why not? Jump in place could be solved by using onFinish or onTerrain and re-launching the missile at reduced speed. A falling meteor was just a missile spawned at a very high starting Z? Am I missing something here?
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Huh? Why not? Jump in place could be solved by using onFinish or onTerrain and re-launching the missile at reduced speed. A falling meteor was just a missile spawned at a very high starting Z? Am I missing something here?
In the previous Missile version the speed was defined by vector components velX and velY.
Also the total distance traveled was calculated by the horizontal velocity*time.

vertical velocity ( movement in z ) was computed by pitch*distanceTraveldXY.

A meteor was de facto not possible, because if the displacement in plane xy is zero,
z doesn't alter ( z = slope*distanceXY ). I built in a mechanism to compensate that issue, by
replacing 0 xy distance with a very small value and adjusting the speed ( xy displacement per tick ) to also a very small value.

In the new code speed has 3 vector components. velX, velY, velZ.
Here you can have speed = 15 while velX = 0, velY = 0, velZ = 15.


I know that the previous Missile fits perfect for most requirements.
It's just not so perfect from an aspect of making a projectile system.
It's a bit sloppy.

I would agree on re-naming the new system I wrote to library projectile and keep the old
one as library Missile.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
I've ran into flaws in the new version. It will take time to fix them.

After some consideration I restored the previous missile library and give
the new system another name. I think they can co-exists as they are different in code.


Therefore I will first update the old Missile to a final version 2.6
with optimizations here and there.

Then I'll upload the fixed other system under the name Projectile.
 
I ran into a little issue when using collision with Missile. If a projectile is supposed to deal area damage on collision, and the collision of the struck object is quite large (like a building), then I call a GroupEnumUnitsInRange to pick everything in the projectile's detonation aoe. The problem that seems to arise is that if the radius of the GroupEnumUnitsInRange doesn't reach the center point of the building, the building doesn't get picked.

Is there a way I can remedy to this, or a function within Missile itself that addresses this?
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Wait you use GroupEnumUnitsInRange yourself instead of using the internal missile collision detection. I see.

You'll have to pick all units in collision range + MAX_COLLISION_SIZE to make sure all desired units are picked.
The largest collision size in Warcraft is the townhall pathing, which is 196.00. Unit pathing normally doesn't surpass 64.00.
Then use the IsUnitInRange(dummy, whichUnit, dummyCollision) native.
"whichUnit" has a collision size which is defined in the object editor.
The dummy has an internal collision of 0.00. That's why you need the "dummyCollision" argument.

IsUnitInRange is an internal distance comparison,
while dX and dY is the distance between x and y coordinates of unit A and unit B
and crA and crB are the obejct editor defined collision radii of unit B and unit B
and "range" is the dummyCollision argument from above

--> dX*dX + dY*dY < crA*crA + crB*crB + (range*range)
 
Wait you use GroupEnumUnitsInRange yourself instead of using the internal missile collision detection. I see.
What's the function to do that?

You'll have to pick all units in collision range + MAX_COLLISION_SIZE to make sure all desired units are picked.
The largest collision size in Warcraft is the townhall pathing, which is 196.00. Unit pathing normally doesn't surpass 64.00.
Then use the IsUnitInRange(dummy, whichUnit, dummyCollision) native.
"whichUnit" has a collision size which is defined in the object editor.
The dummy has an internal collision of 0.00. That's why you need the "dummyCollision" argument.

IsUnitInRange is an internal distance comparison,
while dX and dY is the distance between x and y coordinates of unit A and unit B
and crA and crB are the obejct editor defined collision radii of unit B and unit B
and "range" is the dummyCollision argument from above

--> dX*dX + dY*dY < crA*crA + crB*crB + (range*range)
Huh, I see. I did GroupEnumUnitsInRange and went with Missile AoE radius + Missile_MAXIMUN_COLLISION_SIZE and then checked with if IsUnitInRange(m.dummy, u, m_MissileAOE[m]) then

Seems to be working :)

I would like to know what using the internal Missile collision detection looks like. I do use the m.collision to detect onCollide, but otherwise idk how else to make use of this.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The internal collision is the check that gives you the event "A unit collides with a Missile" (the one created by the system).
You had to do the exact same check to make sure that you include units by collision.
That is what you are doing now.
 
What are you going to change in missile 2.6?

Also, a quick note to method enableHitAfter ... from the description it seems that this doesn't work if the unit was just hit? How am I supposed to add units dynamicly then? If I use it onCollide, it's already too late, isn't it?

What I'm saying is: there should be a method enableHitAfterAll, which automaticly does enableHitAfter for every unit it hits.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
I started to write a v. 2.6 of Missile, but the problem is that is would not be backwards compatible to the current version.

While I made less important minor changes here and there,
the main issue is the current create / createXYZ / createEx methods.


Currently we have:

static method create takes real x, real y, real z, real angle, real distanceXY returns Missile
This is good for a 2D scenario, but in 3D it's rather bad, because there is no pitch argument in this method.
The current createXYZ is ok, because you can derive an target angle and target pitch from its arguments.

At this time I think that the creator method should have been always like:
static method create takes real x, real y, real height, real angle, real pitch returns Missile
This creates a Missile object at pos x/y with a certain fly height, an initial yaw ( angle ) and pitch. ( There is no roll in wc3 )

Methods like:
method setTargetPos takes real x, real y, real height returns nothing
allow you to define a target position and target distance.
Eventually it would require two boolean arguments for applyTargetAngle / applyTargetPitch.

I prefer "height" over "z", because I think it's unnecessary to work with absolute z value in Warcraft.

A lot of Missile systems use vectors, simply because they are easy to modify
and calculations like dot product and projection vector can be very handy.
Another argument is that they are quite fast, because
posX + velX is faster than posX + speed*Cos(angle)*Cos(pitch)
I still want to stick to trigometric functions ( Cos / Sin ), simply because the
previous Missile version was using aswell.
Furthermore Cos(angle)*Cos(pitch)can be cached and the speed difference becomes minimal.

If I release a new Missile version, then it will not be compatible with the previous version
concerning the struct creators.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
I can't decide how to re-implement arc / curved missiles.
In my eyes there are more elegant solutions ( ? ) than the parabola function
z = (4 * h / d) * (d - x) * (x / d)

For example a quadratic bezier, which would also allow a smooth jump in place.
This however is a curve movement over time and not via speed.

Or as probably Wc3 does internally by manipulating the z speed vector component and acceleration:
set velZ = ((distance * arc) / (flyTime / 4.00) + distanceZ / flyTime ) * TIMER_TIMEOUT
set accZ = 2.00 * (distanceZ / flyTime / flyTime * TIMER_TIMEOUT * TIMER_TIMEOUT - (velZ * TIMER_TIMEOUT) / flyTime)

Or all 3 ( 4 ) options and an integer array to decided which type of core movement driver the missile should use?

Or write a new library which covers everything ( collision, MissileStruct module, etc ) but no motion phase and let the user code the missile motion by him/herself.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
That last one sounds good.
I went to go for 3d motion calculations and this is one of the reasons why.
Having a jump in my system would start with lets say 400 speed per second and a 90 degrees pitch, which would result in (0, 0, 400) as xVelocity, yVelocity, zVelocity.
The gravity would do the rest (also coded in the system ofcourse)... games have no real gravity :D
 
Level 14
Joined
Jan 16, 2009
Messages
716
I have experienced a strange bug with this system. Sometimes when creating and launching a dozen missiles at the same time (typically when creating a circle of missiles after a missile removal), a few of them will not appear. This happens at random. From my observation, they indeed are created and are launched but the travel time is instant, because some of my units would get hit by "nothing" at the same time as the circle of missiles was created.
 
Level 13
Joined
Nov 7, 2014
Messages
571
Wc3's built-in artillery (e.g Mortar Team) projectiles have an arc parameter (Combat - Attack 1 - Projectile Arc (uma1)) that seems to work like this:
when the projectile arc is set to 1.0 and the unit fires from a distance of say 500.0 units, the projectile's maximum reached height will be 500.0 units, if it fires from a distance of 1000.0 the max height will be 1000.0, etc.

Now my question is, how can I do this with Missle, i.e launch a parabolic missile that will reach a maximum height equal to that of the distance between the "initial position" and the "impact position"? I am ignoring the case when launching from lower/higher z to higher/lower z, although I suppose it should work in that case as well with a maximum height reached bigger than the distance.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The problem with that is that if the target moves, this calculation would be incorrect.
I assume that if it is set to 0.5, it would be 0.5 * distance(/2 ?) as max height.

With 2d movement calculations, this could be simple, but with 3d movement calculations, it gets really hard.
 
Level 10
Joined
Jun 17, 2014
Messages
236
why not
JASS:
method operator flightDur takes real duration returns nothing
method operator moveSpeed takes real value returns nothing

local Missile m = Missile.createXYZ(x,y,z,tx,ty,tz)
set m.flightDur = 1. // 1 second
set m.moveSpeed = 800. // Warcraft III Speed

instead of
JASS:
method flightTime2Speed takes real duration returns nothing
method setMovementSpeed takes real value returns nothing

and can you explain why static method onPeriod is running so fast on this code
JASS:
//! zinc
library Rake requires Missile
{
    private
    {
        constant integer SPELL_ID = 'plsh';
        constant string MISSILE_MODEL = "Abilities\\Weapons\\GlaiveMissile\\GlaiveMissile.mdl";
        constant real MISSILE_SCALE = 1;
        constant integer MISSILE_TOTAL = 10;
        constant real DISTANCE = 600.;
        constant real TRAVEL_DURATION = 0.5;
        constant real BASE_DAMAGE = 80.;
        constant real LEVEL_DAMAGE = 50;
        constant real COLLISION = 32;
        constant boolean DAMAGE_ONCE = false;
   
        function Damage(integer lvl) -> real{return BASE_DAMAGE + LEVEL_DAMAGE * lvl ;}
    }
    private
    {
        real time[];
        struct Rake extends array
        {
            static method onFinish(Missile m) -> boolean {return false;}
            static method onPeriod(Missile m) -> boolean
            {
                integer data = m.data;
                unit c = m.source;
                time[data] = time[data] + Missile_TIMER_TIMEOUT;
                BJDebugMsg(R2S(time[data]));
                if (time[data] >= TRAVEL_DURATION){
                    //m.origin.move(m.x,m.y,m.z);
                    //m.impact.move(GetUnitX(c),GetUnitY(c),m.z);
                }
                return false;
            }
            module MissileStruct;
        }
// ENDSTR
        function AbetXY(real x1, real y1, real x2, real y2) -> real
        {
            return bj_RADTODEG * Atan2(y2 - y1, x2 - x1);
        }
        function PolarX(real source, real distance, real angle) -> real
        {
            real x = source + distance * Cos(angle * bj_DEGTORAD);
            return x;
        }
        function PolarY(real source, real distance, real angle) -> real
        {
            real y = source + distance * Sin(angle * bj_DEGTORAD);
            return y;
        }
        function AngleFormula() -> real
        {
            integer i = MISSILE_TOTAL;
            if (i == 0)
            {
                return 0.;
            }
            if (i < 4)
            {
                return 40. / (MISSILE_TOTAL - 1);
            }
            return 80. / (MISSILE_TOTAL - 1);
        }
        function ModifyMissile (Missile m, integer lvl)
        {
            m.model = MISSILE_MODEL;
            m.scale = MISSILE_SCALE;
            m.damage = Damage(lvl);
            m.collision = COLLISION;
            time[m.data] = 0.;
            m.flightTime2Speed(TRAVEL_DURATION);
        }
        function onCast() -> boolean
        {
            unit c = GetTriggerUnit();
            real x, y, tx, ty, px, py, angle;
            Missile m;
            integer i = 0, lvl = GetUnitAbilityLevel(c, SPELL_ID);
            x = GetUnitX(c) ; y = GetUnitY(c) ; tx = GetSpellTargetX() ; ty = GetSpellTargetY();
            angle = AbetXY(x, y, tx, ty);
            if (GetSpellAbilityId() != SPELL_ID){return false;}
            for(0 <= i < MISSILE_TOTAL)
            {
                px = PolarX(x, DISTANCE, angle + (i * 1 - (MISSILE_TOTAL / 2 - 0.5)) * AngleFormula());
                py = PolarY(y, DISTANCE, angle + (i * 1 - (MISSILE_TOTAL / 2 - 0.5)) * AngleFormula());
                m = Missile.createXYZ(x, y, 50., px, py, 50);
                m.source = c;
                m.owner = GetOwningPlayer(c);
                ModifyMissile(m, lvl);
                Rake.launch(m);
            }
            return true;
   
        }
   
        function onInit()
        {
       
            trigger t = CreateTrigger();
            Cheat("iseedeadpeople");
            TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
            TriggerAddCondition(t, function onCast);t = null ;
        }
    }
}
//! endzinc

on the onPeriod method, my BJDebugMsg(R2S(time[data])); printing 6~10x faster than Missile_TIMER_TIMEOUT.
example :
actual Missile time = 1 second
time[missiledata] = 8.712 second

it makes my code going wrong, and i got confused because it :(

EDIT : the onPeriod problem is solved!
the problem is, i dont set the missile.data, so missile.data always 0.
And i'm set time[missile.data] on the onPeriod method.
 
Last edited:
Level 14
Joined
Jul 1, 2008
Messages
1,314
Hi BPower,

thank you a lot for creating this resource! I am interested in using this as it simplifies a lot without any down sides to me. I am glad, you added this excellent documentation so I can actually try to understand it. Thank you for that user-friendliness!
However I got some questions about this system which I think, you are able to answer pretty easily anyway..

Question 1----------------------------------------------------------------------------------------------
what is the purpose of the bounce method, if there is the deflect method? Is there some situation, where I would need to use that instead of deflect? (sry if this is a stupid question)

I think I do not understand it because I did not really get these 2 following methods. Sry, can you shortly explain this to me. So why do I have to use these methods and what are they doing? I am kind of confused about this after reading through the whole missile code.

JASS:
call missile.origin.move(missile.x, missile.y, missile.z)
                    call missile.impact.move(missile.x + Cos(missile.angle)*ARROW_FLY_RUN_OUT_DISTANCE, missile.y + Sin(missile.angle)*ARROW_FLY_RUN_OUT_DISTANCE, missile.z)

Do these 2 functions simply reset the start and end point of the missile? It seems so, judged from the demo code, you provided (simple spell collection, guided arrow). but why dont you deflect it there?

Question 2----------------------------------------------------------------------------------------------
I think, there is a typo in the comments about the "onItemFilter"? you wrote 2x "onDestructableFilter", but I think, the second filter should read "onItemFilter". I was not able to spot this in the code, but I hope, the typo occures only in the description? Is this even a mistake, or did I read it wrong?

// By the way, I think there are some more typos in the explanation, e.g. toogles instead of toggles


Question 3----------------------------------------------------------------------------------------------
So, by reading the code and your explanation, it is pretty clear, we do not want unit indexers to recognize missiles, and you kindly provided
JASS:
/**
    *   Unit indexers and missiles ( Only if you don't use a dummy recycling library )
    *   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    *   It is most likely intended that projectiles don't run through a unit indexing process.
    *   ToogleUnitIndexer runs:
    *       • Directly before a dummy is created.
    *       • Directly after dummy unit creation.
    *
    *   Please return the previous setup of your indexing tool ( enabled, disabled ),
    *   so Missile can properly reset it to the original state.
    */
    private function ToogleUnitIndexer takes boolean enable returns boolean
        local boolean prev = true//UnitIndexer.enabled
        // set UnitIndexer.enabled = enable
        return prev
    endfunction

But I do not really understand, how I would link that hypothetical unit indexer to missile. I actually do not use any unit indexer, so I wondered, whether the enabled/disabled state of the indexer can be dynamic, or would I simply add true or false like in the presets?
Sry, I am confused right there, could you simply put an example? Would it be
JASS:
private function ToogleUnitIndexer takes boolean enable returns boolean
        local boolean prev = UnitIndexer.enabled
        set UnitIndexer.enabled = enable
        return prev
    endfunction

Question 4----------------------------------------------------------------------------------------------
Phew, so this is the last question, thanks for reading all that.
It is short: When I copy over MissileRecycler by Bribe, do I have to follow the instructions for implementing it, or does missile do that for me? I guess, I have to follow the instructions, right? And, I assume, that the 'dumi' unit is the same correct one, that is needed for both systems, is that correct?

Thanks for any answers and best regards
 
Last edited:
I have a question about the missile speed - how do the values work? If I look at the projectile speed of the sorceress, it's 900, so it covered 900 units in 1 second. But how does Missile handle speed? A value of 40 seems much faster than the 900 of the sorceress, but it also doesn't look like it's updating the x/y of the missile by 40 units every .03125 seconds. Can you shed some light on this? I need to know the unit of speed to be able to calculate other stuff.
 
JASS:
real      speed       // Vector lenght for missile movement in plane x / y. ( DOES NOT TAKE THE TIMER TIMEOUT IN ACCOUNT )




            method flightTime2Speed takes real duration returns nothing
            //  • Converts a fly time to a vector lenght for member "speed".
            //  • Does not take acceleration into account. ( Disclaimer )
        
            method setMovementSpeed takes real value returns nothing
            //  • Converts Warcraft III movement speed to a vector lenght for member "speed".
^Those might be interesting for you.


40 per tick is faster than 900, or I misunderstand something? 32x40 = 1280 (per second)
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
@Emm-A-

Q1: Method bounce, in short, resets the missile's traveled distance. It's useful for bouncing missile spell like dota's paralyzing cask, you determine the next "impact" position by your self (for instance to the next target unit position) using the call impact.move(x, y, z) method. While method deflect is useful for, well, deflecting missiles. It calculates the new impact point for you depending on the collision point of the missile and the object (unit/wall/etc), passed as parameter x & y. deflectEx allows you to determine the new impact z, useful for bouncing linear trajectory missiles, and maybe something else.

Q3: If you don't use any UnitIndexer then you don't need to touch that part. Different indexers probably have different approach to disable indexing (can be using boolean variable/function/ or method). I think his example is using Nestharus' UnitIndexer. If you use other indexer then you can ask me or moderator about how to edit that part, since BPower isn't active atm.

Q4: You only need to add locust ability to the DummyRecycler's dummy in the object editor, in case it doesn't have one yet.

That being said, how do I call these methods? Missile.flightTime2Speed(value) doesn't work. I'm still pretty fuzzy on a lot of the details pertaining to structs.
It's a non-static method so you have to call it of your missile instance.
JASS:
Missile m = Missile.create(...)
// Use this instad of m.speed = 600.
call m.setMovementSpeed (600.) // Use object editor's speed time scale
 
Last edited:
Apologies for necromancy, but I've ran into a little issue that I'm hoping can be resolved. When I call .createXYZ, the missile pitches up and down as it arcs properlly, but when I do .createEx it doesn't. I'm using my own unit instead of the normal dummy because A) I need that missile to be vulnerable and B) I'd like it to have team colour. Since this system requires the dummy.mdx model, I'm assuming it needs this becuase there's something specific about that that enables Missile to make the model pitch, so my custom missile is using dummy.mdx as a base model and uses an ability as the special effect that can be team coloured. Any insight as to how I fix this?
 
Well... the pitching issue seems to have resolved itself for no reason whatsoever, so I'm still very confused, but I do have another problem now.
JASS:
        //onFinish
        private static method onFinish takes Missile m returns boolean
            if m.data == 1 then
                set m.arc               = 20. * bj_DEGTORAD
                set m.acceleration      = .35
                set m.data              = 0
                call m.deflectEx(X[m], Y[m], 0.)
                return false
            else
                call DestroyEffect(AddSpecialEffect(OWL_IMPACT_EFFECT, m.x, m.y))
                //call UnitApplyTimedLife(m.dummy, 'BTLF', .01)
                return true
            endif
        endmethod
It is my understanding that m.deflectEx will call bounce, which will reset the distance travelled... but it doesn't appear to reset the state of being onFinish, so the moment m.data is set to 0, it immediately calls onFinish again and destroys the missile. How can I stop this from happening? I'm trying to make the missile travel in a straight line and 600. units from impact it will pitch downwards and dive into the ground. I'm trying to do this by calculating the initial 'impact' location and then telling the missile to deflect to the actual impact when it reaches its first 'impact' point.

EDIT: After testing things out a bit more, I just ended up calling Missile.createEx() after destroying the first instance instead of fiddling with m.impact.move() (which was causing the missile to shoot straight down without any arc).
It's working nicely now:

 
Last edited:

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
There are many systems and snippets present in Jass Resources subforum that need an update or upgrade.
I've spoken with Ralle about the possibility of "filter" feature addition on this subforum and some categorization (division of threads to specific categories e.g. events, utils, containers).
Problem is, Ralle does not have much time currently, i.e. he has higher priority task related to THW than this.

This doesn't mean @IcemanBo or other moderators can't step in and fix at least some of the issues. Being idle or doing nothing is the worst thing we can do.
I could fix some of these, though I'm still in-process of fixing mine (that's why 1st page slowly becomes Bannar page because none updates their scripts).

However, without categorization and updating old resources, this subforum (Jass) is dead for any new user. One needs to ask too many questions, ask for everything, be unsure if this or that is working or not.
TLDR: DEAD subforum. Cries for help.
 
Hmm, I see. I had thought projectile systems would get special attention due to the sweet new natives that came with the new patches, allowing users to finally move special effects without the overhead of using units. I'll take a look and see if I can jerry-rig something for special effects inside of Missile, though I'm not very confident my vJass-fu will be up to task.

Thanks for your updates though. Much appreciated :)
 
Top