• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Detect ability hit

Status
Not open for further replies.
Level 7
Joined
Nov 19, 2015
Messages
283
I have a target based spell that throws a missile at a target. I need to detect when the missile makes contact.

I don't want a missile system as the spell is aimed at a sliding dummy missile which is small and moving very fast.

I have tried using sphere however it isn't working for me, so if someone has some ideas on why it isn't working.

As a last resort I might have to change it to a spell that deals a tiny amount of damage and use damage detection. I would prefer not having to do so.
 
As Zwiebelchen said there are already existing solutions but you dont want to use any of them
1)use an ability that places buff on target unit which fires damage take event with 0 damage
2)missile system

Others methods are based on calculating approximate travel time of missile but they are nnot good
 
His reason for not using a missile system is actually legit...
All missile systems (or not :D) use the GroupEnumUnitsInRange() method on the location of the missile... which doesnt work properly if the width is too low or the missile is moving too fast...

Luckily for you, my missile system has a rectangular collision detection :D
It draws a line from your old position to your new position and creates an angled rectangle with the width that you chose away from that line.

I still have to use target collision detection which only checks the distance between the target and the missile... but I thought it didnt have any use for it.


If you really dont want to use a missile system, you can create a dummy unit and store the original caster and ability id in arrays under the index of that dummy unit.
(Make the dummy unit have a long expiration time... 10-20)
Then, when a unit takes damage (DDS), you can check if the source is a dummy, then change the source to the original source and you will have the damage-impact moment with the ability id.
 
BETABABY created a similar thread, the responses seemed useful.
Does that help?
Not a fan of the timer thingy calculated using backswing time and such

They actually are good, but only if the object you want to check for has a predictable path that can not be altered by the player.
Pathing is not predictable

Luckily for you, my missile system has a rectangular collision detection :D
It draws a line from your old position to your new position and creates an angled rectangle with the width that you chose away from that line.

If you really dont want to use a missile system, you can create a dummy unit and store the original caster and ability id in arrays under the index of that dummy unit.
(Make the dummy unit have a long expiration time... 10-20)
Then, when a unit takes damage (DDS), you can check if the source is a dummy, then change the source to the original source and you will have the damage-impact moment with the ability id.

I like the compare distance to the line idea and might try to do something similar in my missile system. I use a timer of 0.01 seconds as my missiles are really small and have high speeds. This will allow me to use a timer of 0.03 seconds and improve the performance of the map.

If you only care about when it hits you can use this trick: https://www.hiveworkshop.com/forums/lab-715/damaging-spell-detection-265036/

Had a look and I guess it basically uses damage detection. I was hoping I wouldn't have to use damage detection.

Just a quick question. Does having multiple damage event triggers slow down the map? Should I have a unit group and turn the trigger off when the group = 0?
 
Damage detection systems typically work regardless of whether you have any triggers currently registered to them. For the one that I use the reason is simple - it breaks spell damage for the sake of telling it apart from physical, so it has to compensate for that.

But typically damage detection systems are quite cheap to keep running in the background, so it's fine.
 
Just another quick question. When you use pick all units in range.
Does this use the center point of the unit or if any part of the unit is within the range?
 
I like the compare distance to the line idea and might try to do something similar in my missile system. I use a timer of 0.01 seconds as my missiles are really small and have high speeds. This will allow me to use a timer of 0.03 seconds and improve the performance of the map.

There is no reason for having something lower than 0.03... 0.03125 is also used often because it is a proper division of 1.
0.04 is kind of the maximum and 0.05 if you really need a lightweight system.
Everything lower like 0.02 or 0.01 is just a waste of cpu.

If you are interested in how I deal with my missiles, collision detection and other stuff, I recommend you to try the system out and setting massive speed missiles.

Just another quick question. When you use pick all units in range.
Does this use the center point of the unit or if any part of the unit is within the range?
All unit enumerations use the center point of a unit.
I could easily write a library to enumerate units using the unit's collision size multiplied with their scaling value but it would be quite heavy for something like this.
 
