| 03-28-2010, 05:16 PM | #2 |
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 |
| 03-28-2010, 05:17 PM | #3 |
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. |
| 03-28-2010, 05:21 PM | #4 |
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. |
| 03-28-2010, 05:30 PM | #5 | |
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:
|
| 03-28-2010, 05:34 PM | #6 | ||
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:
|
| 03-28-2010, 05:47 PM | #7 |
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? |
| 03-28-2010, 05:51 PM | #8 |
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... |
| 03-28-2010, 05:57 PM | #9 |
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. |
| 03-28-2010, 06:01 PM | #10 |
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. |
| 03-28-2010, 06:05 PM | #11 | |
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:
|
| 03-29-2010, 07:41 PM | #12 |
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? |
| 03-29-2010, 08:39 PM | #13 | |
Quote:
|
| 03-29-2010, 08:47 PM | #14 |
If the wave doesn't have a projectile but instead uses those spawned effects, does that change your answer? |
| 03-29-2010, 08:53 PM | #15 |
You don't need, you can just calculate points, if you want to. |
