| 05-21-2009, 11:45 AM | #1 |
JASS:scope Whirlpool initializer Init globals private constant integer SPELL = 'A011' private boolexpr b endglobals private struct data static data TEMP static timer TIMER = CreateTimer() static integer Count = 0 unit caster real lx real ly static method WhirlCheck takes nothing returns boolean local data this = .TEMP return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(.caster)) and GetWidgetLife(GetFilterUnit()) > 0.0451 endmethod static method create takes nothing returns data local data d = data.allocate() local Unit c local unit u local location L = GetSpellTargetLoc() set d.lx = GetLocationX(L) set d.ly = GetLocationY(L) set d.caster = GetTriggerUnit() set d.TEMP = d call GroupClear(ENUM_GROUP) call GroupEnumUnitsInRange(ENUM_GROUP,d.lx,d.ly,400,b) loop set u = FirstOfGroup(ENUM_GROUP) exitwhen u == null set c = Unit.create(u,GetPointDist(d.lx,d.ly,GetUnitX(u),GetUnitY(u))) call GroupRemoveUnit(ENUM_GROUP,u) endloop return d endmethod method onDestroy takes nothing returns nothing endmethod endstruct struct Unit extends data static group Hit unit target real radius real angle real cos real sin static method create takes unit target, real radius returns Unit local Unit c = Unit.allocate() local data d set c.target = target set c.radius = radius set c.angle = 0. * bj_DEGTORAD set c.cos = Cos(c.angle) set c.sin = Sin(c.angle) call GroupAddUnit(c.Hit,target) if d.Count == 0 then call TimerStart(d.TIMER,0.03,true,function Unit.Spiral) endif set d.Count = d.Count + 1 set Unit[target] = c return c endmethod static method Move takes nothing returns nothing local data c local Unit this = Unit[GetEnumUnit()] local unit u = GetEnumUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real cx = 0. local real cy = 0. set .angle = ((.angle * bj_RADTODEG) + 0.03) * bj_DEGTORAD set .cos = Cos(.angle) set .sin = Sin(.angle) set cx = x + 20 * .cos set cy = y + 20 * .sin call SetUnitPosition(u,cx,cy) if .angle*bj_RADTODEG >= 360 then set .radius = .radius - 80 endif if .radius <= 0.00 then call .destroy() set c.Count = c.Count - 1 if c.Count < 0 then call PauseTimer(c.TIMER) endif endif set u = null endmethod static method Spiral takes nothing returns nothing local Unit c if c.Hit != null then call ForGroup(c.Hit,function Unit.Move) elseif c.Hit == null then call PauseTimer(.TIMER) endif endmethod method onDestroy takes nothing returns nothing call GroupRemoveUnit(.Hit,.target) endmethod implement AutoData endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Actions takes nothing returns nothing local data d = data.create() endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(t, function Actions ) call TriggerAddCondition(t,Condition(function Conditions)) set b = Filter(function data.WhirlCheck) endfunction endscope Whenever I cast the spell, wc3 crashes. The spell is a targetting image of 400 AOE. This spell uses GroupUtils & AutoIndex. Some might ask why am I using 2 structs because each unit's radius varies from distance between the unit and the target point. I suspect it has something to do with the struct Unit though. If possible, can anybody tell me a better approach to this? |
| 05-21-2009, 11:59 AM | #2 |
What this spell should do?? |
| 05-21-2009, 01:09 PM | #3 | |
Quote:
|
| 05-21-2009, 01:55 PM | #4 |
This spell creates a "whirlpool" and then pick every unit within x radius and then spiral them to the centre. Updated stuffs Aye, I rewrote the whole crap and tell me if this is good? JASS:scope Whirlpool initializer Init globals private constant integer SPELL = 'A011' private boolexpr b endglobals private struct data static data TEMP static timer TIMER = CreateTimer() static integer Count = 0 static data array D unit caster real lx real ly group g real array angle[8190] real array radius[8190] static method WhirlCheck takes nothing returns boolean local data this = .TEMP return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(.caster)) and GetWidgetLife(GetFilterUnit()) > 0.0451 endmethod static method create takes nothing returns data local data d = data.allocate() local unit u local location L = GetSpellTargetLoc() set d.lx = GetLocationX(L) set d.ly = GetLocationY(L) set d.caster = GetTriggerUnit() set d.TEMP = d set d.g = NewGroup() call GroupClear(ENUM_GROUP) call GroupEnumUnitsInRange(ENUM_GROUP,d.lx,d.ly,400,b) loop set u = FirstOfGroup(ENUM_GROUP) exitwhen u == null call GroupAddUnit(d.g,u) set d.angle[GetUnitId(u)] = 0. set d.radius[GetUnitId(u)] = GetPointDist(GetUnitX(u),GetUnitY(u),d.lx,d.ly) set data[u] = d call GroupRemoveUnit(ENUM_GROUP,u) endloop if d.Count == 0 then call TimerStart(d.TIMER,0.03,true,function data.Periodic) endif set d.D[d.Count] = d set d.Count = d.Count + 1 return d endmethod static method spiral takes nothing returns nothing local data this = data[GetEnumUnit()] local unit u = GetEnumUnit() local real x = GetUnitX(u) local real y = GetUnitY(u) local real cos = Cos(.angle[GetUnitId(u)]) local real sin = Sin(.angle[GetUnitId(u)]) local real cx = x + 10 * cos local real cy = y + 10 * sin call SetUnitPosition(u,cx,cy) set .angle[GetUnitId(u)] = ((.angle[GetUnitId(u)] * bj_RADTODEG) + 10)* bj_DEGTORAD if .radius[GetUnitId(u)] <= 0.00 then call GroupRemoveUnit(.g,u) endif set .radius[GetUnitId(u)] = .radius[GetUnitId(u)] - 2 set u = null endmethod static method Periodic takes nothing returns nothing local integer i = 0 local data this loop exitwhen i >= .Count set this = .D[i] call ForGroup(.g,function data.spiral) if FirstOfGroup(.g) == null then set .Count = .Count - 1 if .Count > 0 then set .D[i] = .D[.Count] set i = i - 1 else call PauseTimer(.TIMER) endif endif set i = i + 1 endloop endmethod method onDestroy takes nothing returns nothing endmethod implement AutoData endstruct private function Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL endfunction private function Actions takes nothing returns nothing local data d = data.create() endfunction //=========================================================================== private function Init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddAction(t, function Actions ) call TriggerAddCondition(t,Condition(function Conditions)) set b = Filter(function data.WhirlCheck) endfunction endscope Ok basically right now when the unit complete a circle and they stop which isn't supposed to be untill radius is lesser than or equal to 0. I know those arrays suck but anyone has a better idea? EDIT: They don't seem to be circling at a radius that I want them to circle, any clues? |
