![]() |
#1 |
LASER DRAGONS IS RELEASED
Development Moderator
User Project: Panto |
![]() Greets!
First, a confession: This isn't really for any particular project. I'm just trying to get a solid handle on the process involved in this trigger for my own education. Any help you can provide is fantastic, and I'm looking for the theoretical best answer more than the easy one. I speak jass if it is useful to answer in code. So, to it. Blizzard has a number of "wave" spells, like Carrion Swarm, Shockwave, Impale, Breath of Fire, Breath of Frost, Breath of Lemmings. Mostly these spells are pretty unfortunate: There's no way to easy "get" who the spell affected, they frequently have hardcoded targets or buffs, they lag through doodads and so on. So I'd like to understand how these spells can be coded. Firstly, one must be able to get all the units/doodads/structures or whathaveyou inside the area that you want to affect. Let's suppose that we have:
Then there's another level of complexity. This is a wave, so it should affect the closest targets first, then farther out et cetera. How do we get the widgets in slices of a certain depth of the original area, so that we may affect them in stages? It might look like this: I ought to tell you that my geometry isn't very fresh, so I welcome any amount of detail you wish to give. Thanks! |
![]() |
![]() |
Sponsored Links - Login to hide this ad! |
|
![]() |
#2 |
Two Blue
|
![]() Enum units in incrementally larger circles. Cull units who's squared distance from the caster is equal to or less than the square of the previous circle's radius. (You use squared distances to avoid needlessly computing squared roots)
__________________This gives you units in an initial circle then in rings. To cull units outside of the cone, you have to ensure the angle between the caster and target is within a certain distance (the width of the code) of the cast angle. Likely horribly suboptimal way: (My maths is subpar in this area) RAD_TO_DEG * Atan2(by-ay, bx-ax) = angle of the line ax->bx in degrees c = angle of the line caster->cast target point t = angle of the line caster->target if t - c <= 180 then d = t - c else d = (c + 360) - t endif if d <= ConeWidth / 2 then // Unit is in cone endif Last edited by Earth-Fury : 03-28-2010 at 06:18 PM. |
![]() |
![]() |
![]() |
#3 |
User
Join Date: Mar 2009
Posts: 149
![]() ![]() |
![]() Blizzard waves can be approximated by a missile with a collision size (the start area), starting at a polar projection from the caster by (start area) in the direction the spell was casted, then increase the collision size of the projectile dynamically while it travels up to the end area size.
I made a testmap for this recently Note that you can see, that blizzard's waves use an update intervall significantly less than 0.025, which xecollider uses :) (I found this to be pretty interesting when testing the map). This map was originally a test for my GroupEnumUnitsInCone function, however it proved, there was almost no use for such a function, because you can hardly tell any difference using this method or a hardcoded wave. Last edited by Kueken : 03-28-2010 at 06:22 PM. |
![]() |
![]() |
![]() |
#4 |
I blink, therefore I am.
Join Date: Sep 2006
Posts: 1,812
![]() ![]() ![]() ![]() |
![]() I would do an emum units in circle for each "slice", determine if the angle between the caster and the target is within the bounds of the wave, check if the unit is within the specified distance from the caster (in the proper slice) and then deal damage to it.
__________________To handle the time delay between slice damages, I would check the previous slice as well, for new units within the slice. |
![]() |
![]() |
![]() |
#5 | |
Procrastination Incarnate
Development Director
|
![]() The wave is most likely not shaped like a slice of a circle. First of all, wave spells can have a starting width, so it would be a slice of a ring rather than full circle or, more likely, an isosceles trapezoid (in the case of shockwave which has the same start and end width, a rectangle).
__________________Furthermore, the units affected are not grouped instantly, but as the spell projectile passes them. This can be easily demonstrated by fireing a slow wave spell towards a unit and then moving the unit out of the way and moving another unit that was outside of the affected area into the way. As such, line/cone spells are best simulated by a moving projectile which affects units in a circular area (I never tested the spells in enough detail to know if this is exactly how they work, but at worst it is still a reasonable approximation while also being the fastest method to code it) with diameter equal to the spell's width (when simulating spells that have different starting and ending width, the diamater changes as the projectile moves). xecollider, for example, can be used to simulate such spells this way. Edit: Damn it, I'm really slow at typing this, three people beat me to it. Quote:
Last edited by Anitarf : 03-28-2010 at 06:34 PM. |
|
![]() |
![]() |
![]() |
#6 | ||
User
Join Date: Mar 2009
Posts: 149
![]() ![]() |
![]() Quote:
Yes, this is exactly what I have done in the testmap, and it matches the hardcoded carrion swarm almost perfectly (for appropiate values, of course) € Sorry, Anitarf. ;) At least you linked xecollider, which I even forgot to mention ;) Oh btw, I am using onLoop for this, but I heard, this would be bad, because those interface methods are really slow (onUnitHit can/should be used, because it is not used every interval but onLoop should be avoided because its like 20 times slower than a function call or more) Is this significant enough to require special handling? (like run another timer just to do the periodic stuff) Quote:
Last edited by Kueken : 03-28-2010 at 06:44 PM. |
||
![]() |
![]() |
![]() |
#7 |
LASER DRAGONS IS RELEASED
Development Moderator
User Project: Panto |
![]() It occurs to me that there's another dimension to this idea that I want to cover. It sounds like the methods discussed are good for finding and affecting target units. I am also interested in defining an area for each slice to play spell effects within that area, should it be desirable to do so. Thoughts on this?
__________________EDIT: Earth-Fury's method touches on finding units in an area, which can be adapted to finding random points in an area for spell effects; however, is there a way to do this without first enumerating a lot of unnecessary units and then culling them out? Last edited by Panto : 03-28-2010 at 06:50 PM. |
![]() |
![]() |
![]() |
#8 |
User
Join Date: Mar 2009
Posts: 149
![]() ![]() |
![]() I am not sure, if I got you right, you want to create special effects alongside with the wave? Like a trail of effects or something? Well, probably I misunderstood, because this would be very easy when picking units in range of coordinates anyway...
Last edited by Kueken : 03-28-2010 at 06:52 PM. |
![]() |
![]() |
![]() |
#9 |
LASER DRAGONS IS RELEASED
Development Moderator
User Project: Panto |
![]() That would work, but I believe it would have some overlap as the size of the picked area increased. In other words, as the wave progresses, it will leave behind more effects in the previous area before the pick circle moves out of it. Or, perhaps I'm missing something, here.
__________________ |
![]() |
![]() |
![]() |
#10 |
User
Join Date: Mar 2009
Posts: 149
![]() ![]() |
![]() If you watch my testmap, I am using xecollider with a constant speed, so the coordinates change with a constant distance. Just the area around this increases.
If you spawn effects periodically, you would get a constant trail of effects alongside with the wave. You can always use counter variables to vary the effect spawning rate, or effects with different sizes, or whatever. Also, xecollider uses enumerations of more units, too, and sorts them out (to consider unit collision size properly). This is not a big deal usually, because every unit filtered out runs like one if statement and some calculations or, in case of xecollider the IsUnitInRangeXY native. YOu do not want to enum more units than you have to, but if you have to enumerate some more units, it is not that bad. Last edited by Kueken : 03-28-2010 at 07:06 PM. |
![]() |
![]() |
![]() |
#11 | |
Procrastination Incarnate
Development Director
|
![]() Again, for a reasonable approximation, you could create some effects in the onLoop method at random points inside the damage area, and increase the number of effects created this way as the damage area radius increases.
__________________Quote:
Last edited by Anitarf : 03-28-2010 at 07:08 PM. |
|
![]() |
![]() |
![]() |
#12 |
LASER DRAGONS IS RELEASED
Development Moderator
User Project: Panto |
![]() The map works great; you really can't tell the difference between the xecollider wave and the original.
__________________I don't speak vjass very well at all. I think this is a solution that I could implement from jass if I can sort out what's happening in the xecollider script. Is that correct? EDIT: Is it necessary to have a "moving projectile"? Can I calculate several points along the path and simply get all units near those points, inside a radius that expands from point to point? Last edited by Panto : 03-29-2010 at 08:56 PM. |
![]() |
![]() |
![]() |
#13 | |
Procrastination Incarnate
Development Director
|
![]() Quote:
|
|
![]() |
![]() |
![]() |
#15 |
User
Join Date: Mar 2009
Posts: 149
![]() ![]() |
![]() You don't need, you can just calculate points, if you want to.
Last edited by Kueken : 03-29-2010 at 09:53 PM. |
![]() |
![]() |
![]() |
Thread Tools | Search this Thread |
|
|