| 03-07-2010, 08:53 PM | #1 |
Hey I worked on simulating Blizzard's cone spells (like carrion swarm) exactly. I created a kind of GroupEnumUnitInCone function, which enums units in a cone shape, just like the hard-coded spells. Usage would be something like this JASS:
call GroupEnumUnitsInCone(ENUM_GROUP,startx,starty,startarea,endx,endy,endarea,filter)
Since this is not that easily achieved for a triggered shockwave or something (at least not exactly, I wanted to make this working as close as possible to hard-coded cone spells. Well maybe there is a much easier solution to get the exact hardcoded cone behavior and I am just overcomplicating things, dunno ;)). However, I thought this might be useful for someone. So my question is now: Should I try and submit a script with this? Or not worth the effort? Or maybe something similar already exists and I did not find it. In case, someone is interested, this is the code until now (not perfect for sure, but I appreciate suggestions of any kind). Zinc://! zinc library UnitsInCone requires optional xebasic,optional GroupUtils { constant real MAX_COLLISION = 197; struct Data { static real maxCollision; static rect tempRect=Rect(0,0,0,0); static boolexpr filter; static thistype temp; static group tempGroup; real x,y,dxn,dyn,width1,width2,l; group g; boolean hasFilter; static method add(group cg, real cx1, real cy1, real cx2, real cy2, real cwidth1, real cwidth2,boolexpr cfilter) { thistype this=thistype.allocate(); real bonus=RMaxBJ(cwidth1,cwidth2)+maxCollision,dx,dy; g=cg; x=cx1; y=cy1; dx=cx2-x; dy=cy2-y; l=SquareRoot(dx*dx+dy*dy); dxn=dx/l; dyn=dy/l; width1=cwidth1; width2=cwidth2; hasFilter=(cfilter!=null); if (dx>0) { if (dy>0) SetRect(tempRect,x-bonus,y-bonus,cx2+bonus,cy2+bonus); else SetRect(tempRect,x-bonus,cy2-bonus,cx2+bonus,y+bonus); } else { if (dy>0) SetRect(tempRect,cx2-bonus,y-bonus,x+bonus,cy2+bonus); else SetRect(tempRect,cx2-bonus,cy2-bonus,x+bonus,y+bonus); } temp=this; GroupEnumUnitsInRect(tempGroup,tempRect,And(filter,cfilter)); } static method onInit() { static if (LIBRARY_xebasic) maxCollision = XE_MAX_COLLISION_SIZE; else maxCollision = MAX_COLLISION; static if (LIBRARY_GroupUtils) tempGroup = ENUM_GROUP; else tempGroup = CreateGroup(); filter=Condition(static method()->boolean { thistype this=temp; unit u=GetFilterUnit(); real d=(GetUnitX(u)-x)*dxn+(GetUnitY(u)-y)*dyn,cx,cy,width; boolean b=false; if (d<=0) d=0; else if (d>=l) d=l; cx = x+d*dxn; cy = y+d*dyn; width = width1+((width2-width1)/l)*d; if (IsUnitInRangeXY(u,cx,cy,width)) { GroupAddUnit(g,u); b=true; } u=null; return b && hasFilter; }); } } public function GroupEnumUnitsInCone(group whichGroup, real startx, real starty, real startwidth, real endx, real endy, real endwidth,boolexpr filter) { GroupClear(whichGroup); Data.add(whichGroup,startx,starty,endx,endy,startwidth,endwidth,filter); } public function GroupUnitsInCone(group whichGroup, real startx, real starty, real startwidth, real endx, real endy, real endwidth) { GroupClear(whichGroup); Data.add(whichGroup,startx,starty,endx,endy,startwidth,endwidth,null); } } //! endzinc The struct is not needed desparately, but I think it is cleaner to submit the struct per global than use single globals for every data needed. I can change that, though. This thread is mainly to receive feedback, if this is needed and ever has a chance of approval, but improvement suggestions are appreciated as well :) I made a simple testmap for demonstration, simulating a carrion swarm, which behaves almost exactly like the original one. If someone is interested, I can upload the map as well. |
| 03-10-2010, 12:19 PM | #2 |
As far as I know, WC3 cone spells do not affect all the units in the cone instantly, but as the spell projectile reaches them. As such, a projectile system like xecollider is a much better simulator of such spells than picking all the units in the cone instantly. |
| 03-10-2010, 09:45 PM | #3 |
You could project a missile (using xe, or other methods) and increase its area of effect as it travels, so that when its at the beginning it will affect a small area and as it reaches the end of its effect the area would be significantly larger. This would result in a "rounded" cone. I really don't know if Blizzard's "spray" spells have rounded edges or they are completely "square". I highly doubt they're completely square-edges. |
| 03-10-2010, 10:08 PM | #4 |
JASS:GroupClear(whichGroup); Data.add(whichGroup,startx,starty,endx,endy,startwidth,endwidth,null); |
| 03-10-2010, 10:22 PM | #5 | |||
Quote:
Quote:
Quote:
@ all: Like stated, I do not know, if this is needed, and the code is not perfect. Well, I just compared with using xecollider with a dynamic collision size, and there is a small difference, but for most ppl it will be negligible, so this function is most likely unneeded at all. |
| 03-11-2010, 05:12 PM | #6 |
Pick all units within X range from a point and then check to see if each of them is between the angles? |
| 03-11-2010, 07:31 PM | #7 | |
Quote:
|
| 03-11-2010, 11:14 PM | #8 |
Ye, I am sorry polluting the T/S with this. In fact, its pretty useless. Can be closed/graveyarded/deleted/left alone, what you prefer ;). The only use for this would be an instant breath spell, for all other situations there are better solutions, as you stated. So, even in my opinion now, it is far too situational to submit it as a script. |