I don't understand jass so I can't really understand your custom missile system.

If you could explain the detection part and if it would be possible in GUI, that would be nice.

Also for the damage detection, do I need a spell that deals damage. I use the Bribe's DDS and wondering if it will detect 0 damage spells.
 
It is possible in GUI... but it is quite a pain.
I basically pick every unit in a region and check if they are inside a rectangle that I calculated before... you could use my missile system in addition to what you have now.
Missile Systems should not have problems when used together.

Bribe's DDS does detect 0 damage but I recommend you to just make it deal damage and then set the damage value to 0.
But to detect 0 damage events, you still have to have a damaging spell.
 
How do you get the 0.03125? Do I have to do something to get more decimal points?

How do you calculate this rectangle. I don't really want to include a system that I can't really understand what is going on. I'm trying to learn jass slowly but your system is too advanced for me atm.

I assume you use your great knowledge off mathematics to calculate this rectangle using x,y coordinates based of the angle and max distance traveled.
 
To get a "accurate" real value, you can simply do 1/32 (=0.03125), but 0.03 should be fine.
At best, it saves you 3.0303...% performance... which is not much.

I simply make 5 variables:
x,y coordinates of the center point of the rectangle.
width and height of the rectangle.
angle where the rectangle is facing to.
(The width is twice the radius of your collision and the height is the width + the traveled distance.)

Then I translate the x,y of the unit in the same angle and check if the new values are within a perpendicular rectangle's bounds.
 
Im a jass noob but from what I get.

You create the rectangle with SetRect(RECT,X-r,Y-r,X+r,Y-r)

You check if they are in the rectangle with:
call GroupEnumUnitsInRect(udg_group, RECT, null)

Where are you rotating the rectangle you have created?
Is it - IsPointAngledRectangleRad(....)


Currently my trigger selects all units within X range (circle). I want it to select all units in a square. Would you be able to make a trigger for me so that it selects all units in a square and puts them into a unit group? Please and thank you.
 
I dont create any rect :D
Same as with locations, it is better to use only one and move it by using MoveLocation() or SetRect().

But in any case, yes, I use that to group all units in the rectangle.
A rect is always a straight rectangle.
That rect is the boundaries of my angled rectangle:
XkekPKG.png

The blue rectangle is my rectangle.
The red rect is the bounds.
The gray stuff is the ground.
The black lines are the X and Y axis.

I pick every unit in that red rect and then check if their position is inside the blue rectangle by using that IsPointInAngledRectangle().
(Rad is merely something to have a function that calculates it for radians.)
I set 5 variables that will define how the rectangle looks like:
RA (Rectangle Angle)
RX (Rectangle Center X)
RY (Rectangle Center Y)
RW (Rectangle Width)
RH (Rectangle Height)

So:
iaRoeN7.png


Angle can be defined in different ways.
Degrees (0 - 360)
Radians (0 - TAU)
Percents (0 - 100)
Factors (0 - 1)
And more depending on how you use directions.
If you copy and paste the BasicFunctions library to your map, you can use the function
"GroupEnumUnitsInRectangleRad()",
"GroupEnumUnitsInRectangleDeg()" and
"GroupEnumUnitsInRectangle()".
(GroupEnumUnitsInRectangle() is the same as GroupEnumUnitsInRectangleDeg().)

You give them parameters
whichGroup (group): a unit group that will be filled.
x (real): the center x
y (real): the center y
width (real): the width
height (real): the height
angle (real): the angle in Radians/Degrees

That function will return the whichGroup again.

To do this in GUI, you pretty much want to store all those 5 real values in variables and use the variables in a custom script calling that function:
"Custom Script: set udg_MyGroup = GroupEnumUnitsInRectangleDeg(CreateGroup(), udg_X, udg_Y, udg_W, udg_H, udg_A)"
 
Last edited:
Ok, I will try this and get back to you.

How the heck do you come up with this stuff in the first place? I assume you made the whole system by yourself.
 
Status
Not open for further replies.
Back
Top